Search in sources :

Example 11 with ReferrerIntent

use of com.android.internal.content.ReferrerIntent in project android_frameworks_base by crdroidandroid.

the class LocalActivityManager method startActivity.

/**
     * Start a new activity running in the group.  Every activity you start
     * must have a unique string ID associated with it -- this is used to keep
     * track of the activity, so that if you later call startActivity() again
     * on it the same activity object will be retained.
     * 
     * <p>When there had previously been an activity started under this id,
     * it may either be destroyed and a new one started, or the current
     * one re-used, based on these conditions, in order:</p>
     * 
     * <ul>
     * <li> If the Intent maps to a different activity component than is
     * currently running, the current activity is finished and a new one
     * started.
     * <li> If the current activity uses a non-multiple launch mode (such
     * as singleTop), or the Intent has the
     * {@link Intent#FLAG_ACTIVITY_SINGLE_TOP} flag set, then the current
     * activity will remain running and its
     * {@link Activity#onNewIntent(Intent) Activity.onNewIntent()} method
     * called.
     * <li> If the new Intent is the same (excluding extras) as the previous
     * one, and the new Intent does not have the
     * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP} set, then the current activity
     * will remain running as-is.
     * <li> Otherwise, the current activity will be finished and a new
     * one started.
     * </ul>
     * 
     * <p>If the given Intent can not be resolved to an available Activity,
     * this method throws {@link android.content.ActivityNotFoundException}.
     * 
     * <p>Warning: There is an issue where, if the Intent does not
     * include an explicit component, we can restore the state for a different
     * activity class than was previously running when the state was saved (if
     * the set of available activities changes between those points).
     * 
     * @param id Unique identifier of the activity to be started
     * @param intent The Intent describing the activity to be started
     * 
     * @return Returns the window of the activity.  The caller needs to take
     * care of adding this window to a view hierarchy, and likewise dealing
     * with removing the old window if the activity has changed.
     * 
     * @throws android.content.ActivityNotFoundException
     */
