Home | History | Annotate | Download | only in tv
      1 /*
      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 
     17 package com.android.systemui.recents.tv;
     18 
     19 import android.app.ActivityManager;
     20 import android.app.ActivityOptions;
     21 import android.content.Context;
     22 import android.content.Intent;
     23 import android.graphics.Bitmap;
     24 import android.graphics.Rect;
     25 import android.os.SystemClock;
     26 import android.os.UserHandle;
     27 
     28 import com.android.systemui.SystemUIApplication;
     29 import com.android.systemui.recents.Recents;
     30 import com.android.systemui.recents.RecentsActivityLaunchState;
     31 import com.android.systemui.recents.RecentsConfiguration;
     32 import com.android.systemui.recents.RecentsImpl;
     33 import com.android.systemui.recents.events.EventBus;
     34 import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
     35 import com.android.systemui.recents.misc.SystemServicesProxy;
     36 import com.android.systemui.recents.model.RecentsTaskLoader;
     37 import com.android.systemui.recents.model.TaskStack;
     38 import com.android.systemui.recents.model.ThumbnailData;
     39 import com.android.systemui.recents.tv.views.TaskCardView;
     40 import com.android.systemui.statusbar.tv.TvStatusBar;
     41 import com.android.systemui.tv.pip.PipManager;
     42 
     43 public class RecentsTvImpl extends RecentsImpl{
     44     public final static String RECENTS_TV_ACTIVITY =
     45             "com.android.systemui.recents.tv.RecentsTvActivity";
     46 
     47     private static final PipManager mPipManager = PipManager.getInstance();
     48 
     49     public RecentsTvImpl(Context context) {
     50         super(context);
     51     }
     52 
     53     @Override
     54     protected void startRecentsActivity(ActivityManager.RunningTaskInfo runningTask,
     55             boolean isHomeStackVisible, boolean animate, int growTarget) {
     56         RecentsTaskLoader loader = Recents.getTaskLoader();
     57 
     58         // In the case where alt-tab is triggered, we never get a preloadRecents() call, so we
     59         // should always preload the tasks now. If we are dragging in recents, reload them as
     60         // the stacks might have changed.
     61         if (mTriggeredFromAltTab || sInstanceLoadPlan == null) {
     62             // Create a new load plan if preloadRecents() was never triggered
     63             sInstanceLoadPlan = loader.createLoadPlan(mContext);
     64         }
     65         if (mTriggeredFromAltTab || !sInstanceLoadPlan.hasTasks()) {
     66             loader.preloadTasks(sInstanceLoadPlan, runningTask.id, !isHomeStackVisible);
     67         }
     68         TaskStack stack = sInstanceLoadPlan.getTaskStack();
     69 
     70         if (!animate) {
     71             ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext, -1, -1);
     72             startRecentsActivity(runningTask, opts, false /* fromHome */, false /* fromThumbnail*/);
     73             return;
     74         }
     75 
     76         boolean hasRecentTasks = stack.getTaskCount() > 0;
     77         boolean useThumbnailTransition = (runningTask != null) && !isHomeStackVisible && hasRecentTasks;
     78 
     79         if (useThumbnailTransition) {
     80             // Try starting with a thumbnail transition
     81             ActivityOptions opts = getThumbnailTransitionActivityOptionsForTV(runningTask,
     82                     stack.getTaskCount());
     83             if (opts != null) {
     84                 startRecentsActivity(runningTask, opts, false /* fromHome */, true /* fromThumbnail */);
     85             } else {
     86                 // Fall through below to the non-thumbnail transition
     87                 useThumbnailTransition = false;
     88             }
     89         }
     90 
     91         if (!useThumbnailTransition) {
     92             startRecentsActivity(runningTask, null, true /* fromHome */, false /* fromThumbnail */);
     93         }
     94         mLastToggleTime = SystemClock.elapsedRealtime();
     95     }
     96 
     97     protected void startRecentsActivity(ActivityManager.RunningTaskInfo runningTask,
     98             ActivityOptions opts, boolean fromHome, boolean fromThumbnail) {
     99         // Update the configuration based on the launch options
    100         RecentsConfiguration config = Recents.getConfiguration();
    101         RecentsActivityLaunchState launchState = config.getLaunchState();
    102         launchState.launchedFromHome = fromHome;
    103         launchState.launchedFromApp = fromThumbnail;
    104         launchState.launchedToTaskId = (runningTask != null) ? runningTask.id : -1;
    105         launchState.launchedWithAltTab = mTriggeredFromAltTab;
    106 
    107         Intent intent = new Intent();
    108         intent.setClassName(RECENTS_PACKAGE, RECENTS_TV_ACTIVITY);
    109         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
    110                 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
    111                 | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
    112 
    113         if (opts != null) {
    114             mContext.startActivityAsUser(intent, opts.toBundle(), UserHandle.CURRENT);
    115         } else {
    116             mContext.startActivityAsUser(intent, UserHandle.CURRENT);
    117         }
    118         EventBus.getDefault().send(new RecentsActivityStartingEvent());
    119     }
    120 
    121     /**
    122      * Creates the activity options for an app->recents transition on TV.
    123      */
    124     private ActivityOptions getThumbnailTransitionActivityOptionsForTV(
    125             ActivityManager.RunningTaskInfo runningTask, int numTasks) {
    126         Rect rect = TaskCardView.getStartingCardThumbnailRect(
    127             mContext, !mPipManager.isPipShown(), numTasks);
    128         SystemServicesProxy ssp = Recents.getSystemServices();
    129         ThumbnailData thumbnailData = ssp.getTaskThumbnail(runningTask.id);
    130         if (thumbnailData.thumbnail != null) {
    131             Bitmap thumbnail = Bitmap.createScaledBitmap(thumbnailData.thumbnail, rect.width(),
    132                     rect.height(), false);
    133             return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
    134                     thumbnail, (int) rect.left, (int) rect.top, (int) rect.width(),
    135                     (int) rect.height(), mHandler, null);
    136         }
    137         // If both the screenshot and thumbnail fails, then just fall back to the default transition
    138         return getUnknownTransitionActivityOptions();
    139     }
    140 
    141     @Override
    142     public void onVisibilityChanged(Context context, boolean visible) {
    143         SystemUIApplication app = (SystemUIApplication) context;
    144         TvStatusBar statusBar = app.getComponent(TvStatusBar.class);
    145         if (statusBar != null) {
    146             statusBar.updateRecentsVisibility(visible);
    147         }
    148     }
    149 }
    150