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

Commit bd53bc80 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix fallback wallpaper connections after reboot" into main

parents b1d4e2ef 679e30ab
Loading
Loading
Loading
Loading
+14 −8
Original line number Diff line number Diff line
@@ -777,7 +777,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
        mWallpaperCompatibleDisplaysForTest.remove(displayId);
    }

    private void updateFallbackConnection() {
    private void updateFallbackConnection(int clientUid) {
        if (mLastWallpaper == null || mFallbackWallpaper == null) return;
        final WallpaperConnection systemConnection = mLastWallpaper.connection;
        final WallpaperConnection fallbackConnection = mFallbackWallpaper.connection;
@@ -793,8 +793,12 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
        }

        if (isDeviceEligibleForDesktopExperienceWallpaper(mContext)) {
            mWallpaperDisplayHelper.forEachDisplayData(displayData -> {
                int displayId = displayData.mDisplayId;
            Display[] displays = mWallpaperDisplayHelper.getDisplays();
            for (int i = displays.length - 1; i >= 0; i--) {
                int displayId = displays[i].getDisplayId();
                if (!mWallpaperDisplayHelper.isUsableDisplay(displayId, clientUid)) {
                    continue;
                }
                // If the display is already connected to the desired wallpaper(s), either the
                // same wallpaper for both lock and system, or different wallpapers for each,
                // any existing fallback wallpaper connection will be removed.
@@ -802,11 +806,13 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
                        && (lockConnection == null || lockConnection.containsDisplay(displayId))) {
                    DisplayConnector fallbackConnector =
                            mFallbackWallpaper.connection.mDisplayConnector.get(displayId);
                    if (fallbackConnector != null && fallbackConnector.mEngine != null) {
                    if (fallbackConnector != null) {
                        if (fallbackConnector.mEngine != null) {
                            fallbackConnector.disconnectLocked(mFallbackWallpaper.connection);
                        }
                        mFallbackWallpaper.connection.mDisplayConnector.remove(displayId);
                    }
                    return;
                    continue;
                }

                // Identify if the fallback wallpaper should be use for lock or system or both.
@@ -844,7 +850,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
                                mFallbackWallpaper);
                    }
                }
            });
            }
        } else if (isWallpaperCompatibleForDisplay(DEFAULT_DISPLAY, systemConnection)) {
            if (fallbackConnection.mDisplayConnector.size() != 0) {
                fallbackConnection.forEachDisplayConnector(connector -> {
@@ -3787,7 +3793,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
            wallpaper.connection = newConn;
            newConn.mReply = reply;
            updateCurrentWallpapers(wallpaper);
            updateFallbackConnection();
            updateFallbackConnection(componentUid);
        } catch (RemoteException e) {
            String msg = "Remote exception for " + componentName + "\n" + e;
            if (fromUser) {
+10 −0
Original line number Diff line number Diff line
@@ -52,6 +52,16 @@
        <uses-library android:name="android.test.runner" />
        <activity
            android:name="android.service.games.GameSessionTrampolineActivityTest$TestActivity" />
        <service android:name="com.android.server.wallpaper.TestWallpaperService"
            android:label="Test Wallpaper Service"
            android:exported="true"
            android:permission="android.permission.BIND_WALLPAPER">
          <intent-filter>
            <action android:name="android.service.wallpaper.WallpaperService"/>
          </intent-filter>
          <meta-data android:name="android.service.wallpaper"
              android:resource="@xml/test_wallpaper"/>
        </service>
    </application>

    <instrumentation
+19 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  Copyright 2025 The Android Open Source Project

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
  -->
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="Test Wallpaper"
    android:supportsMultipleDisplays="true" />
+26 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.wallpaper;

import android.service.wallpaper.WallpaperService;

public final class TestWallpaperService extends WallpaperService {
    @Override
    public Engine onCreateEngine() {
        return new Engine();
    }
}
+57 −47
Original line number Diff line number Diff line
@@ -136,6 +136,10 @@ public class WallpaperManagerServiceTests {

    private static final String TAG = "WallpaperManagerServiceTests";
    private static final int DISPLAY_SIZE_DIMENSION = 100;

    private static final ComponentName TEST_WALLPAPER_COMPONENT = ComponentName.createRelative(
            "com.android.frameworks.mockingservicestests",
            "com.android.server.wallpaper.TestWallpaperService");
    private static StaticMockitoSession sMockitoSession;

    @ClassRule
@@ -212,6 +216,7 @@ public class WallpaperManagerServiceTests {
        }

        sContext.addMockService(sImageWallpaperComponentName, sWallpaperService);
        sContext.addMockService(TEST_WALLPAPER_COMPONENT, sWallpaperService);
        if (sFallbackWallpaperComponentName != null) {
            sContext.addMockService(sFallbackWallpaperComponentName, sWallpaperService);
        }
@@ -1033,35 +1038,33 @@ public class WallpaperManagerServiceTests {
    }
    // Verify a secondary display removes system decorations ended

    // Test setWallpaperComponent on multiple displays.
    // GIVEN 3 displays, 0, 2, 3, the new wallpaper is only compatible for display 0 and 3 but not
    // 2.
    // WHEN the new wallpaper is set for system and lock via setWallpaperComponent.
    // Test fallback connection is correctly established for multiple displays after reboot.
    // GIVEN 3 displays, 0, 2, 3, the wallpaper is only compatible for display 0 and 3 but not 2.
    // WHEN the device is booted.
    // THEN there are 2 connections in mLastWallpaper and 1 connection in mFallbackWallpaper.
    @Test
    @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER)
    public void setWallpaperComponent_multiDisplays_shouldHaveExpectedConnections() {
        // Skip if there is no pre-defined default wallpaper component.
        assumeThat(sDefaultWallpaperComponent,
                not(CoreMatchers.equalTo(sImageWallpaperComponentName)));

        final int testUserId = USER_SYSTEM;
        mService.switchUser(testUserId, null);
    public void deviceBooted_multiDisplays_shouldHaveExpectedConnections() {
        final int incompatibleDisplayId = 2;
        final int compatibleDisplayId = 3;
        setUpDisplays(List.of(DEFAULT_DISPLAY, incompatibleDisplayId, compatibleDisplayId));
        mService.removeWallpaperCompatibleDisplayForTest(incompatibleDisplayId);

        mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(),
                FLAG_SYSTEM | FLAG_LOCK, testUserId);
        final int testUserId = USER_SYSTEM;
        // After reboot, a switch user triggers the wallpapers initialization.
        mService.switchUser(testUserId, null);

        verifyLastWallpaperData(testUserId, sImageWallpaperComponentName);
        verifyCurrentSystemData(testUserId);
        assertThat(mService.mLastWallpaper.connection.getConnectedEngineSize()).isEqualTo(2);
        assertThat(mService.mLastWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isTrue();
        assertThat(mService.mLastWallpaper.connection.containsDisplay(compatibleDisplayId))
                .isTrue();
        assertThat(mService.mFallbackWallpaper.connection.getConnectedEngineSize()).isEqualTo(1);
        assertThat(mService.mLastWallpaper.connection.containsDisplay(incompatibleDisplayId))
                .isFalse();
        assertThat(mService.mFallbackWallpaper.connection.containsDisplay(DEFAULT_DISPLAY))
                .isFalse();
        assertThat(mService.mFallbackWallpaper.connection.containsDisplay(compatibleDisplayId))
                .isFalse();
        assertThat(mService.mFallbackWallpaper.connection.containsDisplay(incompatibleDisplayId))
                .isTrue();
        assertThat(mService.mLastLockWallpaper).isNull();
@@ -1076,30 +1079,31 @@ public class WallpaperManagerServiceTests {
    @Test
    @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER)
    public void setWallpaperComponent_multiDisplays_displayBecomeCompatible_shouldHaveExpectedConnections() {
        // Skip if there is no pre-defined default wallpaper component.
        assumeThat(sDefaultWallpaperComponent,
                not(CoreMatchers.equalTo(sImageWallpaperComponentName)));

        final int testUserId = USER_SYSTEM;
        mService.switchUser(testUserId, null);
        final int display2 = 2;
        final int display3 = 3;
        setUpDisplays(List.of(DEFAULT_DISPLAY, display2, display3));
        mService.removeWallpaperCompatibleDisplayForTest(display2);
        mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(),
        final int testUserId = USER_SYSTEM;
        mService.switchUser(testUserId, null);
        // Switch to a test wallpaper and then image wallpaper later to simulate a wallpaper change.
        mService.setWallpaperComponent(TEST_WALLPAPER_COMPONENT, sContext.getOpPackageName(),
                FLAG_SYSTEM | FLAG_LOCK, testUserId);

        mService.addWallpaperCompatibleDisplayForTest(display2);

        mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(),
                FLAG_SYSTEM | FLAG_LOCK, testUserId);

        verifyLastWallpaperData(testUserId, sImageWallpaperComponentName);
        verifyCurrentSystemData(testUserId);
        assertThat(mService.mLastWallpaper.connection.getConnectedEngineSize()).isEqualTo(3);
        assertThat(mService.mLastWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isTrue();
        assertThat(mService.mLastWallpaper.connection.containsDisplay(display2)).isTrue();
        assertThat(mService.mLastWallpaper.connection.containsDisplay(display3)).isTrue();
        assertThat(mService.mFallbackWallpaper.connection.getConnectedEngineSize()).isEqualTo(0);
        assertThat(
                mService.mFallbackWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isFalse();
        assertThat(
                mService.mFallbackWallpaper.connection.containsDisplay(display2)).isFalse();
        assertThat(
                mService.mFallbackWallpaper.connection.containsDisplay(display3)).isFalse();
        assertThat(mService.mLastLockWallpaper).isNull();
    }

@@ -1112,28 +1116,27 @@ public class WallpaperManagerServiceTests {
    @Test
    @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER)
    public void setWallpaperComponent_multiDisplays_displayBecomeIncompatible_shouldHaveExpectedConnections() {
        // Skip if there is no pre-defined default wallpaper component.
        assumeThat(sDefaultWallpaperComponent,
                not(CoreMatchers.equalTo(sImageWallpaperComponentName)));

        final int testUserId = USER_SYSTEM;
        mService.switchUser(testUserId, null);
        final int display2 = 2;
        final int display3 = 3;
        setUpDisplays(List.of(DEFAULT_DISPLAY, display2, display3));
        mService.removeWallpaperCompatibleDisplayForTest(display2);
        mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(),
        final int testUserId = USER_SYSTEM;
        mService.switchUser(testUserId, null);
        // Switch to a test wallpaper and then image wallpaper later to simulate a wallpaper change.
        mService.setWallpaperComponent(TEST_WALLPAPER_COMPONENT, sContext.getOpPackageName(),
                FLAG_SYSTEM | FLAG_LOCK, testUserId);

        mService.removeWallpaperCompatibleDisplayForTest(display3);

        mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(),
                FLAG_SYSTEM | FLAG_LOCK, testUserId);

        verifyLastWallpaperData(testUserId, sImageWallpaperComponentName);
        verifyCurrentSystemData(testUserId);
        assertThat(mService.mLastWallpaper.connection.getConnectedEngineSize()).isEqualTo(1);
        assertThat(mService.mLastWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isTrue();
        assertThat(mService.mFallbackWallpaper.connection.getConnectedEngineSize()).isEqualTo(2);
        assertThat(mService.mLastWallpaper.connection.containsDisplay(display2)).isFalse();
        assertThat(mService.mLastWallpaper.connection.containsDisplay(display3)).isFalse();
        assertThat(
                mService.mFallbackWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isFalse();
        assertThat(mService.mFallbackWallpaper.connection.containsDisplay(display2)).isTrue();
        assertThat(mService.mFallbackWallpaper.connection.containsDisplay(display3)).isTrue();
        assertThat(mService.mLastLockWallpaper).isNull();
@@ -1148,35 +1151,40 @@ public class WallpaperManagerServiceTests {
    @Test
    @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER)
    public void setWallpaperComponent_systemAndLockWallpapers_multiDisplays_shouldHaveExpectedConnections() {
        // Skip if there is no pre-defined default wallpaper component.
        assumeThat(sDefaultWallpaperComponent,
                not(CoreMatchers.equalTo(sImageWallpaperComponentName)));

        final int testUserId = USER_SYSTEM;
        mService.switchUser(testUserId, null);
        final int incompatibleDisplayId = 2;
        final int compatibleDisplayId = 3;
        setUpDisplays(List.of(DEFAULT_DISPLAY, incompatibleDisplayId, compatibleDisplayId));
        final int testUserId = USER_SYSTEM;
        mService.switchUser(testUserId, null);
        // Switch to a test wallpaper and then image wallpaper later to simulate a wallpaper change.
        mService.setWallpaperComponent(TEST_WALLPAPER_COMPONENT, sContext.getOpPackageName(),
                FLAG_SYSTEM | FLAG_LOCK, testUserId);
        mService.removeWallpaperCompatibleDisplayForTest(incompatibleDisplayId);

        mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(),
                FLAG_SYSTEM, testUserId);
        mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(),
                FLAG_LOCK, testUserId);

        verifyLastWallpaperData(testUserId, sImageWallpaperComponentName);
        verifyLastLockWallpaperData(testUserId, sImageWallpaperComponentName);
        verifyLastLockWallpaperData(testUserId, TEST_WALLPAPER_COMPONENT);
        verifyCurrentSystemData(testUserId);
        assertThat(mService.mLastWallpaper.connection.getConnectedEngineSize()).isEqualTo(2);

        assertThat(mService.mLastWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isTrue();
        assertThat(mService.mLastWallpaper.connection.containsDisplay(compatibleDisplayId))
                .isTrue();
        assertThat(mService.mLastLockWallpaper.connection.getConnectedEngineSize()).isEqualTo(2);
        assertThat(mService.mLastWallpaper.connection.containsDisplay(incompatibleDisplayId))
                .isFalse();
        // mLastLockWallpaper is TEST_WALLPAPER_COMPONENT, which declares external displays support
        // in the wallpaper metadata.
        assertThat(mService.mLastLockWallpaper.connection.containsDisplay(DEFAULT_DISPLAY))
                .isTrue();
        assertThat(mService.mLastLockWallpaper.connection.containsDisplay(compatibleDisplayId))
                .isTrue();
        assertThat(mService.mFallbackWallpaper.connection.getConnectedEngineSize()).isEqualTo(1);
        assertThat(mService.mLastLockWallpaper.connection.containsDisplay(incompatibleDisplayId))
                .isTrue();
        assertThat(mService.mFallbackWallpaper.connection.containsDisplay(DEFAULT_DISPLAY))
                .isFalse();
        assertThat(mService.mFallbackWallpaper.connection.containsDisplay(compatibleDisplayId))
                .isFalse();
        assertThat(mService.mFallbackWallpaper.connection.containsDisplay(incompatibleDisplayId))
                .isTrue();
    }
@@ -1281,4 +1289,6 @@ public class WallpaperManagerServiceTests {
            assertEquals(pfdContents, fileContents);
        }
    }


}