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

相关推荐
QQ_4376643141 天前
常见题目及答案
android·java·开发语言
菜鸟小九1 天前
mysql运维(主从复制)
android·运维·mysql
走在路上的菜鸟1 天前
Android学Dart学习笔记第十一节 分支
android·笔记·学习·flutter
恋猫de小郭1 天前
解读 Claude 对开发者的影响:AI 如何在 Anthropic 改变工作?
android·前端·ai编程
Digitally1 天前
如何将照片从 Mac 传输到 Android
android·macos
用户41659673693551 天前
Android 系统开发进阶:将应用配置为系统应用的完整指南
android
三少爷的鞋1 天前
Retrofit 核心流程模拟实现深解析
android
zhimingwen1 天前
使用 adb shell 命令检查手机上 App的APK大小
android·adb
泥嚎泥嚎1 天前
【Android】RecyclerView 刷新方式全解析:从 notifyDataSetChanged 到 DiffUtil
android·java
用户69371750013841 天前
23.Kotlin 继承:继承的细节:覆盖方法与属性
android·后端·kotlin