blob: ef8d48e7f2cf369db4009356362c77af3d3d2a89 [file] [log] [blame]
/*
* Copyright (C) 2016 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.recents.tv.views;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.IRemoteCallback;
import android.os.RemoteException;
import android.util.Log;
import android.view.WindowManagerGlobal;
import com.android.internal.annotations.GuardedBy;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.*;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
public class RecentsTvTransitionHelper {
private static final String TAG = "RecentsTvTransitionHelper";
private Context mContext;
private Handler mHandler;
public RecentsTvTransitionHelper(Context context, Handler handler) {
mContext = context;
mHandler = handler;
}
public void launchTaskFromRecents(final TaskStack stack, @Nullable final Task task,
final TaskStackHorizontalGridView stackView, final TaskCardView taskView,
final Rect bounds, int destinationStack) {
final ActivityOptions opts = ActivityOptions.makeBasic();
if (bounds != null) {
opts.setLaunchBounds(bounds.isEmpty() ? null : bounds);
}
final ActivityOptions.OnAnimationStartedListener animStartedListener;
if (task.thumbnail != null && task.thumbnail.getWidth() > 0 &&
task.thumbnail.getHeight() > 0) {
animStartedListener = new ActivityOptions.OnAnimationStartedListener() {
@Override
public void onAnimationStarted() {
// If we are launching into another task, cancel the previous task's
// window transition
EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
}
};
} else {
// This is only the case if the task is not on screen (scrolled offscreen for example)
animStartedListener = new ActivityOptions.OnAnimationStartedListener() {
@Override
public void onAnimationStarted() {
EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
}
};
}
if (taskView == null) {
// If there is no task view, then we do not need to worry about animating out occluding
// task views, and we can launch immediately
startTaskActivity(stack, task, taskView, opts, animStartedListener);
} else {
LaunchTvTaskStartedEvent launchStartedEvent = new LaunchTvTaskStartedEvent(taskView);
EventBus.getDefault().send(launchStartedEvent);
startTaskActivity(stack, task, taskView, opts, animStartedListener);
}
}
private void startTaskActivity(TaskStack stack, Task task, @Nullable TaskCardView taskView,
ActivityOptions opts,final ActivityOptions.OnAnimationStartedListener animStartedListener) {
SystemServicesProxy ssp = Recents.getSystemServices();
if (ssp.startActivityFromRecents(mContext, task.key.id, task.title, opts)) {
// Keep track of the index of the task launch
int taskIndexFromFront = 0;
int taskIndex = stack.indexOfStackTask(task);
if (taskIndex > -1) {
taskIndexFromFront = stack.getTaskCount() - taskIndex - 1;
}
EventBus.getDefault().send(new LaunchTaskSucceededEvent(taskIndexFromFront));
} else {
// Keep track of failed launches
EventBus.getDefault().send(new LaunchTaskFailedEvent());
}
IRemoteCallback.Stub callback = null;
if (animStartedListener != null) {
callback = new IRemoteCallback.Stub() {
@Override
public void sendResult(Bundle data) throws RemoteException {
mHandler.post(new Runnable() {
@Override
public void run() {
if (animStartedListener != null) {
animStartedListener.onAnimationStarted();
}
}
});
}
};
}
try {
Rect taskRect = taskView.getGlobalRect();
WindowManagerGlobal.getWindowManagerService()
.overridePendingAppTransitionThumb(task.thumbnail, taskRect.left,
taskRect.top, callback, true);
} catch (RemoteException e) {
Log.w(TAG, "Failed to override transition: " + e);
}
}
}