• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static com.android.window.flags.Flags.multiCrop;
22 
23 import android.app.WallpaperManager;
24 import android.content.res.Resources;
25 import android.graphics.Point;
26 import android.graphics.Rect;
27 import android.hardware.display.DisplayManager;
28 import android.os.Binder;
29 import android.os.Debug;
30 import android.util.Slog;
31 import android.util.SparseArray;
32 import android.view.Display;
33 import android.view.DisplayInfo;
34 import android.view.WindowManager;
35 
36 import com.android.server.wm.WindowManagerInternal;
37 
38 import java.util.function.Consumer;
39 
40 /**
41  * Internal class used to store all the display data relevant to the wallpapers
42  */
43 class WallpaperDisplayHelper {
44 
45     static final class DisplayData {
46         int mWidth = -1;
47         int mHeight = -1;
48         final Rect mPadding = new Rect(0, 0, 0, 0);
49         final int mDisplayId;
DisplayData(int displayId)50         DisplayData(int displayId) {
51             mDisplayId = displayId;
52         }
53     }
54 
55     private static final String TAG = WallpaperDisplayHelper.class.getSimpleName();
56 
57     private final SparseArray<DisplayData> mDisplayDatas = new SparseArray<>();
58     private final DisplayManager mDisplayManager;
59     private final WindowManagerInternal mWindowManagerInternal;
60 
61     private final WallpaperDefaultDisplayInfo mDefaultDisplayInfo;
62 
WallpaperDisplayHelper( DisplayManager displayManager, WindowManager windowManager, WindowManagerInternal windowManagerInternal, Resources resources)63     WallpaperDisplayHelper(
64             DisplayManager displayManager,
65             WindowManager windowManager,
66             WindowManagerInternal windowManagerInternal,
67             Resources resources) {
68         mDisplayManager = displayManager;
69         mWindowManagerInternal = windowManagerInternal;
70         if (!multiCrop()) {
71             mDefaultDisplayInfo = new WallpaperDefaultDisplayInfo();
72             return;
73         }
74         mDefaultDisplayInfo = new WallpaperDefaultDisplayInfo(windowManager, resources);
75     }
76 
getDisplayDataOrCreate(int displayId)77     DisplayData getDisplayDataOrCreate(int displayId) {
78         DisplayData wpdData = mDisplayDatas.get(displayId);
79         if (wpdData == null) {
80             wpdData = new DisplayData(displayId);
81             ensureSaneWallpaperDisplaySize(wpdData, displayId);
82             mDisplayDatas.append(displayId, wpdData);
83         }
84         return wpdData;
85     }
86 
getDefaultDisplayCurrentOrientation()87     int getDefaultDisplayCurrentOrientation() {
88         Point displaySize = new Point();
89         mDisplayManager.getDisplay(DEFAULT_DISPLAY).getSize(displaySize);
90         return WallpaperManager.getOrientation(displaySize);
91     }
92 
removeDisplayData(int displayId)93     void removeDisplayData(int displayId) {
94         mDisplayDatas.remove(displayId);
95     }
96 
ensureSaneWallpaperDisplaySize(DisplayData wpdData, int displayId)97     void ensureSaneWallpaperDisplaySize(DisplayData wpdData, int displayId) {
98         // We always want to have some reasonable width hint.
99         final int baseSize = getMaximumSizeDimension(displayId);
100         if (wpdData.mWidth < baseSize) {
101             wpdData.mWidth = baseSize;
102         }
103         if (wpdData.mHeight < baseSize) {
104             wpdData.mHeight = baseSize;
105         }
106     }
107 
getMaximumSizeDimension(int displayId)108     int getMaximumSizeDimension(int displayId) {
109         Display display = mDisplayManager.getDisplay(displayId);
110         if (display == null) {
111             Slog.w(TAG, "Invalid displayId=" + displayId + " " + Debug.getCallers(4));
112             display = mDisplayManager.getDisplay(DEFAULT_DISPLAY);
113         }
114         return display.getMaximumSizeDimension();
115     }
116 
forEachDisplayData(Consumer<DisplayData> action)117     void forEachDisplayData(Consumer<DisplayData> action) {
118         for (int i = mDisplayDatas.size() - 1; i >= 0; i--) {
119             final DisplayData wpdData = mDisplayDatas.valueAt(i);
120             action.accept(wpdData);
121         }
122     }
123 
getDisplays()124     Display[] getDisplays() {
125         return mDisplayManager.getDisplays();
126     }
127 
getDisplayInfo(int displayId)128     DisplayInfo getDisplayInfo(int displayId) {
129         final DisplayInfo displayInfo = new DisplayInfo();
130         mDisplayManager.getDisplay(displayId).getDisplayInfo(displayInfo);
131         return displayInfo;
132     }
133 
isUsableDisplay(int displayId, int clientUid)134     boolean isUsableDisplay(int displayId, int clientUid) {
135         return isUsableDisplay(mDisplayManager.getDisplay(displayId), clientUid);
136     }
137 
isUsableDisplay(Display display, int clientUid)138     boolean isUsableDisplay(Display display, int clientUid) {
139         if (display == null || !display.hasAccess(clientUid)) {
140             return false;
141         }
142         final int displayId = display.getDisplayId();
143         if (displayId == DEFAULT_DISPLAY) {
144             return true;
145         }
146 
147         final long ident = Binder.clearCallingIdentity();
148         try {
149             return mWindowManagerInternal.isHomeSupportedOnDisplay(displayId);
150         } finally {
151             Binder.restoreCallingIdentity(ident);
152         }
153     }
154 
isValidDisplay(int displayId)155     boolean isValidDisplay(int displayId) {
156         return mDisplayManager.getDisplay(displayId) != null;
157     }
158 
getDefaultDisplaySizes()159     SparseArray<Point> getDefaultDisplaySizes() {
160         return mDefaultDisplayInfo.defaultDisplaySizes;
161     }
162 
163     /** Return the number of pixel of the largest dimension of the default display */
getDefaultDisplayLargestDimension()164     int getDefaultDisplayLargestDimension() {
165         SparseArray<Point> defaultDisplaySizes = mDefaultDisplayInfo.defaultDisplaySizes;
166         int result = -1;
167         for (int i = 0; i < defaultDisplaySizes.size(); i++) {
168             Point size = defaultDisplaySizes.valueAt(i);
169             result = Math.max(result, Math.max(size.x, size.y));
170         }
171         return result;
172     }
173 
getDefaultDisplayInfo()174     public WallpaperDefaultDisplayInfo getDefaultDisplayInfo() {
175         return mDefaultDisplayInfo;
176     }
177 }
178