public Window startActivity(String id, Intent intent) {
    if (mCurState == INITIALIZING) {
        throw new IllegalStateException("Activities can't be added until the containing group has been created.");
    }
    boolean adding = false;
    boolean sameIntent = false;
    ActivityInfo aInfo = null;
    // Already have information about the new activity id?
    LocalActivityRecord r = mActivities.get(id);
    if (r == null) {
        // Need to create it...
        r = new LocalActivityRecord(id, intent);
        adding = true;
    } else if (r.intent != null) {
        sameIntent = r.intent.filterEquals(intent);
        if (sameIntent) {
            // We are starting the same activity.
            aInfo = r.activityInfo;
        }
    }
    if (aInfo == null) {
        aInfo = mActivityThread.resolveActivityInfo(intent);
    }
    // activity is allowed to be running at a time.
    if (mSingleMode) {
        LocalActivityRecord old = mResumed;
        // activity, we need to stop it.
        if (old != null && old != r && mCurState == RESUMED) {
            moveToState(old, STARTED);
        }
    }
    if (adding) {
        // It's a brand new world.
        mActivities.put(id, r);
        mActivityArray.add(r);
    } else if (r.activityInfo != null) {
        // we may be able to reuse it.
        if (aInfo == r.activityInfo || (aInfo.name.equals(r.activityInfo.name) && aInfo.packageName.equals(r.activityInfo.packageName))) {
            if (aInfo.launchMode != ActivityInfo.LAUNCH_MULTIPLE || (intent.getFlags() & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0) {
                // The activity wants onNewIntent() called.
                ArrayList<ReferrerIntent> intents = new ArrayList<>(1);
                intents.add(new ReferrerIntent(intent, mParent.getPackageName()));
                if (localLOGV)
                    Log.v(TAG, r.id + ": new intent");
                mActivityThread.performNewIntents(r, intents, false);
                r.intent = intent;
                moveToState(r, mCurState);
                if (mSingleMode) {
                    mResumed = r;
                }
                return r.window;
            }
            if (sameIntent && (intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_TOP) == 0) {
                // We are showing the same thing, so this activity is
                // just resumed and stays as-is.
                r.intent = intent;
                moveToState(r, mCurState);
                if (mSingleMode) {
                    mResumed = r;
                }
                return r.window;
            }
        }
        // The new activity is different than the current one, or it
        // is a multiple launch activity, so we need to destroy what
        // is currently there.
        performDestroy(r, true);
    }
    r.intent = intent;
    r.curState = INITIALIZING;
    r.activityInfo = aInfo;
    moveToState(r, mCurState);
    // When in single mode keep track of the current activity
    if (mSingleMode) {
        mResumed = r;
    }
    return r.window;
}
Also used : ActivityInfo(android.content.pm.ActivityInfo) ReferrerIntent(com.android.internal.content.ReferrerIntent) ArrayList(java.util.ArrayList)

Example 12 with ReferrerIntent

use of com.android.internal.content.ReferrerIntent in project android_frameworks_base by crdroidandroid.

the class ActivityStackSupervisor method realStartActivityLocked.

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {
    if (!allPausedActivitiesComplete()) {
        // the paused state because they will first be resumed then paused on the client side.
        if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES)
            Slog.v(TAG_PAUSE, "realStartActivityLocked: Skipping start of r=" + r + " some activities pausing...");
        return false;
    }
    if (andResume) {
        r.startFreezingScreenLocked(app, 0);
        mWindowManager.setAppVisibility(r.appToken, true);
        // schedule launch ticks to collect information about slow apps.
        r.startLaunchTickingLocked();
    }
    // just restarting it anyway.
    if (checkConfig) {
        Configuration config = mWindowManager.updateOrientationFromAppTokens(mService.mConfiguration, r.mayFreezeScreenLocked(app) ? r.appToken : null);
        // Deferring resume here because we're going to launch new activity shortly.
        // We don't want to perform a redundant launch of the same record while ensuring
        // configurations and trying to resume top activity of focused stack.
        mService.updateConfigurationLocked(config, r, false, true);
    }
    r.app = app;
    app.waitingToKill = null;
    r.launchCount++;
    r.lastLaunchTime = SystemClock.uptimeMillis();
    if (DEBUG_ALL)
        Slog.v(TAG, "Launching: " + r);
    int idx = app.activities.indexOf(r);
    if (idx < 0) {
        app.activities.add(r);
    }
    mService.updateLruProcessLocked(app, true, null);
    mService.updateOomAdjLocked();
    final TaskRecord task = r.task;
    if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE || task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV) {
        setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", false);
    }
    final ActivityStack stack = task.stack;
    try {
        if (app.thread == null) {
            throw new RemoteException();
        }
        List<ResultInfo> results = null;
        List<ReferrerIntent> newIntents = null;
        if (andResume) {
            results = r.results;
            newIntents = r.newIntents;
        }
        if (DEBUG_SWITCH)
            Slog.v(TAG_SWITCH, "Launching: " + r + " icicle=" + r.icicle + " with results=" + results + " newIntents=" + newIntents + " andResume=" + andResume);
        if (andResume) {
            EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, r.userId, System.identityHashCode(r), task.taskId, r.shortComponentName);
        }
        if (r.isHomeActivity()) {
            // Home process is the root process of the task.
            mService.mHomeProcess = task.mActivities.get(0).app;
        }
        mService.notifyPackageUse(r.intent.getComponent().getPackageName(), PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);
        r.sleeping = false;
        r.forceNewConfig = false;
        mService.showUnsupportedZoomDialogIfNeededLocked(r);
        mService.showAskCompatModeDialogLocked(r);
        r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
        ProfilerInfo profilerInfo = null;
        if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
            if (mService.mProfileProc == null || mService.mProfileProc == app) {
                mService.mProfileProc = app;
                final String profileFile = mService.mProfileFile;
                if (profileFile != null) {
                    ParcelFileDescriptor profileFd = mService.mProfileFd;
                    if (profileFd != null) {
                        try {
                            profileFd = profileFd.dup();
                        } catch (IOException e) {
                            if (profileFd != null) {
                                try {
                                    profileFd.close();
                                } catch (IOException o) {
                                }
                                profileFd = null;
                            }
                        }
                    }
                    profilerInfo = new ProfilerInfo(profileFile, profileFd, mService.mSamplingInterval, mService.mAutoStopProfiler);
                }
            }
        }
        if (andResume) {
            app.hasShownUi = true;
            app.pendingUiClean = true;
        }
        app.forceProcessStateUpTo(mService.mTopProcessState);
        app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
        if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
            // considered heavy-weight.
            if (app.processName.equals(app.info.packageName)) {
                if (mService.mHeavyWeightProcess != null && mService.mHeavyWeightProcess != app) {
                    Slog.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);
            }
        }
    } catch (RemoteException e) {
        if (r.launchFailed) {
            // This is the second time we failed -- finish activity
            // and give up.
            Slog.e(TAG, "Second failure launching " + r.intent.getComponent().flattenToShortString() + ", giving up", e);
            mService.appDiedLocked(app);
            stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, "2nd-crash", false);
            return false;
        }
        // This is the first time we failed -- restart process and
        // retry.
        app.activities.remove(r);
        throw e;
    }
    r.launchFailed = false;
    if (stack.updateLRUListLocked(r)) {
        Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list");
    }
    if (andResume) {
        // As part of the process of launching, ActivityThread also performs
        // a resume.
        stack.minimalResumeActivityLocked(r);
    } else {
        // current icicle and other state.
        if (DEBUG_STATES)
            Slog.v(TAG_STATES, "Moving to PAUSED: " + r + " (starting in paused state)");
        r.state = PAUSED;
    }
    // switch back to it faster and look better.
    if (isFocusedStack(stack)) {
        mService.startSetupActivityLocked();
    }
    // their client may have activities.
    if (r.app != null) {
        mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
    }
    return true;
}
Also used : ProfilerInfo(android.app.ProfilerInfo) Configuration(android.content.res.Configuration) ReferrerIntent(com.android.internal.content.ReferrerIntent) Message(android.os.Message) ReferrerIntent(com.android.internal.content.ReferrerIntent) Intent(android.content.Intent) IOException(java.io.IOException) ParcelFileDescriptor(android.os.ParcelFileDescriptor) RemoteException(android.os.RemoteException) ResultInfo(android.app.ResultInfo)

