Loading core/java/android/app/ActivityThread.java +30 −16 Original line number Original line Diff line number Diff line Loading @@ -433,8 +433,10 @@ public final class ActivityThread { static final class NewIntentData { static final class NewIntentData { List<ReferrerIntent> intents; List<ReferrerIntent> intents; IBinder token; IBinder token; boolean andPause; public String toString() { public String toString() { return "NewIntentData{intents=" + intents + " token=" + token + "}"; return "NewIntentData{intents=" + intents + " token=" + token + " andPause=" + andPause +"}"; } } } } Loading Loading @@ -751,10 +753,12 @@ public final class ActivityThread { configChanges, notResumed, config, overrideConfig, true, preserveWindow); configChanges, notResumed, config, overrideConfig, true, preserveWindow); } } public final void scheduleNewIntent(List<ReferrerIntent> intents, IBinder token) { public final void scheduleNewIntent( List<ReferrerIntent> intents, IBinder token, boolean andPause) { NewIntentData data = new NewIntentData(); NewIntentData data = new NewIntentData(); data.intents = intents; data.intents = intents; data.token = token; data.token = token; data.andPause = andPause; sendMessage(H.NEW_INTENT, data); sendMessage(H.NEW_INTENT, data); } } Loading Loading @@ -2787,9 +2791,12 @@ public final class ActivityThread { } } } } public final void performNewIntents(IBinder token, List<ReferrerIntent> intents) { void performNewIntents(IBinder token, List<ReferrerIntent> intents, boolean andPause) { ActivityClientRecord r = mActivities.get(token); final ActivityClientRecord r = mActivities.get(token); if (r != null) { if (r == null) { return; } final boolean resumed = !r.paused; final boolean resumed = !r.paused; if (resumed) { if (resumed) { r.activity.mTemporaryPause = true; r.activity.mTemporaryPause = true; Loading @@ -2800,11 +2807,18 @@ public final class ActivityThread { r.activity.performResume(); r.activity.performResume(); r.activity.mTemporaryPause = false; r.activity.mTemporaryPause = false; } } if (r.paused && andPause) { // In this case the activity was in the paused state when we delivered the intent, // to guarantee onResume gets called after onNewIntent we temporarily resume the // activity and pause again as the caller wanted. performResumeActivity(token, false, "performNewIntents"); performPauseActivityIfNeeded(r, "performNewIntents"); } } } } private void handleNewIntent(NewIntentData data) { private void handleNewIntent(NewIntentData data) { performNewIntents(data.token, data.intents); performNewIntents(data.token, data.intents, data.andPause); } } public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) { public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) { Loading core/java/android/app/ApplicationThreadNative.java +4 −2 Original line number Original line Diff line number Diff line Loading @@ -190,7 +190,8 @@ public abstract class ApplicationThreadNative extends Binder data.enforceInterface(IApplicationThread.descriptor); data.enforceInterface(IApplicationThread.descriptor); List<ReferrerIntent> pi = data.createTypedArrayList(ReferrerIntent.CREATOR); List<ReferrerIntent> pi = data.createTypedArrayList(ReferrerIntent.CREATOR); IBinder b = data.readStrongBinder(); IBinder b = data.readStrongBinder(); scheduleNewIntent(pi, b); final boolean andPause = data.readInt() == 1; scheduleNewIntent(pi, b, andPause); return true; return true; } } Loading Loading @@ -909,12 +910,13 @@ class ApplicationThreadProxy implements IApplicationThread { data.recycle(); data.recycle(); } } public void scheduleNewIntent(List<ReferrerIntent> intents, IBinder token) public void scheduleNewIntent(List<ReferrerIntent> intents, IBinder token, boolean andPause) throws RemoteException { throws RemoteException { Parcel data = Parcel.obtain(); Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeTypedList(intents); data.writeTypedList(intents); data.writeStrongBinder(token); data.writeStrongBinder(token); data.writeInt(andPause ? 1 : 0); mRemote.transact(SCHEDULE_NEW_INTENT_TRANSACTION, data, null, mRemote.transact(SCHEDULE_NEW_INTENT_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); IBinder.FLAG_ONEWAY); data.recycle(); data.recycle(); Loading core/java/android/app/IApplicationThread.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -67,7 +67,8 @@ public interface IApplicationThread extends IInterface { List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed, List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed, Configuration config, Configuration overrideConfig, boolean preserveWindow) Configuration config, Configuration overrideConfig, boolean preserveWindow) throws RemoteException; throws RemoteException; void scheduleNewIntent(List<ReferrerIntent> intent, IBinder token) throws RemoteException; void scheduleNewIntent( List<ReferrerIntent> intent, IBinder token, boolean andPause) throws RemoteException; void scheduleDestroyActivity(IBinder token, boolean finished, void scheduleDestroyActivity(IBinder token, boolean finished, int configChanges) throws RemoteException; int configChanges) throws RemoteException; void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo, void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo, Loading core/java/android/app/LocalActivityManager.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -314,7 +314,7 @@ public class LocalActivityManager { ArrayList<ReferrerIntent> intents = new ArrayList<>(1); ArrayList<ReferrerIntent> intents = new ArrayList<>(1); intents.add(new ReferrerIntent(intent, mParent.getPackageName())); intents.add(new ReferrerIntent(intent, mParent.getPackageName())); if (localLOGV) Log.v(TAG, r.id + ": new intent"); if (localLOGV) Log.v(TAG, r.id + ": new intent"); mActivityThread.performNewIntents(r, intents); mActivityThread.performNewIntents(r, intents, false /* andPause */); r.intent = intent; r.intent = intent; moveToState(r, mCurState); moveToState(r, mCurState); if (mSingleMode) { if (mSingleMode) { Loading services/core/java/com/android/server/am/ActivityRecord.java +19 −10 Original line number Original line Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.am; package com.android.server.am; import static android.app.ActivityManager.StackId; import static android.app.ActivityManager.StackId; import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS; import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS; Loading Loading @@ -946,21 +947,29 @@ final class ActivityRecord { // The activity now gets access to the data associated with this Intent. // The activity now gets access to the data associated with this Intent. service.grantUriPermissionFromIntentLocked(callingUid, packageName, service.grantUriPermissionFromIntentLocked(callingUid, packageName, intent, getUriPermissionsLocked(), userId); intent, getUriPermissionsLocked(), userId); // We want to immediately deliver the intent to the activity if // it is currently the top resumed activity... however, if the // device is sleeping, then all activities are stopped, so in that // case we will deliver it if this is the current top activity on its // stack. final ReferrerIntent rintent = new ReferrerIntent(intent, referrer); final ReferrerIntent rintent = new ReferrerIntent(intent, referrer); boolean unsent = true; boolean unsent = true; if ((state == ActivityState.RESUMED final ActivityStack stack = task.stack; || (service.isSleepingLocked() && task.stack != null final boolean isTopActivityInStack = && task.stack.topRunningActivityLocked() == this)) stack != null && stack.topRunningActivityLocked() == this; && app != null && app.thread != null) { final boolean isTopActivityWhileSleeping = service.isSleepingLocked() && isTopActivityInStack; final boolean isTopActivityInMinimizedDockedStack = isTopActivityInStack && stack.mStackId == DOCKED_STACK_ID && mStackSupervisor.mIsDockMinimized && state == ActivityState.PAUSED; // We want to immediately deliver the intent to the activity if: // - It is the resumed activity. // - The device is sleeping and it is the top activity behind the lock screen (b/6700897). // - It is the top activity in a minimized docked stack. In this case the activity will be // temporarily resumed then paused again on the client side. if ((state == ActivityState.RESUMED || isTopActivityWhileSleeping || isTopActivityInMinimizedDockedStack) && app != null && app.thread != null) { try { try { ArrayList<ReferrerIntent> ar = new ArrayList<>(1); ArrayList<ReferrerIntent> ar = new ArrayList<>(1); ar.add(rintent); ar.add(rintent); app.thread.scheduleNewIntent(ar, appToken); app.thread.scheduleNewIntent( ar, appToken, isTopActivityInMinimizedDockedStack /* andPause */); unsent = false; unsent = false; } catch (RemoteException e) { } catch (RemoteException e) { Slog.w(TAG, "Exception thrown sending new intent to " + this, e); Slog.w(TAG, "Exception thrown sending new intent to " + this, e); Loading Loading
core/java/android/app/ActivityThread.java +30 −16 Original line number Original line Diff line number Diff line Loading @@ -433,8 +433,10 @@ public final class ActivityThread { static final class NewIntentData { static final class NewIntentData { List<ReferrerIntent> intents; List<ReferrerIntent> intents; IBinder token; IBinder token; boolean andPause; public String toString() { public String toString() { return "NewIntentData{intents=" + intents + " token=" + token + "}"; return "NewIntentData{intents=" + intents + " token=" + token + " andPause=" + andPause +"}"; } } } } Loading Loading @@ -751,10 +753,12 @@ public final class ActivityThread { configChanges, notResumed, config, overrideConfig, true, preserveWindow); configChanges, notResumed, config, overrideConfig, true, preserveWindow); } } public final void scheduleNewIntent(List<ReferrerIntent> intents, IBinder token) { public final void scheduleNewIntent( List<ReferrerIntent> intents, IBinder token, boolean andPause) { NewIntentData data = new NewIntentData(); NewIntentData data = new NewIntentData(); data.intents = intents; data.intents = intents; data.token = token; data.token = token; data.andPause = andPause; sendMessage(H.NEW_INTENT, data); sendMessage(H.NEW_INTENT, data); } } Loading Loading @@ -2787,9 +2791,12 @@ public final class ActivityThread { } } } } public final void performNewIntents(IBinder token, List<ReferrerIntent> intents) { void performNewIntents(IBinder token, List<ReferrerIntent> intents, boolean andPause) { ActivityClientRecord r = mActivities.get(token); final ActivityClientRecord r = mActivities.get(token); if (r != null) { if (r == null) { return; } final boolean resumed = !r.paused; final boolean resumed = !r.paused; if (resumed) { if (resumed) { r.activity.mTemporaryPause = true; r.activity.mTemporaryPause = true; Loading @@ -2800,11 +2807,18 @@ public final class ActivityThread { r.activity.performResume(); r.activity.performResume(); r.activity.mTemporaryPause = false; r.activity.mTemporaryPause = false; } } if (r.paused && andPause) { // In this case the activity was in the paused state when we delivered the intent, // to guarantee onResume gets called after onNewIntent we temporarily resume the // activity and pause again as the caller wanted. performResumeActivity(token, false, "performNewIntents"); performPauseActivityIfNeeded(r, "performNewIntents"); } } } } private void handleNewIntent(NewIntentData data) { private void handleNewIntent(NewIntentData data) { performNewIntents(data.token, data.intents); performNewIntents(data.token, data.intents, data.andPause); } } public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) { public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) { Loading
core/java/android/app/ApplicationThreadNative.java +4 −2 Original line number Original line Diff line number Diff line Loading @@ -190,7 +190,8 @@ public abstract class ApplicationThreadNative extends Binder data.enforceInterface(IApplicationThread.descriptor); data.enforceInterface(IApplicationThread.descriptor); List<ReferrerIntent> pi = data.createTypedArrayList(ReferrerIntent.CREATOR); List<ReferrerIntent> pi = data.createTypedArrayList(ReferrerIntent.CREATOR); IBinder b = data.readStrongBinder(); IBinder b = data.readStrongBinder(); scheduleNewIntent(pi, b); final boolean andPause = data.readInt() == 1; scheduleNewIntent(pi, b, andPause); return true; return true; } } Loading Loading @@ -909,12 +910,13 @@ class ApplicationThreadProxy implements IApplicationThread { data.recycle(); data.recycle(); } } public void scheduleNewIntent(List<ReferrerIntent> intents, IBinder token) public void scheduleNewIntent(List<ReferrerIntent> intents, IBinder token, boolean andPause) throws RemoteException { throws RemoteException { Parcel data = Parcel.obtain(); Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeTypedList(intents); data.writeTypedList(intents); data.writeStrongBinder(token); data.writeStrongBinder(token); data.writeInt(andPause ? 1 : 0); mRemote.transact(SCHEDULE_NEW_INTENT_TRANSACTION, data, null, mRemote.transact(SCHEDULE_NEW_INTENT_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); IBinder.FLAG_ONEWAY); data.recycle(); data.recycle(); Loading
core/java/android/app/IApplicationThread.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -67,7 +67,8 @@ public interface IApplicationThread extends IInterface { List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed, List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed, Configuration config, Configuration overrideConfig, boolean preserveWindow) Configuration config, Configuration overrideConfig, boolean preserveWindow) throws RemoteException; throws RemoteException; void scheduleNewIntent(List<ReferrerIntent> intent, IBinder token) throws RemoteException; void scheduleNewIntent( List<ReferrerIntent> intent, IBinder token, boolean andPause) throws RemoteException; void scheduleDestroyActivity(IBinder token, boolean finished, void scheduleDestroyActivity(IBinder token, boolean finished, int configChanges) throws RemoteException; int configChanges) throws RemoteException; void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo, void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo, Loading
core/java/android/app/LocalActivityManager.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -314,7 +314,7 @@ public class LocalActivityManager { ArrayList<ReferrerIntent> intents = new ArrayList<>(1); ArrayList<ReferrerIntent> intents = new ArrayList<>(1); intents.add(new ReferrerIntent(intent, mParent.getPackageName())); intents.add(new ReferrerIntent(intent, mParent.getPackageName())); if (localLOGV) Log.v(TAG, r.id + ": new intent"); if (localLOGV) Log.v(TAG, r.id + ": new intent"); mActivityThread.performNewIntents(r, intents); mActivityThread.performNewIntents(r, intents, false /* andPause */); r.intent = intent; r.intent = intent; moveToState(r, mCurState); moveToState(r, mCurState); if (mSingleMode) { if (mSingleMode) { Loading
services/core/java/com/android/server/am/ActivityRecord.java +19 −10 Original line number Original line Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.am; package com.android.server.am; import static android.app.ActivityManager.StackId; import static android.app.ActivityManager.StackId; import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS; import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS; Loading Loading @@ -946,21 +947,29 @@ final class ActivityRecord { // The activity now gets access to the data associated with this Intent. // The activity now gets access to the data associated with this Intent. service.grantUriPermissionFromIntentLocked(callingUid, packageName, service.grantUriPermissionFromIntentLocked(callingUid, packageName, intent, getUriPermissionsLocked(), userId); intent, getUriPermissionsLocked(), userId); // We want to immediately deliver the intent to the activity if // it is currently the top resumed activity... however, if the // device is sleeping, then all activities are stopped, so in that // case we will deliver it if this is the current top activity on its // stack. final ReferrerIntent rintent = new ReferrerIntent(intent, referrer); final ReferrerIntent rintent = new ReferrerIntent(intent, referrer); boolean unsent = true; boolean unsent = true; if ((state == ActivityState.RESUMED final ActivityStack stack = task.stack; || (service.isSleepingLocked() && task.stack != null final boolean isTopActivityInStack = && task.stack.topRunningActivityLocked() == this)) stack != null && stack.topRunningActivityLocked() == this; && app != null && app.thread != null) { final boolean isTopActivityWhileSleeping = service.isSleepingLocked() && isTopActivityInStack; final boolean isTopActivityInMinimizedDockedStack = isTopActivityInStack && stack.mStackId == DOCKED_STACK_ID && mStackSupervisor.mIsDockMinimized && state == ActivityState.PAUSED; // We want to immediately deliver the intent to the activity if: // - It is the resumed activity. // - The device is sleeping and it is the top activity behind the lock screen (b/6700897). // - It is the top activity in a minimized docked stack. In this case the activity will be // temporarily resumed then paused again on the client side. if ((state == ActivityState.RESUMED || isTopActivityWhileSleeping || isTopActivityInMinimizedDockedStack) && app != null && app.thread != null) { try { try { ArrayList<ReferrerIntent> ar = new ArrayList<>(1); ArrayList<ReferrerIntent> ar = new ArrayList<>(1); ar.add(rintent); ar.add(rintent); app.thread.scheduleNewIntent(ar, appToken); app.thread.scheduleNewIntent( ar, appToken, isTopActivityInMinimizedDockedStack /* andPause */); unsent = false; unsent = false; } catch (RemoteException e) { } catch (RemoteException e) { Slog.w(TAG, "Exception thrown sending new intent to " + this, e); Slog.w(TAG, "Exception thrown sending new intent to " + this, e); Loading