美文网首页
Activity相关学习-启动(1)

Activity相关学习-启动(1)

作者: weiinter105 | 来源:发表于2019-01-05 21:46 被阅读0次

前言

Activity是四大组件中最常见的,也是相对来说最复杂的,AMS中的逻辑相当复杂,直线很多,且牵涉到WMS显示相关的部分,很难将其完全理清,这里只能说尽力理清主线流程。直接从AMS中的处理开始:

流程

ActivityManagerService#startActivity

    @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }

ActivityManagerService#startActivityAsUser

    @Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                true /*validateIncomingUser*/);
    }

    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
            boolean validateIncomingUser) {
        enforceNotIsolatedCaller("startActivity");

        userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // TODO: Switch to user app stacks here.
        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId)
                .execute();

    }

ActivityStarter#execute

    /**
     * Starts an activity based on the request parameters provided earlier.
     * @return The starter result.
     */
    int execute() {
        try {
            // TODO(b/64750076): Look into passing request directly to these methods to allow
            // for transactional diffs and preprocessing.
            if (mRequest.mayWait) {
                return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                        mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                        mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                        mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                        mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup);
            } else {
                return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                        mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
                        mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
                        mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                        mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
                        mRequest.outActivity, mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup);
            }
        } finally {
            onExecutionComplete();
        }
    }

ActivityStarter#startActivityMayWait

949    private int startActivityMayWait(IApplicationThread caller, int callingUid,
950            String callingPackage, Intent intent, String resolvedType,
951            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
952            IBinder resultTo, String resultWho, int requestCode, int startFlags,
953            ProfilerInfo profilerInfo, WaitResult outResult,
954            Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
955            int userId, TaskRecord inTask, String reason,
956            boolean allowPendingRemoteAnimationRegistryLookup) {
             //resultTo用于接收返回的结果,resultWho用于描述接收结果的对象
             //requestCode由调用者定义,Intent携带的start activity对应的flag
957        // Refuse possible leaked file descriptors
958        if (intent != null && intent.hasFileDescriptors()) {
959            throw new IllegalArgumentException("File descriptors passed in Intent");
960        }
961        mSupervisor.getActivityMetricsLogger().notifyActivityLaunching();
962        boolean componentSpecified = intent.getComponent() != null;
963
964        final int realCallingPid = Binder.getCallingPid();
965        final int realCallingUid = Binder.getCallingUid();
966
967        int callingPid;
968        if (callingUid >= 0) {
969            callingPid = -1;
970        } else if (caller == null) {
971            callingPid = realCallingPid;
972            callingUid = realCallingUid;
973        } else {
974            callingPid = callingUid = -1;
975        }
976
977        // Save a copy in case ephemeral needs it
978        final Intent ephemeralIntent = new Intent(intent);
979        // Don't modify the client's object!
980        intent = new Intent(intent);
981        if (componentSpecified
982                && !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
983                && !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
984                && !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
985                && mService.getPackageManagerInternalLocked()
986                        .isInstantAppInstallerComponent(intent.getComponent())) {
987            // intercept intents targeted directly to the ephemeral installer the
988            // ephemeral installer should never be started with a raw Intent; instead
989            // adjust the intent so it looks like a "normal" instant app launch
990            intent.setComponent(null /*component*/);
991            componentSpecified = false;
992        }
993      //利用PKMS解析满足Intent等参数要求的信息
994        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
995                0 /* matchFlags */,
996                        computeResolveFilterUid(
997                                callingUid, realCallingUid, mRequest.filterCallingUid));
998        if (rInfo == null) {
999            UserInfo userInfo = mSupervisor.getUserInfo(userId);
1000            if (userInfo != null && userInfo.isManagedProfile()) {
1001                // Special case for managed profiles, if attempting to launch non-cryto aware
1002                // app in a locked managed profile from an unlocked parent allow it to resolve
1003                // as user will be sent via confirm credentials to unlock the profile.
1004                UserManager userManager = UserManager.get(mService.mContext);
1005                boolean profileLockedAndParentUnlockingOrUnlocked = false;
1006                long token = Binder.clearCallingIdentity();
1007                try {
1008                    UserInfo parent = userManager.getProfileParent(userId);
1009                    profileLockedAndParentUnlockingOrUnlocked = (parent != null)
1010                            && userManager.isUserUnlockingOrUnlocked(parent.id)
1011                            && !userManager.isUserUnlockingOrUnlocked(userId);
1012                } finally {
1013                    Binder.restoreCallingIdentity(token);
1014                }
1015                if (profileLockedAndParentUnlockingOrUnlocked) {
1016                    rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
1017                            PackageManager.MATCH_DIRECT_BOOT_AWARE
1018                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
1019                            computeResolveFilterUid(
1020                                    callingUid, realCallingUid, mRequest.filterCallingUid));
1021                }
1022            }
1023        }
1024        // Collect information about the target of the Intent.
               //通过ActivityStackSupervisor解析ActivityInfo
