blob: 06205c5c1c41aca2191c26c41987e58de5e01e74 [file] [log] [blame]
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.bubbles;
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityOptions;
import android.app.PendingIntent;
import android.window.TaskEmbedder;
import android.window.TaskOrganizerTaskEmbedder;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.view.IWindow;
import android.view.SurfaceControl;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import dalvik.system.CloseGuard;
public class BubbleTaskView extends SurfaceView implements SurfaceHolder.Callback,
TaskEmbedder.Host {
private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleTaskView" : TAG_BUBBLES;
private final CloseGuard mGuard = CloseGuard.get();
private boolean mOpened; // Protected by mGuard.
private TaskEmbedder mTaskEmbedder;
private final SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction();
private final Rect mTmpRect = new Rect();
public BubbleTaskView(Context context) {
super(context);
mTaskEmbedder = new TaskOrganizerTaskEmbedder(context, this);
setUseAlpha();
getHolder().addCallback(this);
mOpened = true;
mGuard.open("release");
}
public void setCallback(TaskEmbedder.Listener callback) {
if (callback == null) {
mTaskEmbedder.setListener(null);
return;
}
mTaskEmbedder.setListener(callback);
}
public void startShortcutActivity(@NonNull ShortcutInfo shortcut,
@NonNull ActivityOptions options, @Nullable Rect sourceBounds) {
mTaskEmbedder.startShortcutActivity(shortcut, options, sourceBounds);
}
public void startActivity(@NonNull PendingIntent pendingIntent, @Nullable Intent fillInIntent,
@NonNull ActivityOptions options) {
mTaskEmbedder.startActivity(pendingIntent, fillInIntent, options);
}
public void onLocationChanged() {
mTaskEmbedder.notifyBoundsChanged();
}
@Override
public Rect getScreenBounds() {
getBoundsOnScreen(mTmpRect);
return mTmpRect;
}
@Override
public void onTaskBackgroundColorChanged(TaskEmbedder ts, int bgColor) {
setResizeBackgroundColor(bgColor);
}
@Override
public Region getTapExcludeRegion() {
// Not used
return null;
}
@Override
public Matrix getScreenToTaskMatrix() {
// Not used
return null;
}
@Override
public IWindow getWindow() {
// Not used
return null;
}
@Override
public Point getPositionInWindow() {
// Not used
return null;
}
@Override
public boolean canReceivePointerEvents() {
// Not used
return false;
}
public void release() {
if (!mTaskEmbedder.isInitialized()) {
throw new IllegalStateException(
"Trying to release container that is not initialized.");
}
performRelease();
}
@Override
protected void finalize() throws Throwable {
try {
if (mGuard != null) {
mGuard.warnIfOpen();
performRelease();
}
} finally {
super.finalize();
}
}
private void performRelease() {
if (!mOpened) {
return;
}
getHolder().removeCallback(this);
mTaskEmbedder.release();
mTaskEmbedder.setListener(null);
mGuard.close();
mOpened = false;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (!mTaskEmbedder.isInitialized()) {
mTaskEmbedder.initialize(getSurfaceControl());
} else {
mTmpTransaction.reparent(mTaskEmbedder.getSurfaceControl(),
getSurfaceControl()).apply();
}
mTaskEmbedder.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mTaskEmbedder.resizeTask(width, height);
mTaskEmbedder.notifyBoundsChanged();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mTaskEmbedder.stop();
}
}