自动填充服务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的绑定过程,很多细节都略过了,后续可能会逐步补充细节。

相关推荐
江上清风山间明月2 小时前
Flutter开发的应用页面非常多时如何高效管理路由
android·flutter·路由·页面管理·routes·ongenerateroute
子非衣6 小时前
MySQL修改JSON格式数据示例
android·mysql·json
openinstall全渠道统计9 小时前
免填邀请码工具:赋能六大核心场景,重构App增长新模型
android·ios·harmonyos
双鱼大猫9 小时前
一句话说透Android里面的ServiceManager的注册服务
android
双鱼大猫9 小时前
一句话说透Android里面的查找服务
android
双鱼大猫9 小时前
一句话说透Android里面的SystemServer进程的作用
android
双鱼大猫9 小时前
一句话说透Android里面的View的绘制流程和实现原理
android
双鱼大猫10 小时前
一句话说透Android里面的Window的内部机制
android
双鱼大猫11 小时前
一句话说透Android里面的为什么要设计Window?
android
双鱼大猫11 小时前
一句话说透Android里面的主线程创建时机,frameworks层面分析
android