android 7.0 加入 android:directBootAware

Posted 曹纪乾

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android 7.0 加入 android:directBootAware相关的知识,希望对你有一定的参考价值。

android N引入了一个新特性: Direct Boot Mode—— 设备启动后进入的一个新模式,直到用户解锁(unlock)设备此阶段结束。

在此 Direct Boot Mode 下 APP 主要使用在如果情况

  • Alarm、clock 类的操作
  • 需要做重要的或紧急的通知
  • 底层服务类

使用场景的话,如手机丢了,捡到的人解不开锁,也做不了啥操作,现在任意工作在Direct Boot Mode 下的APP都可以“安全地”跑起来,和服务器建链,可以全方位的和捡手机的人进行沟通或拍照。

APP 要工作在DBM (Direct Boot Mode)下的话,manifest 中加入:

<activity|provider|receiver|service ...  
     android:directBootAware=”true”>

APP在进入DBM后会收到系统的广播消息: Intent.ACTION_LOCKED_BOOT_COMPLETED ——之前是开机完成,现在如果没有解锁。

用户解锁手机后,APP会收到另一条: Intent.ACTION_BOOT_COMPLETED —— 开机完成。

DBM下和正常模式下最大的不同是:使用一种新的存储空间:Device protected storage,在正常模式下是看不到这个空间的数据的,这样的话就可以做一些更加完备的安全机制,比如:
把网络连接的Tocken、SSH……放在此独立空间,防止用户平常使用时被其他APP侦听、窃取。

还有一点:DBM模式下的APP只能和同在此模式中的APP通信,貌似是废话哦,这个阶段其他APP也没跑起来呢。

最后一点:一台安装了Android N的设备,第一次使用要创建这个Device protected storage加密分区,方式有:

  • 设备的setting中修改:Settings > Developer options > Convert to file encryption
  • fastboot中修改:
    $ adb reboot-bootloader  
    $ fastboot --wipe-and-use-fbe

在ActivityManagerService的systemReady函数中:

public void systemReady(final Runnable goingCallback) 
    ............
    //注意此处的参数MATCH_DIRECT_BOOT_AWARE
    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
    ............

从上面的代码可以看出,systemReady将调用startPersistentApps启动某一类Application。

private void startPersistentApps(int matchFlags) 
    ........
    synchronized (this) 
        try
            //从PackageManagerService中获取同时具有Persistent和directBootAware标签的应用列表
            final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
                             .getPersistentApplications(STOCK_PM_FLAGS | matchFlags)
                             .getList();
            for (ApplicationInfo app : apps) 
                if (!"android".equals(app.packageName)) 
                    //启动这些应用
                    addAppLocked(app, false, null /* ABI override */);
                
            
        catch (RemoteException ex) 
        
    

  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

从上面的代码,我们知道PhoneApp将有addAppLocked进行处理:

final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, String abiOverride) 
    .........
    startProcessLocked(app, "added application", app.processName, abiOverride,
                    null /* entryPoint */, null /* entryPointArgs */);
    .........


private final void startProcessLocked(........) 
    .........
    //这里之前的blog提到过,将利用socket发送消息给zygote分裂出应用所需的进程
    //进程创建出后,将调用对应类的main函数,对于PhoneApp而言,即android.app.ActivityThread
    Process.ProcessStartResult startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                    app.info.dataDir, entryPointArgs);

  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在ActivityThread.java的main函数中:

.........
ActivityThread thread = new ActivityThread();
//PhoneApp不是系统App
thread.attach(false);
.........
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

继续看看attach函数:

private void attach(boolean system) 
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) 
        .............
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        //binder通信,获取Remote端
        final IActivityManager mgr = ActivityManagerNative.getDefault();
        try 
            //将ApplicationThread传给AM,实际上传递的是binder代理
            mgr.attachApplication(mAppThread);
         catch (RemoteException ex) 
            throw ex.rethrowFromSystemServer();
        
        ...........
    ..............
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

从上面的代码可以看出,流程再次回到了ActivityManagerService:

@Override
public final void attachApplication(IApplicationThread thread) 
    synchronized (this) 
        int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid);
        Binder.restoreCallingIdentity(origId);
    


private final boolean attachApplicationLocked(IApplicationThread thread, int pid) 
    ...........
    //将调用ApplicationThread的bindApplication
    thread.bindApplication(.....);
    ...........

  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

我们看看ApplicationThreadNative.java中ApplicationThreadProxy的bindApplication函数:

class ApplicationThreadProxy implements IApplicationThread 
    ............
    @Override
    public final void bindApplication(....) 
        ........
        //利用binder通信,ActivityManagerService将消息发回给PhoneApp中的ActivityThread
        mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null,IBinder.FLAG_ONEWAY);
        ........
    

  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在ActivityThread.java中的handler H的handleMessage处理消息(在PhoneApp中的binder解析完收到的数据后,触发BIND_APPLICATION消息给H):

.............
case BIND_APPLICATION:
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
    AppBindData data = (AppBindData)msg.obj;
    //处理数据
    handleBindApplication(data);
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    break;
............
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
private void handleBindApplication(AppBindData data) 
    ..........
    try 
        mInstrumentation.callApplicationOnCreate(app);
     catch (Exception e) 
        ........
    
    ........

  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
public void callApplicationOnCreate(Application app) 
    app.onCreate();



以上是关于android 7.0 加入 android:directBootAware的主要内容,如果未能解决你的问题,请参考以下文章

Android7.0怎么样?安卓7.0有啥新功能

目标检测YOLOv5-7.0:加入实例分割

Centos 7.0 下安装 Zabbix server 服务器的安装及 监控主机的加入

移动端自动化测试-Windows-Android-Appium环境搭建

Android 7.0都有哪些新功能 Android 7.0新特性汇总

Android 7.0下仿7.0之前的时间框及去掉日选择框方法