1 /*
2  * Copyright (C) 2016 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.wm;
18 
19 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
20 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
21 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
22 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
23 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
24 
25 import android.os.Bundle;
26 import android.os.IBinder;
27 import android.os.RemoteException;
28 import android.util.Slog;
29 import android.view.DisplayInfo;
30 import android.view.animation.Animation;
31 
32 /**
33  * A token that represents a set of wallpaper windows.
34  */
35 class WallpaperWindowToken extends WindowToken {
36 
37     private static final String TAG = TAG_WITH_CLASS_NAME ? "WallpaperWindowToken" : TAG_WM;
38 
WallpaperWindowToken(WindowManagerService service, IBinder token, boolean explicit, DisplayContent dc, boolean ownerCanManageAppTokens)39     WallpaperWindowToken(WindowManagerService service, IBinder token, boolean explicit,
40             DisplayContent dc, boolean ownerCanManageAppTokens) {
41         super(service, token, TYPE_WALLPAPER, explicit, dc, ownerCanManageAppTokens);
42         dc.mWallpaperController.addWallpaperToken(this);
43     }
44 
45     @Override
setExiting()46     void setExiting() {
47         super.setExiting();
48         mDisplayContent.mWallpaperController.removeWallpaperToken(this);
49     }
50 
hideWallpaperToken(boolean wasDeferred, String reason)51     void hideWallpaperToken(boolean wasDeferred, String reason) {
52         for (int j = mChildren.size() - 1; j >= 0; j--) {
53             final WindowState wallpaper = mChildren.get(j);
54             wallpaper.hideWallpaperWindow(wasDeferred, reason);
55         }
56         setHidden(true);
57     }
58 
sendWindowWallpaperCommand( String action, int x, int y, int z, Bundle extras, boolean sync)59     void sendWindowWallpaperCommand(
60             String action, int x, int y, int z, Bundle extras, boolean sync) {
61         for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
62             final WindowState wallpaper = mChildren.get(wallpaperNdx);
63             try {
64                 wallpaper.mClient.dispatchWallpaperCommand(action, x, y, z, extras, sync);
65                 // We only want to be synchronous with one wallpaper.
66                 sync = false;
67             } catch (RemoteException e) {
68             }
69         }
70     }
71 
updateWallpaperOffset(int dw, int dh, boolean sync)72     void updateWallpaperOffset(int dw, int dh, boolean sync) {
73         final WallpaperController wallpaperController = mDisplayContent.mWallpaperController;
74         for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
75             final WindowState wallpaper = mChildren.get(wallpaperNdx);
76             if (wallpaperController.updateWallpaperOffset(wallpaper, dw, dh, sync)) {
77                 // We only want to be synchronous with one wallpaper.
78                 sync = false;
79             }
80         }
81     }
82 
updateWallpaperVisibility(boolean visible)83     void updateWallpaperVisibility(boolean visible) {
84         final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
85         final int dw = displayInfo.logicalWidth;
86         final int dh = displayInfo.logicalHeight;
87 
88         if (isHidden() == visible) {
89             setHidden(!visible);
90 
91             // Need to do a layout to ensure the wallpaper now has the correct size.
92             mDisplayContent.setLayoutNeeded();
93         }
94 
95         final WallpaperController wallpaperController = mDisplayContent.mWallpaperController;
96         for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
97             final WindowState wallpaper = mChildren.get(wallpaperNdx);
98             if (visible) {
99                 wallpaperController.updateWallpaperOffset(wallpaper, dw, dh, false);
100             }
101 
102             wallpaper.dispatchWallpaperVisibility(visible);
103         }
104     }
105 
106     /**
107      * Starts {@param anim} on all children.
108      */
startAnimation(Animation anim)109     void startAnimation(Animation anim) {
110         for (int ndx = mChildren.size() - 1; ndx >= 0; ndx--) {
111             final WindowState windowState = mChildren.get(ndx);
112             windowState.startAnimation(anim);
113         }
114     }
115 
updateWallpaperWindows(boolean visible)116     void updateWallpaperWindows(boolean visible) {
117 
118         if (isHidden() == visible) {
119             if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG,
120                     "Wallpaper token " + token + " hidden=" + !visible);
121             setHidden(!visible);
122             // Need to do a layout to ensure the wallpaper now has the correct size.
123             mDisplayContent.setLayoutNeeded();
124         }
125 
126         final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
127         final int dw = displayInfo.logicalWidth;
128         final int dh = displayInfo.logicalHeight;
129         final WallpaperController wallpaperController = mDisplayContent.mWallpaperController;
130         for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
131             final WindowState wallpaper = mChildren.get(wallpaperNdx);
132 
133             if (visible) {
134                 wallpaperController.updateWallpaperOffset(wallpaper, dw, dh, false);
135             }
136 
137             // First, make sure the client has the current visibility state.
138             wallpaper.dispatchWallpaperVisibility(visible);
139 
140             if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win "
141                     + wallpaper);
142         }
143     }
144 
hasVisibleNotDrawnWallpaper()145     boolean hasVisibleNotDrawnWallpaper() {
146         for (int j = mChildren.size() - 1; j >= 0; --j) {
147             final WindowState wallpaper = mChildren.get(j);
148             if (wallpaper.hasVisibleNotDrawnWallpaper()) {
149                 return true;
150             }
151         }
152         return false;
153     }
154 
155     @Override
toString()156     public String toString() {
157         if (stringName == null) {
158             StringBuilder sb = new StringBuilder();
159             sb.append("WallpaperWindowToken{");
160             sb.append(Integer.toHexString(System.identityHashCode(this)));
161             sb.append(" token="); sb.append(token); sb.append('}');
162             stringName = sb.toString();
163         }
164         return stringName;
165     }
166 }
167