Example 13 with ReferrerIntent

use of com.android.internal.content.ReferrerIntent in project android_frameworks_base by crdroidandroid.

the class ActivityRecord method deliverNewIntentLocked.

/**
     * Deliver a new Intent to an existing activity, so that its onNewIntent()
     * method will be called at the proper time.
     */
final void deliverNewIntentLocked(int callingUid, Intent intent, String referrer) {
    // The activity now gets access to the data associated with this Intent.
    service.grantUriPermissionFromIntentLocked(callingUid, packageName, intent, getUriPermissionsLocked(), userId);
    final ReferrerIntent rintent = new ReferrerIntent(intent, referrer);
    boolean unsent = true;
    final ActivityStack stack = task.stack;
    final boolean isTopActivityInStack = stack != null && stack.topRunningActivityLocked() == this;
    final boolean isTopActivityWhileSleeping = service.isSleepingLocked() && isTopActivityInStack;
    // - The device is sleeping and it is the top activity behind the lock screen (b/6700897).
    if ((state == ActivityState.RESUMED || state == ActivityState.PAUSED || isTopActivityWhileSleeping) && app != null && app.thread != null) {
        try {
            ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
            ar.add(rintent);
            app.thread.scheduleNewIntent(ar, appToken, state == ActivityState.PAUSED);
            unsent = false;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
        } catch (NullPointerException e) {
            Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
        }
    }
    if (unsent) {
        addNewIntentLocked(rintent);
    }
}
Also used : ReferrerIntent(com.android.internal.content.ReferrerIntent) ArrayList(java.util.ArrayList) RemoteException(android.os.RemoteException)

Example 14 with ReferrerIntent

use of com.android.internal.content.ReferrerIntent in project platform_frameworks_base by android.

the class ActivityRecord method deliverNewIntentLocked.

/**
     * Deliver a new Intent to an existing activity, so that its onNewIntent()
     * method will be called at the proper time.
     */
