自动填充服务AutoFillService的QA

1.AutoFillService 是在什么时候开始被绑定的

View获得焦点的时候,开始获取相关服务,经过一系列调用,最终bindAutoFillService

  • 焦点获取时,onFocusChanged被调用
less 复制代码
protected void onFocusChanged(boolean gainFocus, @FocusDirection int direction,
        @Nullable Rect previouslyFocusedRect) {
    ........
    ........
    ........
    notifyEnterOrExitForAutoFillIfNeeded(gainFocus);
  
}
  • notifyEnterOrExitForAutoFillIfNeededonFocusChanged 中被调用
java 复制代码
public void notifyEnterOrExitForAutoFillIfNeeded(boolean enter) {
   
   AutofillManager afm = getAutofillManager();
   afm.notifyViewEntered(this);
}

notifyEnterOrExitForAutoFillIfNeeded 中就开始获取相关服务了,通过AutofillManager.notifyViewEntered开始了跨进程,准备与AutofillManagerServiceImpl 通信,绑定AotoFillService

autofill相关服务或者是类有以下几个,这里先把类名列举出来,有个大概的印象,后面会逐渐的串联起来

  1. AutofillManager
  2. AutofillManagerServiceImpl
  3. AutofillManagerService
  4. RemoteFillService
  5. 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 的实例
  • 系统进程 AutofillManagerServicestartSession的逻辑

这里又构造了一个AutofillManagerServiceImpl,调用了startSessionLocked

从这里到bindservice被分为了两个过程

  1. startSessionLockedSession.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);
}
  1. 在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;
}

上面三个过程都在系统进程中:

  1. 调用到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();
}
  1. 最后一步了,再次回到系统进程后,就要绑定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的绑定过程,很多细节都略过了,后续可能会逐步补充细节。

相关推荐
龙之叶36 分钟前
Android系统定制APP开发_如何对应用进行系统签名
android·gradle·android studio
砖厂小工3 小时前
Now In Android 精讲 3 - 眼花缭乱 Kotlin 类型
android·kotlin·android jetpack
李歘歘3 小时前
Golang——channel
android·开发语言·后端·golang
molong9317 小时前
Android广播和阿里云消息推送服务
android·阿里云·云计算
肖老师xy13 小时前
uniapp使用chooseLocation安卓篇
android·javascript·uni-app
勿忘初心9114 小时前
Android车机DIY开发之软件篇(八)单独编译
android·嵌入式硬件·mcu·学习
zjy_hll14 小时前
RK3568 Android 13 内置搜狗输入法小计
android
云卓SKYDROID14 小时前
工业级手持地面站(支持Android和IOS)技术详解!
android·ios·无人机·科普·高科技·云卓科技
satadriver18 小时前
android分区和root
android