Home | History | Annotate | Download | only in stackdivider
      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.stackdivider;
     18 
     19 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
     20 import static android.view.WindowManager.DOCKED_INVALID;
     21 
     22 import android.app.ActivityManager;
     23 import android.graphics.Rect;
     24 import android.os.RemoteException;
     25 import android.util.Log;
     26 import android.view.WindowManagerGlobal;
     27 
     28 import com.android.internal.annotations.GuardedBy;
     29 
     30 import java.util.concurrent.ExecutorService;
     31 import java.util.concurrent.Executors;
     32 
     33 /**
     34  * Proxy to simplify calls into window manager/activity manager
     35  */
     36 public class WindowManagerProxy {
     37 
     38     private static final String TAG = "WindowManagerProxy";
     39 
     40     private static final WindowManagerProxy sInstance = new WindowManagerProxy();
     41 
     42     @GuardedBy("mDockedRect")
     43     private final Rect mDockedRect = new Rect();
     44     private final Rect mTempDockedTaskRect = new Rect();
     45     private final Rect mTempDockedInsetRect = new Rect();
     46     private final Rect mTempOtherTaskRect = new Rect();
     47     private final Rect mTempOtherInsetRect = new Rect();
     48 
     49     private final Rect mTmpRect1 = new Rect();
     50     private final Rect mTmpRect2 = new Rect();
     51     private final Rect mTmpRect3 = new Rect();
     52     private final Rect mTmpRect4 = new Rect();
     53     private final Rect mTmpRect5 = new Rect();
     54 
     55     @GuardedBy("mDockedRect")
     56     private final Rect mTouchableRegion = new Rect();
     57 
     58     private boolean mDimLayerVisible;
     59     private int mDimLayerTargetStack;
     60     private float mDimLayerAlpha;
     61 
     62     private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
     63 
     64     private final Runnable mResizeRunnable = new Runnable() {
     65         @Override
     66         public void run() {
     67             synchronized (mDockedRect) {
     68                 mTmpRect1.set(mDockedRect);
     69                 mTmpRect2.set(mTempDockedTaskRect);
     70                 mTmpRect3.set(mTempDockedInsetRect);
     71                 mTmpRect4.set(mTempOtherTaskRect);
     72                 mTmpRect5.set(mTempOtherInsetRect);
     73             }
     74             try {
     75                 ActivityManager.getService()
     76                         .resizeDockedStack(mTmpRect1,
     77                                 mTmpRect2.isEmpty() ? null : mTmpRect2,
     78                                 mTmpRect3.isEmpty() ? null : mTmpRect3,
     79                                 mTmpRect4.isEmpty() ? null : mTmpRect4,
     80                                 mTmpRect5.isEmpty() ? null : mTmpRect5);
     81             } catch (RemoteException e) {
     82                 Log.w(TAG, "Failed to resize stack: " + e);
     83             }
     84         }
     85     };
     86 
     87     private final Runnable mDismissRunnable = new Runnable() {
     88         @Override
     89         public void run() {
     90             try {
     91                 ActivityManager.getService().moveTasksToFullscreenStack(
     92                         DOCKED_STACK_ID, false /* onTop */);
     93             } catch (RemoteException e) {
     94                 Log.w(TAG, "Failed to remove stack: " + e);
     95             }
     96         }
     97     };
     98 
     99     private final Runnable mMaximizeRunnable = new Runnable() {
    100         @Override
    101         public void run() {
    102             try {
    103                 ActivityManager.getService().resizeStack(
    104                         DOCKED_STACK_ID, null, true, true, false, -1);
    105             } catch (RemoteException e) {
    106                 Log.w(TAG, "Failed to resize stack: " + e);
    107             }
    108         }
    109     };
    110 
    111     private final Runnable mDimLayerRunnable = new Runnable() {
    112         @Override
    113         public void run() {
    114             try {
    115                 WindowManagerGlobal.getWindowManagerService().setResizeDimLayer(mDimLayerVisible,
    116                         mDimLayerTargetStack, mDimLayerAlpha);
    117             } catch (RemoteException e) {
    118                 Log.w(TAG, "Failed to resize stack: " + e);
    119             }
    120         }
    121     };
    122 
    123     private final Runnable mSwapRunnable = new Runnable() {
    124         @Override
    125         public void run() {
    126             try {
    127                 ActivityManager.getService().swapDockedAndFullscreenStack();
    128             } catch (RemoteException e) {
    129                 Log.w(TAG, "Failed to resize stack: " + e);
    130             }
    131         }
    132     };
    133 
    134     private final Runnable mSetTouchableRegionRunnable = new Runnable() {
    135         @Override
    136         public void run() {
    137             try {
    138                 synchronized (mDockedRect) {
    139                     mTmpRect1.set(mTouchableRegion);
    140                 }
    141                 WindowManagerGlobal.getWindowManagerService().setDockedStackDividerTouchRegion(
    142                         mTmpRect1);
    143             } catch (RemoteException e) {
    144                 Log.w(TAG, "Failed to set touchable region: " + e);
    145             }
    146         }
    147     };
    148 
    149     private WindowManagerProxy() {
    150     }
    151 
    152     public static WindowManagerProxy getInstance() {
    153         return sInstance;
    154     }
    155 
    156     public void resizeDockedStack(Rect docked, Rect tempDockedTaskRect, Rect tempDockedInsetRect,
    157             Rect tempOtherTaskRect, Rect tempOtherInsetRect) {
    158         synchronized (mDockedRect) {
    159             mDockedRect.set(docked);
    160             if (tempDockedTaskRect != null) {
    161                 mTempDockedTaskRect.set(tempDockedTaskRect);
    162             } else {
    163                 mTempDockedTaskRect.setEmpty();
    164             }
    165             if (tempDockedInsetRect != null) {
    166                 mTempDockedInsetRect.set(tempDockedInsetRect);
    167             } else {
    168                 mTempDockedInsetRect.setEmpty();
    169             }
    170             if (tempOtherTaskRect != null) {
    171                 mTempOtherTaskRect.set(tempOtherTaskRect);
    172             } else {
    173                 mTempOtherTaskRect.setEmpty();
    174             }
    175             if (tempOtherInsetRect != null) {
    176                 mTempOtherInsetRect.set(tempOtherInsetRect);
    177             } else {
    178                 mTempOtherInsetRect.setEmpty();
    179             }
    180         }
    181         mExecutor.execute(mResizeRunnable);
    182     }
    183 
    184     public void dismissDockedStack() {
    185         mExecutor.execute(mDismissRunnable);
    186     }
    187 
    188     public void maximizeDockedStack() {
    189         mExecutor.execute(mMaximizeRunnable);
    190     }
    191 
    192     public void setResizing(final boolean resizing) {
    193         mExecutor.execute(new Runnable() {
    194             @Override
    195             public void run() {
    196                 try {
    197                     WindowManagerGlobal.getWindowManagerService().setDockedStackResizing(resizing);
    198                 } catch (RemoteException e) {
    199                     Log.w(TAG, "Error calling setDockedStackResizing: " + e);
    200                 }
    201             }
    202         });
    203     }
    204 
    205     public int getDockSide() {
    206         try {
    207             return WindowManagerGlobal.getWindowManagerService().getDockedStackSide();
    208         } catch (RemoteException e) {
    209             Log.w(TAG, "Failed to get dock side: " + e);
    210         }
    211         return DOCKED_INVALID;
    212     }
    213 
    214     public void setResizeDimLayer(boolean visible, int targetStackId, float alpha) {
    215         mDimLayerVisible = visible;
    216         mDimLayerTargetStack = targetStackId;
    217         mDimLayerAlpha = alpha;
    218         mExecutor.execute(mDimLayerRunnable);
    219     }
    220 
    221     public void swapTasks() {
    222         mExecutor.execute(mSwapRunnable);
    223     }
    224 
    225     public void setTouchRegion(Rect region) {
    226         synchronized (mDockedRect) {
    227             mTouchableRegion.set(region);
    228         }
    229         mExecutor.execute(mSetTouchableRegionRunnable);
    230     }
    231 }
    232