Idle/Home architecture and code structure




SystemServer.java启动后,将在ActivityManagerService.systemReady()里运行Home应用,参见Android SystemServer学习一文。


frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

    public void systemReady(final Runnable goingCallback) {
        if (!Process.supportsProcesses()) {
            mStartRunning = true;
            mTopAction = Intent.ACTION_MAIN;
        }

        synchronized(this) {
            if (mSystemReady) {
                if (goingCallback != null) goingCallback.run();
                return;
            }
            
            // Check to see if there are any update receivers to run.
            if (!mDidUpdate) {
                if (mWaitingUpdate) {
                    return;
                }
                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
                List<ResolveInfo> ris = null;
                try {
                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
                                intent, null, 0);
                } catch (RemoteException e) {
                }
                if (ris != null) {
                    for (int i=ris.size()-1; i>=0; i--) {
                        if ((ris.get(i).activityInfo.applicationInfo.flags
                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
                            ris.remove(i);
                        }
                    }
                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
                    
                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
                    
                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
                    for (int i=0; i<ris.size(); i++) {
                        ActivityInfo ai = ris.get(i).activityInfo;
                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
                        if (lastDoneReceivers.contains(comp)) {
                            ris.remove(i);
                            i--;
                        }
                    }
                    
                    for (int i=0; i<ris.size(); i++) {
                        ActivityInfo ai = ris.get(i).activityInfo;
                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
                        doneReceivers.add(comp);
                        intent.setComponent(comp);
                        IIntentReceiver finisher = null;
                        if (i == ris.size()-1) {
                            finisher = new IIntentReceiver.Stub() {
                                public void performReceive(Intent intent, int resultCode,
                                        String data, Bundle extras, boolean ordered,
                                        boolean sticky) {
                                    // The raw IIntentReceiver interface is called
                                    // with the AM lock held, so redispatch to
                                    // execute our code without the lock.
                                    mHandler.post(new Runnable() {
                                        public void run() {
                                            synchronized (ActivityManagerService.this) {
                                                mDidUpdate = true;
                                            }
                                            writeLastDonePreBootReceivers(doneReceivers);
                                            systemReady(goingCallback);
                                        }
                                    });
                                }
                            };
                        }
                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
                        broadcastIntentLocked(null, null, intent, null, finisher,
                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
                        if (finisher != null) {
                            mWaitingUpdate = true;
                        }
                    }
                }
                if (mWaitingUpdate) {
                    return;
                }
                mDidUpdate = true;
            }
            
            mSystemReady = true;
            
            if (!mStartRunning) {
                return;
            }
        }
        ArrayList<ProcessRecord> procsToKill = null;
        synchronized(mPidsSelfLocked) {
            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
                if (!isAllowedWhileBooting(proc.info)){
                    if (procsToKill == null) {
                        procsToKill = new ArrayList<ProcessRecord>();
                    }
                    procsToKill.add(proc);
                }
            }
        }
        
        synchronized(this) {
            if (procsToKill != null) {
                for (int i=procsToKill.size()-1; i>=0; i--) {
                    ProcessRecord proc = procsToKill.get(i);
                    Slog.i(TAG, "Removing system update proc: " + proc);
                    removeProcessLocked(proc, true);
                }
            }
            
            // Now that we have cleaned up any update processes, we
            // are ready to start launching real processes and know that
            // we won't trample on them any more.
            mProcessesReady = true;
        }       
...
        
        synchronized (this) {
            ...
            // Start up initial activity.
            mBooting = true;
            ...
            mMainStack.resumeTopActivityLocked(null);         //这里启动Home
        }
    }


刚启动时,栈里没有其它的Activity,故启动HomeActivity。

frameworks/base/services/java/com/android/server/am/ActivityStack.java

public class ActivityStack {
    final boolean resumeTopActivityLocked(ActivityRecord prev) {
        // Find the first activity that is not finishing.
        ActivityRecord next = topRunningActivityLocked(null);

        // Remember how we'll process this pause/resume situation, and ensure
        // that the state is reset however we wind up proceeding.
        final boolean userLeaving = mUserLeaving;
        mUserLeaving = false;

        if (next == null) {
            // There are no more activities!  Let's just start up the
            // Launcher...
            if (mMainStack) {
                return mService.startHomeActivityLocked(); //转到ActivityManagerService里
            }
        }

frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

    boolean startHomeActivityLocked() {
...
        Intent intent = new Intent(
            mTopAction,
            mTopData != null ? Uri.parse(mTopData) : null);
        intent.setComponent(mTopComponent); //如果刚启动应为null
        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
            intent.addCategory(Intent.CATEGORY_HOME); //指定要查找的app必须在AndroidManifest.xml intent-filter部分指明<category android:name="android.intent.category.HOME" />
        }
        ActivityInfo aInfo =
            intent.resolveActivityInfo(mContext.getPackageManager(),
                    STOCK_PM_FLAGS); //注意:此处查找所有申明满足Intent中定义的component,action,mimetype的app.
        //此处仅为满足category=android.intent.category.HOME的app,如果有多个app满足,则根据priority来选择intent-filter android:priority为最大优先级的app
        if (aInfo != null) { //如果找到声明为Home的应用程序
              intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));            // Don't do this if the home app is currently being  instrumented.
              ProcessRecord app = getProcessRecordLocked(aInfo.processName,aInfo.applicationInfo.uid);
              if (app == null || app.instrumentationClass == null) {
                  intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
                  mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,null, null, 0, 0, 0, false, false);
               }
         }
         return true;
 }


