| /* |
| * Copyright (C) 2015 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.stackdivider; |
| |
| import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; |
| import static android.view.WindowManager.DOCKED_INVALID; |
| |
| import android.app.ActivityManagerNative; |
| import android.graphics.Rect; |
| import android.os.RemoteException; |
| import android.util.Log; |
| import android.view.WindowManagerGlobal; |
| |
| import com.android.internal.annotations.GuardedBy; |
| |
| import java.util.concurrent.ExecutorService; |
| import java.util.concurrent.Executors; |
| |
| /** |
| * Proxy to simplify calls into window manager/activity manager |
| */ |
| public class WindowManagerProxy { |
| |
| private static final String TAG = "WindowManagerProxy"; |
| |
| private static final WindowManagerProxy sInstance = new WindowManagerProxy(); |
| |
| @GuardedBy("mDockedRect") |
| private final Rect mDockedRect = new Rect(); |
| private final Rect mTempDockedTaskRect = new Rect(); |
| private final Rect mTempDockedInsetRect = new Rect(); |
| private final Rect mTempOtherTaskRect = new Rect(); |
| private final Rect mTempOtherInsetRect = new Rect(); |
| |
| private final Rect mTmpRect1 = new Rect(); |
| private final Rect mTmpRect2 = new Rect(); |
| private final Rect mTmpRect3 = new Rect(); |
| private final Rect mTmpRect4 = new Rect(); |
| private final Rect mTmpRect5 = new Rect(); |
| |
| @GuardedBy("mDockedRect") |
| private final Rect mTouchableRegion = new Rect(); |
| |
| private boolean mDimLayerVisible; |
| private int mDimLayerTargetStack; |
| private float mDimLayerAlpha; |
| |
| private final ExecutorService mExecutor = Executors.newSingleThreadExecutor(); |
| |
| private final Runnable mResizeRunnable = new Runnable() { |
| @Override |
| public void run() { |
| synchronized (mDockedRect) { |
| mTmpRect1.set(mDockedRect); |
| mTmpRect2.set(mTempDockedTaskRect); |
| mTmpRect3.set(mTempDockedInsetRect); |
| mTmpRect4.set(mTempOtherTaskRect); |
| mTmpRect5.set(mTempOtherInsetRect); |
| } |
| try { |
| ActivityManagerNative.getDefault() |
| .resizeDockedStack(mTmpRect1, |
| mTmpRect2.isEmpty() ? null : mTmpRect2, |
| mTmpRect3.isEmpty() ? null : mTmpRect3, |
| mTmpRect4.isEmpty() ? null : mTmpRect4, |
| mTmpRect5.isEmpty() ? null : mTmpRect5); |
| } catch (RemoteException e) { |
| Log.w(TAG, "Failed to resize stack: " + e); |
| } |
| } |
| }; |
| |
| private final Runnable mDismissRunnable = new Runnable() { |
| @Override |
| public void run() { |
| try { |
| ActivityManagerNative.getDefault().moveTasksToFullscreenStack( |
| DOCKED_STACK_ID, false /* onTop */); |
| } catch (RemoteException e) { |
| Log.w(TAG, "Failed to remove stack: " + e); |
| } |
| } |
| }; |
| |
| private final Runnable mMaximizeRunnable = new Runnable() { |
| @Override |
| public void run() { |
| try { |
| ActivityManagerNative.getDefault().resizeStack( |
| DOCKED_STACK_ID, null, true, true, false, -1); |
| } catch (RemoteException e) { |
| Log.w(TAG, "Failed to resize stack: " + e); |
| } |
| } |
| }; |
| |
| private final Runnable mDimLayerRunnable = new Runnable() { |
| @Override |
| public void run() { |
| try { |
| WindowManagerGlobal.getWindowManagerService().setResizeDimLayer(mDimLayerVisible, |
| mDimLayerTargetStack, mDimLayerAlpha); |
| } catch (RemoteException e) { |
| Log.w(TAG, "Failed to resize stack: " + e); |
| } |
| } |
| }; |
| |
| private final Runnable mSwapRunnable = new Runnable() { |
| @Override |
| public void run() { |
| try { |
| ActivityManagerNative.getDefault().swapDockedAndFullscreenStack(); |
| } catch (RemoteException e) { |
| Log.w(TAG, "Failed to resize stack: " + e); |
| } |
| } |
| }; |
| |
| private final Runnable mSetTouchableRegionRunnable = new Runnable() { |
| @Override |
| public void run() { |
| try { |
| synchronized (mDockedRect) { |
| mTmpRect1.set(mTouchableRegion); |
| } |
| WindowManagerGlobal.getWindowManagerService().setDockedStackDividerTouchRegion( |
| mTmpRect1); |
| } catch (RemoteException e) { |
| Log.w(TAG, "Failed to set touchable region: " + e); |
| } |
| } |
| }; |
| |
| private WindowManagerProxy() { |
| } |
| |
| public static WindowManagerProxy getInstance() { |
| return sInstance; |
| } |
| |
| public void resizeDockedStack(Rect docked, Rect tempDockedTaskRect, Rect tempDockedInsetRect, |
| Rect tempOtherTaskRect, Rect tempOtherInsetRect) { |
| synchronized (mDockedRect) { |
| mDockedRect.set(docked); |
| if (tempDockedTaskRect != null) { |
| mTempDockedTaskRect.set(tempDockedTaskRect); |
| } else { |
| mTempDockedTaskRect.setEmpty(); |
| } |
| if (tempDockedInsetRect != null) { |
| mTempDockedInsetRect.set(tempDockedInsetRect); |
| } else { |
| mTempDockedInsetRect.setEmpty(); |
| } |
| if (tempOtherTaskRect != null) { |
| mTempOtherTaskRect.set(tempOtherTaskRect); |
| } else { |
| mTempOtherTaskRect.setEmpty(); |
| } |
| if (tempOtherInsetRect != null) { |
| mTempOtherInsetRect.set(tempOtherInsetRect); |
| } else { |
| mTempOtherInsetRect.setEmpty(); |
| } |
| } |
| mExecutor.execute(mResizeRunnable); |
| } |
| |
| public void dismissDockedStack() { |
| mExecutor.execute(mDismissRunnable); |
| } |
| |
| public void maximizeDockedStack() { |
| mExecutor.execute(mMaximizeRunnable); |
| } |
| |
| public void setResizing(final boolean resizing) { |
| mExecutor.execute(new Runnable() { |
| @Override |
| public void run() { |
| try { |
| WindowManagerGlobal.getWindowManagerService().setDockedStackResizing(resizing); |
| } catch (RemoteException e) { |
| Log.w(TAG, "Error calling setDockedStackResizing: " + e); |
| } |
| } |
| }); |
| } |
| |
| public int getDockSide() { |
| try { |
| return WindowManagerGlobal.getWindowManagerService().getDockedStackSide(); |
| } catch (RemoteException e) { |
| Log.w(TAG, "Failed to get dock side: " + e); |
| } |
| return DOCKED_INVALID; |
| } |
| |
| public void setResizeDimLayer(boolean visible, int targetStackId, float alpha) { |
| mDimLayerVisible = visible; |
| mDimLayerTargetStack = targetStackId; |
| mDimLayerAlpha = alpha; |
| mExecutor.execute(mDimLayerRunnable); |
| } |
| |
| public void swapTasks() { |
| mExecutor.execute(mSwapRunnable); |
| } |
| |
| public void setTouchRegion(Rect region) { |
| synchronized (mDockedRect) { |
| mTouchableRegion.set(region); |
| } |
| mExecutor.execute(mSetTouchableRegionRunnable); |
| } |
| } |