Home | History | Annotate | Download | only in recents
      1 /*
      2  * Copyright (C) 2015 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;
     18 
     19 import android.app.AlertDialog;
     20 import android.app.Dialog;
     21 import android.app.DialogFragment;
     22 import android.app.FragmentManager;
     23 import android.content.Context;
     24 import android.content.DialogInterface;
     25 import android.graphics.Rect;
     26 import android.os.Bundle;
     27 import android.util.Pair;
     28 import android.view.LayoutInflater;
     29 import android.view.View;
     30 import android.widget.Button;
     31 import com.android.systemui.R;
     32 import com.android.systemui.recents.misc.SystemServicesProxy;
     33 import com.android.systemui.recents.model.RecentsTaskLoader;
     34 import com.android.systemui.recents.model.Task;
     35 import com.android.systemui.recents.RecentsActivity;
     36 import com.android.systemui.recents.views.RecentsView;
     37 
     38 import java.util.ArrayList;
     39 
     40 /**
     41  * A helper for the dialogs that show when task debugging is on.
     42  */
     43 public class RecentsResizeTaskDialog extends DialogFragment {
     44 
     45     static final String TAG = "RecentsResizeTaskDialog";
     46 
     47     // The various window arrangements we can handle.
     48     private static final int PLACE_LEFT = 1;
     49     private static final int PLACE_RIGHT = 2;
     50     private static final int PLACE_TOP = 3;
     51     private static final int PLACE_BOTTOM = 4;
     52     private static final int PLACE_TOP_LEFT = 5;
     53     private static final int PLACE_TOP_RIGHT = 6;
     54     private static final int PLACE_BOTTOM_LEFT = 7;
     55     private static final int PLACE_BOTTOM_RIGHT = 8;
     56     private static final int PLACE_FULL = 9;
     57 
     58     // The button resource ID combined with the arrangement command.
     59     private static final int[][] BUTTON_DEFINITIONS =
     60            {{R.id.place_left, PLACE_LEFT},
     61             {R.id.place_right, PLACE_RIGHT},
     62             {R.id.place_top, PLACE_TOP},
     63             {R.id.place_bottom, PLACE_BOTTOM},
     64             {R.id.place_top_left, PLACE_TOP_LEFT},
     65             {R.id.place_top_right, PLACE_TOP_RIGHT},
     66             {R.id.place_bottom_left, PLACE_BOTTOM_LEFT},
     67             {R.id.place_bottom_right, PLACE_BOTTOM_RIGHT},
     68             {R.id.place_full, PLACE_FULL}};
     69 
     70     // The task we want to resize.
     71     private FragmentManager mFragmentManager;
     72     private View mResizeTaskDialogContent;
     73     private RecentsActivity mRecentsActivity;
     74     private RecentsView mRecentsView;
     75     private SystemServicesProxy mSsp;
     76     private Rect[] mBounds = {new Rect(), new Rect(), new Rect(), new Rect()};
     77     private Task[] mTasks = {null, null, null, null};
     78 
     79     public RecentsResizeTaskDialog(FragmentManager mgr, RecentsActivity activity) {
     80         mFragmentManager = mgr;
     81         mRecentsActivity = activity;
     82         mSsp = RecentsTaskLoader.getInstance().getSystemServicesProxy();
     83     }
     84 
     85     /** Shows the resize-task dialog. */
     86     void showResizeTaskDialog(Task mainTask, RecentsView rv) {
     87         mTasks[0] = mainTask;
     88         mRecentsView = rv;
     89 
     90         show(mFragmentManager, TAG);
     91     }
     92 
     93     /** Creates a new resize-task dialog. */
     94     private void createResizeTaskDialog(final Context context, LayoutInflater inflater,
     95             AlertDialog.Builder builder) {
     96         builder.setTitle(R.string.recents_caption_resize);
     97         mResizeTaskDialogContent =
     98                 inflater.inflate(R.layout.recents_task_resize_dialog, null, false);
     99 
    100         for (int i = 0; i < BUTTON_DEFINITIONS.length; i++) {
    101             Button b = (Button)mResizeTaskDialogContent.findViewById(BUTTON_DEFINITIONS[i][0]);
    102             if (b != null) {
    103                 final int action = BUTTON_DEFINITIONS[i][1];
    104                 b.setOnClickListener(
    105                         new View.OnClickListener() {
    106                             public void onClick(View v) {
    107                                 placeTasks(action);
    108                             }
    109                         });
    110             }
    111         }
    112 
    113         builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
    114             @Override
    115             public void onClick(DialogInterface dialog, int which) {
    116                 dismiss();
    117             }
    118         });
    119 
    120         builder.setView(mResizeTaskDialogContent);
    121     }
    122 
    123     /** Helper function to place window(s) on the display according to an arrangement request. */
    124     private void placeTasks(int arrangement) {
    125         Rect rect = mSsp.getWindowRect();
    126         for (int i = 0; i < mBounds.length; ++i) {
    127             mBounds[i].set(rect);
    128             if (i != 0) {
    129                 mTasks[i] = null;
    130             }
    131         }
    132         int additionalTasks = 0;
    133         switch (arrangement) {
    134             case PLACE_LEFT:
    135                 mBounds[0].right = mBounds[0].centerX();
    136                 mBounds[1].left = mBounds[0].right;
    137                 additionalTasks = 1;
    138                 break;
    139             case PLACE_RIGHT:
    140                 mBounds[1].right = mBounds[1].centerX();
    141                 mBounds[0].left = mBounds[1].right;
    142                 additionalTasks = 1;
    143                 break;
    144             case PLACE_TOP:
    145                 mBounds[0].bottom = mBounds[0].centerY();
    146                 mBounds[1].top = mBounds[0].bottom;
    147                 additionalTasks = 1;
    148                 break;
    149             case PLACE_BOTTOM:
    150                 mBounds[1].bottom = mBounds[1].centerY();
    151                 mBounds[0].top = mBounds[1].bottom;
    152                 additionalTasks = 1;
    153                 break;
    154             case PLACE_TOP_LEFT:  // TL, TR, BL, BR
    155                 mBounds[0].right = mBounds[0].centerX();
    156                 mBounds[0].bottom = mBounds[0].centerY();
    157                 mBounds[1].left = mBounds[0].right;
    158                 mBounds[1].bottom = mBounds[0].bottom;
    159                 mBounds[2].right = mBounds[0].right;
    160                 mBounds[2].top = mBounds[0].bottom;
    161                 mBounds[3].left = mBounds[0].right;
    162                 mBounds[3].top = mBounds[0].bottom;
    163                 additionalTasks = 3;
    164                 break;
    165             case PLACE_TOP_RIGHT:  // TR, TL, BR, BL
    166                 mBounds[0].left = mBounds[0].centerX();
    167                 mBounds[0].bottom = mBounds[0].centerY();
    168                 mBounds[1].right = mBounds[0].left;
    169                 mBounds[1].bottom = mBounds[0].bottom;
    170                 mBounds[2].left = mBounds[0].left;
    171                 mBounds[2].top = mBounds[0].bottom;
    172                 mBounds[3].right = mBounds[0].left;
    173                 mBounds[3].top = mBounds[0].bottom;
    174                 additionalTasks = 3;
    175                 break;
    176             case PLACE_BOTTOM_LEFT:  // BL, BR, TL, TR
    177                 mBounds[0].right = mBounds[0].centerX();
    178                 mBounds[0].top = mBounds[0].centerY();
    179                 mBounds[1].left = mBounds[0].right;
    180                 mBounds[1].top = mBounds[0].top;
    181                 mBounds[2].right = mBounds[0].right;
    182                 mBounds[2].bottom = mBounds[0].top;
    183                 mBounds[3].left = mBounds[0].right;
    184                 mBounds[3].bottom = mBounds[0].top;
    185                 additionalTasks = 3;
    186                 break;
    187             case PLACE_BOTTOM_RIGHT:  // BR, BL, TR, TL
    188                 mBounds[0].left = mBounds[0].centerX();
    189                 mBounds[0].top = mBounds[0].centerY();
    190                 mBounds[1].right = mBounds[0].left;
    191                 mBounds[1].top = mBounds[0].top;
    192                 mBounds[2].left = mBounds[0].left;
    193                 mBounds[2].bottom = mBounds[0].top;
    194                 mBounds[3].right = mBounds[0].left;
    195                 mBounds[3].bottom = mBounds[0].top;
    196                 additionalTasks = 3;
    197                 break;
    198             case PLACE_FULL:
    199                 // Nothing to change.
    200                 break;
    201         }
    202 
    203         // Get the other tasks.
    204         for (int i = 1; i <= additionalTasks && mTasks[i - 1] != null; ++i) {
    205             mTasks[i] = mRecentsView.getNextTaskOrTopTask(mTasks[i - 1]);
    206             // Do stop if we circled back to the first item.
    207             if (mTasks[i] == mTasks[0]) {
    208                 mTasks[i] = null;
    209             }
    210         }
    211 
    212         // Get rid of the dialog.
    213         dismiss();
    214         mRecentsActivity.dismissRecentsToHomeWithoutTransitionAnimation();
    215 
    216         // Resize all tasks beginning from the "oldest" one.
    217         for (int i = additionalTasks; i >= 0; --i) {
    218             if (mTasks[i] != null) {
    219                mSsp.resizeTask(mTasks[i].key.id, mBounds[i]);
    220             }
    221         }
    222 
    223         // Show tasks as they might not be currently visible - beginning with the oldest so that
    224         // the focus ends on the selected one.
    225         for (int i = additionalTasks; i >= 0; --i) {
    226             if (mTasks[i] != null) {
    227                 mRecentsView.launchTask(mTasks[i]);
    228             }
    229         }
    230     }
    231 
    232     @Override
    233     public Dialog onCreateDialog(Bundle args) {
    234         final Context context = this.getActivity();
    235         LayoutInflater inflater = getActivity().getLayoutInflater();
    236         AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    237         createResizeTaskDialog(context, inflater, builder);
    238         return builder.create();
    239     }
    240 }
    241