OSDN Git Service

Use splashscreen if we can't fill horizontaly with snapshot
authorJorim Jaggi <jjaggi@google.com>
Tue, 13 Jun 2017 18:54:04 +0000 (11:54 -0700)
committerJorim Jaggi <jjaggi@google.com>
Thu, 15 Jun 2017 01:34:37 +0000 (18:34 -0700)
A gap at the right side of the snapshot looks pretty bad. Thus,
we use a splash screen in case there would be a gap on the right
side. However, we don't want to do this from recents as we'd
produce another flicker

Test: go/wm-smoke
Test: Open app portrait, go launcher, rotate, open app landscape
Test: Open app landscape, go launcher rotate, open app portrait
Fixes: 62094756
Change-Id: Iaf1fecced822685187477a4698fa6b67c6e485d7

services/core/java/com/android/server/am/ActivityManagerService.java
services/core/java/com/android/server/am/ActivityRecord.java
services/core/java/com/android/server/am/ActivityStackSupervisor.java
services/core/java/com/android/server/wm/AppWindowContainerController.java
services/core/java/com/android/server/wm/WindowManagerService.java
services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java

index 30df978..a25a1bf 100644 (file)
@@ -10254,11 +10254,11 @@ public class ActivityManagerService extends IActivityManager.Stub
 
         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
         synchronized(this) {
-            moveTaskToFrontLocked(taskId, flags, bOptions);
+            moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
         }
     }
 
-    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
+    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
 
         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
@@ -10291,7 +10291,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                 // We are reshowing a task, use a starting window to hide the initial draw delay
                 // so the transition can start earlier.
                 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
-                        true /* taskSwitch */);
+                        true /* taskSwitch */, fromRecents);
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
index ec6a4f6..a826b68 100644 (file)
@@ -2153,6 +2153,11 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
     }
 
     void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch) {
+        showStartingWindow(prev, newTask, taskSwitch, false /* fromRecents */);
+    }
+
+    void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch,
+            boolean fromRecents) {
         if (mWindowContainerController == null) {
             return;
         }
@@ -2167,7 +2172,8 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
                 compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
                 prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
                 allowTaskSnapshot(),
-                state.ordinal() >= RESUMED.ordinal() && state.ordinal() <= STOPPED.ordinal());
+                state.ordinal() >= RESUMED.ordinal() && state.ordinal() <= STOPPED.ordinal(),
+                fromRecents);
         if (shown) {
             mStartingWindowState = STARTING_WINDOW_SHOWN;
         }
index 53afe78..7de56fa 100644 (file)
@@ -5131,7 +5131,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
                     && task.getRootActivity() != null) {
                 mService.mActivityStarter.sendPowerHintForLaunchStartIfNeeded(true /* forceSend */);
                 mActivityMetricsLogger.notifyActivityLaunching();
-                mService.moveTaskToFrontLocked(task.taskId, 0, bOptions);
+                mService.moveTaskToFrontLocked(task.taskId, 0, bOptions, true /* fromRecents */);
                 mActivityMetricsLogger.notifyActivityLaunched(ActivityManager.START_TASK_TO_FRONT,
                         task.getTopActivity());
 
index 8cfbf68..e550a5e 100644 (file)
@@ -40,6 +40,7 @@ import android.os.Handler;
 import android.os.IBinder;
 import android.os.Trace;
 import android.util.Slog;
+import android.view.DisplayInfo;
 import android.view.IApplicationToken;
 import android.view.WindowManagerPolicy.StartingSurface;
 
@@ -481,7 +482,7 @@ public class AppWindowContainerController
     public boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo,
             CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
             IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning,
-            boolean allowTaskSnapshot, boolean activityCreated) {
+            boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents) {
         synchronized(mWindowMap) {
             if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "setAppStartingWindow: token=" + mToken
                     + " pkg=" + pkg + " transferFrom=" + transferFrom + " newTask=" + newTask
@@ -510,11 +511,14 @@ public class AppWindowContainerController
                 return false;
             }
 
+            final TaskSnapshot snapshot = mService.mTaskSnapshotController.getSnapshot(
+                    mContainer.getTask().mTaskId, mContainer.getTask().mUserId,
+                    false /* restoreFromDisk */, false /* reducedResolution */);
             final int type = getStartingWindowType(newTask, taskSwitch, processRunning,
-                    allowTaskSnapshot, activityCreated);
+                    allowTaskSnapshot, activityCreated, fromRecents, snapshot);
 
             if (type == STARTING_WINDOW_TYPE_SNAPSHOT) {
-                return createSnapshot();
+                return createSnapshot(snapshot);
             }
 
             // If this is a translucent window, then don't show a starting window -- the current
@@ -582,7 +586,8 @@ public class AppWindowContainerController
     }
 
     private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning,
