ContentService的两大作用
android平台数据更新的执行者
android平台数据同步服务的管理中枢
目录
数据更新机制
数据同步机制之AccountManagerService
数据同步机制之SyncManager
ContentObserver概览
1.数据更新机制
通知机制的实施包括两个部分:
第一是:注册观察者
第二是:数据改变时通知观察者
在android平台中,这两个部分都离不开ContentService
1.1对ContentService的认识:ContentService创建的过程
概述:在SystemServer中调用ContentService的静态main方法来创建一个ContentService实例,并调用systemReady实例方法创建SyncManager。
继承关系:ContentService继承自 IContentService.Stub
IContentService.Stub继承自Binder并实现了IContentService接口
public final class ContentService extends IContentService.Stub
public static abstract class Stub extends android.os.Binder
implements android.content.IContentService
第一个:SystemServer中调用ContentService的静态main函数创建ContentService,并调用systemReady函数来确定调用SyncManager是否成功
public void run{
...//
contentService = ContentService.main(context,
factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);
...
try {
if (contentService != null)
contentService.systemReady();
} catch (Throwable e) {
reportWtf("making Content Service ready", e);
}
}
第二个:ContentService的静态main函数调用构造函数创建ContentService对象实例,并把该对象实例添加给ServiceManger
public static ContentService main(Context context, boolean factoryTest) {
ContentService service = new ContentService(context, factoryTest);
ServiceManager.addService(ContentResolver.CONTENT_SERVICE_NAME, service);
return service;
}
第三个:ContentService 的构造函数和systemReady函数
ContentService(Context context, boolean factoryTest) {
mContext = context;
mFactoryTest = factoryTest;
}
public void systemReady() {
getSyncManager();
}
第五个:getSyncManager函数
private SyncManager getSyncManager() {
synchronized(mSyncManagerLock) {
try {
// Try to create the SyncManager, return null if it fails
if (mSyncManager == null)
mSyncManager = new SyncManager(mContext, mFactoryTest);
} catch (SQLiteException e) {//创建异常
Log.e(TAG, "Can't create SyncManager", e);
}
return mSyncManager;
}
}
1.2ContentResolver的registerContentObserver分析:更新机制的第一部分注册ContentObserver
1:ContentResolver的registerContentObserver
该方法会调用getContentService.registerContentObserver方法
uri:客户端设置的需要监听的数据项地址
notifyForDescendents:true则所有包含uri的数据发生变化都会触发通知,否则只有uri指定数据改变的会触发通知
observer:监听对象,当监听的数据发生改变时,该对象的onChange方法会被调用
public final void registerContentObserver(Uri uri, boolean notifyForDescendents,
ContentObserver observer, int userHandle)
{
try {
getContentService().registerContentObserver(uri, notifyForDescendents,
observer.getContentObserver(), userHandle);
} catch (RemoteException e) {
}
}
2:getContentService方法
从ServiceManager中根据字符串CONTENT_SERVICE_NAME去获取ConentService实例对象
在ContentService 的main方法中,执行完ContentService 的构造函数之后有这样一行代码
ServiceManager.addService(ContentResolver.CONTENT_SERVICE_NAME, service);
也就是将CONTENT_SERVICE_NAME和contentService对象相关联
public static IContentService getContentService() {
if (sContentService != null) {
return sContentService;
}
IBinder b = ServiceManager.getService(CONTENT_SERVICE_NAME);
if (false) Log.v("ContentService", "default service binder = " + b);
sContentService = IContentService.Stub.asInterface(b);
if (false) Log.v("ContentService", "default service = " + sContentService);
return sContentService;
}
3:observer.getContentObserver()
返回的是一个Transport类的对象实例
该类继承自IConentObserver.Stub
而IConentObserver.Stub继承了Binder同时实现了IConentObserver
所以Transport类用于Binder通信
public IContentObserver getContentObserver() {
synchronized (mLock) {
if (mTransport == null) {
mTransport = new Transport(this);
}
return mTransport;
}
}
4:ContentService 的registerContentObserver
这里实现的功能是:保存uri和observer的对应关系到其内部变量mRootNode中
mRootNode的类型是ObserverNode,ObserverNode的组织形式是树,其叶子节点是ObserverEntry,它保存了uri和对应的IContentObserver对象
@Override
public void registerContentObserver(Uri uri, boolean notifyForDescendants,
IContentObserver observer, int userHandle) {
...
synchronized (mRootNode) {
mRootNode.addObserverLocked(uri, observer, notifyForDescendants, mRootNode,
Binder.getCallingUid(), Binder.getCallingPid(), userHandle);
...
}
}
1.3ContentResolver的notifyChange分析:更新机制的第二部分通知
通知由ContentResolver的notifyChange触发
1ContentResolver的notifyChange会调用ContentService的notifyChange
public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork,
int userHandle) {
try {
getContentService().notifyChange(
uri, observer == null ? null : observer.getContentObserver(),
observer != null && observer.deliverSelfNotifications(), syncToNetwork,
userHandle);
} catch (RemoteException e) {
}
}
2 ContentService的notifyChange方法
@Override
public void notifyChange(Uri uri, IContentObserver observer,
boolean observerWantsSelfNotifications, boolean syncToNetwork,
int userHandle) {
try {
ArrayList calls = new ArrayList();
synchronized (mRootNode) {//从根节点开始搜索所有需要通知的观察者,结果保存在calls中
mRootNode.collectObserversLocked(uri, 0, observer, observerWantsSelfNotifications,
userHandle, calls);
}
final int numCalls = calls.size();
for (int i=0; i
2.数据同步机制之AccountManagerService
AccountManagerService负责管理手机中的online账户,主要涉及账户的添加和删除,authtoken的获取和更新等
authtoken:有了authtoken,客户端无须每次操作都想服务器发送密码
2.1认识AccountManagerService
2.1.1AccountManagerService的创建
1:在SystemServer中:和ContentService的创建基本一样,不同的是ContentService是调用main方法来创建,因为创建之后还初始化了SyncManager
try {
accountManager = new AccountManagerService(context);
ServiceManager.addService(Context.ACCOUNT_SERVICE, accountManager);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Account Manager", e);
}
2: AccountManagerService的构造方法
public AccountManagerService(Context context) {
this(context, context.getPackageManager(), new AccountAuthenticatorCache(context));
}
public AccountManagerService(Context context, PackageManager packageManager,
IAccountAuthenticatorCache authenticatorCache) {
mContext = context;
mPackageManager = packageManager;
mMessageThread = new HandlerThread("AccountManagerService");
mMessageThread.start();
mMessageHandler = new MessageHandler(mMessageThread.getLooper());
mAuthenticatorCache = authenticatorCache;
mAuthenticatorCache.setListener(this, null /* Handler */);
sThis.set(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
intentFilter.addDataScheme("package");
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context1, Intent intent) {
purgeOldGrantsAll();
}
}, intentFilter);
IntentFilter userFilter = new IntentFilter();
userFilter.addAction(Intent.ACTION_USER_REMOVED);
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
onUserRemoved(intent);
}
}, userFilter);
}
2.1.2 AccountAuthenticatorCache的分析
AccountAuthenticatorCache是android authenticator service的管理中心
大致的功能就是通过PMS分析所有指定的action和metadata的service,并记录这些service的uid和type(账户类型)到指定文件中(pms的数据更新是通过RegisteredAutheticator注册观察者来实现数据更新)
(data/system/resigered_services/android.accounts.AccountAuthenticator.xml)
2.1.2.1 AuthenticatorDescription 源码
public class AuthenticatorDescription implements Parcelable {
final public String type;
final public int labelId;
final public int iconId;
final public int smallIconId;
final public int accountPreferencesId;
final public String packageName;
final public boolean customTokens;
public AuthenticatorDescription(String type, String packageName, int labelId, int iconId,
int smallIconId, int prefId, boolean customTokens) {
if (type == null) throw new IllegalArgumentException("type cannot be null");
if (packageName == null) throw new IllegalArgumentException("packageName cannot be null");
this.type = type;
this.packageName = packageName;
this.labelId = labelId;
this.iconId = iconId;
this.smallIconId = smallIconId;
this.accountPreferencesId = prefId;
this.customTokens = customTokens;
}
private AuthenticatorDescription(Parcel source) {
this.type = source.readString();
this.packageName = source.readString();
this.labelId = source.readInt();
this.iconId = source.readInt();
this.smallIconId = source.readInt();
this.accountPreferencesId = source.readInt();
this.customTokens = source.readByte() == 1;
}
/** @inheritDoc */
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(type);
dest.writeString(packageName);
dest.writeInt(labelId);
dest.writeInt(iconId);
dest.writeInt(smallIconId);
dest.writeInt(accountPreferencesId);
dest.writeByte((byte) (customTokens ? 1 : 0));
}
/** Used to create the object from a parcel. */
public static final Creator CREATOR =
new Creator() {
/** @inheritDoc */
public AuthenticatorDescription createFromParcel(Parcel source) {
return new AuthenticatorDescription(source);
}
/** @inheritDoc */
public AuthenticatorDescription[] newArray(int size) {
return new AuthenticatorDescription[size];
}
};
}
2.1.2.2 AccountAuthenticatorCache源码
public static final String ACTION_AUTHENTICATOR_INTENT =
"android.accounts.AccountAuthenticator";
public static final String AUTHENTICATOR_META_DATA_NAME =
"android.accounts.AccountAuthenticator";
public static final String AUTHENTICATOR_ATTRIBUTES_NAME = "account-authenticator";
这三个参数用于控制RegisteredServicesCache从PMS中获取哪些Service的信息
class AccountAuthenticatorCache
extends RegisteredServicesCache
implements IAccountAuthenticatorCache {
private static final String TAG = "Account";
private static final MySerializer sSerializer = new MySerializer();
public AccountAuthenticatorCache(Context context) {
super(context, AccountManager.ACTION_AUTHENTICATOR_INTENT,
AccountManager.AUTHENTICATOR_META_DATA_NAME,
AccountManager.AUTHENTICATOR_ATTRIBUTES_NAME, sSerializer);
}
public AuthenticatorDescription parseServiceAttributes(Resources res,
String packageName, AttributeSet attrs) {
TypedArray sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AccountAuthenticator);
try {
final String accountType =
sa.getString(com.android.internal.R.styleable.AccountAuthenticator_accountType);
final int labelId = sa.getResourceId(
com.android.internal.R.styleable.AccountAuthenticator_label, 0);
final int iconId = sa.getResourceId(
com.android.internal.R.styleable.AccountAuthenticator_icon, 0);
final int smallIconId = sa.getResourceId(
com.android.internal.R.styleable.AccountAuthenticator_smallIcon, 0);
final int prefId = sa.getResourceId(
com.android.internal.R.styleable.AccountAuthenticator_accountPreferences, 0);
final boolean customTokens = sa.getBoolean(
com.android.internal.R.styleable.AccountAuthenticator_customTokens, false);
if (TextUtils.isEmpty(accountType)) {
return null;
}
return new AuthenticatorDescription(accountType, packageName, labelId, iconId,
smallIconId, prefId, customTokens);
} finally {
sa.recycle();
}
}
private static class MySerializer implements XmlSerializerAndParser {
public void writeAsXml(AuthenticatorDescription item, XmlSerializer out)
throws IOException {
out.attribute(null, "type", item.type);
}
public AuthenticatorDescription createFromXml(XmlPullParser parser)
throws IOException, XmlPullParserException {
return AuthenticatorDescription.newKey(parser.getAttributeValue(null, "type"));
}
}
}
2.1.2.3 RegisteredServicesCache的分析
mPersistentServicesFile 保存了之前获取的指定的Service的信息
由于安装卸载以及sdcard的挂载可能会造成应用的改变,所以发生这些事件的时候会再一次获取指定的Service信息
public RegisteredServicesCache(Context context, String interfaceName, String metaDataName,
String attributeName, XmlSerializerAndParser serializerAndParser) {
mContext = context;
//保存传递过来的参数
mInterfaceName = interfaceName;
mMetaDataName = metaDataName;
mAttributesName = attributeName;
mSerializerAndParser = serializerAndParser;
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
//syncDir 目录指向/data/system/registered_services目录
File syncDir = new File(systemDir, "registered_services");
//文件指向syncDir目录下interfaceName.xml文件,interfaceName有参数传递
//AccountAuthenticatorCache传递过来的是“android.accounts.AccountAuthenticator”
mPersistentServicesFile = new AtomicFile(new File(syncDir, interfaceName + ".xml"));
// Load persisted services from disk
readPersistentServicesLocked();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
intentFilter.addDataScheme("package");
//注册apk安装卸载监听
mContext.registerReceiverAsUser(mPackageReceiver, UserHandle.ALL, intentFilter, null, null);
// Register for events related to sdcard installation.
//注册sdcard的挂载监听
IntentFilter sdFilter = new IntentFilter();
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
mContext.registerReceiver(mExternalReceiver, sdFilter);
}
private final BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
if (uid != -1) {
generateServicesMap(UserHandle.getUserId(uid));
}
}
};
private final BroadcastReceiver mExternalReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// External apps can't coexist with multi-user, so scan owner
generateServicesMap(UserHandle.USER_OWNER);
}
};
2.1.2.4 RegisteredServicesCache的generateServicesMap
首先从PMS中获取metadata是android.accounts.AccountAuthenticator的Service
对比persistentServices保存的服务信息和当前获取到的服务信息,判断是否有变化,如果有变化通知监听者
private void generateServicesMap(int userId) {
final PackageManager pm = mContext.getPackageManager();
final ArrayList> serviceInfos = new ArrayList>();
//从pms中获取metadata为指定信息的Service并保存
final List resolveInfos = pm.queryIntentServicesAsUser(
new Intent(mInterfaceName), PackageManager.GET_META_DATA, userId);
for (ResolveInfo resolveInfo : resolveInfos) {
try {
ServiceInfo info = parseServiceInfo(resolveInfo);
if (info == null) {
Log.w(TAG, "Unable to load service info " + resolveInfo.toString());
continue;
}
serviceInfos.add(info);
} catch (XmlPullParserException e) {
} catch (IOException e) {
}
}
synchronized (mServicesLock) {
//获取或创建以前保存的Service信息
final UserServices user = findOrCreateUserLocked(userId);
final boolean firstScan = user.services == null;
if (firstScan) {
user.services = Maps.newHashMap();
} else {
user.services.clear();
}
StringBuilder changes = new StringBuilder();
boolean changed = false;
//对比获取到的Service 和之前保存的Service,如果发生改变就通知监听者
for (ServiceInfo info : serviceInfos) {
// four cases:
// - doesn't exist yet
// - add, notify user that it was added
// - exists and the UID is the same
// - replace, don't notify user
// - exists, the UID is different, and the new one is not a system package
// - ignore
// - exists, the UID is different, and the new one is a system package
// - add, notify user that it was added
Integer previousUid = user.persistentServices.get(info.type);
if (previousUid == null) {
changed = true;
user.services.put(info.type, info);
user.persistentServices.put(info.type, info.uid);
if (!(mPersistentServicesFileDidNotExist && firstScan)) {
notifyListener(info.type, userId, false /* removed */);
}
} else if (previousUid == info.uid) {
user.services.put(info.type, info);//更新,但不用通知
} else if (inSystemImage(info.uid)
|| !containsTypeAndUid(serviceInfos, info.type, previousUid)) {
changed = true;
user.services.put(info.type, info);
user.persistentServices.put(info.type, info.uid);
notifyListener(info.type, userId, false /* removed */);
} else {
}
}
ArrayList toBeRemoved = Lists.newArrayList();
for (V v1 : user.persistentServices.keySet()) {
if (!containsType(serviceInfos, v1)) {
toBeRemoved.add(v1);
}
}
for (V v1 : toBeRemoved) {
changed = true;
user.persistentServices.remove(v1);
notifyListener(v1, userId, true /* removed */);
}
if (changed) {
writePersistentServicesLocked();
}
}
}
2.1.2.5 RegisteredServicesCache的 监听的设置和响应
public void setListener(RegisteredServicesCacheListener listener, Handler handler) {
if (handler == null) {
handler = new Handler(mContext.getMainLooper());
}
synchronized (this) {
mHandler = handler;
mListener = listener;
}
}
private void notifyListener(final V type, final int userId, final boolean removed) {
RegisteredServicesCacheListener listener;
Handler handler;
synchronized (this) {
listener = mListener;
handler = mHandler;
}
if (listener == null) {
return;
}
final RegisteredServicesCacheListener listener2 = listener;
handler.post(new Runnable() {
public void run() {
listener2.onServiceChanged(type, userId, removed);
}
});
}
listener的实现类
public class AccountManagerService
extends IAccountManager.Stub
implements RegisteredServicesCacheListener
listener的设置
public AccountManagerService(Context context, PackageManager packageManager,
IAccountAuthenticatorCache authenticatorCache) {
mContext = context;
mPackageManager = packageManager;
mMessageThread = new HandlerThread("AccountManagerService");
mMessageThread.start();
mMessageHandler = new MessageHandler(mMessageThread.getLooper());
mAuthenticatorCache = authenticatorCache;
//设置监听,在Service
mAuthenticatorCache.setListener(this, null /* Handler */);
2.1.2.6 AccountAuthenticatorCache的分析总结
AccountAuthenticator相关服务的定义
一个Service的action和metadata为AccountAuthenticatorCache指定的action和metadata如:
而metadata的具体信息保存在resource文件中
系统中存在的此类服务在/data/system/registered_services/android.accounts.AccountAuthenticator.xml文件中
从整个文件中可以看到当前手机上有多少个AAS服务(accout authenticator service)
2.2AccountManger的addAccout方法的流程分析
AccountMangerService有一个重要的函数addAccount,该函数的作用是为某个账户添加一个用户,AccountMangerService是一个服务,客户端进程需要通过AccountManager提供的api来使用AccountMangerService服务。所以流程的开端是AccountManager的addAccount方法
流程总结:
2.2.1AccountManager的addAccount发起请求
public AccountManagerFuture addAccount(final String accountType,
//accountType是账户类型,不能为空,email的账户类型是"com.android.email"
final String authTokenType, final String[] requiredFeatures,
final Bundle addAccountOptions,
//第二到第四个参数与具体的AAS服务有关
//activity是指如果需要输入用户名密码的话,要启动的activity
//callback和handler与获取返回值有关,如果这两个参数是空,客户端需要启动一个线程去获取AccountManagerFuture的getResult
final Activity activity, AccountManagerCallback callback, Handler handler) {
if (accountType == null) throw new IllegalArgumentException("accountType is null");
final Bundle optionsIn = new Bundle();
if (addAccountOptions != null) {//保存客户端传入的addAccountOptions
optionsIn.putAll(addAccountOptions);
}
optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
//AmsTask类
return new AmsTask(activity, handler, callback) {
public void doWork() throws RemoteException {
mService.addAccount(mResponse, accountType, authTokenType,
requiredFeatures, activity != null, optionsIn);
}
}.start();
}
2.2.1.1AmsTask类的介绍
- AmsTask继承自FutureTask,并实现了AccountManagerFutrue接口,AmsTask定义了一个doWork虚函数,该函数必须由子类实现
- AmsTask对象中有一个mResponse成员,该成员的类型是AmsTask的内部类Response,从Response的派生关系可知,Response将参与Binder通信并且它是Binder的Bn端,而AccountManagerService会得到Binder的Bp端对象,当添加完账户之后,AccountManagerService会通过Bp端对象的onResult或者onError函数向Response通知处理结果。
IAccountManagerResponse
onResponse和onError
public interface IAccountManagerResponse extends android.os.IInterface {
public static abstract class Stub extends android.os.Binder implements
android.accounts.IAccountManagerResponse {
private static final java.lang.String DESCRIPTOR = "android.accounts.IAccountManagerResponse";
@Override
public boolean onTransact(int code, android.os.Parcel data,
android.os.Parcel reply, int flags)
throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_onResult: {
...
this.onResult(_arg0);//回调onResult
return true;
}
case TRANSACTION_onError: {
data.enforceInterface(DESCRIPTOR);
...
this.onError(_arg0, _arg1);//回调onError
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements
android.accounts.IAccountManagerResponse {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override
public void onResult(android.os.Bundle value)
throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
....
//这里的调用会被onTransact响应到
mRemote.transact(Stub.TRANSACTION_onResult, _data, null,
android.os.IBinder.FLAG_ONEWAY);
} finally {
_data.recycle();
}
}
@Override
public void onError(int errorCode, java.lang.String errorMessage)
throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
....
mRemote.transact(Stub.TRANSACTION_onError, _data, null,
android.os.IBinder.FLAG_ONEWAY);
} finally {
_data.recycle();
}
}
}
static final int TRANSACTION_onResult = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_onError = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
public void onResult(android.os.Bundle value)
throws android.os.RemoteException;
public void onError(int errorCode, java.lang.String errorMessage)
throws android.os.RemoteException;
}
AmsTask的分析
final IAccountManagerResponse mResponse;
final Handler mHandler;
final AccountManagerCallback mCallback;
final Activity mActivity;
public AmsTask(Activity activity, Handler handler, AccountManagerCallback callback) {
super(new Callable() {
public Bundle call() throws Exception {
throw new IllegalStateException("this should never be called");
}
});
mHandler = handler;
mCallback = callback;
mActivity = activity;
mResponse = new Response();
}
//start会调用doWork
public final AccountManagerFuture start() {
try {
doWork();
} catch (RemoteException e) {
setException(e);
}
return this;
}
2.2.2AccountManagerService的addAccount转发请求
public void addAcount(final IAccountManagerResponse response, final String accountType,
final String authTokenType, final String[] requiredFeatures,
final boolean expectActivityLaunch, final Bundle optionsIn) {
//检查客户端进程是否有MANAGE_ACCOUNTS的权限
checkManageAccountsPermission();
UserAccounts accounts = getUserAccountsForCaller();
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
//将传入的optionsIn保存到options中
final Bundle options = (optionsIn == null) ? new Bundle() : optionsIn;
options.putInt(AccountManager.KEY_CALLER_UID, uid);
options.putInt(AccountManager.KEY_CALLER_PID, pid);
long identityToken = clearCallingIdentity();
//调用Session的bind函数
try {
new Session(accounts, response, accountType, expectActivityLaunch,
true /* stripAuthTokenFromResult */) {
public void run() throws RemoteException {
mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures,
options);
}
protected String toDebugString(long now) {
...
}
}.bind();
} finally {
restoreCallingIdentity(identityToken);
}
}
Session的介绍
- Session从IAccountAuthenticatorResponse.Stub派生,表名它会参与Binder通信,并且它是Bn端,通信的目标是具体的AAS服务,AccountManagerService会将自己传给AAS,这样AAS就得到IAccountAuthenticatorResponse的Bp对象,当AAS完成了账户添加工作之后,就会通过IAccountAuthenticatorResponse的Bp端往Session返回结果。
- Session的mResponse变量指向指向客户端的IAccountManagerResponse接口,当Session收到AAS的返回结果后,又通过IAccountManagerService的Bp端对象向客户端返回处理结果
- mAuthenticator变量的类型是IAccountAuthenticator,用于和ASS通信,客户端发起的请求通过Session由mAuthenticator调用对应的AAS的函数
客户端将请求发送给AccountManagerService,AccountManagerService再将请求转发给对应的AAS
AAS处理完成之后,先将结果交给AccountManagerService,然后AccountManagerService再将结果返回给客户端
2.2.2.1Session处理流程分析
1.Session的构造函数
/**
* @param accounts
* @param response
* @param accountType
* @param expectActivityLaunch有客戶端傳遞,表示是否需要activity
* @param stripAuthTokenFromResult
*/
public Session(UserAccounts accounts, IAccountManagerResponse response, String accountType,
boolean expectActivityLaunch, boolean stripAuthTokenFromResult) {
super();
...
synchronized (mSessions) {
//把當前的Session對象保存到AccountManagerService的mSessions成員中
mSessions.put(toString(), this);
}
try {//監聽客戶端死亡的消息
response.asBinder().linkToDeath(this, 0 /* flags */);
} catch (RemoteException e) {
mResponse = null;
binderDied();
}
}
2.bind方法,bindToAutheticator
void bind() {
//绑定到mAccontType指定的AAS,email的AAS是com.android.email
//davdroid指定的AAS是bitfire.at.davdroid
if (!bindToAuthenticator(mAccountType)) {
Log.d(TAG, "bind attempt failed for " + toDebugString());
//onError回调
onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "bind failure");
}
}
3.bindToAuthenticator
private boolean bindToAuthenticator(String authenticatorType) {
//从AccountAuthenticatorCache中获取authenticatorType对应的Service
final AccountAuthenticatorCache.ServiceInfo authenticatorInfo;
authenticatorInfo = mAuthenticatorCache.getServiceInfo(
AuthenticatorDescription.newKey(authenticatorType),
mAccounts.userId);
if (authenticatorInfo == null) {
return false;
}
Intent intent = new Intent();
intent.setAction(AccountManager.ACTION_AUTHENTICATOR_INTENT);
//设置目标的componentName
intent.setComponent(authenticatorInfo.componentName);
//通过bindService启动指定的服务
if (!mContext.bindService(intent, this, Context.BIND_AUTO_CREATE,
mAccounts.userId)) {
return false;
}
return true;
}
4.Session的bind函数会通过bindService来启动指定的Service,如果服务启动成功,那么Session的onServiceConnected函数将被调用,onServiceConnected会调用run方法
public void onServiceConnected(ComponentName name, IBinder service) {
mAuthenticator = IAccountAuthenticator.Stub.asInterface(service);
try {
run();
} catch (RemoteException e) {
onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION,
"remote exception");
}
}
5.run方法,调用mAuthenticator的addAccount方法
也就是说最终是调用AAS的addAccount方法去实现
new Session(accounts, response, accountType, expectActivityLaunch,
true /* stripAuthTokenFromResult */) {
public void run() throws RemoteException {
mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures,
options);
}
}.bind();
2.2.3返回值的处理流程
AbstractAuthenticator通过IAccountAuthenticatorService的onResult将结果返回给AccountManagerService创建的匿名Session类对象,Session的onResult函数
public void onResult(Bundle result) {
mNumResults++;
if (result != null
&& !TextUtils.isEmpty(result
.getString(AccountManager.KEY_AUTHTOKEN))) {
//从返回的result中取出相关的信息
String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME);
String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE);
if (!TextUtils.isEmpty(accountName)&& !TextUtils.isEmpty(accountType)) {
Account account = new Account(accountName, accountType);
cancelNotification(
getSigninRequiredNotificationId(mAccounts, account),
new UserHandle(mAccounts.userId));
}
}
IAccountManagerResponse response;
//AAS返回keyIntent表明需要弹出activity以输入用户名和密码
if (mExpectActivityLaunch && result != null
&& result.containsKey(AccountManager.KEY_INTENT)) {
response = mResponse;
} else {
response = getResponseAndClose();
}
if (response != null) {
try {
if (result == null) {
response.onError(
AccountManager.ERROR_CODE_INVALID_RESPONSE,
"null bundle returned");
} else {
if (mStripAuthTokenFromResult) {
result.remove(AccountManager.KEY_AUTHTOKEN);
}
//调用位于客户端的IAccountManagerService的onResult函数
response.onResult(result);
}
} catch (RemoteException e) {
// if the caller is dead then there is no one to care about
// remote exceptions
}
}
}
客户端的IAccountManagerService由AmsTask的内部类Response实现
private class Response extends IAccountManagerResponse.Stub {
public void onResult(Bundle bundle) {
Intent intent = bundle.getParcelable(KEY_INTENT);
if (intent != null && mActivity != null) {
//如果需要启动activity,则要启动ASS指定的activity
mActivity.startActivity(intent);
// leave the Future running to wait for the real response to this request
} else if (bundle.getBoolean("retry")) {
//如果需要重试,则再次调用doWork方法
try {
doWork();
} catch (RemoteException e) {
// this will only happen if the system process is dead, which means
// we will be dying ourselves
}
} else {//将返回结果保存起来,当客户端调用getResult的时候,将会得到相应的结果
set(bundle);
}
}