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