-            boolean allowTaskSnapshot, boolean activityCreated) {
+            boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents,
+            TaskSnapshot snapshot) {
         if (mService.mAppTransition.getAppTransition() == TRANSIT_DOCK_TASK_FROM_RECENTS) {
             // TODO(b/34099271): Remove this statement to add back the starting window and figure
             // out why it causes flickering, the starting window appears over the thumbnail while
@@ -591,7 +596,9 @@ public class AppWindowContainerController
         } else if (newTask || !processRunning || (taskSwitch && !activityCreated)) {
             return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
         } else if (taskSwitch && allowTaskSnapshot) {
-            return STARTING_WINDOW_TYPE_SNAPSHOT;
+            return snapshot == null ? STARTING_WINDOW_TYPE_NONE
+                    : snapshotFillsWidth(snapshot) || fromRecents ? STARTING_WINDOW_TYPE_SNAPSHOT
+                    : STARTING_WINDOW_TYPE_SPLASH_SCREEN;
         } else {
             return STARTING_WINDOW_TYPE_NONE;
         }
@@ -605,11 +612,7 @@ public class AppWindowContainerController
         mService.mAnimationHandler.postAtFrontOfQueue(mAddStartingWindow);
     }
 
-    private boolean createSnapshot() {
-        final TaskSnapshot snapshot = mService.mTaskSnapshotController.getSnapshot(
-                mContainer.getTask().mTaskId, mContainer.getTask().mUserId,
-                false /* restoreFromDisk */, false /* reducedResolution */);
-
+    private boolean createSnapshot(TaskSnapshot snapshot) {
         if (snapshot == null) {
             return false;
         }
@@ -620,6 +623,24 @@ public class AppWindowContainerController
         return true;
     }
 
+    private boolean snapshotFillsWidth(TaskSnapshot snapshot) {
+        if (snapshot == null) {
+            return false;
+        }
+        final Rect rect = new Rect(0, 0, snapshot.getSnapshot().getWidth(),
+                snapshot.getSnapshot().getHeight());
+        rect.inset(snapshot.getContentInsets());
+        final Rect taskBoundsWithoutInsets = new Rect();
+        mContainer.getTask().getBounds(taskBoundsWithoutInsets);
+        final DisplayInfo di = mContainer.getDisplayContent().getDisplayInfo();
+        final Rect displayBounds = new Rect(0, 0, di.logicalWidth, di.logicalHeight);
+        final Rect stableInsets = new Rect();
+        mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
+                stableInsets);
+        displayBounds.inset(stableInsets);
+        return rect.width() >= displayBounds.width();
+    }
+
     public void removeStartingWindow() {
         synchronized (mWindowMap) {
             if (mHandler.hasCallbacks(mRemoveStartingWindow)) {
index 768b03a..6e1d0d8 100644 (file)
@@ -1266,14 +1266,6 @@ public class WindowManagerService extends IWindowManager.Stub
                           + token + ".  Aborting.");
                     return WindowManagerGlobal.ADD_APP_EXITING;
                 }
-                if (rootType == TYPE_APPLICATION_STARTING
-                        && (attrs.privateFlags & PRIVATE_FLAG_TASK_SNAPSHOT) == 0
-                        && atoken.firstWindowDrawn) {
-                    // No need for this guy!
-                    if (DEBUG_STARTING_WINDOW || localLOGV) Slog.v(
-                            TAG_WM, "**** NO NEED TO START: " + attrs.getTitle());
-                    return WindowManagerGlobal.ADD_STARTING_NOT_NEEDED;
-                }
             } else if (rootType == TYPE_INPUT_METHOD) {
                 if (token.windowType != TYPE_INPUT_METHOD) {
                     Slog.w(TAG_WM, "Attempted to add input method window with bad token "
index 65a5632..6060881 100644 (file)
@@ -107,7 +107,7 @@ public class AppWindowContainerControllerTests extends WindowTestsBase {
                 createAppWindowController();
         controller.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
-                false);
+                false, false);
         waitUntilHandlersIdle();
         final AppWindowToken atoken = controller.getAppWindowToken(mDisplayContent);
         assertHasStartingWindow(atoken);
@@ -125,7 +125,7 @@ public class AppWindowContainerControllerTests extends WindowTestsBase {
                     createAppWindowController();
             controller.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
                     android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
-                    false);
+                    false, false);
             controller.removeStartingWindow();
             waitUntilHandlersIdle();
             assertNoStartingWindow(controller.getAppWindowToken(mDisplayContent));
@@ -140,11 +140,11 @@ public class AppWindowContainerControllerTests extends WindowTestsBase {
                 createAppWindowController();
         controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
-                false);
+                false, false);
         waitUntilHandlersIdle();
         controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(),
-                true, true, false, true, false);
+                true, true, false, true, false, false);
         waitUntilHandlersIdle();
         assertNoStartingWindow(controller1.getAppWindowToken(mDisplayContent));
         assertHasStartingWindow(controller2.getAppWindowToken(mDisplayContent));
@@ -161,11 +161,11 @@ public class AppWindowContainerControllerTests extends WindowTestsBase {
             // Surprise, ...! Transfer window in the middle of the creation flow.
             controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
                     android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(),
-                    true, true, false, true, false);
+                    true, true, false, true, false, false);
         });
         controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
-                false);
+                false, false);
         waitUntilHandlersIdle();
         assertNoStartingWindow(controller1.getAppWindowToken(mDisplayContent));
         assertHasStartingWindow(controller2.getAppWindowToken(mDisplayContent));