1025        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
1026
1027        synchronized (mService) {
1028            final ActivityStack stack = mSupervisor.mFocusedStack;
1029            stack.mConfigWillChange = globalConfig != null
1030                    && mService.getGlobalConfiguration().diff(globalConfig) != 0;
1031            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1032                    "Starting activity when config will change = " + stack.mConfigWillChange);
1033
1034            final long origId = Binder.clearCallingIdentity();
1035
1036            if (aInfo != null &&
1037                    (aInfo.applicationInfo.privateFlags
1038                            & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&
1039                    mService.mHasHeavyWeightFeature) {
                   //正常情况下,当一个Application退到后台时,系统会为它保存状态;当调度其到前台时,恢复它之前的状态,以保证用户体验的连续性
                   //AndroidManifest.xml中的Application标签可以申明一个CANT_SAVE_STATE属性
                   //设置了该属性的Application将不享受系统提供的状态保存/恢复功能,被称为heavy-weight process
1040                // This may be a heavy-weight process!  Check to see if we already
1041                // have another, different heavy-weight process running.
1042                if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
1043                    final ProcessRecord heavy = mService.mHeavyWeightProcess;
1044                    if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid
1045                            || !heavy.processName.equals(aInfo.processName))) {
1046                        int appCallingUid = callingUid;
1047                        if (caller != null) {
1048                            ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
1049                            if (callerApp != null) {
1050                                appCallingUid = callerApp.info.uid;
1051                            } else {
1052                                Slog.w(TAG, "Unable to find app for caller " + caller
1053                                        + " (pid=" + callingPid + ") when starting: "
1054                                        + intent.toString());
1055                                SafeActivityOptions.abort(options);
1056                                return ActivityManager.START_PERMISSION_DENIED;
1057                            }
1058                        }
1059
1060                        IIntentSender target = mService.getIntentSenderLocked(
1061                                ActivityManager.INTENT_SENDER_ACTIVITY, "android",
1062                                appCallingUid, userId, null, null, 0, new Intent[] { intent },
1063                                new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
1064                                        | PendingIntent.FLAG_ONE_SHOT, null);
1065
1066                        Intent newIntent = new Intent();
1067                        if (requestCode >= 0) {
1068                            // Caller is requesting a result.
1069                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
1070                        }
1071                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
1072                                new IntentSender(target));
1073                        if (heavy.activities.size() > 0) {
1074                            ActivityRecord hist = heavy.activities.get(0);
1075                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
1076                                    hist.packageName);
1077                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
1078                                    hist.getTask().taskId);
1079                        }
1080                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
1081                                aInfo.packageName);
1082                        newIntent.setFlags(intent.getFlags());
1083                        newIntent.setClassName("android",
1084                                HeavyWeightSwitcherActivity.class.getName());
1085                        intent = newIntent;
1086                        resolvedType = null;
1087                        caller = null;
1088                        callingUid = Binder.getCallingUid();
1089                        callingPid = Binder.getCallingPid();
1090                        componentSpecified = true;
1091                        rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId,
1092                                0 /* matchFlags */, computeResolveFilterUid(
1093                                        callingUid, realCallingUid, mRequest.filterCallingUid));
1094                        aInfo = rInfo != null ? rInfo.activityInfo : null;
1095                        if (aInfo != null) {
1096                            aInfo = mService.getActivityInfoForUser(aInfo, userId);
1097                        }
1098                    }
1099                }
1100            }
1101
1102            final ActivityRecord[] outRecord = new ActivityRecord[1];
1103            int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
1104                    voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
1105                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
1106                    ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
1107                    allowPendingRemoteAnimationRegistryLookup);
1108
1109            Binder.restoreCallingIdentity(origId);
1110
1111            if (stack.mConfigWillChange) {
1112                // If the caller also wants to switch to a new configuration,
1113                // do so now.  This allows a clean switch, as we are waiting
1114                // for the current activity to pause (so we will not destroy
1115                // it), and have not yet started the next activity.
1116                mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
1117                        "updateConfiguration()");
1118                stack.mConfigWillChange = false;
1119                if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
1120                        "Updating to new configuration after starting activity.");
1121                mService.updateConfigurationLocked(globalConfig, null, false);
1122            }
1123
1124            if (outResult != null) {
1125                outResult.result = res;
1126
1127                final ActivityRecord r = outRecord[0];
1128
1129                switch(res) {
1130                    case START_SUCCESS: {
1131                        mSupervisor.mWaitingActivityLaunched.add(outResult);
1132                        do {
1133                            try {
1134                                mService.wait();
1135                            } catch (InterruptedException e) {
1136                            }
1137                        } while (outResult.result != START_TASK_TO_FRONT
1138                                && !outResult.timeout && outResult.who == null);
1139                        if (outResult.result == START_TASK_TO_FRONT) {
1140                            res = START_TASK_TO_FRONT;
1141                        }
1142                        break;
1143                    }
1144                    case START_DELIVERED_TO_TOP: {
1145                        outResult.timeout = false;
1146                        outResult.who = r.realActivity;
1147                        outResult.totalTime = 0;
1148                        outResult.thisTime = 0;
1149                        break;
1150                    }
1151                    case START_TASK_TO_FRONT: {
1152                        // ActivityRecord may represent a different activity, but it should not be
1153                        // in the resumed state.
1154                        if (r.nowVisible && r.isState(RESUMED)) {
1155                            outResult.timeout = false;
1156                            outResult.who = r.realActivity;
1157                            outResult.totalTime = 0;
1158                            outResult.thisTime = 0;
1159                        } else {
1160                            outResult.thisTime = SystemClock.uptimeMillis();
1161                            mSupervisor.waitActivityVisible(r.realActivity, outResult);
1162                            // Note: the timeout variable is not currently not ever set.
1163                            do {
1164                                try {
1165                                    mService.wait();
1166                                } catch (InterruptedException e) {
1167                                }
1168                            } while (!outResult.timeout && outResult.who == null);
1169                        }
1170                        break;
1171                    }
1172                }
1173            }
1174
1175            mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
1176            return res;
1177        }
1178    }

