use of com.android.internal.content.ReferrerIntent in project android_frameworks_base by ResurrectionRemix.
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);
}
}
use of com.android.internal.content.ReferrerIntent in project android_frameworks_base by ResurrectionRemix.
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;
}
use of com.android.internal.content.ReferrerIntent in project android_frameworks_base by ResurrectionRemix.
the class ActivityThread method deliverNewIntents.
private void deliverNewIntents(ActivityClientRecord r, List<ReferrerIntent> intents) {
final int N = intents.size();
for (int i = 0; i < N; i++) {
ReferrerIntent intent = intents.get(i);
intent.setExtrasClassLoader(r.activity.getClassLoader());
intent.prepareToEnterProcess();
r.activity.mFragments.noteStateNotSaved();
mInstrumentation.callActivityOnNewIntent(r.activity, intent);
}
}
use of com.android.internal.content.ReferrerIntent in project android_frameworks_base by crdroidandroid.
the class ActivityThread method deliverNewIntents.
private void deliverNewIntents(ActivityClientRecord r, List<ReferrerIntent> intents) {
final int N = intents.size();
for (int i = 0; i < N; i++) {
ReferrerIntent intent = intents.get(i);
intent.setExtrasClassLoader(r.activity.getClassLoader());
intent.prepareToEnterProcess();
r.activity.mFragments.noteStateNotSaved();
mInstrumentation.callActivityOnNewIntent(r.activity, intent);
}
}
use of com.android.internal.content.ReferrerIntent in project android_frameworks_base by crdroidandroid.
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;
}
Aggregations