1.AutoFillService 是在什么时候开始被绑定的
View获得焦点的时候,开始获取相关服务,经过一系列调用,最终bindAutoFillService
- 焦点获取时,onFocusChanged被调用
less
protected void onFocusChanged(boolean gainFocus, @FocusDirection int direction,
@Nullable Rect previouslyFocusedRect) {
........
........
........
notifyEnterOrExitForAutoFillIfNeeded(gainFocus);
}
notifyEnterOrExitForAutoFillIfNeeded
在onFocusChanged
中被调用
java
public void notifyEnterOrExitForAutoFillIfNeeded(boolean enter) {
AutofillManager afm = getAutofillManager();
afm.notifyViewEntered(this);
}
notifyEnterOrExitForAutoFillIfNeeded
中就开始获取相关服务了,通过AutofillManager.notifyViewEntered
开始了跨进程,准备与AutofillManagerServiceImpl
通信,绑定AotoFillService
和autofill相关服务或者是类有以下几个,这里先把类名列举出来,有个大概的印象,后面会逐渐的串联起来
AutofillManager
AutofillManagerServiceImpl
AutofillManagerService
RemoteFillService
com.android.server.autofill.Session
当然还有一些 callback 用来各类之间的通信
AutofillManager
算是一个代理,其中有个重要的变量IAutoFillManager ,IAutoFillManager
是一个binder对象,即 AutofillManagerService
的客户端部分.
afm.notifyViewEntered
中就是通过 IAutoFillManager.startSession
正式开启了binder通信.
scss
mService.startSession(client.autofillClientGetActivityToken(),
mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(),
mCallback != null, flags, clientActivity,
isCompatibilityModeEnabledLocked(), receiver);
// mService 是 IAutoFillManager 的实例
- 系统进程
AutofillManagerService
中startSession
的逻辑
这里又构造了一个AutofillManagerServiceImpl
,调用了startSessionLocked
从这里到bindservice被分为了两个过程
- 从
startSessionLocked
到Session.requestAssistStructureLocked
2.在requestAssistStructureLocked
中有调用了 AMS 的 requestAutofillData
scss
try {
if (!ActivityTaskManager.getService().requestAutofillData(mAssistReceiver,
receiverExtras, mActivityToken, flags)) {
Slog.w(TAG, "failed to request autofill data for " + mActivityToken);
}
} finally {
Binder.restoreCallingIdentity(identity);
}
- 在AMS 的
requestAutofillData
中又通过IApplicationThreada.requestAssistContextExtras
调回了app
csharp
try {
activity.app.getThread().requestAssistContextExtras(activity.token, pae,
requestType, mViSessionId, flags);
mPendingAssistExtras.add(pae);
mUiHandler.postDelayed(pae, timeout);
} catch (RemoteException e) {
Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
return null;
}
上面三个过程都在系统进程中:
- 调用到
IApplicationThreada.requestAssistContextExtras
后,在app中的调用链是:
最后又通过ams.reportAssistContextExtras
再次回到系统进程中
ini
IActivityTaskManager mgr = ActivityTaskManager.getService();
try {
mgr.reportAssistContextExtras(cmd.requestToken, data, structure, content, referrer);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
- 最后一步了,再次回到系统进程后,就要绑定autofillservice
enqueue
的实现如下,绑定逻辑在 enqueueJobThread
less
private boolean enqueue(@NonNull Job<I, ?> job) {
cancelTimeout();
android.util.Log.e("heyan","heyan ServiceConnector$Impl enqueue======",new Exception());
return mHandler.post(() -> enqueueJobThread(job));
}
enqueueJobThread
中调用了 bindService
less
void enqueueJobThread(@NonNull Job<I, ?> job) {
if (DEBUG) {
Log.i(LOG_TAG, "post(" + job + ", this = " + this + ")");
}
cancelTimeout();
if (mUnbinding) {
completeExceptionally(job,
new IllegalStateException("Service is unbinding. Ignoring " + job));
} else if (!mQueue.offer(job)) {
completeExceptionally(job,
new IllegalStateException("Failed to add to queue: " + job));
} else if (isBound()) {
processQueue();
} else if (!mBinding) {
if (bindService(mServiceConnection)) {
mBinding = true;
} else {
completeExceptionally(job,
new IllegalStateException("Failed to bind to service " + mIntent));
}
}
}
bindService
直接调用了 mContext.bindService
,绑定成功了!!!
less
protected boolean bindService(@NonNull ServiceConnection serviceConnection) {
if (DEBUG) {
logTrace();
}
return mContext.bindService(mIntent, Context.BIND_AUTO_CREATE | mBindingFlags,
mExecutor, serviceConnection);
}
暂存
本篇只是粗略的走了一遍自动填充服务AutoFillService的绑定过程,很多细节都略过了,后续可能会逐步补充细节。