Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9fbd2e0f authored by Lingyu Feng's avatar Lingyu Feng Committed by Android (Google) Code Review
Browse files

Merge "Notify wallpaper via onDisplayRemoveSystemDecorations when starting mirroring" into main

parents 4cf45a33 6b09e047
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -28,6 +28,9 @@ public abstract class WallpaperManagerInternal {
     */
    public abstract void onDisplayReady(int displayId);

    /** Notifies when display stop showing system decorations and wallpaper. */
    public abstract void onDisplayRemoveSystemDecorations(int displayId);

    /** Notifies when the screen finished turning on and is visible to the user. */
    public abstract void onScreenTurnedOn(int displayId);

+80 −65
Original line number Diff line number Diff line
@@ -667,71 +667,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub

        @Override
        public void onDisplayRemoved(int displayId) {
            synchronized (mLock) {
                if (enableConnectedDisplaysWallpaper()) {
                    // There could be at most 2 wallpaper connections per display:
                    // 1. system & lock are the same: mLastWallpaper
                    // 2. system, lock are different: mLastWallpaper, mLastLockWallpaper
                    // 3. fallback used as both system & lock wallpaper: mFallbackWallpaper
                    // 4. fallback used as lock only wallpaper: mFallbackWallpaper,
                    //    mLastWallpaper
                    // 5. fallback used as system only wallpaper: mFallbackWallpaper,
                    //    mLastLockWallpaper
                    List<WallpaperData> pendingDisconnectWallpapers = new ArrayList<>();
                    if (mLastWallpaper != null && mLastWallpaper.connection != null
                            && mLastWallpaper.connection.containsDisplay(displayId)) {
                        pendingDisconnectWallpapers.add(mLastWallpaper);
                    }
                    if (mLastLockWallpaper != null && mLastLockWallpaper.connection != null
                            && mLastLockWallpaper.connection.containsDisplay(displayId)) {
                        pendingDisconnectWallpapers.add(mLastLockWallpaper);
                    }
                    if (mFallbackWallpaper != null && mFallbackWallpaper.connection != null
                            && mFallbackWallpaper.connection.containsDisplay(displayId)) {
                        pendingDisconnectWallpapers.add(mFallbackWallpaper);
                    }
                    for (int i = 0; i < pendingDisconnectWallpapers.size(); i++) {
                        WallpaperData wallpaper = pendingDisconnectWallpapers.get(i);
                        DisplayConnector displayConnector =
                                wallpaper.connection.getDisplayConnectorOrCreate(displayId);
                        if (displayConnector == null) {
                            Slog.w(TAG,
                                    "Fail to disconnect wallpaper upon display removal");
                            return;
                        }
                        displayConnector.disconnectLocked(wallpaper.connection);
                        wallpaper.connection.removeDisplayConnector(displayId);
                    }
                } else {
                    if (mLastWallpaper != null) {
                        WallpaperData targetWallpaper = null;
                        if (mLastWallpaper.connection != null
                                && mLastWallpaper.connection.containsDisplay(displayId)) {
                            targetWallpaper = mLastWallpaper;
                        } else if (mFallbackWallpaper != null
                                && mFallbackWallpaper.connection != null
                                && mFallbackWallpaper.connection.containsDisplay(
                                displayId)) {
                            targetWallpaper = mFallbackWallpaper;
                        }
                        if (targetWallpaper == null) return;
                        DisplayConnector connector =
                                targetWallpaper.connection.getDisplayConnectorOrCreate(
                                        displayId);
                        if (connector == null) return;
                        connector.disconnectLocked(targetWallpaper.connection);
                        targetWallpaper.connection.removeDisplayConnector(displayId);
                    }
                }

                mWallpaperDisplayHelper.removeDisplayData(displayId);

                for (int i = mColorsChangedListeners.size() - 1; i >= 0; i--) {
                    final SparseArray<RemoteCallbackList<IWallpaperManagerCallback>> callbacks =
                            mColorsChangedListeners.valueAt(i);
                    callbacks.delete(displayId);
                }
            }
            onDisplayRemovedInternal(displayId);
        }

        @Override
@@ -1704,6 +1640,13 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
            onDisplayReadyInternal(displayId);
        }

        @Override
        public void onDisplayRemoveSystemDecorations(int displayId) {
            // The display mirroring starts. The handling logic is the same as when removing a
            // display.
            onDisplayRemovedInternal(displayId);
        }

        @Override
        public void onScreenTurnedOn(int displayId) {
            notifyScreenTurnedOn(displayId);
@@ -4063,6 +4006,78 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
        }
    }

    // This method may be called even if the display is not being removed from the system.
    // This can be called when the display is removed, or when the display system decorations are
    // removed to start mirroring.
    private void onDisplayRemovedInternal(int displayId) {
        synchronized (mLock) {
            if (enableConnectedDisplaysWallpaper()) {
                // There could be at most 2 wallpaper connections per display:
                // 1. system & lock are the same: mLastWallpaper
                // 2. system, lock are different: mLastWallpaper, mLastLockWallpaper
                // 3. fallback used as both system & lock wallpaper: mFallbackWallpaper
                // 4. fallback used as lock only wallpaper: mFallbackWallpaper,
                //    mLastWallpaper
                // 5. fallback used as system only wallpaper: mFallbackWallpaper,
                //    mLastLockWallpaper
                List<WallpaperData> pendingDisconnectWallpapers = new ArrayList<>();
                if (mLastWallpaper != null && mLastWallpaper.connection != null
                        && mLastWallpaper.connection.containsDisplay(displayId)) {
                    pendingDisconnectWallpapers.add(mLastWallpaper);
                }
                if (mLastLockWallpaper != null && mLastLockWallpaper.connection != null
                        && mLastLockWallpaper.connection.containsDisplay(displayId)) {
                    pendingDisconnectWallpapers.add(mLastLockWallpaper);
                }
                if (mFallbackWallpaper != null && mFallbackWallpaper.connection != null
                        && mFallbackWallpaper.connection.containsDisplay(displayId)) {
                    pendingDisconnectWallpapers.add(mFallbackWallpaper);
                }
                for (int i = 0; i < pendingDisconnectWallpapers.size(); i++) {
                    WallpaperData wallpaper = pendingDisconnectWallpapers.get(i);
                    DisplayConnector displayConnector =
                            wallpaper.connection.getDisplayConnectorOrCreate(displayId);
                    if (displayConnector == null) {
                        Slog.w(TAG,
                                "Fail to disconnect wallpaper upon display removes system "
                                        + "decorations");
                        return;
                    }
                    displayConnector.disconnectLocked(wallpaper.connection);
                    wallpaper.connection.removeDisplayConnector(displayId);
                }
            } else {
                if (mLastWallpaper != null) {
                    WallpaperData targetWallpaper = null;
                    if (mLastWallpaper.connection != null
                            && mLastWallpaper.connection.containsDisplay(displayId)) {
                        targetWallpaper = mLastWallpaper;
                    } else if (mFallbackWallpaper != null
                            && mFallbackWallpaper.connection != null
                            && mFallbackWallpaper.connection.containsDisplay(
                            displayId)) {
                        targetWallpaper = mFallbackWallpaper;
                    }
                    if (targetWallpaper == null) return;
                    DisplayConnector connector =
                            targetWallpaper.connection.getDisplayConnectorOrCreate(
                                    displayId);
                    if (connector == null) return;
                    connector.disconnectLocked(targetWallpaper.connection);
                    targetWallpaper.connection.removeDisplayConnector(displayId);
                }
            }

            mWallpaperDisplayHelper.removeDisplayData(displayId);

            for (int i = mColorsChangedListeners.size() - 1; i >= 0; i--) {
                final SparseArray<RemoteCallbackList<IWallpaperManagerCallback>> callbacks =
                        mColorsChangedListeners.valueAt(i);
                callbacks.delete(displayId);
            }
        }
    }

    void saveSettingsLocked(int userId) {
        TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG);
        t.traceBegin("WPMS.saveSettingsLocked-" + userId);
