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

相关推荐
s***117012 小时前
Mysql convert函数、convert用法、字符串转数字、字符串转日期、类型转换函数
android·数据库·mysql
n***265613 小时前
【MySQL】MVCC详解, 图文并茂简单易懂
android·数据库·mysql
程序猿陌名!13 小时前
Android-EDLA RK3576谷歌ATTESTION-KEY从申请到烧录以及验证谷歌认证标志全流程
android
安卓理事人13 小时前
安卓版本升级功能
android
s***353013 小时前
怎么下载安装yarn
android·前端·后端
z***948413 小时前
使用rustDesk搭建私有远程桌面
android·前端·后端
q***062913 小时前
【细如狗】记录一次使用MySQL的Binlog进行数据回滚的完整流程
android·数据库·mysql
0***863313 小时前
图文详述:MySQL的下载、安装、配置、使用
android·mysql·adb
9***446313 小时前
SQLyog安装配置(注册码)连接MySQL
android·mysql·adb
o***111414 小时前
【MySQL】MySQL库的操作
android·数据库·mysql