frameworks/base/services/java/com/android/server/am/ActivityStack.java


    private final void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid);
        
        if (r.launchTime == 0) {
            r.launchTime = SystemClock.uptimeMillis(); //保存Activity启动时间
            if (mInitialStartTime == 0) {
                mInitialStartTime = r.launchTime;
            }
        } else if (mInitialStartTime == 0) {
            mInitialStartTime = SystemClock.uptimeMillis();
        }
        
        if (app != null && app.thread != null) {
            try {
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }

        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false); //如果由于程序crash引起RemoteException,重新启动进程
    }

    final boolean realStartActivityLocked(ActivityRecord r,
            ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {

        r.startFreezingScreenLocked(app, 0);
        mService.mWindowManager.setAppVisibility(r, true);
...
        r.app = app;

        int idx = app.activities.indexOf(r);
        if (idx < 0) {
            app.activities.add(r);
        }
        mService.updateLruProcessLocked(app, true, true);

        try {
            if (app.thread == null) {
                throw new RemoteException();
            }
            List<ResultInfo> results = null;
            List<Intent> newIntents = null;
            if (andResume) {
                results = r.results;
                newIntents = r.newIntents;
            }
   
            if (r.isHomeActivity) { //保存HomeActivity
                mService.mHomeProcess = app;
                mService.mHomeTask = r.task.taskId;
            }
            mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
                    System.identityHashCode(r),
                    r.info, r.icicle, results, newIntents, !andResume,
                    mService.isNextTransitionForward()); //发送运行Activity消息LAUNCH_ACTIVITY到消息队列
            
            if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
                // This may be a heavy-weight process!  Note that the package
                // manager will ensure that only activity can run in the main
                // process of the .apk, which is the only thing that will be
                // considered heavy-weight.
                if (app.processName.equals(app.info.packageName)) {
                    if (mService.mHeavyWeightProcess != null
                            && mService.mHeavyWeightProcess != app) {
                        Log.w(TAG, "Starting new heavy weight process " + app
                                + " when already running "
                                + mService.mHeavyWeightProcess);
                    }
                    mService.mHeavyWeightProcess = app;
                    Message msg = mService.mHandler.obtainMessage(
                            ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
                    msg.obj = r;
                    mService.mHandler.sendMessage(msg);
                }
            }
            
        }
...
        r.launchFailed = false; //初始化
...
        if (andResume) {
            // As part of the process of launching, ActivityThread also performs
            // a resume.
            r.state = ActivityState.RESUMED;
            r.icicle = null;
            r.haveState = false;
            r.stopped = false;
            mResumedActivity = r;
            r.task.touchActiveTime();
            completeResumeLocked(r);
            pauseIfSleepingLocked();                
        } else {
            // This activity is not starting in the resumed state... which
            // should look like we asked it to pause+stop (but remain visible),
            // and it has done so and reported back the current icicle and
            // other state.
            r.state = ActivityState.STOPPED;
            r.stopped = true;
        }

        //似乎mMainStack总是true??? 在启动Home时才启动SetupActivity
        if (mMainStack) {
            mService.startSetupActivityLocked();
        }
        
        return true;
    }


frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

    void startSetupActivityLocked() {
        // Only do this once per boot.
        if (mCheckedForSetup) {
            return;
        }
        
        // We will show this screen if the current one is a different
        // version than the last one shown, and we are not running in
        // low-level factory test mode.
        final ContentResolver resolver = mContext.getContentResolver();
        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
                Settings.Secure.getInt(resolver,
                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { //注意DEVICE_PROVISIONED设置如果为0将触发SetupActivity
            mCheckedForSetup = true; //置位以防止再次启动Setup
            
            // See if we should be showing the platform update setup UI.
            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
                    .queryIntentActivities(intent, PackageManager.GET_META_DATA); //查找接收ACTION_UPGRADE_SETUP的所有APP
            
            // We don't allow third party apps to replace this
            ResolveInfo ri = null;
            for (int i=0; ris != null && i<ris.size(); i++) {
                if ((ris.get(i).activityInfo.applicationInfo.flags
                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
                    ri = ris.get(i); //得到第一个满足在/system/app下得app,注意仅检查一个,所以如果有多个应用声明
ACTION_UPGRADE_SETUP,则只有第一个应用会被调用
                    break;
                }
            }
            
            if (ri != null) { //得到待安装程序的版本号
                String vers = ri.activityInfo.metaData != null
                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
                        : null;
                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
                    vers = ri.activityInfo.applicationInfo.metaData.getString(
                            Intent.METADATA_SETUP_VERSION);
                }
                String lastVers = Settings.Secure.getString(
                        resolver, Settings.Secure.LAST_SETUP_SHOWN); //得到Phone目前版本号
                if (vers != null && !vers.equals(lastVers)) { //仅当当前版本号和待安装程序版本号不一致时会启动安装程序
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    intent.setComponent(new ComponentName(
                            ri.activityInfo.packageName, ri.activityInfo.name));
                    mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
                            null, null, 0, 0, 0, false, false); //Show Setup Activity
                }
            }
        }
    }





   

你可能感兴趣的:(Idle/Home architecture and code structure)