+5 −0
Original line number Diff line number Diff line
@@ -1910,6 +1910,11 @@ public class DisplayPolicy {
                    if (statusBar != null) {
                        statusBar.onDisplayRemoveSystemDecorations(displayId);
                    }
                    final WallpaperManagerInternal wpMgr =
                            LocalServices.getService(WallpaperManagerInternal.class);
                    if (wpMgr != null) {
                        wpMgr.onDisplayRemoveSystemDecorations(displayId);
                    }
                });
    }

+68 −0
Original line number Diff line number Diff line
@@ -960,6 +960,74 @@ public class WallpaperManagerServiceTests {
                .isEqualTo(FLAG_LOCK | FLAG_SYSTEM);
    }

    // Verify a secondary display removes system decorations started
    @Test
    @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER)
    public void displayRemoveSystemDecorations_sameSystemAndLockWallpaper_shouldDetachWallpaperServiceOnce()
            throws Exception {
        // GIVEN the same wallpaper used for the lock and system.
        final int testUserId = USER_SYSTEM;
        mService.switchUser(testUserId, null);
        final WallpaperData wallpaper = mService.getCurrentWallpaperData(FLAG_SYSTEM, testUserId);
        IWallpaperService mockIWallpaperService = mock(IWallpaperService.class);
        wallpaper.connection.mService = mockIWallpaperService;
        // GIVEN there are two displays: DEFAULT_DISPLAY, 2
        final int testDisplayId = 2;
        setUpDisplays(List.of(DEFAULT_DISPLAY, testDisplayId));
        // GIVEN wallpaper connections have been established for displayID, 2.
        WallpaperManagerInternal wallpaperManagerInternal = LocalServices.getService(
                WallpaperManagerInternal.class);
        wallpaperManagerInternal.onDisplayReady(testDisplayId);
        // Save displayConnector for displayId 2 before display removal.
        WallpaperManagerService.DisplayConnector displayConnector =
                wallpaper.connection.getDisplayConnectorOrCreate(testDisplayId);

        // WHEN displayId, 2, is removed.
        wallpaperManagerInternal.onDisplayRemoveSystemDecorations(testDisplayId);

        // Then the wallpaper connection for displayId, 2, is detached.
        verify(mockIWallpaperService).detach(eq(displayConnector.mToken));
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER)
    public void displayRemoveSystemDecorations_differentSystemAndLockWallpapers_shouldDetachWallpaperServiceTwice()
            throws Exception {
        // GIVEN different wallpapers used for the lock and system.
        final int testUserId = USER_SYSTEM;
        mService.switchUser(testUserId, null);
        mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(),
                FLAG_LOCK, testUserId);
        final WallpaperData systemWallpaper = mService.getCurrentWallpaperData(FLAG_SYSTEM,
                testUserId);
        final WallpaperData lockWallpaper = mService.getCurrentWallpaperData(FLAG_LOCK,
                testUserId);
        IWallpaperService mockIWallpaperService = mock(IWallpaperService.class);
        systemWallpaper.connection.mService = mockIWallpaperService;
        lockWallpaper.connection.mService = mockIWallpaperService;
        // GIVEN there are two displays: DEFAULT_DISPLAY, 2
        final int testDisplayId = 2;
        setUpDisplays(List.of(DEFAULT_DISPLAY, testDisplayId));
        // GIVEN wallpaper connections have been established for displayID, 2.
        WallpaperManagerInternal wallpaperManagerInternal = LocalServices.getService(
                WallpaperManagerInternal.class);
        wallpaperManagerInternal.onDisplayReady(testDisplayId);
        // Save displayConnectors for displayId 2 before display removal.
        WallpaperManagerService.DisplayConnector systemWallpaperDisplayConnector =
                systemWallpaper.connection.getDisplayConnectorOrCreate(testDisplayId);
        WallpaperManagerService.DisplayConnector lockWallpaperDisplayConnector =
                lockWallpaper.connection.getDisplayConnectorOrCreate(testDisplayId);

        // WHEN displayId, 2, is removed.
        wallpaperManagerInternal.onDisplayRemoveSystemDecorations(testDisplayId);

        // Then the system wallpaper connection for displayId, 2, is detached.
        verify(mockIWallpaperService).detach(eq(systemWallpaperDisplayConnector.mToken));
        // Then the lock wallpaper connection for displayId, 2, is detached.
        verify(mockIWallpaperService).detach(eq(lockWallpaperDisplayConnector.mToken));
    }
    // Verify a secondary display removes system decorations ended

    // Verify that after continue switch user from userId 0 to lastUserId, the wallpaper data for
    // non-current user must not bind to wallpaper service.
    private void verifyNoConnectionBeforeLastUser(int lastUserId) {