DO NOT MERGE -- Only use saved surface if started by launcher or moved to front
Restrict saved surface to launcher start (ACTION_MAIN&CATEGORY_
LAUNCHER), or there is no intent at all (eg. task being brought to
front). If the intent is something else, likely the app is going
to show some specific page or view, instead of what's left last time.
This solves problems like the launcher shortcuts on DeckClock,
each of them is a different intent and will show one specific
view regardless of last states. Another example is Chrome tab
opened directly by action VIEW to open some URL.
(Note that this doesn't solve the problem with Chrome homescreen
shortcuts, it will still start with saved surface (if Chrome
is already open). This is because the shortcut is a trampoline
activity that starts the real chrome tab activity, but when
the trampoline is started, the whole task is already brought
to front, and ChromeTab could become visible with the task
before we actually start it.)
bug: 31055479
bug: 27747315
Change-Id: Id3e61c61ef516b0edc1f174320f02661222f226b
(cherry picked from commit ad24f96def)
This commit is contained in:
@@ -173,7 +173,7 @@ interface IWindowManager
|
||||
in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
|
||||
int icon, int logo, int windowFlags, IBinder transferFrom, boolean createIfNeeded);
|
||||
void setAppVisibility(IBinder token, boolean visible);
|
||||
void notifyAppResumed(IBinder token, boolean wasStopped);
|
||||
void notifyAppResumed(IBinder token, boolean wasStopped, boolean allowSavedSurface);
|
||||
void notifyAppStopped(IBinder token);
|
||||
void startAppFreezingScreen(IBinder token, int configChanges);
|
||||
void stopAppFreezingScreen(IBinder token, boolean force);
|
||||
|
||||
@@ -750,6 +750,14 @@ final class ActivityRecord {
|
||||
&& intent.getType() == null;
|
||||
}
|
||||
|
||||
static boolean isMainIntent(Intent intent) {
|
||||
return Intent.ACTION_MAIN.equals(intent.getAction())
|
||||
&& intent.hasCategory(Intent.CATEGORY_LAUNCHER)
|
||||
&& intent.getCategories().size() == 1
|
||||
&& intent.getData() == null
|
||||
&& intent.getType() == null;
|
||||
}
|
||||
|
||||
private boolean canLaunchHomeActivity(int uid, ActivityRecord sourceRecord) {
|
||||
if (uid == Process.myUid() || uid == 0) {
|
||||
// System process can launch home activity.
|
||||
|
||||
@@ -2485,13 +2485,25 @@ final class ActivityStack {
|
||||
}
|
||||
}
|
||||
|
||||
boolean allowSavedSurface = true;
|
||||
if (next.newIntents != null) {
|
||||
// Restrict saved surface to launcher start, or there is no intent at all
|
||||
// (eg. task being brought to front). If the intent is something else,
|
||||
// likely the app is going to show some specific page or view, instead of
|
||||
// what's left last time.
|
||||
for (int i = next.newIntents.size() - 1; i >= 0; i--) {
|
||||
final Intent intent = next.newIntents.get(i);
|
||||
if (intent != null && !ActivityRecord.isMainIntent(intent)) {
|
||||
allowSavedSurface = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);
|
||||
}
|
||||
|
||||
// Well the app will no longer be stopped.
|
||||
// Clear app token stopped state in window manager if needed.
|
||||
mWindowManager.notifyAppResumed(next.appToken, next.stopped);
|
||||
mWindowManager.notifyAppResumed(next.appToken, next.stopped, allowSavedSurface);
|
||||
|
||||
EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
|
||||
System.identityHashCode(next), next.task.taskId, next.shortComponentName);
|
||||
|
||||
@@ -439,12 +439,16 @@ class AppWindowToken extends WindowToken {
|
||||
* Notify that the app is now resumed, and it was not stopped before, perform a clean
|
||||
* up of the surfaces
|
||||
*/
|
||||
void notifyAppResumed(boolean wasStopped) {
|
||||
if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped + " " + this);
|
||||
void notifyAppResumed(boolean wasStopped, boolean allowSavedSurface) {
|
||||
if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped
|
||||
+ " allowSavedSurface=" + allowSavedSurface + " " + this);
|
||||
mAppStopped = false;
|
||||
if (!wasStopped) {
|
||||
destroySurfaces(true /*cleanupOnResume*/);
|
||||
}
|
||||
if (!allowSavedSurface) {
|
||||
destroySavedSurfaces();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4480,7 +4480,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyAppResumed(IBinder token, boolean wasStopped) {
|
||||
public void notifyAppResumed(IBinder token, boolean wasStopped, boolean allowSavedSurface) {
|
||||
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
|
||||
"notifyAppResumed()")) {
|
||||
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
|
||||
@@ -4493,7 +4493,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: " + token);
|
||||
return;
|
||||
}
|
||||
wtoken.notifyAppResumed(wasStopped);
|
||||
wtoken.notifyAppResumed(wasStopped, allowSavedSurface);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -351,7 +351,8 @@ public class IWindowManagerImpl implements IWindowManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyAppResumed(IBinder token, boolean wasStopped) throws RemoteException {
|
||||
public void notifyAppResumed(IBinder token, boolean wasStopped, boolean allowSavedSurface)
|
||||
throws RemoteException {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user