blob: 42f1b1424877ee02464366c2f171045821270232 [file] [log] [blame]
Winson73bc1592016-10-18 18:47:43 -07001/*
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
17package com.android.systemui.pip.phone;
18
Winson Chunga29eb982016-12-14 12:01:27 -080019import static android.view.Display.DEFAULT_DISPLAY;
20
Sudheer Shankadc589ac2016-11-10 15:30:17 -080021import android.app.ActivityManager;
Winson73bc1592016-10-18 18:47:43 -070022import android.app.IActivityManager;
Winson Chung3535df22017-01-17 18:43:39 -080023import android.content.ComponentName;
Winson73bc1592016-10-18 18:47:43 -070024import android.content.Context;
Winson Chunga29eb982016-12-14 12:01:27 -080025import android.content.pm.ParceledListSlice;
Winson Chung2a82fe52017-02-02 14:43:34 -080026import android.graphics.Rect;
Winson Chunga29eb982016-12-14 12:01:27 -080027import android.os.Handler;
28import android.os.RemoteException;
29import android.util.Log;
30import android.view.IPinnedStackController;
31import android.view.IPinnedStackListener;
Winson73bc1592016-10-18 18:47:43 -070032import android.view.IWindowManager;
33import android.view.WindowManagerGlobal;
34
Winson Chung29a78652017-02-09 18:35:26 -080035import com.android.systemui.pip.BasePipManager;
Winson Chung929d4f72017-01-13 10:21:33 -080036import com.android.systemui.recents.misc.SystemServicesProxy;
37import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
38
Winson Chung29a78652017-02-09 18:35:26 -080039import java.io.PrintWriter;
40
Winson73bc1592016-10-18 18:47:43 -070041/**
42 * Manages the picture-in-picture (PIP) UI and states for Phones.
43 */
Winson Chung29a78652017-02-09 18:35:26 -080044public class PipManager implements BasePipManager {
Winson73bc1592016-10-18 18:47:43 -070045 private static final String TAG = "PipManager";
46
47 private static PipManager sPipController;
48
49 private Context mContext;
50 private IActivityManager mActivityManager;
51 private IWindowManager mWindowManager;
Winson Chunga29eb982016-12-14 12:01:27 -080052 private Handler mHandler = new Handler();
53
54 private final PinnedStackListener mPinnedStackListener = new PinnedStackListener();
Winson73bc1592016-10-18 18:47:43 -070055
Winson Chung15504af2016-11-02 18:11:36 -070056 private PipMenuActivityController mMenuController;
Winson Chung97a60d92017-01-18 16:01:53 -080057 private PipMediaController mMediaController;
Winson73bc1592016-10-18 18:47:43 -070058 private PipTouchHandler mTouchHandler;
59
Winson Chunga29eb982016-12-14 12:01:27 -080060 /**
Winson Chung929d4f72017-01-13 10:21:33 -080061 * Handler for system task stack changes.
62 */
63 TaskStackListener mTaskStackListener = new TaskStackListener() {
64 @Override
65 public void onActivityPinned() {
Winson Chung3535df22017-01-17 18:43:39 -080066 if (!checkCurrentUserId(false /* debug */)) {
67 return;
68 }
Winson Chung929d4f72017-01-13 10:21:33 -080069 mTouchHandler.onActivityPinned();
Winson Chung97a60d92017-01-18 16:01:53 -080070 mMediaController.onActivityPinned();
Winson Chung929d4f72017-01-13 10:21:33 -080071 }
72
73 @Override
74 public void onPinnedStackAnimationEnded() {
75 // TODO(winsonc): Disable touch interaction with the PiP until the animation ends
76 }
77
78 @Override
Winson Chung3535df22017-01-17 18:43:39 -080079 public void onPinnedActivityRestartAttempt(ComponentName sourceComponent) {
80 if (!checkCurrentUserId(false /* debug */)) {
81 return;
82 }
83
84 // Expand the activity back to fullscreen only if it was attempted to be restarted from
85 // another package than the top activity in the stack
86 boolean expandPipToFullscreen = true;
87 if (sourceComponent != null) {
Winson Chung734c9c02017-01-23 19:08:37 -080088 ComponentName topActivity = PipUtils.getTopPinnedActivity(mContext,
89 mActivityManager);
90 if (topActivity != null && topActivity.getPackageName().equals(
91 sourceComponent.getPackageName())) {
92 expandPipToFullscreen = false;
93 }
Winson Chung3535df22017-01-17 18:43:39 -080094 }
95 if (expandPipToFullscreen) {
Winson Chung2a82fe52017-02-02 14:43:34 -080096 mTouchHandler.getMotionHelper().expandPip();
Winson Chung3535df22017-01-17 18:43:39 -080097 } else {
98 Log.w(TAG, "Can not expand PiP to fullscreen via intent from the same package.");
99 }
Winson Chung929d4f72017-01-13 10:21:33 -0800100 }
101 };
102
103 /**
Winson Chunga29eb982016-12-14 12:01:27 -0800104 * Handler for messages from the PIP controller.
105 */
106 private class PinnedStackListener extends IPinnedStackListener.Stub {
107
108 @Override
109 public void onListenerRegistered(IPinnedStackController controller) {
110 mHandler.post(() -> {
111 mTouchHandler.setPinnedStackController(controller);
112 });
113 }
114
115 @Override
Winson Chung2a82fe52017-02-02 14:43:34 -0800116 public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
Winson Chunga29eb982016-12-14 12:01:27 -0800117 mHandler.post(() -> {
Winson Chung2a82fe52017-02-02 14:43:34 -0800118 mTouchHandler.onImeVisibilityChanged(imeVisible, imeHeight);
Winson Chunga29eb982016-12-14 12:01:27 -0800119 });
120 }
121
122 @Override
123 public void onMinimizedStateChanged(boolean isMinimized) {
124 mHandler.post(() -> {
Winson Chung2a82fe52017-02-02 14:43:34 -0800125 mTouchHandler.setMinimizedState(isMinimized, true /* fromController */);
Winson Chunga29eb982016-12-14 12:01:27 -0800126 });
127 }
128
129 @Override
Winson Chung2a82fe52017-02-02 14:43:34 -0800130 public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds,
131 boolean fromImeAdjustement) {
Winson Chunga29eb982016-12-14 12:01:27 -0800132 mHandler.post(() -> {
Winson Chung2a82fe52017-02-02 14:43:34 -0800133 mTouchHandler.onMovementBoundsChanged(insetBounds, normalBounds, fromImeAdjustement);
134 });
135 }
136
137 @Override
138 public void onActionsChanged(ParceledListSlice actions) {
139 mHandler.post(() -> {
140 mMenuController.setAppActions(actions);
Winson Chunga29eb982016-12-14 12:01:27 -0800141 });
142 }
143 }
144
Winson73bc1592016-10-18 18:47:43 -0700145 private PipManager() {}
146
147 /**
148 * Initializes {@link PipManager}.
149 */
150 public void initialize(Context context) {
151 mContext = context;
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800152 mActivityManager = ActivityManager.getService();
Winson73bc1592016-10-18 18:47:43 -0700153 mWindowManager = WindowManagerGlobal.getWindowManagerService();
154
Winson Chunga29eb982016-12-14 12:01:27 -0800155 try {
156 mWindowManager.registerPinnedStackListener(DEFAULT_DISPLAY, mPinnedStackListener);
157 } catch (RemoteException e) {
158 Log.e(TAG, "Failed to register pinned stack listener", e);
159 }
Winson Chung929d4f72017-01-13 10:21:33 -0800160 SystemServicesProxy.getInstance(mContext).registerTaskStackListener(mTaskStackListener);
Winson Chunga29eb982016-12-14 12:01:27 -0800161
Winson Chung97a60d92017-01-18 16:01:53 -0800162 mMediaController = new PipMediaController(context, mActivityManager);
163 mMenuController = new PipMenuActivityController(context, mActivityManager, mWindowManager,
164 mMediaController);
Winson Chung15504af2016-11-02 18:11:36 -0700165 mTouchHandler = new PipTouchHandler(context, mMenuController, mActivityManager,
166 mWindowManager);
Winson73bc1592016-10-18 18:47:43 -0700167 }
168
169 /**
170 * Updates the PIP per configuration changed.
171 */
Winson Chung303c6b72016-10-24 17:12:49 -0700172 public void onConfigurationChanged() {
173 mTouchHandler.onConfigurationChanged();
174 }
Winson73bc1592016-10-18 18:47:43 -0700175
176 /**
177 * Gets an instance of {@link PipManager}.
178 */
179 public static PipManager getInstance() {
180 if (sPipController == null) {
181 sPipController = new PipManager();
182 }
183 return sPipController;
184 }
Winson Chung29a78652017-02-09 18:35:26 -0800185
186 public void dump(PrintWriter pw) {
187 final String innerPrefix = " ";
188 pw.println(TAG);
189 mMenuController.dump(pw, innerPrefix);
190 mTouchHandler.dump(pw, innerPrefix);
191 }
Winson73bc1592016-10-18 18:47:43 -0700192}