1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wallpaper; 18 19 import static android.view.Display.DEFAULT_DISPLAY; 20 21 import android.graphics.Rect; 22 import android.hardware.display.DisplayManager; 23 import android.os.Binder; 24 import android.os.Debug; 25 import android.util.Slog; 26 import android.util.SparseArray; 27 import android.view.Display; 28 import android.view.DisplayInfo; 29 30 import com.android.server.wm.WindowManagerInternal; 31 32 import java.util.function.Consumer; 33 34 /** 35 * Internal class used to store all the display data relevant to the wallpapers 36 */ 37 class WallpaperDisplayHelper { 38 39 static final class DisplayData { 40 int mWidth = -1; 41 int mHeight = -1; 42 final Rect mPadding = new Rect(0, 0, 0, 0); 43 final int mDisplayId; DisplayData(int displayId)44 DisplayData(int displayId) { 45 mDisplayId = displayId; 46 } 47 } 48 49 private static final String TAG = WallpaperDisplayHelper.class.getSimpleName(); 50 private final SparseArray<DisplayData> mDisplayDatas = new SparseArray<>(); 51 private final DisplayManager mDisplayManager; 52 private final WindowManagerInternal mWindowManagerInternal; 53 WallpaperDisplayHelper( DisplayManager displayManager, WindowManagerInternal windowManagerInternal)54 WallpaperDisplayHelper( 55 DisplayManager displayManager, 56 WindowManagerInternal windowManagerInternal) { 57 mDisplayManager = displayManager; 58 mWindowManagerInternal = windowManagerInternal; 59 } 60 getDisplayDataOrCreate(int displayId)61 DisplayData getDisplayDataOrCreate(int displayId) { 62 DisplayData wpdData = mDisplayDatas.get(displayId); 63 if (wpdData == null) { 64 wpdData = new DisplayData(displayId); 65 ensureSaneWallpaperDisplaySize(wpdData, displayId); 66 mDisplayDatas.append(displayId, wpdData); 67 } 68 return wpdData; 69 } 70 removeDisplayData(int displayId)71 void removeDisplayData(int displayId) { 72 mDisplayDatas.remove(displayId); 73 } 74 ensureSaneWallpaperDisplaySize(DisplayData wpdData, int displayId)75 void ensureSaneWallpaperDisplaySize(DisplayData wpdData, int displayId) { 76 // We always want to have some reasonable width hint. 77 final int baseSize = getMaximumSizeDimension(displayId); 78 if (wpdData.mWidth < baseSize) { 79 wpdData.mWidth = baseSize; 80 } 81 if (wpdData.mHeight < baseSize) { 82 wpdData.mHeight = baseSize; 83 } 84 } 85 getMaximumSizeDimension(int displayId)86 int getMaximumSizeDimension(int displayId) { 87 Display display = mDisplayManager.getDisplay(displayId); 88 if (display == null) { 89 Slog.w(TAG, "Invalid displayId=" + displayId + " " + Debug.getCallers(4)); 90 display = mDisplayManager.getDisplay(DEFAULT_DISPLAY); 91 } 92 return display.getMaximumSizeDimension(); 93 } 94 forEachDisplayData(Consumer<DisplayData> action)95 void forEachDisplayData(Consumer<DisplayData> action) { 96 for (int i = mDisplayDatas.size() - 1; i >= 0; i--) { 97 final DisplayData wpdData = mDisplayDatas.valueAt(i); 98 action.accept(wpdData); 99 } 100 } 101 getDisplays()102 Display[] getDisplays() { 103 return mDisplayManager.getDisplays(); 104 } 105 getDisplayInfo(int displayId)106 DisplayInfo getDisplayInfo(int displayId) { 107 final DisplayInfo displayInfo = new DisplayInfo(); 108 mDisplayManager.getDisplay(displayId).getDisplayInfo(displayInfo); 109 return displayInfo; 110 } 111 isUsableDisplay(int displayId, int clientUid)112 boolean isUsableDisplay(int displayId, int clientUid) { 113 return isUsableDisplay(mDisplayManager.getDisplay(displayId), clientUid); 114 } 115 isUsableDisplay(Display display, int clientUid)116 boolean isUsableDisplay(Display display, int clientUid) { 117 if (display == null || !display.hasAccess(clientUid)) { 118 return false; 119 } 120 final int displayId = display.getDisplayId(); 121 if (displayId == DEFAULT_DISPLAY) { 122 return true; 123 } 124 125 final long ident = Binder.clearCallingIdentity(); 126 try { 127 return mWindowManagerInternal.shouldShowSystemDecorOnDisplay(displayId); 128 } finally { 129 Binder.restoreCallingIdentity(ident); 130 } 131 } 132 isValidDisplay(int displayId)133 boolean isValidDisplay(int displayId) { 134 return mDisplayManager.getDisplay(displayId) != null; 135 } 136 } 137