final void deliverNewIntentLocked(int callingUid, Intent intent, String referrer) {
    // The activity now gets access to the data associated with this Intent.
    service.grantUriPermissionFromIntentLocked(callingUid, packageName, intent, getUriPermissionsLocked(), userId);
    final ReferrerIntent rintent = new ReferrerIntent(intent, referrer);
    boolean unsent = true;
    final ActivityStack stack = task.stack;
    final boolean isTopActivityInStack = stack != null && stack.topRunningActivityLocked() == this;
    final boolean isTopActivityWhileSleeping = service.isSleepingLocked() && isTopActivityInStack;
    // - The device is sleeping and it is the top activity behind the lock screen (b/6700897).
    if ((state == ActivityState.RESUMED || state == ActivityState.PAUSED || isTopActivityWhileSleeping) && app != null && app.thread != null) {
        try {
            ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
            ar.add(rintent);
            app.thread.scheduleNewIntent(ar, appToken, state == ActivityState.PAUSED);
            unsent = false;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
        } catch (NullPointerException e) {
            Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
        }
    }
    if (unsent) {
        addNewIntentLocked(rintent);
    }
}
Also used : ReferrerIntent(com.android.internal.content.ReferrerIntent) ArrayList(java.util.ArrayList) RemoteException(android.os.RemoteException)

Example 15 with ReferrerIntent

use of com.android.internal.content.ReferrerIntent in project platform_frameworks_base by android.

the class ActivityStack method relaunchActivityLocked.

private void relaunchActivityLocked(ActivityRecord r, int changes, boolean andResume, boolean preserveWindow) {
    if (mService.mSuppressResizeConfigChanges && preserveWindow) {
        r.configChangeFlags = 0;
        return;
    }
    List<ResultInfo> results = null;
    List<ReferrerIntent> newIntents = null;
    if (andResume) {
        results = r.results;
        newIntents = r.newIntents;
    }
    if (DEBUG_SWITCH)
        Slog.v(TAG_SWITCH, "Relaunching: " + r + " with results=" + results + " newIntents=" + newIntents + " andResume=" + andResume + " preserveWindow=" + preserveWindow);
    EventLog.writeEvent(andResume ? EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY : EventLogTags.AM_RELAUNCH_ACTIVITY, r.userId, System.identityHashCode(r), r.task.taskId, r.shortComponentName);
    r.startFreezingScreenLocked(r.app, 0);
    mStackSupervisor.removeChildActivityContainers(r);
    try {
        if (DEBUG_SWITCH || DEBUG_STATES)
            Slog.i(TAG_SWITCH, "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + r + " callers=" + Debug.getCallers(6));
        r.forceNewConfig = false;
        mStackSupervisor.activityRelaunchingLocked(r);
        r.app.thread.scheduleRelaunchActivity(r.appToken, results, newIntents, changes, !andResume, new Configuration(mService.mConfiguration), new Configuration(r.task.mOverrideConfig), preserveWindow);
    // Note: don't need to call pauseIfSleepingLocked() here, because
    // the caller will only pass in 'andResume' if this activity is
    // currently resumed, which implies we aren't sleeping.
    } catch (RemoteException e) {
        if (DEBUG_SWITCH || DEBUG_STATES)
            Slog.i(TAG_SWITCH, "Relaunch failed", e);
    }
    if (andResume) {
        if (DEBUG_STATES) {
            Slog.d(TAG_STATES, "Resumed after relaunch " + r);
        }
        r.state = ActivityState.RESUMED;
        // code in resumeTopActivityInnerLocked to complete the resume might be skipped.
        if (!r.visible || r.stopped) {
            mWindowManager.setAppVisibility(r.appToken, true);
            completeResumeLocked(r);
        } else {
            r.results = null;
            r.newIntents = null;
        }
        mService.showUnsupportedZoomDialogIfNeededLocked(r);
        mService.showAskCompatModeDialogLocked(r);
    } else {
        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
        r.state = ActivityState.PAUSED;
    }
    r.configChangeFlags = 0;
    r.deferRelaunchUntilPaused = false;
    r.preserveWindowOnDeferredRelaunch = false;
}
Also used : ReferrerIntent(com.android.internal.content.ReferrerIntent) Configuration(android.content.res.Configuration) ResultInfo(android.app.ResultInfo) RemoteException(android.os.RemoteException)

Aggregations

ReferrerIntent (com.android.internal.content.ReferrerIntent)25 RemoteException (android.os.RemoteException)15 ResultInfo (android.app.ResultInfo)10 Configuration (android.content.res.Configuration)10 ArrayList (java.util.ArrayList)10 ProfilerInfo (android.app.ProfilerInfo)5 Intent (android.content.Intent)5 ActivityInfo (android.content.pm.ActivityInfo)5 Message (android.os.Message)5 ParcelFileDescriptor (android.os.ParcelFileDescriptor)5 IOException (java.io.IOException)5