Loading core/java/android/window/flags/windowing_frontend.aconfig +11 −0 Original line number Diff line number Diff line Loading @@ -511,6 +511,17 @@ flag { } } flag { name: "exclude_non_main_window_from_snapshot" namespace: "windowing_frontend" description: "Exclude non-main windows during their removal from being captured in the snapshot." bug: "412295455" is_fixed_read_only: true metadata { purpose: PURPOSE_BUGFIX } } flag { name: "current_animator_scale_uses_shared_memory" namespace: "wear_system_health" Loading services/core/java/com/android/server/wm/AbsAppSnapshotController.java +18 −13 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; Loading Loading @@ -54,6 +55,7 @@ import com.android.server.wm.utils.InsetUtils; import com.android.window.flags.Flags; import java.io.PrintWriter; import java.util.ArrayList; import java.util.function.Consumer; import java.util.function.Supplier; Loading @@ -62,7 +64,7 @@ import java.util.function.Supplier; * @param <TYPE> The basic type, either Task or ActivityRecord * @param <CACHE> The basic cache for either Task or ActivityRecord */ abstract class AbsAppSnapshotController<TYPE extends WindowContainer, abstract class AbsAppSnapshotController<TYPE extends WindowContainer<?>, CACHE extends SnapshotCache<TYPE>> { static final String TAG = TAG_WITH_CLASS_NAME ? "SnapshotController" : TAG_WM; /** Loading Loading @@ -267,28 +269,31 @@ abstract class AbsAppSnapshotController<TYPE extends WindowContainer, } return null; } SurfaceControl[] excludeLayers; final WindowState imeWindow = source.getDisplayContent().mInputMethodWindow; // Exclude IME window snapshot when IME isn't proper to attach to app. final boolean excludeIme = imeWindow != null && imeWindow.getSurfaceControl() != null && !source.getDisplayContent().shouldImeAttachedToApp(); final WindowState navWindow = source.getDisplayContent().getDisplayPolicy().getNavigationBar(); final ArrayList<SurfaceControl> excludeSurfaces = new ArrayList<>(); if (excludeIme) { excludeSurfaces.add(imeWindow.getSurfaceControl()); } // If config_attachNavBarToAppDuringTransition is true, the nav bar will be reparent to the // the swiped app when entering recent app, therefore the task will contain the navigation // bar and we should exclude it from snapshot. final boolean excludeNavBar = navWindow != null; if (excludeIme && excludeNavBar) { excludeLayers = new SurfaceControl[2]; excludeLayers[0] = imeWindow.getSurfaceControl(); excludeLayers[1] = navWindow.getSurfaceControl(); } else if (excludeIme || excludeNavBar) { excludeLayers = new SurfaceControl[1]; excludeLayers[0] = excludeIme ? imeWindow.getSurfaceControl() : navWindow.getSurfaceControl(); } else { excludeLayers = new SurfaceControl[0]; if (navWindow != null) { excludeSurfaces.add(navWindow.getSurfaceControl()); } if (Flags.excludeNonMainWindowFromSnapshot()) { source.forAllWindows(w -> { if (w.mAnimatingExit && !w.mRemoved && w.mAttrs.type != TYPE_BASE_APPLICATION) { excludeSurfaces.add(w.getSurfaceControl()); } }, true /* traverseTopToBottom */); } final SurfaceControl[] excludeLayers = excludeSurfaces.toArray(new SurfaceControl[excludeSurfaces.size()]); builder.setHasImeSurface(!excludeIme && imeWindow != null && imeWindow.isVisible()); final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer = ScreenCapture.captureLayersExcluding( Loading services/core/java/com/android/server/wm/ActivitySnapshotController.java +12 −5 Original line number Diff line number Diff line Loading @@ -574,12 +574,18 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord }, false /* traverseTopToBottom */); } boolean invalidateSnapshot(ActivityRecord activity) { if (shouldDisableSnapshots()) { return false; } return removeIfUserSavedFileExist(activity); } @Override void onAppRemoved(ActivityRecord activity) { if (shouldDisableSnapshots()) { if (!invalidateSnapshot(activity)) { return; } removeIfUserSavedFileExist(activity); if (DEBUG) { Slog.d(TAG, "ActivitySnapshotController#onAppRemoved delete snapshot " + activity); } Loading @@ -587,10 +593,9 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord @Override void onAppDied(ActivityRecord activity) { if (shouldDisableSnapshots()) { if (!invalidateSnapshot(activity)) { return; } removeIfUserSavedFileExist(activity); if (DEBUG) { Slog.d(TAG, "ActivitySnapshotController#onAppDied delete snapshot " + activity); } Loading Loading @@ -659,7 +664,7 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord } } private void removeIfUserSavedFileExist(ActivityRecord ar) { private boolean removeIfUserSavedFileExist(ActivityRecord ar) { final UserSavedFile usf = findSavedFile(ar); if (usf != null) { final SparseArray<UserSavedFile> usfs = getUserFiles(ar.mUserId); Loading @@ -671,7 +676,9 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord } mSavedFilesInOrder.remove(usf); mPersister.removeSnapshot(usf.mFileId, ar.mUserId); return true; } return false; } @VisibleForTesting Loading services/core/java/com/android/server/wm/WindowState.java +9 −0 Original line number Diff line number Diff line Loading @@ -2307,6 +2307,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mActivityRecord != null && mActivityRecord.inTransition(), Debug.getCallers(6)); if (Flags.excludeNonMainWindowFromSnapshot() && mAttrs.type != TYPE_BASE_APPLICATION && mHasSurface && mActivityRecord != null && !mActivityRecord.isVisibleRequested() && mWinAnimator.getShown()) { // Only remove the activity snapshot, because the user might still want to see the // task snapshot during the recents animation. mWmService.mSnapshotController.mActivitySnapshotController .invalidateSnapshot(mActivityRecord); } // First, see if we need to run an animation. If we do, we have to hold off on removing the // window until the animation is done. If the display is frozen, just remove immediately, // since the animation wouldn't be seen. Loading Loading
core/java/android/window/flags/windowing_frontend.aconfig +11 −0 Original line number Diff line number Diff line Loading @@ -511,6 +511,17 @@ flag { } } flag { name: "exclude_non_main_window_from_snapshot" namespace: "windowing_frontend" description: "Exclude non-main windows during their removal from being captured in the snapshot." bug: "412295455" is_fixed_read_only: true metadata { purpose: PURPOSE_BUGFIX } } flag { name: "current_animator_scale_uses_shared_memory" namespace: "wear_system_health" Loading
services/core/java/com/android/server/wm/AbsAppSnapshotController.java +18 −13 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; Loading Loading @@ -54,6 +55,7 @@ import com.android.server.wm.utils.InsetUtils; import com.android.window.flags.Flags; import java.io.PrintWriter; import java.util.ArrayList; import java.util.function.Consumer; import java.util.function.Supplier; Loading @@ -62,7 +64,7 @@ import java.util.function.Supplier; * @param <TYPE> The basic type, either Task or ActivityRecord * @param <CACHE> The basic cache for either Task or ActivityRecord */ abstract class AbsAppSnapshotController<TYPE extends WindowContainer, abstract class AbsAppSnapshotController<TYPE extends WindowContainer<?>, CACHE extends SnapshotCache<TYPE>> { static final String TAG = TAG_WITH_CLASS_NAME ? "SnapshotController" : TAG_WM; /** Loading Loading @@ -267,28 +269,31 @@ abstract class AbsAppSnapshotController<TYPE extends WindowContainer, } return null; } SurfaceControl[] excludeLayers; final WindowState imeWindow = source.getDisplayContent().mInputMethodWindow; // Exclude IME window snapshot when IME isn't proper to attach to app. final boolean excludeIme = imeWindow != null && imeWindow.getSurfaceControl() != null && !source.getDisplayContent().shouldImeAttachedToApp(); final WindowState navWindow = source.getDisplayContent().getDisplayPolicy().getNavigationBar(); final ArrayList<SurfaceControl> excludeSurfaces = new ArrayList<>(); if (excludeIme) { excludeSurfaces.add(imeWindow.getSurfaceControl()); } // If config_attachNavBarToAppDuringTransition is true, the nav bar will be reparent to the // the swiped app when entering recent app, therefore the task will contain the navigation // bar and we should exclude it from snapshot. final boolean excludeNavBar = navWindow != null; if (excludeIme && excludeNavBar) { excludeLayers = new SurfaceControl[2]; excludeLayers[0] = imeWindow.getSurfaceControl(); excludeLayers[1] = navWindow.getSurfaceControl(); } else if (excludeIme || excludeNavBar) { excludeLayers = new SurfaceControl[1]; excludeLayers[0] = excludeIme ? imeWindow.getSurfaceControl() : navWindow.getSurfaceControl(); } else { excludeLayers = new SurfaceControl[0]; if (navWindow != null) { excludeSurfaces.add(navWindow.getSurfaceControl()); } if (Flags.excludeNonMainWindowFromSnapshot()) { source.forAllWindows(w -> { if (w.mAnimatingExit && !w.mRemoved && w.mAttrs.type != TYPE_BASE_APPLICATION) { excludeSurfaces.add(w.getSurfaceControl()); } }, true /* traverseTopToBottom */); } final SurfaceControl[] excludeLayers = excludeSurfaces.toArray(new SurfaceControl[excludeSurfaces.size()]); builder.setHasImeSurface(!excludeIme && imeWindow != null && imeWindow.isVisible()); final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer = ScreenCapture.captureLayersExcluding( Loading
services/core/java/com/android/server/wm/ActivitySnapshotController.java +12 −5 Original line number Diff line number Diff line Loading @@ -574,12 +574,18 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord }, false /* traverseTopToBottom */); } boolean invalidateSnapshot(ActivityRecord activity) { if (shouldDisableSnapshots()) { return false; } return removeIfUserSavedFileExist(activity); } @Override void onAppRemoved(ActivityRecord activity) { if (shouldDisableSnapshots()) { if (!invalidateSnapshot(activity)) { return; } removeIfUserSavedFileExist(activity); if (DEBUG) { Slog.d(TAG, "ActivitySnapshotController#onAppRemoved delete snapshot " + activity); } Loading @@ -587,10 +593,9 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord @Override void onAppDied(ActivityRecord activity) { if (shouldDisableSnapshots()) { if (!invalidateSnapshot(activity)) { return; } removeIfUserSavedFileExist(activity); if (DEBUG) { Slog.d(TAG, "ActivitySnapshotController#onAppDied delete snapshot " + activity); } Loading Loading @@ -659,7 +664,7 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord } } private void removeIfUserSavedFileExist(ActivityRecord ar) { private boolean removeIfUserSavedFileExist(ActivityRecord ar) { final UserSavedFile usf = findSavedFile(ar); if (usf != null) { final SparseArray<UserSavedFile> usfs = getUserFiles(ar.mUserId); Loading @@ -671,7 +676,9 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord } mSavedFilesInOrder.remove(usf); mPersister.removeSnapshot(usf.mFileId, ar.mUserId); return true; } return false; } @VisibleForTesting Loading
services/core/java/com/android/server/wm/WindowState.java +9 −0 Original line number Diff line number Diff line Loading @@ -2307,6 +2307,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mActivityRecord != null && mActivityRecord.inTransition(), Debug.getCallers(6)); if (Flags.excludeNonMainWindowFromSnapshot() && mAttrs.type != TYPE_BASE_APPLICATION && mHasSurface && mActivityRecord != null && !mActivityRecord.isVisibleRequested() && mWinAnimator.getShown()) { // Only remove the activity snapshot, because the user might still want to see the // task snapshot during the recents animation. mWmService.mSnapshotController.mActivitySnapshotController .invalidateSnapshot(mActivityRecord); } // First, see if we need to run an animation. If we do, we have to hold off on removing the // window until the animation is done. If the display is frozen, just remove immediately, // since the animation wouldn't be seen. Loading