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.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 20 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; 21 22 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS; 23 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WALLPAPER; 24 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; 25 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 26 27 import android.annotation.Nullable; 28 import android.os.Bundle; 29 import android.os.IBinder; 30 import android.os.RemoteException; 31 import android.view.animation.Animation; 32 33 import com.android.internal.protolog.common.ProtoLog; 34 35 import java.util.function.Consumer; 36 37 /** 38 * A token that represents a set of wallpaper windows. 39 */ 40 class WallpaperWindowToken extends WindowToken { 41 42 private static final String TAG = TAG_WITH_CLASS_NAME ? "WallpaperWindowToken" : TAG_WM; 43 44 private boolean mShowWhenLocked = false; 45 WallpaperWindowToken(WindowManagerService service, IBinder token, boolean explicit, DisplayContent dc, boolean ownerCanManageAppTokens)46 WallpaperWindowToken(WindowManagerService service, IBinder token, boolean explicit, 47 DisplayContent dc, boolean ownerCanManageAppTokens) { 48 this(service, token, explicit, dc, ownerCanManageAppTokens, null /* options */); 49 } 50 WallpaperWindowToken(WindowManagerService service, IBinder token, boolean explicit, DisplayContent dc, boolean ownerCanManageAppTokens, @Nullable Bundle options)51 WallpaperWindowToken(WindowManagerService service, IBinder token, boolean explicit, 52 DisplayContent dc, boolean ownerCanManageAppTokens, @Nullable Bundle options) { 53 super(service, token, TYPE_WALLPAPER, explicit, dc, ownerCanManageAppTokens, 54 false /* roundedCornerOverlay */, false /* fromClientToken */, options); 55 dc.mWallpaperController.addWallpaperToken(this); 56 setWindowingMode(WINDOWING_MODE_FULLSCREEN); 57 } 58 59 @Override asWallpaperToken()60 WallpaperWindowToken asWallpaperToken() { 61 return this; 62 } 63 64 @Override setExiting(boolean animateExit)65 void setExiting(boolean animateExit) { 66 super.setExiting(animateExit); 67 mDisplayContent.mWallpaperController.removeWallpaperToken(this); 68 } 69 70 /** 71 * Controls whether this wallpaper shows underneath the keyguard or is hidden and only 72 * revealed once keyguard is dismissed. 73 */ setShowWhenLocked(boolean showWhenLocked)74 void setShowWhenLocked(boolean showWhenLocked) { 75 if (showWhenLocked == mShowWhenLocked) { 76 return; 77 } 78 mShowWhenLocked = showWhenLocked; 79 if (mDisplayContent.mWallpaperController.mIsLockscreenLiveWallpaperEnabled) { 80 // Move the window token to the front (private) or back (showWhenLocked). This is 81 // possible 82 // because the DisplayArea underneath TaskDisplayArea only contains TYPE_WALLPAPER 83 // windows. 84 final int position = showWhenLocked ? POSITION_BOTTOM : POSITION_TOP; 85 86 // Note: Moving all the way to the front or back breaks ordering based on addition 87 // times. 88 // We should never have more than one non-animating token of each type. 89 getParent().positionChildAt(position, this /* child */, false /*includingParents */); 90 } 91 } 92 canShowWhenLocked()93 boolean canShowWhenLocked() { 94 return mShowWhenLocked; 95 } 96 sendWindowWallpaperCommand( String action, int x, int y, int z, Bundle extras, boolean sync)97 void sendWindowWallpaperCommand( 98 String action, int x, int y, int z, Bundle extras, boolean sync) { 99 for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) { 100 final WindowState wallpaper = mChildren.get(wallpaperNdx); 101 try { 102 wallpaper.mClient.dispatchWallpaperCommand(action, x, y, z, extras, sync); 103 // We only want to be synchronous with one wallpaper. 104 sync = false; 105 } catch (RemoteException e) { 106 } 107 } 108 } 109 updateWallpaperOffset(boolean sync)110 void updateWallpaperOffset(boolean sync) { 111 final WallpaperController wallpaperController = mDisplayContent.mWallpaperController; 112 for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) { 113 final WindowState wallpaper = mChildren.get(wallpaperNdx); 114 if (wallpaperController.updateWallpaperOffset(wallpaper, sync)) { 115 // We only want to be synchronous with one wallpaper. 116 sync = false; 117 } 118 } 119 } 120 121 /** 122 * Starts {@param anim} on all children. 123 */ startAnimation(Animation anim)124 void startAnimation(Animation anim) { 125 for (int ndx = mChildren.size() - 1; ndx >= 0; ndx--) { 126 final WindowState windowState = mChildren.get(ndx); 127 windowState.startAnimation(anim); 128 } 129 } 130 updateWallpaperWindows(boolean visible)131 void updateWallpaperWindows(boolean visible) { 132 if (mVisibleRequested != visible) { 133 ProtoLog.d(WM_DEBUG_WALLPAPER, "Wallpaper token %s visible=%b", 134 token, visible); 135 setVisibility(visible); 136 } 137 138 final WindowState wallpaperTarget = 139 mDisplayContent.mWallpaperController.getWallpaperTarget(); 140 141 if (visible && wallpaperTarget != null) { 142 final RecentsAnimationController recentsAnimationController = 143 mWmService.getRecentsAnimationController(); 144 if (recentsAnimationController != null 145 && recentsAnimationController.isAnimatingTask(wallpaperTarget.getTask())) { 146 // If the Recents animation is running, and the wallpaper target is the animating 147 // task we want the wallpaper to be rotated in the same orientation as the 148 // RecentsAnimation's target (e.g the launcher) 149 recentsAnimationController.linkFixedRotationTransformIfNeeded(this); 150 } else if ((wallpaperTarget.mActivityRecord == null 151 // Ignore invisible activity because it may be moving to background. 152 || wallpaperTarget.mActivityRecord.isVisibleRequested()) 153 && wallpaperTarget.mToken.hasFixedRotationTransform()) { 154 // If the wallpaper target has a fixed rotation, we want the wallpaper to follow its 155 // rotation 156 linkFixedRotationTransform(wallpaperTarget.mToken); 157 } 158 } 159 if (mTransitionController.inTransition(this)) { 160 // If wallpaper is in transition, setVisible() will be called from commitVisibility() 161 // when finishing transition. Otherwise commitVisibility() is already called from above 162 // setVisibility(). 163 return; 164 } 165 166 setVisible(visible); 167 } 168 setVisible(boolean visible)169 private void setVisible(boolean visible) { 170 final boolean wasClientVisible = isClientVisible(); 171 setClientVisible(visible); 172 if (visible && !wasClientVisible) { 173 for (int i = mChildren.size() - 1; i >= 0; i--) { 174 final WindowState wallpaper = mChildren.get(i); 175 wallpaper.requestUpdateWallpaperIfNeeded(); 176 } 177 } 178 } 179 180 /** 181 * Sets the requested visibility of this token. The visibility may not be if this is part of a 182 * transition. In that situation, make sure to call {@link #commitVisibility} when done. 183 */ setVisibility(boolean visible)184 void setVisibility(boolean visible) { 185 if (mVisibleRequested != visible) { 186 // Before setting mVisibleRequested so we can track changes. 187 mTransitionController.collect(this); 188 189 setVisibleRequested(visible); 190 } 191 192 // If in a transition, defer commits for activities that are going invisible 193 if (!visible && (mTransitionController.inTransition() 194 || getDisplayContent().mAppTransition.isRunning())) { 195 return; 196 } 197 198 commitVisibility(visible); 199 } 200 201 /** Commits the visibility of this token. This will directly update the visibility. */ commitVisibility(boolean visible)202 void commitVisibility(boolean visible) { 203 if (visible == isVisible()) return; 204 205 ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, 206 "commitVisibility: %s: visible=%b mVisibleRequested=%b", this, 207 isVisible(), mVisibleRequested); 208 209 setVisibleRequested(visible); 210 setVisible(visible); 211 } 212 hasVisibleNotDrawnWallpaper()213 boolean hasVisibleNotDrawnWallpaper() { 214 if (!isVisible()) return false; 215 for (int j = mChildren.size() - 1; j >= 0; --j) { 216 final WindowState wallpaper = mChildren.get(j); 217 if (!wallpaper.isDrawn() && wallpaper.isVisible()) { 218 return true; 219 } 220 } 221 return false; 222 } 223 224 @Override forAllWallpaperWindows(Consumer<WallpaperWindowToken> callback)225 void forAllWallpaperWindows(Consumer<WallpaperWindowToken> callback) { 226 callback.accept(this); 227 } 228 229 @Override fillsParent()230 boolean fillsParent() { 231 return true; 232 } 233 234 @Override showWallpaper()235 boolean showWallpaper() { 236 return false; 237 } 238 239 @Override setVisibleRequested(boolean visible)240 protected boolean setVisibleRequested(boolean visible) { 241 if (!super.setVisibleRequested(visible)) return false; 242 setInsetsFrozen(!visible); 243 return true; 244 } 245 246 @Override onChildVisibleRequestedChanged(@ullable WindowContainer child)247 protected boolean onChildVisibleRequestedChanged(@Nullable WindowContainer child) { 248 // Wallpaper manages visibleRequested directly (it's not determined by children) 249 return false; 250 } 251 252 @Override isVisible()253 boolean isVisible() { 254 return isClientVisible(); 255 } 256 257 @Override toString()258 public String toString() { 259 if (stringName == null) { 260 StringBuilder sb = new StringBuilder(); 261 sb.append("WallpaperWindowToken{"); 262 sb.append(Integer.toHexString(System.identityHashCode(this))); 263 sb.append(" token="); sb.append(token); sb.append('}'); 264 stringName = sb.toString(); 265 } 266 return stringName; 267 } 268 } 269