blob: 99f710bd8bd4676bd6aef0446b7fe1bc94e2b050 [file] [log] [blame]
Evan Rosky22b6bbd2019-09-26 14:29:57 -07001/*
2 * Copyright (C) 2019 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
17package com.android.server.wm;
18
Evan Rosky0ad8d2c2020-03-16 12:09:58 -070019import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
20
21import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
22import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
23
Evan Rosky22b6bbd2019-09-26 14:29:57 -070024import android.annotation.NonNull;
Evan Rosky0ad8d2c2020-03-16 12:09:58 -070025import android.graphics.Point;
Evan Rosky2ffddde2020-04-16 19:14:56 -070026import android.graphics.Rect;
Evan Rosky22b6bbd2019-09-26 14:29:57 -070027import android.os.IBinder;
28import android.os.RemoteException;
29import android.util.Slog;
Evan Rosky0ad8d2c2020-03-16 12:09:58 -070030import android.view.DisplayInfo;
Evan Rosky22b6bbd2019-09-26 14:29:57 -070031import android.view.IWindow;
32import android.view.SurfaceControl;
Evan Rosky2ffddde2020-04-16 19:14:56 -070033import android.view.WindowInfo;
Evan Rosky0ad8d2c2020-03-16 12:09:58 -070034import android.view.animation.Animation;
Evan Rosky22b6bbd2019-09-26 14:29:57 -070035
36/**
37 * Represents a piece of the hierarchy under which a client Shell can manage sub-windows.
38 */
39public class ShellRoot {
40 private static final String TAG = "ShellRoot";
41 private final DisplayContent mDisplayContent;
42 private IWindow mClient;
43 private WindowToken mToken;
44 private final IBinder.DeathRecipient mDeathRecipient;
45 private SurfaceControl mSurfaceControl = null;
Evan Roskycff7ebb2020-04-22 16:54:49 -070046 private IWindow mAccessibilityWindow;
47 private IBinder.DeathRecipient mAccessibilityWindowDeath;
Evan Rosky22b6bbd2019-09-26 14:29:57 -070048
49 ShellRoot(@NonNull IWindow client, @NonNull DisplayContent dc, final int windowType) {
50 mDisplayContent = dc;
51 mDeathRecipient = () -> mDisplayContent.removeShellRoot(windowType);
52 try {
53 client.asBinder().linkToDeath(mDeathRecipient, 0);
54 } catch (RemoteException e) {
55 Slog.e(TAG, "Unable to add shell root for layer " + windowType + " on display "
56 + dc.getDisplayId(), e);
57 return;
58 }
59 mClient = client;
60 mToken = new WindowToken(
61 dc.mWmService, client.asBinder(), windowType, true, dc, true, false);
62 mSurfaceControl = mToken.makeChildSurface(null)
63 .setContainerLayer().setName("Shell Root Leash " + dc.getDisplayId()).build();
64 mToken.getPendingTransaction().show(mSurfaceControl);
65 }
66
67 void clear() {
68 if (mClient != null) {
69 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
70 mClient = null;
71 }
72 if (mToken != null) {
73 mToken.removeImmediately();
74 mToken = null;
75 }
76 }
77
78 SurfaceControl getSurfaceControl() {
79 return mSurfaceControl;
80 }
81
82 IWindow getClient() {
83 return mClient;
84 }
Evan Rosky0ad8d2c2020-03-16 12:09:58 -070085
86 void startAnimation(Animation anim) {
87 // Only do this for the divider
88 if (mToken.windowType != TYPE_DOCK_DIVIDER) {
89 return;
90 }
91
92 DisplayInfo displayInfo = mToken.getFixedRotationTransformDisplayInfo();
93 if (displayInfo == null) {
94 displayInfo = mDisplayContent.getDisplayInfo();
95 }
96
97 // Mostly copied from WindowState to enable keyguard transition animation
98 anim.initialize(displayInfo.logicalWidth, displayInfo.logicalHeight,
99 displayInfo.appWidth, displayInfo.appHeight);
100 anim.restrictDuration(MAX_ANIMATION_DURATION);
101 anim.scaleCurrentDuration(mDisplayContent.mWmService.getWindowAnimationScaleLocked());
102 final AnimationAdapter adapter = new LocalAnimationAdapter(
103 new WindowAnimationSpec(anim, new Point(0, 0), false /* canSkipFirstFrame */,
104 0 /* windowCornerRadius */),
105 mDisplayContent.mWmService.mSurfaceAnimationRunner);
106 mToken.startAnimation(mToken.getPendingTransaction(), adapter, false /* hidden */,
107 ANIMATION_TYPE_WINDOW_ANIMATION, null /* animationFinishedCallback */);
108 }
Evan Rosky2ffddde2020-04-16 19:14:56 -0700109
110 WindowInfo getWindowInfo() {
111 if (mToken.windowType != TYPE_DOCK_DIVIDER) {
112 return null;
113 }
114 if (!mDisplayContent.getDefaultTaskDisplayArea().isSplitScreenModeActivated()) {
115 return null;
116 }
Evan Roskycff7ebb2020-04-22 16:54:49 -0700117 if (mAccessibilityWindow == null) {
118 return null;
119 }
Evan Rosky2ffddde2020-04-16 19:14:56 -0700120 WindowInfo windowInfo = WindowInfo.obtain();
121 windowInfo.displayId = mToken.getDisplayArea().getDisplayContent().mDisplayId;
122 windowInfo.type = mToken.windowType;
123 windowInfo.layer = mToken.getWindowLayerFromType();
Evan Roskycff7ebb2020-04-22 16:54:49 -0700124 windowInfo.token = mAccessibilityWindow.asBinder();
Evan Rosky2ffddde2020-04-16 19:14:56 -0700125 windowInfo.title = "Splitscreen Divider";
126 windowInfo.focused = false;
127 windowInfo.inPictureInPicture = false;
128 windowInfo.hasFlagWatchOutsideTouch = false;
129 final Rect regionRect = new Rect();
130 mDisplayContent.getDockedDividerController().getTouchRegion(regionRect);
131 windowInfo.regionInScreen.set(regionRect);
132 return windowInfo;
133 }
Evan Roskycff7ebb2020-04-22 16:54:49 -0700134
135 void setAccessibilityWindow(IWindow window) {
136 if (mAccessibilityWindow != null) {
137 mAccessibilityWindow.asBinder().unlinkToDeath(mAccessibilityWindowDeath, 0);
138 }
139 mAccessibilityWindow = window;
140 if (mAccessibilityWindow != null) {
141 try {
142 mAccessibilityWindowDeath = () -> {
143 synchronized (mDisplayContent.mWmService.mGlobalLock) {
144 mAccessibilityWindow = null;
145 setAccessibilityWindow(null);
146 }
147 };
148 mAccessibilityWindow.asBinder().linkToDeath(mAccessibilityWindowDeath, 0);
149 } catch (RemoteException e) {
150 mAccessibilityWindow = null;
151 }
152 }
153 if (mDisplayContent.mWmService.mAccessibilityController != null) {
154 mDisplayContent.mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(
155 mDisplayContent.getDisplayId());
156 }
157 }
Evan Rosky22b6bbd2019-09-26 14:29:57 -0700158}
159