blob: aaab6b4099e54fe2f68d40a0eeb93f81ccde9712 [file] [log] [blame]
Andrii Kuliand3134692017-06-26 14:57:02 -07001/**
2 * Copyright (c) 2017 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 android.app;
18
19import android.annotation.NonNull;
Mady Mellorc41ed322019-09-25 11:19:26 -070020import android.annotation.Nullable;
Wale Ogunwale691af682019-02-11 03:09:10 -080021import android.annotation.TestApi;
Mark Renouf7b71a5d2019-01-23 17:12:34 -050022import android.content.ComponentName;
Andrii Kuliand3134692017-06-26 14:57:02 -070023import android.content.Context;
24import android.content.Intent;
Mady Mellor1bd16752019-10-25 12:30:09 -070025import android.content.pm.LauncherApps;
26import android.content.pm.ShortcutInfo;
Issei Suzukia5dbf522019-02-01 17:58:15 +010027import android.graphics.Insets;
Yohei Yukawab4f328a2019-05-02 08:41:27 -070028import android.graphics.Matrix;
Mark Renouf89ac9882019-10-07 16:28:18 -040029import android.graphics.Point;
Mark Renoufe574ad02019-08-12 16:22:15 -040030import android.graphics.Rect;
Tiger Huang2b210c22019-03-18 21:21:26 +080031import android.graphics.Region;
Mady Mellor1bd16752019-10-25 12:30:09 -070032import android.os.Bundle;
Brad Stenninga1dbe9c2018-05-02 08:29:28 -070033import android.os.UserHandle;
Andrii Kuliand3134692017-06-26 14:57:02 -070034import android.util.AttributeSet;
Andrii Kuliand3134692017-06-26 14:57:02 -070035import android.util.Log;
Mark Renouf89ac9882019-10-07 16:28:18 -040036import android.view.IWindow;
Andrii Kulianf0379de2018-03-14 16:24:07 -070037import android.view.IWindowManager;
Mark Renouf041d7262019-02-06 12:09:41 -050038import android.view.KeyEvent;
chaviwff2e7d82018-11-02 11:11:27 -070039import android.view.SurfaceControl;
Andrii Kuliand3134692017-06-26 14:57:02 -070040import android.view.SurfaceHolder;
41import android.view.SurfaceView;
chaviwd44449d2019-01-02 16:33:12 -080042import android.view.View;
Andrii Kuliand3134692017-06-26 14:57:02 -070043import android.view.ViewGroup;
Tiger Huang2b210c22019-03-18 21:21:26 +080044import android.view.ViewParent;
Andrii Kuliand3134692017-06-26 14:57:02 -070045
46import dalvik.system.CloseGuard;
47
48/**
Mark Renouf89ac9882019-10-07 16:28:18 -040049 * Task container that allows launching activities into itself.
Andrii Kuliand3134692017-06-26 14:57:02 -070050 * <p>Activity launching into this container is restricted by the same rules that apply to launching
51 * on VirtualDisplays.
52 * @hide
53 */
Wale Ogunwale691af682019-02-11 03:09:10 -080054@TestApi
Mark Renouf89ac9882019-10-07 16:28:18 -040055public class ActivityView extends ViewGroup implements TaskEmbedder.Host {
Andrii Kuliand3134692017-06-26 14:57:02 -070056
Andrii Kuliand3134692017-06-26 14:57:02 -070057 private static final String TAG = "ActivityView";
58
Mark Renouf89ac9882019-10-07 16:28:18 -040059 private TaskEmbedder mTaskEmbedder;
60
Andrii Kuliand3134692017-06-26 14:57:02 -070061 private final SurfaceView mSurfaceView;
Andrii Kuliand3134692017-06-26 14:57:02 -070062 private final SurfaceCallback mSurfaceCallback;
Andrii Kuliancf8f6832018-01-23 19:43:30 -080063
Andrii Kuliand3134692017-06-26 14:57:02 -070064 private final CloseGuard mGuard = CloseGuard.get();
65 private boolean mOpened; // Protected by mGuard.
66
chaviwff2e7d82018-11-02 11:11:27 -070067 private final SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction();
chaviwff2e7d82018-11-02 11:11:27 -070068
Mark Renouf89ac9882019-10-07 16:28:18 -040069 // For Host
70 private final Point mWindowPosition = new Point();
71 private final int[] mTmpArray = new int[2];
72 private final Matrix mScreenSurfaceMatrix = new Matrix();
73 private final Region mTapExcludeRegion = new Region();
Mark Renoufe574ad02019-08-12 16:22:15 -040074
Andrii Kuliand3134692017-06-26 14:57:02 -070075 public ActivityView(Context context) {
76 this(context, null /* attrs */);
77 }
78
79 public ActivityView(Context context, AttributeSet attrs) {
80 this(context, attrs, 0 /* defStyle */);
81 }
82
83 public ActivityView(Context context, AttributeSet attrs, int defStyle) {
Wale Ogunwale9e737db2018-12-17 15:42:37 -080084 this(context, attrs, defStyle, false /*singleTaskInstance*/);
85 }
86
87 public ActivityView(
88 Context context, AttributeSet attrs, int defStyle, boolean singleTaskInstance) {
Andrii Kuliand3134692017-06-26 14:57:02 -070089 super(context, attrs, defStyle);
Mark Renouf89ac9882019-10-07 16:28:18 -040090 mTaskEmbedder = new TaskEmbedder(getContext(), this, singleTaskInstance);
Andrii Kuliand3134692017-06-26 14:57:02 -070091 mSurfaceView = new SurfaceView(context);
lumark3f51e3c2019-07-23 21:18:17 +080092 // Since ActivityView#getAlpha has been overridden, we should use parent class's alpha
93 // as master to synchronize surface view's alpha value.
94 mSurfaceView.setAlpha(super.getAlpha());
Issei Suzuki006b71f2019-06-17 15:56:57 +020095 mSurfaceView.setUseAlpha();
Andrii Kuliand3134692017-06-26 14:57:02 -070096 mSurfaceCallback = new SurfaceCallback();
97 mSurfaceView.getHolder().addCallback(mSurfaceCallback);
98 addView(mSurfaceView);
99
100 mOpened = true;
101 mGuard.open("release");
102 }
103
104 /** Callback that notifies when the container is ready or destroyed. */
105 public abstract static class StateCallback {
Mark Renouf7b71a5d2019-01-23 17:12:34 -0500106
Andrii Kuliand3134692017-06-26 14:57:02 -0700107 /**
108 * Called when the container is ready for launching activities. Calling
109 * {@link #startActivity(Intent)} prior to this callback will result in an
110 * {@link IllegalStateException}.
111 *
112 * @see #startActivity(Intent)
113 */
114 public abstract void onActivityViewReady(ActivityView view);
Mark Renouf7b71a5d2019-01-23 17:12:34 -0500115
Andrii Kuliand3134692017-06-26 14:57:02 -0700116 /**
117 * Called when the container can no longer launch activities. Calling
118 * {@link #startActivity(Intent)} after this callback will result in an
119 * {@link IllegalStateException}.
120 *
121 * @see #startActivity(Intent)
122 */
123 public abstract void onActivityViewDestroyed(ActivityView view);
Mark Renouf7b71a5d2019-01-23 17:12:34 -0500124
125 /**
126 * Called when a task is created inside the container.
127 * This is a filtered version of {@link TaskStackListener}
128 */
129 public void onTaskCreated(int taskId, ComponentName componentName) { }
130
Brad Stenninga1dbe9c2018-05-02 08:29:28 -0700131 /**
132 * Called when a task is moved to the front of the stack inside the container.
133 * This is a filtered version of {@link TaskStackListener}
134 */
Wale Ogunwale691af682019-02-11 03:09:10 -0800135 public void onTaskMovedToFront(int taskId) { }
Mark Renouf7b71a5d2019-01-23 17:12:34 -0500136
137 /**
138 * Called when a task is about to be removed from the stack inside the container.
139 * This is a filtered version of {@link TaskStackListener}
140 */
141 public void onTaskRemovalStarted(int taskId) { }
Andrii Kuliand3134692017-06-26 14:57:02 -0700142 }
143
144 /**
145 * Set the callback to be notified about state changes.
146 * <p>This class must finish initializing before {@link #startActivity(Intent)} can be called.
147 * <p>Note: If the instance was ready prior to this call being made, then
148 * {@link StateCallback#onActivityViewReady(ActivityView)} will be called from within
149 * this method call.
150 *
151 * @param callback The callback to report events to.
152 *
153 * @see StateCallback
154 * @see #startActivity(Intent)
155 */
156 public void setCallback(StateCallback callback) {
Mark Renouf89ac9882019-10-07 16:28:18 -0400157 if (callback == null) {
158 mTaskEmbedder.setListener(null);
159 return;
Andrii Kuliand3134692017-06-26 14:57:02 -0700160 }
Mark Renouf89ac9882019-10-07 16:28:18 -0400161 mTaskEmbedder.setListener(new StateCallbackAdapter(callback));
Andrii Kuliand3134692017-06-26 14:57:02 -0700162 }
163
164 /**
Mark Renouf34d04f32019-05-13 15:53:18 -0400165 * Sets the corner radius for the Activity displayed here. The corners will be
166 * cropped from the window painted by the contained Activity.
167 *
168 * @param cornerRadius the radius for the corners, in pixels
169 * @hide
170 */
171 public void setCornerRadius(float cornerRadius) {
172 mSurfaceView.setCornerRadius(cornerRadius);
173 }
174
175 /**
Mark Renoufe574ad02019-08-12 16:22:15 -0400176 * @hide
177 */
178 public float getCornerRadius() {
179 return mSurfaceView.getCornerRadius();
180 }
181
182 /**
183 * Control whether the surface is clipped to the same bounds as the View. If true, then
184 * the bounds set by {@link #setSurfaceClipBounds(Rect)} are applied to the surface as
185 * window-crop.
186 *
187 * @param clippingEnabled whether to enable surface clipping
188 * @hide
189 */
190 public void setSurfaceClippingEnabled(boolean clippingEnabled) {
191 mSurfaceView.setEnableSurfaceClipping(clippingEnabled);
192 }
193
194 /**
195 * Sets an area on the contained surface to which it will be clipped
196 * when it is drawn. Setting the value to null will remove the clip bounds
197 * and the surface will draw normally, using its full bounds.
198 *
199 * @param clipBounds The rectangular area, in the local coordinates of
200 * this view, to which future drawing operations will be clipped.
201 * @hide
202 */
203 public void setSurfaceClipBounds(Rect clipBounds) {
204 mSurfaceView.setClipBounds(clipBounds);
205 }
206
207 /**
208 * @hide
209 */
210 public boolean getSurfaceClipBounds(Rect outRect) {
211 return mSurfaceView.getClipBounds(outRect);
212 }
213
214 /**
Mady Mellor1bd16752019-10-25 12:30:09 -0700215 * Launch an activity represented by {@link ShortcutInfo} into this container.
216 * <p>The owner of this container must be allowed to access the shortcut information,
217 * as defined in {@link LauncherApps#hasShortcutHostPermission()} to use this method.
218 * <p>Activity resolved by the provided {@link ShortcutInfo} must have
219 * {@link android.R.attr#resizeableActivity} attribute set to {@code true} in order to be
220 * launched here. Also, if activity is not owned by the owner of this container, it must allow
221 * embedding and the caller must have permission to embed.
222 * <p>Note: This class must finish initializing and
223 * {@link StateCallback#onActivityViewReady(ActivityView)} callback must be triggered before
224 * this method can be called.
225 *
226 * @param shortcut the shortcut used to launch the activity.
227 * @param options for the activity.
228 * @param sourceBounds the rect containing the source bounds of the clicked icon to open
229 * this shortcut.
230 * @see StateCallback
231 * @see LauncherApps#startShortcut(ShortcutInfo, Rect, Bundle)
232 *
233 * @hide
234 */
235 public void startShortcutActivity(@NonNull ShortcutInfo shortcut,
236 @NonNull ActivityOptions options, @Nullable Rect sourceBounds) {
237 mTaskEmbedder.startShortcutActivity(shortcut, options, sourceBounds);
238 }
239
240 /**
Andrii Kuliand3134692017-06-26 14:57:02 -0700241 * Launch a new activity into this container.
242 * <p>Activity resolved by the provided {@link Intent} must have
243 * {@link android.R.attr#resizeableActivity} attribute set to {@code true} in order to be
244 * launched here. Also, if activity is not owned by the owner of this container, it must allow
245 * embedding and the caller must have permission to embed.
246 * <p>Note: This class must finish initializing and
247 * {@link StateCallback#onActivityViewReady(ActivityView)} callback must be triggered before
248 * this method can be called.
249 *
250 * @param intent Intent used to launch an activity.
251 *
252 * @see StateCallback
253 * @see #startActivity(PendingIntent)
254 */
255 public void startActivity(@NonNull Intent intent) {
Mark Renouf89ac9882019-10-07 16:28:18 -0400256 mTaskEmbedder.startActivity(intent);
Andrii Kuliand3134692017-06-26 14:57:02 -0700257 }
258
259 /**
260 * Launch a new activity into this container.
Brad Stenninga1dbe9c2018-05-02 08:29:28 -0700261 * <p>Activity resolved by the provided {@link Intent} must have
262 * {@link android.R.attr#resizeableActivity} attribute set to {@code true} in order to be
263 * launched here. Also, if activity is not owned by the owner of this container, it must allow
264 * embedding and the caller must have permission to embed.
265 * <p>Note: This class must finish initializing and
266 * {@link StateCallback#onActivityViewReady(ActivityView)} callback must be triggered before
267 * this method can be called.
268 *
269 * @param intent Intent used to launch an activity.
270 * @param user The UserHandle of the user to start this activity for.
271 *
272 *
273 * @see StateCallback
274 * @see #startActivity(PendingIntent)
275 */
276 public void startActivity(@NonNull Intent intent, UserHandle user) {
Mark Renouf89ac9882019-10-07 16:28:18 -0400277 mTaskEmbedder.startActivity(intent, user);
Brad Stenninga1dbe9c2018-05-02 08:29:28 -0700278 }
279
280 /**
281 * Launch a new activity into this container.
Andrii Kuliand3134692017-06-26 14:57:02 -0700282 * <p>Activity resolved by the provided {@link PendingIntent} must have
283 * {@link android.R.attr#resizeableActivity} attribute set to {@code true} in order to be
284 * launched here. Also, if activity is not owned by the owner of this container, it must allow
285 * embedding and the caller must have permission to embed.
286 * <p>Note: This class must finish initializing and
287 * {@link StateCallback#onActivityViewReady(ActivityView)} callback must be triggered before
288 * this method can be called.
289 *
290 * @param pendingIntent Intent used to launch an activity.
291 *
292 * @see StateCallback
293 * @see #startActivity(Intent)
294 */
295 public void startActivity(@NonNull PendingIntent pendingIntent) {
Mark Renouf89ac9882019-10-07 16:28:18 -0400296 mTaskEmbedder.startActivity(pendingIntent);
Andrii Kuliand3134692017-06-26 14:57:02 -0700297 }
298
299 /**
Mady Mellor60101c92019-04-11 19:04:00 -0700300 * Launch a new activity into this container.
301 * <p>Activity resolved by the provided {@link PendingIntent} must have
302 * {@link android.R.attr#resizeableActivity} attribute set to {@code true} in order to be
303 * launched here. Also, if activity is not owned by the owner of this container, it must allow
304 * embedding and the caller must have permission to embed.
305 * <p>Note: This class must finish initializing and
306 * {@link StateCallback#onActivityViewReady(ActivityView)} callback must be triggered before
307 * this method can be called.
308 *
309 * @param pendingIntent Intent used to launch an activity.
Mady Mellorc41ed322019-09-25 11:19:26 -0700310 * @param fillInIntent Additional Intent data, see {@link Intent#fillIn Intent.fillIn()}.
Mady Mellor60101c92019-04-11 19:04:00 -0700311 * @param options options for the activity
312 *
313 * @see StateCallback
314 * @see #startActivity(Intent)
315 */
Mady Mellorc41ed322019-09-25 11:19:26 -0700316 public void startActivity(@NonNull PendingIntent pendingIntent, @Nullable Intent fillInIntent,
Mady Mellor60101c92019-04-11 19:04:00 -0700317 @NonNull ActivityOptions options) {
Mark Renouf89ac9882019-10-07 16:28:18 -0400318 mTaskEmbedder.startActivity(pendingIntent, fillInIntent, options);
Andrii Kuliand3134692017-06-26 14:57:02 -0700319 }
320
321 /**
322 * Release this container. Activity launching will no longer be permitted.
323 * <p>Note: Calling this method is allowed after
324 * {@link StateCallback#onActivityViewReady(ActivityView)} callback was triggered and before
325 * {@link StateCallback#onActivityViewDestroyed(ActivityView)}.
326 *
327 * @see StateCallback
328 */
329 public void release() {
Mark Renouf89ac9882019-10-07 16:28:18 -0400330 if (!mTaskEmbedder.isInitialized()) {
Andrii Kuliand3134692017-06-26 14:57:02 -0700331 throw new IllegalStateException(
332 "Trying to release container that is not initialized.");
333 }
334 performRelease();
335 }
336
Andrii Kulian4b6599e2018-01-15 17:24:08 -0800337 /**
Tiger Huang2b210c22019-03-18 21:21:26 +0800338 * Triggers an update of {@link ActivityView}'s location in window to properly set tap exclude
Andrii Kulian4b6599e2018-01-15 17:24:08 -0800339 * regions and avoid focus switches by touches on this view.
340 */
341 public void onLocationChanged() {
Mark Renouf89ac9882019-10-07 16:28:18 -0400342 mTaskEmbedder.notifyBoundsChanged();
Yohei Yukawab4f328a2019-05-02 08:41:27 -0700343 }
344
Andrii Kuliand3134692017-06-26 14:57:02 -0700345 @Override
346 public void onLayout(boolean changed, int l, int t, int r, int b) {
347 mSurfaceView.layout(0 /* left */, 0 /* top */, r - l /* right */, b - t /* bottom */);
348 }
349
lumark3f51e3c2019-07-23 21:18:17 +0800350 /**
351 * Sets the alpha value when the content of {@link SurfaceView} needs to show or hide.
352 * <p>Note: The surface view may ignore the alpha value in some cases. Refer to
353 * {@link SurfaceView#setAlpha} for more details.
354 *
355 * @param alpha The opacity of the view.
356 */
Tiger Huang2b210c22019-03-18 21:21:26 +0800357 @Override
Issei Suzukicac2a502019-04-16 16:52:50 +0200358 public void setAlpha(float alpha) {
lumark3f51e3c2019-07-23 21:18:17 +0800359 super.setAlpha(alpha);
360
361 if (mSurfaceView != null) {
362 mSurfaceView.setAlpha(alpha);
363 }
Issei Suzukicac2a502019-04-16 16:52:50 +0200364 }
365
366 @Override
367 public float getAlpha() {
368 return mSurfaceView.getAlpha();
369 }
370
371 @Override
Tiger Huang2b210c22019-03-18 21:21:26 +0800372 public boolean gatherTransparentRegion(Region region) {
373 // The tap exclude region may be affected by any view on top of it, so we detect the
374 // possible change by monitoring this function.
Mark Renouf89ac9882019-10-07 16:28:18 -0400375 mTaskEmbedder.notifyBoundsChanged();
Tiger Huang2b210c22019-03-18 21:21:26 +0800376 return super.gatherTransparentRegion(region);
377 }
378
Andrii Kuliand3134692017-06-26 14:57:02 -0700379 private class SurfaceCallback implements SurfaceHolder.Callback {
380 @Override
381 public void surfaceCreated(SurfaceHolder surfaceHolder) {
Mark Renouf89ac9882019-10-07 16:28:18 -0400382 if (!mTaskEmbedder.isInitialized()) {
383 initTaskEmbedder(mSurfaceView.getSurfaceControl());
Andrii Kuliand3134692017-06-26 14:57:02 -0700384 } else {
Mark Renouf89ac9882019-10-07 16:28:18 -0400385 mTmpTransaction.reparent(mTaskEmbedder.getSurfaceControl(),
Robert Carr10584fa2019-01-14 15:55:19 -0800386 mSurfaceView.getSurfaceControl()).apply();
Andrii Kuliand3134692017-06-26 14:57:02 -0700387 }
Mark Renouf89ac9882019-10-07 16:28:18 -0400388 mTaskEmbedder.start();
Andrii Kuliand3134692017-06-26 14:57:02 -0700389 }
390
391 @Override
392 public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
Mark Renouf89ac9882019-10-07 16:28:18 -0400393 mTaskEmbedder.resizeTask(width, height);
394 mTaskEmbedder.notifyBoundsChanged();
Andrii Kuliand3134692017-06-26 14:57:02 -0700395 }
396
397 @Override
398 public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
Mark Renouf89ac9882019-10-07 16:28:18 -0400399 mTaskEmbedder.stop();
Andrii Kuliand3134692017-06-26 14:57:02 -0700400 }
401 }
402
chaviwd44449d2019-01-02 16:33:12 -0800403 @Override
404 protected void onVisibilityChanged(View changedView, int visibility) {
405 super.onVisibilityChanged(changedView, visibility);
406 mSurfaceView.setVisibility(visibility);
407 }
408
Mark Renouf041d7262019-02-06 12:09:41 -0500409 /**
Mady Mellor390bff42019-04-05 15:09:01 -0700410 * @return the display id of the virtual display.
411 */
412 public int getVirtualDisplayId() {
Mark Renouf89ac9882019-10-07 16:28:18 -0400413 return mTaskEmbedder.getDisplayId();
Mady Mellor390bff42019-04-05 15:09:01 -0700414 }
415
416 /**
Mark Renouf041d7262019-02-06 12:09:41 -0500417 * Injects a pair of down/up key events with keycode {@link KeyEvent#KEYCODE_BACK} to the
418 * virtual display.
419 */
420 public void performBackPress() {
Mark Renouf89ac9882019-10-07 16:28:18 -0400421 mTaskEmbedder.performBackPress();
Mark Renouf041d7262019-02-06 12:09:41 -0500422 }
423
Mark Renouf89ac9882019-10-07 16:28:18 -0400424 /**
425 * Initializes the task embedder.
426 *
427 * @param parent control for the surface to parent to
428 * @return true if the task embedder has been initialized
429 */
430 private boolean initTaskEmbedder(SurfaceControl parent) {
431 if (!mTaskEmbedder.initialize(parent)) {
Andrii Kuliand3134692017-06-26 14:57:02 -0700432 Log.e(TAG, "Failed to initialize ActivityView");
Mark Renouf89ac9882019-10-07 16:28:18 -0400433 return false;
Andrii Kuliand3134692017-06-26 14:57:02 -0700434 }
Mark Renouf89ac9882019-10-07 16:28:18 -0400435 mTmpTransaction.show(mTaskEmbedder.getSurfaceControl()).apply();
436 return true;
Andrii Kuliand3134692017-06-26 14:57:02 -0700437 }
438
439 private void performRelease() {
440 if (!mOpened) {
441 return;
442 }
Andrii Kuliand3134692017-06-26 14:57:02 -0700443 mSurfaceView.getHolder().removeCallback(mSurfaceCallback);
Mark Renouf89ac9882019-10-07 16:28:18 -0400444 mTaskEmbedder.release();
Yuncheol Heo9076eac2019-11-10 11:32:27 -0800445 mTaskEmbedder.setListener(null);
Andrii Kuliand3134692017-06-26 14:57:02 -0700446
447 mGuard.close();
448 mOpened = false;
449 }
450
Andrii Kuliand3134692017-06-26 14:57:02 -0700451 @Override
452 protected void finalize() throws Throwable {
453 try {
454 if (mGuard != null) {
455 mGuard.warnIfOpen();
456 performRelease();
457 }
458 } finally {
459 super.finalize();
460 }
461 }
Andrii Kuliancf8f6832018-01-23 19:43:30 -0800462
463 /**
Issei Suzukia5dbf522019-02-01 17:58:15 +0100464 * Set forwarded insets on the virtual display.
465 *
466 * @see IWindowManager#setForwardedInsets
467 */
468 public void setForwardedInsets(Insets insets) {
Mark Renouf89ac9882019-10-07 16:28:18 -0400469 mTaskEmbedder.setForwardedInsets(insets);
470 }
471
472 // Host
473
474 /** @hide */
475 @Override
476 public void onTaskBackgroundColorChanged(TaskEmbedder ts, int bgColor) {
477 if (mSurfaceView != null) {
478 mSurfaceView.setResizeBackgroundColor(bgColor);
Issei Suzukia5dbf522019-02-01 17:58:15 +0100479 }
480 }
481
Mark Renouf89ac9882019-10-07 16:28:18 -0400482 /** @hide */
483 @Override
484 public Region getTapExcludeRegion() {
485 if (isAttachedToWindow() && canReceivePointerEvents()) {
486 Point windowPos = getPositionInWindow();
487 mTapExcludeRegion.set(
488 windowPos.x,
489 windowPos.y,
490 windowPos.x + getWidth(),
491 windowPos.y + getHeight());
492 // There might be views on top of us. We need to subtract those areas from the tap
493 // exclude region.
494 final ViewParent parent = getParent();
495 if (parent != null) {
496 parent.subtractObscuredTouchableRegion(mTapExcludeRegion, this);
497 }
498 } else {
499 mTapExcludeRegion.setEmpty();
500 }
501 return mTapExcludeRegion;
502 }
Andrii Kuliancf8f6832018-01-23 19:43:30 -0800503
Mark Renouf89ac9882019-10-07 16:28:18 -0400504 /** @hide */
505 @Override
506 public Matrix getScreenToTaskMatrix() {
507 getLocationOnScreen(mTmpArray);
508 mScreenSurfaceMatrix.set(getMatrix());
509 mScreenSurfaceMatrix.postTranslate(mTmpArray[0], mTmpArray[1]);
510 return mScreenSurfaceMatrix;
511 }
Andrii Kuliancf8f6832018-01-23 19:43:30 -0800512
Mark Renouf89ac9882019-10-07 16:28:18 -0400513 /** @hide */
514 @Override
515 public Point getPositionInWindow() {
516 getLocationInWindow(mTmpArray);
517 mWindowPosition.set(mTmpArray[0], mTmpArray[1]);
518 return mWindowPosition;
519 }
520
521 /** @hide */
522 @Override
523 public IWindow getWindow() {
524 return super.getWindow();
525 }
526
527 /** @hide */
528 @Override
529 public boolean canReceivePointerEvents() {
530 return super.canReceivePointerEvents();
531 }
532
533 private final class StateCallbackAdapter implements TaskEmbedder.Listener {
534 private final StateCallback mCallback;
535
536 private StateCallbackAdapter(ActivityView.StateCallback cb) {
537 mCallback = cb;
Brad Stenninga1dbe9c2018-05-02 08:29:28 -0700538 }
539
540 @Override
Mark Renouf89ac9882019-10-07 16:28:18 -0400541 public void onInitialized() {
542 mCallback.onActivityViewReady(ActivityView.this);
Mark Renouf7b71a5d2019-01-23 17:12:34 -0500543 }
544
545 @Override
Mark Renouf89ac9882019-10-07 16:28:18 -0400546 public void onReleased() {
547 mCallback.onActivityViewDestroyed(ActivityView.this);
Mark Renouf7b71a5d2019-01-23 17:12:34 -0500548 }
549
550 @Override
Mark Renouf89ac9882019-10-07 16:28:18 -0400551 public void onTaskCreated(int taskId, ComponentName name) {
552 mCallback.onTaskCreated(taskId, name);
Brad Stenninga1dbe9c2018-05-02 08:29:28 -0700553 }
554
Mark Renouf89ac9882019-10-07 16:28:18 -0400555 @Override
556 public void onTaskMovedToFront(int taskId) {
557 mCallback.onTaskMovedToFront(taskId);
558 }
Andrii Kuliancf8f6832018-01-23 19:43:30 -0800559
Mark Renouf89ac9882019-10-07 16:28:18 -0400560 @Override
561 public void onTaskRemovalStarted(int taskId) {
562 mCallback.onTaskRemovalStarted(taskId);
Andrii Kuliancf8f6832018-01-23 19:43:30 -0800563 }
564 }
Andrii Kuliand3134692017-06-26 14:57:02 -0700565}