• AMS 、PMS服务探索


    一、前言

    在上篇Zygote进程探索我们说到zygote进程fork出了SystemServer进程,SystemServer进程又开启了AMS、PMS等重要服务。今天我们就来探索AMS的世界。

    二、AMS的启动

    前面说到是SystemServer来启动的AMS,那么我们就来看看SystemServer的源码。这个类的路径在frameworks/base/services/java/com/android/server/SystemServer.java,找到源码可以发现是个Java类,那么我们就看看它的main方法吧。

    在这里插入图片描述

    我们可以看到在main方法中只有一行代码,只调用了run方法。跟着代码走吧。

    这个方法的源码很长,我们只看其中的关键部分。

    在这里插入图片描述

    我们在run()方法的后半部分可以找到上述一段代码。就是用来启动各种服务。去startBootstrapServices中浅看一下。

    我们可以在其中找到关键的代码。

    在这里插入图片描述

    我们可以看到ActivityManagerService调用了lifecycle的startService方法。我们再看看Lifecycle是个什么样子吧。

    在这里插入图片描述

    大家可以发现Lifecycle其实是AMS的内部类,在构造函数中实例化了我们需要的AMS实例。那么谁又调用了Lifecycle的构造方法呢?我们接着往下看,我们知道,最终调用了Lifecycle.startService(),而我们可以看到在Lifecycle.startService方法中其实是调用了SystemServiceManager.startService()方法,并把Lifecycle的class传入进去了。那么在SystemServiceManager.startService()里是不是会调用到Lifecycle的构造方法呢。

    我们来瞧瞧。

    在这里插入图片描述

    我们往下可以看到通过反射调用到Lifecycle的构造方法并将Lifecycle实例返回给上层调用。返回Lifecycle实例之后,会调用getService()方法获取到已经实例化的AMS。

    有人会问那么实例化,也没有看见服务启动啊。我们仔细看在SystemService.startService()中在返回service之前,有一个startService()方法,我们去看看。

    在这里插入图片描述

    我们返回的是Lifecycle实例,被添加到容器中,然后启动。可能我们都忽略一个细节,那就是Lifecycle这个内部类其实是继承了SystemService的并且重写了onStart方法,而在Lifecycle重写的方法中,调用了AMS的start方法。

    到这里大家对于整个AMS的启动有没有了解呢。

    三、PMS的作用

    上面分析过了AMS启动过程,那么我们现在还不知道AMS在Android系统中起什么作用。下面就一起来看看吧。
    假设系统中没有AMS和PMS,我们从一个activity跳转到另一个activity的话,就需要自己去解压缩apk文件,然后解析AndroidManifest.xml解析出activity,再实例化再去跳转。每一次跳转都会去做这样的操作,非常耗时。所以我们就需要我们AMS和PMS出场了。
    PMS全称是PackageManagerService,一看就是管理包相关的。大家打开Android模拟器的存储目录会发现一个/data/app目录,目录里面是我们手机上应用的包名,PMS就会去扫描这个目录。我们再去SystemServer中看看PMS的逻辑吧。
    在这里插入图片描述

    我们可以看到直接调用了PMS的main方法。既然是扫描/data/app/目录,那我们就找到相关代码阅读一下。
    PMS的main方法里面代码很多,但是肯定会在里面实例化一个PMS实例,我们就依据这个来看看吧。
    在这里插入图片描述
    可以看到PMS没有那么多花里胡哨的实例化,直接new了一个PMS对象。看样子扫描目录应该就在构造方法里面。
    在这里插入图片描述

    果然在构造方法去访问了/data/app目录,Environment.getDataDirectory()返回的就是/data/字符串。既然拿到了文件实例,那么肯定是需要使用的,只需要看看这个变量在哪里使用就好了。
    在这里插入图片描述

    查找时会发现,这段代码其实也在构造方法中。我们去看看这个方法里都做了啥吧。

    在这里插入图片描述
    可以看到开始对目录下的APK文件开始扫描了,并且使用一个线程池来开始扫描任务。因为这里是最新源码(Android 12)所以大家可以看到的是使用线程池来开启任务。在之前Android 7 的时候在主线程中开启扫描任务。有兴趣的同学可以去看看Android 7 的源码对比来看看。我们再追踪到submit方法中。

    在这里插入图片描述

    在submit方法中最终会调用到parsePackage()中,这个mPackageParser是一个 PackageParser2对象,最终会走到PackageParser2.parsePackage()中。我们接下来去看看吧。
    在这里插入图片描述

    我们可以看到在核心代码中解析工作还是交给了一个parsingUtils.parsePackage最后会得到一个ParsingPackage。所有的解析操作都在ParsingPackageUtils这个类中完成,我们之后再分析,当然解析主要是解析AndroidManifest.xml,会把里面所有涉及到的结点都会缓存下来。
    可以看看ParsingPackage里面的相关代码。

    public interface ParsingPackage extends ParsingPackageRead {
        
        ParsingPackage addActivity(ParsedActivity parsedActivity);
        
        ParsingPackage addAdoptPermission(String adoptPermission);
        
        ParsingPackage addConfigPreference(ConfigurationInfo configPreference);
        
        ParsingPackage addFeatureGroup(FeatureGroupInfo featureGroup);
        
        ParsingPackage addImplicitPermission(String permission);
        
        ParsingPackage addInstrumentation(ParsedInstrumentation instrumentation);
        
        ParsingPackage addKeySet(String keySetName, PublicKey publicKey);
        
        ParsingPackage addLibraryName(String libraryName);
        
        ParsingPackage addOriginalPackage(String originalPackage);
        
        ParsingPackage addOverlayable(String overlayableName, String actorName);
        
        ParsingPackage addPermission(ParsedPermission permission);
        // ...省略部分代码
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    是不是可以看到好多熟悉的东西,在解析之后就会存起来,方便AMS调用。我们还可以看看实现类。

    public class ParsingPackageImpl implements ParsingPackage, Parcelable {
    
        private static final String TAG = "PackageImpl";
    
        @NonNull
        @DataClass.ParcelWith(ForInternedStringList.class)
        protected List<String> protectedBroadcasts = emptyList();
    
        @NonNull
        protected List<ParsedActivity> activities = emptyList();
    
        @NonNull
        protected List<ParsedActivity> receivers = emptyList();
    
        @NonNull
        protected List<ParsedService> services = emptyList();
    
        @NonNull
        protected List<ParsedProvider> providers = emptyList();
    
        @NonNull
        private List<ParsedAttribution> attributions = emptyList();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    看到熟悉的四大组件没,其中的ParsedActivity、ParsedService等大家可以理解成一个bean类用来存放解析出来的数据。
    在PMS是用final WatchedArrayMap<String, AndroidPackage> mPackages = new WatchedArrayMap<>() 这样的一个map存起来的。key是包名,值就是上面所存储的 ParsingPackage。
    这样整个PMS的工作也就完成了,解压缩apk,解析xml文件。

    四、AMS与PMS的联动

    上面分析了PMS的逻辑,下面来看看AMS都做了什么吧。

    AMS是用来管理activity的,想要了解我们就从最简单的跳转开始吧,从startActivity()开始吧。

    @Override
        public void startActivity(Intent intent, @Nullable Bundle options) {
            if (mIntent != null && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)
                    && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY)) {
                if (TextUtils.equals(getPackageName(),
                        intent.resolveActivity(getPackageManager()).getPackageName())) {
                    // Apply Autofill restore mechanism on the started activity by startActivity()
                    final IBinder token =
                            mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN);
                    // Remove restore ability from current activity
                    mIntent.removeExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN);
                    mIntent.removeExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY);
                    // Put restore token
                    intent.putExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN, token);
                    intent.putExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY, true);
                }
            }
            if (options != null) {
                startActivityForResult(intent, -1, options);
            } else {
                // Note we want to go through this call for compatibility with
                // applications that may have overridden the method.
                startActivityForResult(intent, -1);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    我们在外部调用startActivity方法时,我们最后就会调用到上述代码。

     public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
                @Nullable Bundle options) {
            if (mParent == null) {
                options = transferSpringboardActivityOptions(options);
                Instrumentation.ActivityResult ar =
                    mInstrumentation.execStartActivity(
                        this, mMainThread.getApplicationThread(), mToken, this,
                        intent, requestCode, options);
                if (ar != null) {
                    mMainThread.sendActivityResult(
                        mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                        ar.getResultData());
                }
                //...省略代码
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    最终会走到mInstrumentation.execStartActivity()中。这里也没有涉及到AMS,我们接着往下看。

    public ActivityResult execStartActivity(
                Context who, IBinder contextThread, IBinder token, Activity target,
                Intent intent, int requestCode, Bundle options) {
          //....省略代码
            try {
                intent.migrateExtraStreamToClipData(who);
                intent.prepareToLeaveProcess(who);
                int result = ActivityTaskManager.getService().startActivity(whoThread,
                        who.getOpPackageName(), who.getAttributionTag(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()), token,
                        target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
                checkStartActivityResult(result, intent);
            } catch (RemoteException e) {
                throw new RuntimeException("Failure from system", e);
            }
            return null;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    这里开始就有点AMS的味道了,那么这个getService()获取的到底是不是AMS呢,我们接着探索。

        /** @hide */
        public static IActivityTaskManager getService() {
            return IActivityTaskManagerSingleton.get();
        }
    
        @UnsupportedAppUsage(trackingBug = 129726065)
        private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
                new Singleton<IActivityTaskManager>() {
                    @Override
                    protected IActivityTaskManager create() {
                        final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                        return IActivityTaskManager.Stub.asInterface(b);
                    }
                };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    看到这里我们可能发现AMS还没有出现,代替的是ActivityTaskManager,没错,Android10 之后,AMS就把管理Activity的工作交给了ActivityTaskManager。
    我们先来分析分析上述代码吧。getService返回的是IActivityTaskManagerSingleton.get(),具体我们看看Singleton这个类就好了。

    public abstract class Singleton<T> {
    
        @UnsupportedAppUsage
        public Singleton() {
        }
    
        @UnsupportedAppUsage
        private T mInstance;
    
        protected abstract T create();
    
        @UnsupportedAppUsage
        public final T get() {
            synchronized (this) {
                if (mInstance == null) {
                    mInstance = create();
                }
                return mInstance;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    不知道大家看清楚这个单例模式没有,实例不是自己new的,是通过create方法返回的。那么之前的代码就非常好理解了,get()方法其实拿到的是create()的返回值,就是返回了一个Binder对象并转化IActivityTaskManager,也就是说其实我们app内部跳转Activity是一个跨进程通信。这里就是从APP进程到AMS的进程里面去了。
    我们可以接着往下看Stub的实现类ActivityTaskManagerService。我们找到如下代码。

    @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
                                   String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
                                   String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
                                   Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
                                   resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
                                   UserHandle.getCallingUserId());
        }
    最终会走到startActivityAsUser。
      private int startActivityAsUser(IApplicationThread caller, String callingPackage,
                @Nullable String callingFeatureId, Intent intent, String resolvedType,
                IBinder resultTo, String resultWho, int requestCode, int startFlags,
                ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
            assertPackageMatchesCallingUid(callingPackage);
            enforceNotIsolatedCaller("startActivityAsUser");
    
            userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                    Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
    
            // TODO: Switch to user app stacks here.
            return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                    .setCaller(caller)
                    .setCallingPackage(callingPackage)
                    .setCallingFeatureId(callingFeatureId)
                    .setResolvedType(resolvedType)
                    .setResultTo(resultTo)
                    .setResultWho(resultWho)
                    .setRequestCode(requestCode)
                    .setStartFlags(startFlags)
                    .setProfilerInfo(profilerInfo)
                    .setActivityOptions(bOptions)
                    .setUserId(userId)
                    .execute();
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    不用看上面的一大堆代码,我们只看最后的方法execute(),上面一大堆设置变量最后也会到execute()中执行。

     int execute() {
            try {
                // Refuse possible leaked file descriptors
                if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
                    throw new IllegalArgumentException("File descriptors passed in Intent");
                }
    
                final LaunchingState launchingState;
                synchronized (mService.mGlobalLock) {
                    final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);
                    final int callingUid = mRequest.realCallingUid == Request.DEFAULT_REAL_CALLING_UID
                            ?  Binder.getCallingUid() : mRequest.realCallingUid;
                    launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
                            mRequest.intent, caller, callingUid);
                }
    
                // If the caller hasn't already resolved the activity, we're willing
                // to do so here. If the caller is already holding the WM lock here,
                // and we need to check dynamic Uri permissions, then we're forced
                // to assume those permissions are denied to avoid deadlocking.
                if (mRequest.activityInfo == null) {
                    mRequest.resolveActivity(mSupervisor);
                }
            }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    我们可以看代码中的注释哈。会在resolveActivity中处理相关逻辑。

     void resolveActivity(ActivityTaskSupervisor supervisor) {
               //....省略部分代码
                resolveInfo = supervisor.resolveIntent(intent, resolvedType, userId,
                        0 /* matchFlags */,
                        computeResolveFilterUid(callingUid, realCallingUid, filterCallingUid));
     }
    最后会在resolveIntent中拿到我们所需要的东西的。
     ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags,
                int filterCallingUid) {
                  //...省略部分代码
                final long token = Binder.clearCallingIdentity();
                try {
                    return mService.getPackageManagerInternalLocked().resolveIntent(
                            intent, resolvedType, modifiedFlags, privateResolveFlags, userId, true,
                            filterCallingUid);
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
            } finally {
                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    其中mService是ActivityTaskManagerService。看看返回的对象是什么吧。

    PackageManagerInternal getPackageManagerInternalLocked() {
            if (mPmInternal == null) {
                mPmInternal = LocalServices.getService(PackageManagerInternal.class);
            }
            return mPmInternal;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    看到这里AMS是不是就应该和PMS产生了联系呢,我们再仔细看看。看看PackageManagerInternal能不能在PMS中找到吧。

     private class PackageManagerInternalImpl extends PackageManagerInternal {
            @Override
            public List<ApplicationInfo> getInstalledApplications(int flags, int userId,
                    int callingUid) {
                return PackageManagerService.this.getInstalledApplicationsListInternal(flags, userId,
                        callingUid);
            }
    
            @Override
            public boolean isPlatformSigned(String packageName) {
                PackageSetting packageSetting = mSettings.getPackageLPr(packageName);
                if (packageSetting == null) {
                    return false;
                }
                AndroidPackage pkg = packageSetting.pkg;
                if (pkg == null) {
                    // May happen if package in on a removable sd card
                    return false;
                }
                return pkg.getSigningDetails().hasAncestorOrSelf(mPlatformPackage.getSigningDetails())
                        || mPlatformPackage.getSigningDetails().checkCapability(pkg.getSigningDetails(),
                        PackageParser.SigningDetails.CertCapabilities.PERMISSION);
            }
         //...省略部分代码
    
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    我们可以在PMS中找到一个实现类,其实我们最终返回的对象就是PackageManagerInternalImpl。我们可以看其中部分的代码实现。因为是PMS的内部类,所以直接调用PMS的对象访问PMS自己的方法再通过内部类提供给外部。我们再回过头看看ResloveInfo。

    public class ResolveInfo implements Parcelable {
        private static final String TAG = "ResolveInfo";
        private static final String INTENT_FORWARDER_ACTIVITY =
                "com.android.internal.app.IntentForwarderActivity";
    
        /**
         * The activity or broadcast receiver that corresponds to this resolution
         * match, if this resolution is for an activity or broadcast receiver.
         * Exactly one of {@link #activityInfo}, {@link #serviceInfo}, or
         * {@link #providerInfo} will be non-null.
         */
        public ActivityInfo activityInfo;
    
        /**
         * The service that corresponds to this resolution match, if this resolution
         * is for a service. Exactly one of {@link #activityInfo},
         * {@link #serviceInfo}, or {@link #providerInfo} will be non-null.
         */
        public ServiceInfo serviceInfo;
    
        /**
         * The provider that corresponds to this resolution match, if this
         * resolution is for a provider. Exactly one of {@link #activityInfo},
         * {@link #serviceInfo}, or {@link #providerInfo} will be non-null.
         */
        public ProviderInfo providerInfo;
    
        /**
         * An auxiliary response that may modify the resolved information. This is
         * only set under certain circumstances; such as when resolving instant apps
         * or components defined in un-installed splits.
         * @hide
         */
        public AuxiliaryResolveInfo auxiliaryInfo;
    
        /**
         * Whether or not an instant app is available for the resolved intent.
         */
        public boolean isInstantAppAvailable;
    
        /**
         * The IntentFilter that was matched for this ResolveInfo.
         */
        public IntentFilter filter;
        //...省略部分代码
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    在ResloveInfo中是存储了关于四大组件的所有信息了。我们通过PMS之前解析的东西都放在ResolveInfo中,我们就可以在ResolveInfo中拿到我们所需要的所有东西。
    拿到我们想要的东西之后,就回到最开始的地方execute方法。execute方法中会调用resolveActivity方法,就是在这里我们就去和PMS通信了。我们现在就从这里开始吧。

     // Collect information about the target of the Intent.
                activityInfo = supervisor.resolveActivity(intent, resolveInfo, startFlags,
                        profilerInfo);
    
    • 1
    • 2
    • 3

    这里拿到activityInfo之后,我们就接着回去看execute方法。这里activityInfo是一个全局变量,存放在一个Request 的内部类中。我们再看看execute方法中其他的代码吧。

        if (mRequest.activityInfo == null) {
                    mRequest.resolveActivity(mSupervisor);
                }
    
           //...省略部分代码
           res = executeRequest(mRequest); 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在我们拿到信息之后就会去执行executeRequest方法,在这里面去接着执行我们的启动流程。
    之后就是看源码的的流程了就不再多说了。
    我们已经了解AMS、PMS各自逻辑以及相互的联系了,这也是本次文章的目的。

  • 相关阅读:
    Java集合篇:Map接口、Map接口的实现类、Collections集合工具类
    安全两方推理问题
    Golang 语法入门
    GaussDB之SQL Audit,面向应用开发的SQL审核工具
    JAVA医院绩效考核系统源码 功能特点:大型医院绩效考核系统源码
    pytest自动化框架运行全局配置文件pytest.ini
    HCIP中的MSTP多域配置
    敏捷Scrum实施落地中的3大典型问题及解法
    Windows Server 2016
    详解AQS中的condition源码原理
  • 原文地址:https://blog.csdn.net/qq_41677326/article/details/125313247