ActivityStarter#startActivity

    private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, TaskRecord inTask, String reason,
            boolean allowPendingRemoteAnimationRegistryLookup) {

        if (TextUtils.isEmpty(reason)) {
            throw new IllegalArgumentException("Need to specify a reason.");
        }
        mLastStartReason = reason;
        mLastStartActivityTimeMs = System.currentTimeMillis();
        mLastStartActivityRecord[0] = null;

        mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                inTask, allowPendingRemoteAnimationRegistryLookup);

        if (outActivity != null) {
            // mLastStartActivityRecord[0] is set in the call to startActivity above.
            outActivity[0] = mLastStartActivityRecord[0];
        }

        return getExternalResult(mLastStartActivityResult);
    }
575    private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
576            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
577            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
578            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
579            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
580            SafeActivityOptions options,
581            boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
582            TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
583        int err = ActivityManager.START_SUCCESS;
584        // Pull the optional Ephemeral Installer-only bundle out of the options early.
585        final Bundle verificationBundle
586                = options != null ? options.popAppVerificationBundle() : null;
587
588        ProcessRecord callerApp = null;
589        if (caller != null) {
590            callerApp = mService.getRecordForAppLocked(caller);
591            if (callerApp != null) {
592                callingPid = callerApp.pid;
593                callingUid = callerApp.info.uid;
594            } else {
595                Slog.w(TAG, "Unable to find app for caller " + caller
596                        + " (pid=" + callingPid + ") when starting: "
597                        + intent.toString());
598                err = ActivityManager.START_PERMISSION_DENIED;
599            }
600        }
601
602        final int userId = aInfo != null && aInfo.applicationInfo != null
603                ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
604
605        if (err == ActivityManager.START_SUCCESS) {
606            Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
607                    + "} from uid " + callingUid);
608        }
609
610        ActivityRecord sourceRecord = null;
611        ActivityRecord resultRecord = null;
612        if (resultTo != null) {
613            sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
614            if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
615                    "Will send result to " + resultTo + " " + sourceRecord);
616            if (sourceRecord != null) {
617                if (requestCode >= 0 && !sourceRecord.finishing) {
618                    resultRecord = sourceRecord;
619                }
620            }
621        }
622
623        final int launchFlags = intent.getFlags();
624
625        if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
626            // Transfer the result target from the source activity to the new
627            // one being started, including any failures.
628            if (requestCode >= 0) {
629                SafeActivityOptions.abort(options);
630                return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
631            }
632            resultRecord = sourceRecord.resultTo;
633            if (resultRecord != null && !resultRecord.isInStackLocked()) {
634                resultRecord = null;
635            }
636            resultWho = sourceRecord.resultWho;
637            requestCode = sourceRecord.requestCode;
638            sourceRecord.resultTo = null;
639            if (resultRecord != null) {
640                resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
641            }
642            if (sourceRecord.launchedFromUid == callingUid) {
643                // The new activity is being launched from the same uid as the previous
644                // activity in the flow, and asking to forward its result back to the
645                // previous.  In this case the activity is serving as a trampoline between
646                // the two, so we also want to update its launchedFromPackage to be the
647                // same as the previous activity.  Note that this is safe, since we know
648                // these two packages come from the same uid; the caller could just as
649                // well have supplied that same package name itself.  This specifially
650                // deals with the case of an intent picker/chooser being launched in the app
651                // flow to redirect to an activity picked by the user, where we want the final
652                // activity to consider it to have been launched by the previous app activity.
653                callingPackage = sourceRecord.launchedFromPackage;
654            }
655        }
656
657        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
658            // We couldn't find a class that can handle the given Intent.
659            // That's the end of that!
660            err = ActivityManager.START_INTENT_NOT_RESOLVED;
661        }
662
663        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
664            // We couldn't find the specific class specified in the Intent.
665            // Also the end of the line.
666            err = ActivityManager.START_CLASS_NOT_FOUND;
667        }
668
669        if (err == ActivityManager.START_SUCCESS && sourceRecord != null
670                && sourceRecord.getTask().voiceSession != null) {
671            // If this activity is being launched as part of a voice session, we need
672            // to ensure that it is safe to do so.  If the upcoming activity will also
673            // be part of the voice session, we can only launch it if it has explicitly
674            // said it supports the VOICE category, or it is a part of the calling app.
675            if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
676                    && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
677                try {
678                    intent.addCategory(Intent.CATEGORY_VOICE);
679                    if (!mService.getPackageManager().activitySupportsIntent(
680                            intent.getComponent(), intent, resolvedType)) {
681                        Slog.w(TAG,
682                                "Activity being started in current voice task does not support voice: "
683                                        + intent);
684                        err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
685                    }
686                } catch (RemoteException e) {
687                    Slog.w(TAG, "Failure checking voice capabilities", e);
688                    err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
689                }
690            }
691        }
692
693        if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
694            // If the caller is starting a new voice session, just make sure the target
695            // is actually allowing it to run this way.
696            try {
697                if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
698                        intent, resolvedType)) {
699                    Slog.w(TAG,
700                            "Activity being started in new voice task does not support: "
701                                    + intent);
702                    err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
703                }
704            } catch (RemoteException e) {
705                Slog.w(TAG, "Failure checking voice capabilities", e);
706                err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
707            }
708        }
709
710        final ActivityStack resultStack = resultRecord == null ? null : resultRecord.getStack();
711
712        if (err != START_SUCCESS) {
713            if (resultRecord != null) {
714                resultStack.sendActivityResultLocked(
715                        -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
716            }
717            SafeActivityOptions.abort(options);
718            return err;
719        }
720
721        boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
722                requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
723                inTask != null, callerApp, resultRecord, resultStack);
724        abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
725                callingPid, resolvedType, aInfo.applicationInfo);
726
727        // Merge the two options bundles, while realCallerOptions takes precedence.
728        ActivityOptions checkedOptions = options != null
729                ? options.getOptions(intent, aInfo, callerApp, mSupervisor)
730                : null;
731        if (allowPendingRemoteAnimationRegistryLookup) {
732            checkedOptions = mService.getActivityStartController()
733                    .getPendingRemoteAnimationRegistry()
734                    .overrideOptionsIfNeeded(callingPackage, checkedOptions);
735        }
736        if (mService.mController != null) {
737            try {
738                // The Intent we give to the watcher has the extra data
739                // stripped off, since it can contain private information.
740                Intent watchIntent = intent.cloneFilter();
741                abort |= !mService.mController.activityStarting(watchIntent,
742                        aInfo.applicationInfo.packageName);
743            } catch (RemoteException e) {
744                mService.mController = null;
745            }
746        }
747
748        mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage);
749        if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,
750                callingUid, checkedOptions)) {
751            // activity start was intercepted, e.g. because the target user is currently in quiet
752            // mode (turn off work) or the target application is suspended
753            intent = mInterceptor.mIntent;
754            rInfo = mInterceptor.mRInfo;
755            aInfo = mInterceptor.mAInfo;
756            resolvedType = mInterceptor.mResolvedType;
757            inTask = mInterceptor.mInTask;
758            callingPid = mInterceptor.mCallingPid;
759            callingUid = mInterceptor.mCallingUid;
760            checkedOptions = mInterceptor.mActivityOptions;
761        }
762
763        if (abort) {
764            if (resultRecord != null) {
765                resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
766                        RESULT_CANCELED, null);
767            }
768            // We pretend to the caller that it was really started, but
769            // they will just get a cancel result.
770            ActivityOptions.abort(checkedOptions);
771            return START_ABORTED;
772        }
773
774        // If permissions need a review before any of the app components can run, we
775        // launch the review activity and pass a pending intent to start the activity
776        // we are to launching now after the review is completed.
777        if (mService.mPermissionReviewRequired && aInfo != null) {
778            if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
779                    aInfo.packageName, userId)) {
780                IIntentSender target = mService.getIntentSenderLocked(
781                        ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
782                        callingUid, userId, null, null, 0, new Intent[]{intent},
783                        new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
784                                | PendingIntent.FLAG_ONE_SHOT, null);
785
786                final int flags = intent.getFlags();
787                Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
788                newIntent.setFlags(flags
789                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
790                newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
791                newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
792                if (resultRecord != null) {
793                    newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
794                }
795                intent = newIntent;
796
797                resolvedType = null;
798                callingUid = realCallingUid;
799                callingPid = realCallingPid;
800
801                rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
802                        computeResolveFilterUid(
803                                callingUid, realCallingUid, mRequest.filterCallingUid));
804                aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
805                        null /*profilerInfo*/);
806
807                if (DEBUG_PERMISSIONS_REVIEW) {
808                    Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
809                            true, false) + "} from uid " + callingUid + " on display "
810                            + (mSupervisor.mFocusedStack == null
811                            ? DEFAULT_DISPLAY : mSupervisor.mFocusedStack.mDisplayId));
812                }
813            }
814        }
815
816        // If we have an ephemeral app, abort the process of launching the resolved intent.
817        // Instead, launch the ephemeral installer. Once the installer is finished, it
818        // starts either the intent we resolved here [on install error] or the ephemeral
819        // app [on install success].
820        if (rInfo != null && rInfo.auxiliaryInfo != null) {
821            intent = createLaunchIntent(rInfo.auxiliaryInfo, ephemeralIntent,
822                    callingPackage, verificationBundle, resolvedType, userId);
823            resolvedType = null;
824            callingUid = realCallingUid;
825            callingPid = realCallingPid;
826
827            aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
828        }
829        //创建要启动的Activity对应的ActivityRecord
830        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
831                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
832                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
833                mSupervisor, checkedOptions, sourceRecord);
834        if (outActivity != null) {
835            outActivity[0] = r;
836        }
837
838        if (r.appTimeTracker == null && sourceRecord != null) {
839            // If the caller didn't specify an explicit time tracker, we want to continue
840            // tracking under any it has.
841            r.appTimeTracker = sourceRecord.appTimeTracker;
842        }
843
844        final ActivityStack stack = mSupervisor.mFocusedStack;
845
846        // If we are starting an activity that is not from the same uid as the currently resumed
847        // one, check whether app switches are allowed.
848        if (voiceSession == null && (stack.getResumedActivity() == null
849                || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
850            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
851                    realCallingPid, realCallingUid, "Activity start")) {
852                mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
853                        sourceRecord, startFlags, stack, callerApp));
854                ActivityOptions.abort(checkedOptions);
855                return ActivityManager.START_SWITCHES_CANCELED;
856            }
857        }
858
859        if (mService.mDidAppSwitch) {
860            // This is the second allowed switch since we stopped switches,
861            // so now just generally allow switches.  Use case: user presses
862            // home (switches disabled, switch to home, mDidAppSwitch now true);
863            // user taps a home icon (coming from home so allowed, we hit here
864            // and now allow anyone to switch again).
865            mService.mAppSwitchesAllowedTime = 0;
866        } else {
867            mService.mDidAppSwitch = true;
868        }
869
870        mController.doPendingActivityLaunches(false);
871
872        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
873                true /* doResume */, checkedOptions, inTask, outActivity);
874    }
1197    private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
1198                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1199                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
1200                ActivityRecord[] outActivity) {
1201        int result = START_CANCELED;
1202        try {
1203            mService.mWindowManager.deferSurfaceLayout();
1204            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
1205                    startFlags, doResume, options, inTask, outActivity);
1206        } finally {
1207            // If we are not able to proceed, disassociate the activity from the task. Leaving an
1208            // activity in an incomplete state can lead to issues, such as performing operations
1209            // without a window container.
1210            final ActivityStack stack = mStartActivity.getStack();
1211            if (!ActivityManager.isStartResultSuccessful(result) && stack != null) {
1212                stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
1213                        null /* intentResultData */, "startActivity", true /* oomAdj */);
1214            }
1215            mService.mWindowManager.continueSurfaceLayout();
1216        }
1217
1218        postStartActivityProcessing(r, result, mTargetStack);
1219
1220        return result;
1221    }

以上做完了参数准备工作和检查工作,下面开始真正启动Activity的核心操作,见startActivityUnchecked

相关文章

网友评论

      本文标题:Activity相关学习-启动(1)

      本文链接:https://www.haomeiwen.com/subject/ldzfrqtx.html