Migrate wm package in sysui to WM shell lib (1/n)
Bug: 161655636
Test: atest WindowManagerShellTests
Test: atest SystemUITests
Change-Id: I42f13ee7fbb14ba3b7f33ed5654ec72454dc6dba
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index dfc4758..2fbd9ba 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -45,7 +45,7 @@
"WindowManager-Shell",
"SystemUIPluginLib",
"SystemUISharedLib",
- "SystemUI-statsd",
+ "SystemUI-statsd",
"SettingsLib",
"androidx.viewpager2_viewpager2",
"androidx.legacy_legacy-support-v4",
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 02d2b8e..49a2328 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -122,9 +122,9 @@
import com.android.systemui.util.leak.LeakDetector;
import com.android.systemui.util.leak.LeakReporter;
import com.android.systemui.util.sensors.AsyncSensorManager;
-import com.android.systemui.wm.DisplayController;
-import com.android.systemui.wm.DisplayImeController;
-import com.android.systemui.wm.SystemWindows;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.SystemWindows;
import java.util.function.Consumer;
diff --git a/packages/SystemUI/src/com/android/systemui/TransactionPool.java b/packages/SystemUI/src/com/android/systemui/TransactionPool.java
deleted file mode 100644
index 801cf8a..0000000
--- a/packages/SystemUI/src/com/android/systemui/TransactionPool.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2020 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;
-
-import android.util.Pools;
-import android.view.SurfaceControl;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/**
- * Provides a synchronized pool of {@link SurfaceControl.Transaction}s to minimize allocations.
- */
-@Singleton
-public class TransactionPool {
- private final Pools.SynchronizedPool<SurfaceControl.Transaction> mTransactionPool =
- new Pools.SynchronizedPool<>(4);
-
- @Inject
- TransactionPool() {
- }
-
- /** Gets a transaction from the pool. */
- public SurfaceControl.Transaction acquire() {
- SurfaceControl.Transaction t = mTransactionPool.acquire();
- if (t == null) {
- return new SurfaceControl.Transaction();
- }
- return t;
- }
-
- /**
- * Return a transaction to the pool. DO NOT call {@link SurfaceControl.Transaction#close()} if
- * returning to pool.
- */
- public void release(SurfaceControl.Transaction t) {
- if (!mTransactionPool.release(t)) {
- t.close();
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
index cd0ba29..803e56d 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
@@ -59,6 +59,7 @@
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl;
import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.wmshell.WindowManagerShellModule;
import javax.inject.Named;
import javax.inject.Singleton;
@@ -71,7 +72,7 @@
* A dagger module for injecting default implementations of components of System UI that may be
* overridden by the System UI implementation.
*/
-@Module(includes = {DividerModule.class, QSModule.class})
+@Module(includes = {DividerModule.class, QSModule.class, WindowManagerShellModule.class})
public abstract class SystemUIDefaultModule {
@Singleton
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java
index 16e05f1..c0b9258 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java
@@ -27,7 +27,6 @@
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
-import android.view.Surface;
import android.view.SurfaceControl;
import android.window.DisplayAreaInfo;
import android.window.DisplayAreaOrganizer;
@@ -39,7 +38,7 @@
import com.android.internal.os.SomeArgs;
import com.android.systemui.Dumpable;
-import com.android.systemui.wm.DisplayController;
+import com.android.wm.shell.common.DisplayController;
import java.io.FileDescriptor;
import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java
index f995bf9..71c5f80 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java
@@ -41,8 +41,8 @@
import com.android.systemui.R;
import com.android.systemui.statusbar.phone.NavigationModeController;
-import com.android.systemui.wm.DisplayChangeController;
-import com.android.systemui.wm.DisplayController;
+import com.android.wm.shell.common.DisplayChangeController;
+import com.android.wm.shell.common.DisplayController;
import javax.inject.Inject;
import javax.inject.Singleton;
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedManagerImpl.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedManagerImpl.java
index 586761b..70a81aa 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedManagerImpl.java
@@ -33,8 +33,8 @@
import com.android.systemui.model.SysUiState;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListener;
-import com.android.systemui.wm.DisplayChangeController;
-import com.android.systemui.wm.DisplayController;
+import com.android.wm.shell.common.DisplayChangeController;
+import com.android.wm.shell.common.DisplayController;
import java.io.FileDescriptor;
import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
index 665b90e..df3aead 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
@@ -39,8 +39,8 @@
import android.view.Gravity;
import android.window.WindowContainerTransaction;
-import com.android.systemui.wm.DisplayController;
-import com.android.systemui.wm.DisplayLayout;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayLayout;
import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
index 35e56ee..312d6d6 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
@@ -58,8 +58,8 @@
import com.android.internal.os.SomeArgs;
import com.android.systemui.pip.phone.PipUpdateThread;
import com.android.systemui.stackdivider.Divider;
-import com.android.systemui.wm.DisplayController;
import com.android.wm.shell.R;
+import com.android.wm.shell.common.DisplayController;
import java.io.PrintWriter;
import java.util.ArrayList;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 02bf475..eb73e13 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -56,9 +56,8 @@
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.FloatingContentCoordinator;
-import com.android.systemui.wm.DisplayChangeController;
-import com.android.systemui.wm.DisplayController;
-import com.android.systemui.wm.DisplayLayout;
+import com.android.wm.shell.common.DisplayChangeController;
+import com.android.wm.shell.common.DisplayController;
import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index 570a4bb..eb72312 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -39,16 +39,16 @@
import com.android.internal.policy.DividerSnapAlgorithm;
import com.android.systemui.R;
import com.android.systemui.SystemUI;
-import com.android.systemui.TransactionPool;
import com.android.systemui.recents.Recents;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.wm.DisplayChangeController;
-import com.android.systemui.wm.DisplayController;
-import com.android.systemui.wm.DisplayImeController;
-import com.android.systemui.wm.DisplayLayout;
-import com.android.systemui.wm.SystemWindows;
+import com.android.wm.shell.common.DisplayChangeController;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.common.SystemWindows;
+import com.android.wm.shell.common.TransactionPool;
import java.io.FileDescriptor;
import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java
index 5aeca5e..84ec387 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java
@@ -33,8 +33,8 @@
import androidx.annotation.Nullable;
-import com.android.systemui.TransactionPool;
-import com.android.systemui.wm.DisplayImeController;
+import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.TransactionPool;
class DividerImeController implements DisplayImeController.ImePositionProcessor {
private static final String TAG = "DividerImeController";
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerModule.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerModule.java
index 3b7f315..c24431c 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerModule.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerModule.java
@@ -19,13 +19,13 @@
import android.content.Context;
import android.os.Handler;
-import com.android.systemui.TransactionPool;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.recents.Recents;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.wm.DisplayController;
-import com.android.systemui.wm.DisplayImeController;
-import com.android.systemui.wm.SystemWindows;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.SystemWindows;
+import com.android.wm.shell.common.TransactionPool;
import java.util.Optional;
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java
index 6ea3132..d869333 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java
@@ -32,7 +32,7 @@
import android.view.View;
import android.view.WindowManager;
-import com.android.systemui.wm.SystemWindows;
+import com.android.wm.shell.common.SystemWindows;
/**
* Manages the window parameters of the docked stack divider.
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitDisplayLayout.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitDisplayLayout.java
index 69095f7..a34e85517 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitDisplayLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitDisplayLayout.java
@@ -34,7 +34,7 @@
import com.android.internal.policy.DividerSnapAlgorithm;
import com.android.internal.policy.DockedDividerUtils;
-import com.android.systemui.wm.DisplayLayout;
+import com.android.wm.shell.common.DisplayLayout;
/**
* Handles split-screen related internal display layout. In general, this represents the
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SyncTransactionQueue.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SyncTransactionQueue.java
index 1ff4046..6812f62 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/SyncTransactionQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SyncTransactionQueue.java
@@ -25,7 +25,7 @@
import androidx.annotation.NonNull;
-import com.android.systemui.TransactionPool;
+import com.android.wm.shell.common.TransactionPool;
import java.util.ArrayList;
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
index 410e3dd..2b36812 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
@@ -40,7 +40,7 @@
import android.window.WindowOrganizer;
import com.android.internal.annotations.GuardedBy;
-import com.android.systemui.TransactionPool;
+import com.android.wm.shell.common.TransactionPool;
import java.util.ArrayList;
import java.util.List;
diff --git a/packages/SystemUI/src/com/android/systemui/wm/DisplayChangeController.java b/packages/SystemUI/src/com/android/systemui/wm/DisplayChangeController.java
deleted file mode 100644
index 6eba9ac..0000000
--- a/packages/SystemUI/src/com/android/systemui/wm/DisplayChangeController.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2019 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.wm;
-
-import android.os.Handler;
-import android.os.RemoteException;
-import android.view.IDisplayWindowRotationCallback;
-import android.view.IDisplayWindowRotationController;
-import android.view.IWindowManager;
-import android.window.WindowContainerTransaction;
-
-import java.util.ArrayList;
-
-/**
- * This module deals with display rotations coming from WM. When WM starts a rotation: after it has
- * frozen the screen, it will call into this class. This will then call all registered local
- * controllers and give them a chance to queue up task changes to be applied synchronously with that
- * rotation.
- */
-public class DisplayChangeController {
-
- private final Handler mHandler;
- private final IWindowManager mWmService;
-
- private final ArrayList<OnDisplayChangingListener> mRotationListener =
- new ArrayList<>();
- private final ArrayList<OnDisplayChangingListener> mTmpListeners = new ArrayList<>();
-
- private final IDisplayWindowRotationController mDisplayRotationController =
- new IDisplayWindowRotationController.Stub() {
- @Override
- public void onRotateDisplay(int displayId, final int fromRotation,
- final int toRotation, IDisplayWindowRotationCallback callback) {
- mHandler.post(() -> {
- WindowContainerTransaction t = new WindowContainerTransaction();
- synchronized (mRotationListener) {
- mTmpListeners.clear();
- // Make a local copy in case the handlers add/remove themselves.
- mTmpListeners.addAll(mRotationListener);
- }
- for (OnDisplayChangingListener c : mTmpListeners) {
- c.onRotateDisplay(displayId, fromRotation, toRotation, t);
- }
- try {
- callback.continueRotateDisplay(toRotation, t);
- } catch (RemoteException e) {
- }
- });
- }
- };
-
- public DisplayChangeController(Handler mainHandler, IWindowManager wmService) {
- mHandler = mainHandler;
- mWmService = wmService;
- try {
- mWmService.setDisplayWindowRotationController(mDisplayRotationController);
- } catch (RemoteException e) {
- throw new RuntimeException("Unable to register rotation controller");
- }
- }
-
- /**
- * Adds a display rotation controller.
- */
- public void addRotationListener(OnDisplayChangingListener listener) {
- synchronized (mRotationListener) {
- mRotationListener.add(listener);
- }
- }
-
- /**
- * Removes a display rotation controller.
- */
- public void removeRotationListener(OnDisplayChangingListener listener) {
- synchronized (mRotationListener) {
- mRotationListener.remove(listener);
- }
- }
-
- /**
- * Give a listener a chance to queue up configuration changes to execute as part of a
- * display rotation. The contents of {@link #onRotateDisplay} must run synchronously.
- */
- public interface OnDisplayChangingListener {
- /**
- * Called before the display is rotated. Contents of this method must run synchronously.
- * @param displayId Id of display that is rotating.
- * @param fromRotation starting rotation of the display.
- * @param toRotation target rotation of the display (after rotating).
- * @param t A task transaction to populate.
- */
- void onRotateDisplay(int displayId, int fromRotation, int toRotation,
- WindowContainerTransaction t);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/wm/DisplayController.java b/packages/SystemUI/src/com/android/systemui/wm/DisplayController.java
deleted file mode 100644
index 083c243..0000000
--- a/packages/SystemUI/src/com/android/systemui/wm/DisplayController.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2019 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.wm;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.hardware.display.DisplayManager;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.view.Display;
-import android.view.IDisplayWindowListener;
-import android.view.IWindowManager;
-
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.wm.DisplayChangeController.OnDisplayChangingListener;
-
-import java.util.ArrayList;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/**
- * This module deals with display rotations coming from WM. When WM starts a rotation: after it has
- * frozen the screen, it will call into this class. This will then call all registered local
- * controllers and give them a chance to queue up task changes to be applied synchronously with that
- * rotation.
- */
-@Singleton
-public class DisplayController {
- private static final String TAG = "DisplayController";
-
- private final Handler mHandler;
- private final Context mContext;
- private final IWindowManager mWmService;
- private final DisplayChangeController mChangeController;
-
- private final SparseArray<DisplayRecord> mDisplays = new SparseArray<>();
- private final ArrayList<OnDisplaysChangedListener> mDisplayChangedListeners = new ArrayList<>();
-
- /**
- * Get's a display by id from DisplayManager.
- */
- public Display getDisplay(int displayId) {
- final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
- return displayManager.getDisplay(displayId);
- }
-
- private final IDisplayWindowListener mDisplayContainerListener =
- new IDisplayWindowListener.Stub() {
- @Override
- public void onDisplayAdded(int displayId) {
- mHandler.post(() -> {
- synchronized (mDisplays) {
- if (mDisplays.get(displayId) != null) {
- return;
- }
- Display display = getDisplay(displayId);
- if (display == null) {
- // It's likely that the display is private to some app and thus not
- // accessible by system-ui.
- return;
- }
- DisplayRecord record = new DisplayRecord();
- record.mDisplayId = displayId;
- record.mContext = (displayId == Display.DEFAULT_DISPLAY) ? mContext
- : mContext.createDisplayContext(display);
- record.mDisplayLayout = new DisplayLayout(record.mContext, display);
- mDisplays.put(displayId, record);
- for (int i = 0; i < mDisplayChangedListeners.size(); ++i) {
- mDisplayChangedListeners.get(i).onDisplayAdded(displayId);
- }
- }
- });
- }
-
- @Override
- public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
- mHandler.post(() -> {
- synchronized (mDisplays) {
- DisplayRecord dr = mDisplays.get(displayId);
- if (dr == null) {
- Slog.w(TAG, "Skipping Display Configuration change on non-added"
- + " display.");
- return;
- }
- Display display = getDisplay(displayId);
- if (display == null) {
- Slog.w(TAG, "Skipping Display Configuration change on invalid"
- + " display. It may have been removed.");
- return;
- }
- Context perDisplayContext = mContext;
- if (displayId != Display.DEFAULT_DISPLAY) {
- perDisplayContext = mContext.createDisplayContext(display);
- }
- dr.mContext = perDisplayContext.createConfigurationContext(newConfig);
- dr.mDisplayLayout = new DisplayLayout(dr.mContext, display);
- for (int i = 0; i < mDisplayChangedListeners.size(); ++i) {
- mDisplayChangedListeners.get(i).onDisplayConfigurationChanged(
- displayId, newConfig);
- }
- }
- });
- }
-
- @Override
- public void onDisplayRemoved(int displayId) {
- mHandler.post(() -> {
- synchronized (mDisplays) {
- if (mDisplays.get(displayId) == null) {
- return;
- }
- for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) {
- mDisplayChangedListeners.get(i).onDisplayRemoved(displayId);
- }
- mDisplays.remove(displayId);
- }
- });
- }
-
- @Override
- public void onFixedRotationStarted(int displayId, int newRotation) {
- mHandler.post(() -> {
- synchronized (mDisplays) {
- if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) {
- Slog.w(TAG, "Skipping onFixedRotationStarted on unknown"
- + " display, displayId=" + displayId);
- return;
- }
- for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) {
- mDisplayChangedListeners.get(i).onFixedRotationStarted(
- displayId, newRotation);
- }
- }
- });
- }
-
- @Override
- public void onFixedRotationFinished(int displayId) {
- mHandler.post(() -> {
- synchronized (mDisplays) {
- if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) {
- Slog.w(TAG, "Skipping onFixedRotationFinished on unknown"
- + " display, displayId=" + displayId);
- return;
- }
- for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) {
- mDisplayChangedListeners.get(i).onFixedRotationFinished(displayId);
- }
- }
- });
- }
- };
-
- @Inject
- public DisplayController(Context context, @Main Handler mainHandler,
- IWindowManager wmService) {
- mHandler = mainHandler;
- mContext = context;
- mWmService = wmService;
- mChangeController = new DisplayChangeController(mHandler, mWmService);
- try {
- mWmService.registerDisplayWindowListener(mDisplayContainerListener);
- } catch (RemoteException e) {
- throw new RuntimeException("Unable to register hierarchy listener");
- }
- }
-
- /**
- * Gets the DisplayLayout associated with a display.
- */
- public @Nullable DisplayLayout getDisplayLayout(int displayId) {
- final DisplayRecord r = mDisplays.get(displayId);
- return r != null ? r.mDisplayLayout : null;
- }
-
- /**
- * Gets a display-specific context for a display.
- */
- public @Nullable Context getDisplayContext(int displayId) {
- final DisplayRecord r = mDisplays.get(displayId);
- return r != null ? r.mContext : null;
- }
-
- /**
- * Add a display window-container listener. It will get notified whenever a display's
- * configuration changes or when displays are added/removed from the WM hierarchy.
- */
- public void addDisplayWindowListener(OnDisplaysChangedListener listener) {
- synchronized (mDisplays) {
- if (mDisplayChangedListeners.contains(listener)) {
- return;
- }
- mDisplayChangedListeners.add(listener);
- for (int i = 0; i < mDisplays.size(); ++i) {
- listener.onDisplayAdded(mDisplays.keyAt(i));
- }
- }
- }
-
- /**
- * Remove a display window-container listener.
- */
- public void removeDisplayWindowListener(OnDisplaysChangedListener listener) {
- synchronized (mDisplays) {
- mDisplayChangedListeners.remove(listener);
- }
- }
-
- /**
- * Adds a display rotation controller.
- */
- public void addDisplayChangingController(OnDisplayChangingListener controller) {
- mChangeController.addRotationListener(controller);
- }
-
- /**
- * Removes a display rotation controller.
- */
- public void removeDisplayChangingController(OnDisplayChangingListener controller) {
- mChangeController.removeRotationListener(controller);
- }
-
- private static class DisplayRecord {
- int mDisplayId;
- Context mContext;
- DisplayLayout mDisplayLayout;
- }
-
- /**
- * Gets notified when a display is added/removed to the WM hierarchy and when a display's
- * window-configuration changes.
- *
- * @see IDisplayWindowListener
- */
- public interface OnDisplaysChangedListener {
- /**
- * Called when a display has been added to the WM hierarchy.
- */
- default void onDisplayAdded(int displayId) {}
-
- /**
- * Called when a display's window-container configuration changes.
- */
- default void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {}
-
- /**
- * Called when a display is removed.
- */
- default void onDisplayRemoved(int displayId) {}
-
- /**
- * Called when fixed rotation on a display is started.
- */
- default void onFixedRotationStarted(int displayId, int newRotation) {}
-
- /**
- * Called when fixed rotation on a display is finished.
- */
- default void onFixedRotationFinished(int displayId) {}
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java
deleted file mode 100644
index 89f469a..0000000
--- a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * Copyright (C) 2019 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.wm;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.annotation.IntDef;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.view.IDisplayWindowInsetsController;
-import android.view.InsetsSource;
-import android.view.InsetsSourceControl;
-import android.view.InsetsState;
-import android.view.Surface;
-import android.view.SurfaceControl;
-import android.view.WindowInsets;
-import android.view.animation.Interpolator;
-import android.view.animation.PathInterpolator;
-
-import com.android.internal.view.IInputMethodManager;
-import com.android.systemui.TransactionPool;
-import com.android.systemui.dagger.qualifiers.Main;
-
-import java.util.ArrayList;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/**
- * Manages IME control at the display-level. This occurs when IME comes up in multi-window mode.
- */
-@Singleton
-public class DisplayImeController implements DisplayController.OnDisplaysChangedListener {
- private static final String TAG = "DisplayImeController";
-
- private static final boolean DEBUG = false;
-
- // NOTE: All these constants came from InsetsController.
- public static final int ANIMATION_DURATION_SHOW_MS = 275;
- public static final int ANIMATION_DURATION_HIDE_MS = 340;
- public static final Interpolator INTERPOLATOR = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
- private static final int DIRECTION_NONE = 0;
- private static final int DIRECTION_SHOW = 1;
- private static final int DIRECTION_HIDE = 2;
- private static final int FLOATING_IME_BOTTOM_INSET = -80;
-
- SystemWindows mSystemWindows;
- final Handler mHandler;
- final TransactionPool mTransactionPool;
-
- final SparseArray<PerDisplay> mImePerDisplay = new SparseArray<>();
-
- final ArrayList<ImePositionProcessor> mPositionProcessors = new ArrayList<>();
-
- @Inject
- public DisplayImeController(SystemWindows syswin, DisplayController displayController,
- @Main Handler mainHandler, TransactionPool transactionPool) {
- mHandler = mainHandler;
- mSystemWindows = syswin;
- mTransactionPool = transactionPool;
- displayController.addDisplayWindowListener(this);
- }
-
- @Override
- public void onDisplayAdded(int displayId) {
- // Add's a system-ui window-manager specifically for ime. This type is special because
- // WM will defer IME inset handling to it in multi-window scenarious.
- PerDisplay pd = new PerDisplay(displayId,
- mSystemWindows.mDisplayController.getDisplayLayout(displayId).rotation());
- try {
- mSystemWindows.mWmService.setDisplayWindowInsetsController(displayId, pd);
- } catch (RemoteException e) {
- Slog.w(TAG, "Unable to set insets controller on display " + displayId);
- }
- mImePerDisplay.put(displayId, pd);
- }
-
- @Override
- public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
- PerDisplay pd = mImePerDisplay.get(displayId);
- if (pd == null) {
- return;
- }
- if (mSystemWindows.mDisplayController.getDisplayLayout(displayId).rotation()
- != pd.mRotation && isImeShowing(displayId)) {
- pd.startAnimation(true, false /* forceRestart */);
- }
- }
-
- @Override
- public void onDisplayRemoved(int displayId) {
- try {
- mSystemWindows.mWmService.setDisplayWindowInsetsController(displayId, null);
- } catch (RemoteException e) {
- Slog.w(TAG, "Unable to remove insets controller on display " + displayId);
- }
- mImePerDisplay.remove(displayId);
- }
-
- private boolean isImeShowing(int displayId) {
- PerDisplay pd = mImePerDisplay.get(displayId);
- if (pd == null) {
- return false;
- }
- final InsetsSource imeSource = pd.mInsetsState.getSource(InsetsState.ITYPE_IME);
- return imeSource != null && pd.mImeSourceControl != null && imeSource.isVisible();
- }
-
- private void dispatchPositionChanged(int displayId, int imeTop,
- SurfaceControl.Transaction t) {
- synchronized (mPositionProcessors) {
- for (ImePositionProcessor pp : mPositionProcessors) {
- pp.onImePositionChanged(displayId, imeTop, t);
- }
- }
- }
-
- @ImePositionProcessor.ImeAnimationFlags
- private int dispatchStartPositioning(int displayId, int hiddenTop, int shownTop,
- boolean show, boolean isFloating, SurfaceControl.Transaction t) {
- synchronized (mPositionProcessors) {
- int flags = 0;
- for (ImePositionProcessor pp : mPositionProcessors) {
- flags |= pp.onImeStartPositioning(
- displayId, hiddenTop, shownTop, show, isFloating, t);
- }
- return flags;
- }
- }
-
- private void dispatchEndPositioning(int displayId, boolean cancel,
- SurfaceControl.Transaction t) {
- synchronized (mPositionProcessors) {
- for (ImePositionProcessor pp : mPositionProcessors) {
- pp.onImeEndPositioning(displayId, cancel, t);
- }
- }
- }
-
- /**
- * Adds an {@link ImePositionProcessor} to be called during ime position updates.
- */
- public void addPositionProcessor(ImePositionProcessor processor) {
- synchronized (mPositionProcessors) {
- if (mPositionProcessors.contains(processor)) {
- return;
- }
- mPositionProcessors.add(processor);
- }
- }
-
- /**
- * Removes an {@link ImePositionProcessor} to be called during ime position updates.
- */
- public void removePositionProcessor(ImePositionProcessor processor) {
- synchronized (mPositionProcessors) {
- mPositionProcessors.remove(processor);
- }
- }
-
- class PerDisplay extends IDisplayWindowInsetsController.Stub {
- final int mDisplayId;
- final InsetsState mInsetsState = new InsetsState();
- InsetsSourceControl mImeSourceControl = null;
- int mAnimationDirection = DIRECTION_NONE;
- ValueAnimator mAnimation = null;
- int mRotation = Surface.ROTATION_0;
- boolean mImeShowing = false;
- final Rect mImeFrame = new Rect();
- boolean mAnimateAlpha = true;
-
- PerDisplay(int displayId, int initialRotation) {
- mDisplayId = displayId;
- mRotation = initialRotation;
- }
-
- @Override
- public void insetsChanged(InsetsState insetsState) {
- mHandler.post(() -> {
- if (mInsetsState.equals(insetsState)) {
- return;
- }
-
- final InsetsSource newSource = insetsState.getSource(InsetsState.ITYPE_IME);
- final Rect newFrame = newSource.getFrame();
- final Rect oldFrame = mInsetsState.getSource(InsetsState.ITYPE_IME).getFrame();
-
- mInsetsState.set(insetsState, true /* copySources */);
- if (mImeShowing && !newFrame.equals(oldFrame) && newSource.isVisible()) {
- if (DEBUG) Slog.d(TAG, "insetsChanged when IME showing, restart animation");
- startAnimation(mImeShowing, true /* forceRestart */);
- }
- });
- }
-
- @Override
- public void insetsControlChanged(InsetsState insetsState,
- InsetsSourceControl[] activeControls) {
- insetsChanged(insetsState);
- if (activeControls != null) {
- for (InsetsSourceControl activeControl : activeControls) {
- if (activeControl == null) {
- continue;
- }
- if (activeControl.getType() == InsetsState.ITYPE_IME) {
- mHandler.post(() -> {
- final Point lastSurfacePosition = mImeSourceControl != null
- ? mImeSourceControl.getSurfacePosition() : null;
- mImeSourceControl = activeControl;
- if (!activeControl.getSurfacePosition().equals(lastSurfacePosition)
- && mAnimation != null) {
- startAnimation(mImeShowing, true /* forceRestart */);
- } else if (!mImeShowing) {
- removeImeSurface();
- }
- });
- }
- }
- }
- }
-
- @Override
- public void showInsets(int types, boolean fromIme) {
- if ((types & WindowInsets.Type.ime()) == 0) {
- return;
- }
- if (DEBUG) Slog.d(TAG, "Got showInsets for ime");
- mHandler.post(() -> startAnimation(true /* show */, false /* forceRestart */));
- }
-
- @Override
- public void hideInsets(int types, boolean fromIme) {
- if ((types & WindowInsets.Type.ime()) == 0) {
- return;
- }
- if (DEBUG) Slog.d(TAG, "Got hideInsets for ime");
- mHandler.post(() -> startAnimation(false /* show */, false /* forceRestart */));
- }
-
- @Override
- public void topFocusedWindowChanged(String packageName) {
- // no-op
- }
-
- /**
- * Sends the local visibility state back to window manager. Needed for legacy adjustForIme.
- */
- private void setVisibleDirectly(boolean visible) {
- mInsetsState.getSource(InsetsState.ITYPE_IME).setVisible(visible);
- try {
- mSystemWindows.mWmService.modifyDisplayWindowInsets(mDisplayId, mInsetsState);
- } catch (RemoteException e) {
- }
- }
-
- private int imeTop(float surfaceOffset) {
- return mImeFrame.top + (int) surfaceOffset;
- }
-
- private boolean calcIsFloating(InsetsSource imeSource) {
- final Rect frame = imeSource.getFrame();
- if (frame.height() == 0) {
- return true;
- }
- // Some Floating Input Methods will still report a frame, but the frame is actually
- // a nav-bar inset created by WM and not part of the IME (despite being reported as
- // an IME inset). For now, we assume that no non-floating IME will be <= this nav bar
- // frame height so any reported frame that is <= nav-bar frame height is assumed to
- // be floating.
- return frame.height() <= mSystemWindows.mDisplayController.getDisplayLayout(mDisplayId)
- .navBarFrameHeight();
- }
-
- private void startAnimation(final boolean show, final boolean forceRestart) {
- final InsetsSource imeSource = mInsetsState.getSource(InsetsState.ITYPE_IME);
- if (imeSource == null || mImeSourceControl == null) {
- return;
- }
- final Rect newFrame = imeSource.getFrame();
- final boolean isFloating = calcIsFloating(imeSource) && show;
- if (isFloating) {
- // This is a "floating" or "expanded" IME, so to get animations, just
- // pretend the ime has some size just below the screen.
- mImeFrame.set(newFrame);
- final int floatingInset = (int) (
- mSystemWindows.mDisplayController.getDisplayLayout(mDisplayId).density()
- * FLOATING_IME_BOTTOM_INSET);
- mImeFrame.bottom -= floatingInset;
- } else if (newFrame.height() != 0) {
- // Don't set a new frame if it's empty and hiding -- this maintains continuity
- mImeFrame.set(newFrame);
- }
- if (DEBUG) {
- Slog.d(TAG, "Run startAnim show:" + show + " was:"
- + (mAnimationDirection == DIRECTION_SHOW ? "SHOW"
- : (mAnimationDirection == DIRECTION_HIDE ? "HIDE" : "NONE")));
- }
- if (!forceRestart && (mAnimationDirection == DIRECTION_SHOW && show)
- || (mAnimationDirection == DIRECTION_HIDE && !show)) {
- return;
- }
- boolean seek = false;
- float seekValue = 0;
- if (mAnimation != null) {
- if (mAnimation.isRunning()) {
- seekValue = (float) mAnimation.getAnimatedValue();
- seek = true;
- }
- mAnimation.cancel();
- }
- final float defaultY = mImeSourceControl.getSurfacePosition().y;
- final float x = mImeSourceControl.getSurfacePosition().x;
- final float hiddenY = defaultY + mImeFrame.height();
- final float shownY = defaultY;
- final float startY = show ? hiddenY : shownY;
- final float endY = show ? shownY : hiddenY;
- if (mAnimationDirection == DIRECTION_NONE && mImeShowing && show) {
- // IME is already showing, so set seek to end
- seekValue = shownY;
- seek = true;
- }
- mAnimationDirection = show ? DIRECTION_SHOW : DIRECTION_HIDE;
- mImeShowing = show;
- mAnimation = ValueAnimator.ofFloat(startY, endY);
- mAnimation.setDuration(
- show ? ANIMATION_DURATION_SHOW_MS : ANIMATION_DURATION_HIDE_MS);
- if (seek) {
- mAnimation.setCurrentFraction((seekValue - startY) / (endY - startY));
- }
-
- mAnimation.addUpdateListener(animation -> {
- SurfaceControl.Transaction t = mTransactionPool.acquire();
- float value = (float) animation.getAnimatedValue();
- t.setPosition(mImeSourceControl.getLeash(), x, value);
- final float alpha = (mAnimateAlpha || isFloating)
- ? (value - hiddenY) / (shownY - hiddenY) : 1.f;
- t.setAlpha(mImeSourceControl.getLeash(), alpha);
- dispatchPositionChanged(mDisplayId, imeTop(value), t);
- t.apply();
- mTransactionPool.release(t);
- });
- mAnimation.setInterpolator(INTERPOLATOR);
- mAnimation.addListener(new AnimatorListenerAdapter() {
- private boolean mCancelled = false;
- @Override
- public void onAnimationStart(Animator animation) {
- SurfaceControl.Transaction t = mTransactionPool.acquire();
- t.setPosition(mImeSourceControl.getLeash(), x, startY);
- if (DEBUG) {
- Slog.d(TAG, "onAnimationStart d:" + mDisplayId + " top:"
- + imeTop(hiddenY) + "->" + imeTop(shownY)
- + " showing:" + (mAnimationDirection == DIRECTION_SHOW));
- }
- int flags = dispatchStartPositioning(mDisplayId, imeTop(hiddenY),
- imeTop(shownY), mAnimationDirection == DIRECTION_SHOW, isFloating, t);
- mAnimateAlpha = (flags & ImePositionProcessor.IME_ANIMATION_NO_ALPHA) == 0;
- final float alpha = (mAnimateAlpha || isFloating)
- ? (startY - hiddenY) / (shownY - hiddenY)
- : 1.f;
- t.setAlpha(mImeSourceControl.getLeash(), alpha);
- if (mAnimationDirection == DIRECTION_SHOW) {
- t.show(mImeSourceControl.getLeash());
- }
- t.apply();
- mTransactionPool.release(t);
- }
- @Override
- public void onAnimationCancel(Animator animation) {
- mCancelled = true;
- }
- @Override
- public void onAnimationEnd(Animator animation) {
- if (DEBUG) Slog.d(TAG, "onAnimationEnd " + mCancelled);
- SurfaceControl.Transaction t = mTransactionPool.acquire();
- if (!mCancelled) {
- t.setPosition(mImeSourceControl.getLeash(), x, endY);
- t.setAlpha(mImeSourceControl.getLeash(), 1.f);
- }
- dispatchEndPositioning(mDisplayId, mCancelled, t);
- if (mAnimationDirection == DIRECTION_HIDE && !mCancelled) {
- t.hide(mImeSourceControl.getLeash());
- removeImeSurface();
- }
- t.apply();
- mTransactionPool.release(t);
-
- mAnimationDirection = DIRECTION_NONE;
- mAnimation = null;
- }
- });
- if (!show) {
- // When going away, queue up insets change first, otherwise any bounds changes
- // can have a "flicker" of ime-provided insets.
- setVisibleDirectly(false /* visible */);
- }
- mAnimation.start();
- if (show) {
- // When showing away, queue up insets change last, otherwise any bounds changes
- // can have a "flicker" of ime-provided insets.
- setVisibleDirectly(true /* visible */);
- }
- }
- }
-
- void removeImeSurface() {
- final IInputMethodManager imms = getImms();
- if (imms != null) {
- try {
- // Remove the IME surface to make the insets invisible for
- // non-client controlled insets.
- imms.removeImeSurface();
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to remove IME surface.", e);
- }
- }
- }
-
- /**
- * Allows other things to synchronize with the ime position
- */
- public interface ImePositionProcessor {
- /**
- * Indicates that ime shouldn't animate alpha. It will always be opaque. Used when stuff
- * behind the IME shouldn't be visible (for example during split-screen adjustment where
- * there is nothing behind the ime).
- */
- int IME_ANIMATION_NO_ALPHA = 1;
-
- /** @hide */
- @IntDef(prefix = { "IME_ANIMATION_" }, value = {
- IME_ANIMATION_NO_ALPHA,
- })
- @interface ImeAnimationFlags {}
-
- /**
- * Called when the IME position is starting to animate.
- *
- * @param hiddenTop The y position of the top of the IME surface when it is hidden.
- * @param shownTop The y position of the top of the IME surface when it is shown.
- * @param showing {@code true} when we are animating from hidden to shown, {@code false}
- * when animating from shown to hidden.
- * @param isFloating {@code true} when the ime is a floating ime (doesn't inset).
- * @return flags that may alter how ime itself is animated (eg. no-alpha).
- */
- @ImeAnimationFlags
- default int onImeStartPositioning(int displayId, int hiddenTop, int shownTop,
- boolean showing, boolean isFloating, SurfaceControl.Transaction t) {
- return 0;
- }
-
- /**
- * Called when the ime position changed. This is expected to be a synchronous call on the
- * animation thread. Operations can be added to the transaction to be applied in sync.
- *
- * @param imeTop The current y position of the top of the IME surface.
- */
- default void onImePositionChanged(int displayId, int imeTop,
- SurfaceControl.Transaction t) {}
-
- /**
- * Called when the IME position is done animating.
- *
- * @param cancel {@code true} if this was cancelled. This implies another start is coming.
- */
- default void onImeEndPositioning(int displayId, boolean cancel,
- SurfaceControl.Transaction t) {}
- }
-
- public IInputMethodManager getImms() {
- return IInputMethodManager.Stub.asInterface(
- ServiceManager.getService(Context.INPUT_METHOD_SERVICE));
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/wm/DisplayLayout.java b/packages/SystemUI/src/com/android/systemui/wm/DisplayLayout.java
deleted file mode 100644
index a341f305..0000000
--- a/packages/SystemUI/src/com/android/systemui/wm/DisplayLayout.java
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * Copyright (C) 2019 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.wm;
-
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
-import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
-import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
-import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
-import static android.os.Process.SYSTEM_UID;
-import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
-import static android.view.Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
-import static android.view.Surface.ROTATION_0;
-import static android.view.Surface.ROTATION_270;
-import static android.view.Surface.ROTATION_90;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Insets;
-import android.graphics.Rect;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.util.DisplayMetrics;
-import android.util.RotationUtils;
-import android.util.Size;
-import android.view.Display;
-import android.view.DisplayCutout;
-import android.view.DisplayInfo;
-import android.view.Gravity;
-import android.view.Surface;
-
-import com.android.internal.R;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Contains information about the layout-properties of a display. This refers to internal layout
- * like insets/cutout/rotation. In general, this can be thought of as the System-UI analog to
- * DisplayPolicy.
- */
-public class DisplayLayout {
- @IntDef(prefix = { "NAV_BAR_" }, value = {
- NAV_BAR_LEFT,
- NAV_BAR_RIGHT,
- NAV_BAR_BOTTOM,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface NavBarPosition {}
-
- // Navigation bar position values
- public static final int NAV_BAR_LEFT = 1 << 0;
- public static final int NAV_BAR_RIGHT = 1 << 1;
- public static final int NAV_BAR_BOTTOM = 1 << 2;
-
- private int mUiMode;
- private int mWidth;
- private int mHeight;
- private DisplayCutout mCutout;
- private int mRotation;
- private int mDensityDpi;
- private final Rect mNonDecorInsets = new Rect();
- private final Rect mStableInsets = new Rect();
- private boolean mHasNavigationBar = false;
- private boolean mHasStatusBar = false;
- private int mNavBarFrameHeight = 0;
-
- /**
- * Create empty layout.
- */
- public DisplayLayout() {
- }
-
- /**
- * Construct a custom display layout using a DisplayInfo.
- * @param info
- * @param res
- */
- public DisplayLayout(DisplayInfo info, Resources res, boolean hasNavigationBar,
- boolean hasStatusBar) {
- init(info, res, hasNavigationBar, hasStatusBar);
- }
-
- /**
- * Construct a display layout based on a live display.
- * @param context Used for resources.
- */
- public DisplayLayout(@NonNull Context context, @NonNull Display rawDisplay) {
- final int displayId = rawDisplay.getDisplayId();
- DisplayInfo info = new DisplayInfo();
- rawDisplay.getDisplayInfo(info);
- init(info, context.getResources(), hasNavigationBar(info, context, displayId),
- hasStatusBar(displayId));
- }
-
- public DisplayLayout(DisplayLayout dl) {
- set(dl);
- }
-
- /** sets this DisplayLayout to a copy of another on. */
- public void set(DisplayLayout dl) {
- mUiMode = dl.mUiMode;
- mWidth = dl.mWidth;
- mHeight = dl.mHeight;
- mCutout = dl.mCutout;
- mRotation = dl.mRotation;
- mDensityDpi = dl.mDensityDpi;
- mHasNavigationBar = dl.mHasNavigationBar;
- mHasStatusBar = dl.mHasStatusBar;
- mNonDecorInsets.set(dl.mNonDecorInsets);
- mStableInsets.set(dl.mStableInsets);
- }
-
- private void init(DisplayInfo info, Resources res, boolean hasNavigationBar,
- boolean hasStatusBar) {
- mUiMode = res.getConfiguration().uiMode;
- mWidth = info.logicalWidth;
- mHeight = info.logicalHeight;
- mRotation = info.rotation;
- mCutout = info.displayCutout;
- mDensityDpi = info.logicalDensityDpi;
- mHasNavigationBar = hasNavigationBar;
- mHasStatusBar = hasStatusBar;
- recalcInsets(res);
- }
-
- private void recalcInsets(Resources res) {
- computeNonDecorInsets(res, mRotation, mWidth, mHeight, mCutout, mUiMode, mNonDecorInsets,
- mHasNavigationBar);
- mStableInsets.set(mNonDecorInsets);
- if (mHasStatusBar) {
- convertNonDecorInsetsToStableInsets(res, mStableInsets, mWidth, mHeight, mHasStatusBar);
- }
- mNavBarFrameHeight = getNavigationBarFrameHeight(res, mWidth > mHeight);
- }
-
- /**
- * Apply a rotation to this layout and its parameters.
- * @param res
- * @param targetRotation
- */
- public void rotateTo(Resources res, @Surface.Rotation int targetRotation) {
- final int rotationDelta = (targetRotation - mRotation + 4) % 4;
- final boolean changeOrient = (rotationDelta % 2) != 0;
-
- final int origWidth = mWidth;
- final int origHeight = mHeight;
-
- mRotation = targetRotation;
- if (changeOrient) {
- mWidth = origHeight;
- mHeight = origWidth;
- }
-
- if (mCutout != null && !mCutout.isEmpty()) {
- mCutout = calculateDisplayCutoutForRotation(mCutout, rotationDelta, origWidth,
- origHeight);
- }
-
- recalcInsets(res);
- }
-
- /** Get this layout's non-decor insets. */
- public Rect nonDecorInsets() {
- return mNonDecorInsets;
- }
-
- /** Get this layout's stable insets. */
- public Rect stableInsets() {
- return mStableInsets;
- }
-
- /** Get this layout's width. */
- public int width() {
- return mWidth;
- }
-
- /** Get this layout's height. */
- public int height() {
- return mHeight;
- }
-
- /** Get this layout's display rotation. */
- public int rotation() {
- return mRotation;
- }
-
- /** Get this layout's display density. */
- public int densityDpi() {
- return mDensityDpi;
- }
-
- /** Get the density scale for the display. */
- public float density() {
- return mDensityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
- }
-
- /** Get whether this layout is landscape. */
- public boolean isLandscape() {
- return mWidth > mHeight;
- }
-
- /** Get the navbar frame height (used by ime). */
- public int navBarFrameHeight() {
- return mNavBarFrameHeight;
- }
-
- /** Gets the orientation of this layout */
- public int getOrientation() {
- return (mWidth > mHeight) ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT;
- }
-
- /** Gets the calculated stable-bounds for this layout */
- public void getStableBounds(Rect outBounds) {
- outBounds.set(0, 0, mWidth, mHeight);
- outBounds.inset(mStableInsets);
- }
-
- /**
- * Gets navigation bar position for this layout
- * @return Navigation bar position for this layout.
- */
- public @NavBarPosition int getNavigationBarPosition(Resources res) {
- return navigationBarPosition(res, mWidth, mHeight, mRotation);
- }
-
- /**
- * Rotates bounds as if parentBounds and bounds are a group. The group is rotated by `delta`
- * 90-degree counter-clockwise increments. This assumes that parentBounds is at 0,0 and
- * remains at 0,0 after rotation.
- *
- * Only 'bounds' is mutated.
- */
- public static void rotateBounds(Rect inOutBounds, Rect parentBounds, int delta) {
- int rdelta = ((delta % 4) + 4) % 4;
- int origLeft = inOutBounds.left;
- switch (rdelta) {
- case 0:
- return;
- case 1:
- inOutBounds.left = inOutBounds.top;
- inOutBounds.top = parentBounds.right - inOutBounds.right;
- inOutBounds.right = inOutBounds.bottom;
- inOutBounds.bottom = parentBounds.right - origLeft;
- return;
- case 2:
- inOutBounds.left = parentBounds.right - inOutBounds.right;
- inOutBounds.right = parentBounds.right - origLeft;
- return;
- case 3:
- inOutBounds.left = parentBounds.bottom - inOutBounds.bottom;
- inOutBounds.bottom = inOutBounds.right;
- inOutBounds.right = parentBounds.bottom - inOutBounds.top;
- inOutBounds.top = origLeft;
- return;
- }
- }
-
- /**
- * Calculates the stable insets if we already have the non-decor insets.
- */
- private static void convertNonDecorInsetsToStableInsets(Resources res, Rect inOutInsets,
- int displayWidth, int displayHeight, boolean hasStatusBar) {
- if (!hasStatusBar) {
- return;
- }
- int statusBarHeight = getStatusBarHeight(displayWidth > displayHeight, res);
- inOutInsets.top = Math.max(inOutInsets.top, statusBarHeight);
- }
-
- /**
- * Calculates the insets for the areas that could never be removed in Honeycomb, i.e. system
- * bar or button bar.
- *
- * @param displayRotation the current display rotation
- * @param displayWidth the current display width
- * @param displayHeight the current display height
- * @param displayCutout the current display cutout
- * @param outInsets the insets to return
- */
- static void computeNonDecorInsets(Resources res, int displayRotation, int displayWidth,
- int displayHeight, DisplayCutout displayCutout, int uiMode, Rect outInsets,
- boolean hasNavigationBar) {
- outInsets.setEmpty();
-
- // Only navigation bar
- if (hasNavigationBar) {
- int position = navigationBarPosition(res, displayWidth, displayHeight, displayRotation);
- int navBarSize =
- getNavigationBarSize(res, position, displayWidth > displayHeight, uiMode);
- if (position == NAV_BAR_BOTTOM) {
- outInsets.bottom = navBarSize;
- } else if (position == NAV_BAR_RIGHT) {
- outInsets.right = navBarSize;
- } else if (position == NAV_BAR_LEFT) {
- outInsets.left = navBarSize;
- }
- }
-
- if (displayCutout != null) {
- outInsets.left += displayCutout.getSafeInsetLeft();
- outInsets.top += displayCutout.getSafeInsetTop();
- outInsets.right += displayCutout.getSafeInsetRight();
- outInsets.bottom += displayCutout.getSafeInsetBottom();
- }
- }
-
- /**
- * Calculates the stable insets without running a layout.
- *
- * @param displayRotation the current display rotation
- * @param displayWidth the current display width
- * @param displayHeight the current display height
- * @param displayCutout the current display cutout
- * @param outInsets the insets to return
- */
- static void computeStableInsets(Resources res, int displayRotation, int displayWidth,
- int displayHeight, DisplayCutout displayCutout, int uiMode, Rect outInsets,
- boolean hasNavigationBar, boolean hasStatusBar) {
- outInsets.setEmpty();
-
- // Navigation bar and status bar.
- computeNonDecorInsets(res, displayRotation, displayWidth, displayHeight, displayCutout,
- uiMode, outInsets, hasNavigationBar);
- convertNonDecorInsetsToStableInsets(res, outInsets, displayWidth, displayHeight,
- hasStatusBar);
- }
-
- /** Retrieve the statusbar height from resources. */
- static int getStatusBarHeight(boolean landscape, Resources res) {
- return landscape ? res.getDimensionPixelSize(
- com.android.internal.R.dimen.status_bar_height_landscape)
- : res.getDimensionPixelSize(
- com.android.internal.R.dimen.status_bar_height_portrait);
- }
-
- /** Calculate the DisplayCutout for a particular display size/rotation. */
- public static DisplayCutout calculateDisplayCutoutForRotation(
- DisplayCutout cutout, int rotation, int displayWidth, int displayHeight) {
- if (cutout == null || cutout == DisplayCutout.NO_CUTOUT) {
- return null;
- }
- final Insets waterfallInsets =
- RotationUtils.rotateInsets(cutout.getWaterfallInsets(), rotation);
- if (rotation == ROTATION_0) {
- return computeSafeInsets(cutout, displayWidth, displayHeight);
- }
- final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
- Rect[] cutoutRects = cutout.getBoundingRectsAll();
- final Rect[] newBounds = new Rect[cutoutRects.length];
- final Rect displayBounds = new Rect(0, 0, displayWidth, displayHeight);
- for (int i = 0; i < cutoutRects.length; ++i) {
- final Rect rect = new Rect(cutoutRects[i]);
- if (!rect.isEmpty()) {
- rotateBounds(rect, displayBounds, rotation);
- }
- newBounds[getBoundIndexFromRotation(i, rotation)] = rect;
- }
- return computeSafeInsets(
- DisplayCutout.fromBoundsAndWaterfall(newBounds, waterfallInsets),
- rotated ? displayHeight : displayWidth,
- rotated ? displayWidth : displayHeight);
- }
-
- private static int getBoundIndexFromRotation(int index, int rotation) {
- return (index - rotation) < 0
- ? index - rotation + DisplayCutout.BOUNDS_POSITION_LENGTH
- : index - rotation;
- }
-
- /** Calculate safe insets. */
- public static DisplayCutout computeSafeInsets(DisplayCutout inner,
- int displayWidth, int displayHeight) {
- if (inner == DisplayCutout.NO_CUTOUT) {
- return null;
- }
-
- final Size displaySize = new Size(displayWidth, displayHeight);
- final Rect safeInsets = computeSafeInsets(displaySize, inner);
- return inner.replaceSafeInsets(safeInsets);
- }
-
- private static Rect computeSafeInsets(
- Size displaySize, DisplayCutout cutout) {
- if (displaySize.getWidth() == displaySize.getHeight()) {
- throw new UnsupportedOperationException("not implemented: display=" + displaySize
- + " cutout=" + cutout);
- }
-
- int leftInset = Math.max(cutout.getWaterfallInsets().left,
- findCutoutInsetForSide(displaySize, cutout.getBoundingRectLeft(), Gravity.LEFT));
- int topInset = Math.max(cutout.getWaterfallInsets().top,
- findCutoutInsetForSide(displaySize, cutout.getBoundingRectTop(), Gravity.TOP));
- int rightInset = Math.max(cutout.getWaterfallInsets().right,
- findCutoutInsetForSide(displaySize, cutout.getBoundingRectRight(), Gravity.RIGHT));
- int bottomInset = Math.max(cutout.getWaterfallInsets().bottom,
- findCutoutInsetForSide(displaySize, cutout.getBoundingRectBottom(),
- Gravity.BOTTOM));
-
- return new Rect(leftInset, topInset, rightInset, bottomInset);
- }
-
- private static int findCutoutInsetForSide(Size display, Rect boundingRect, int gravity) {
- if (boundingRect.isEmpty()) {
- return 0;
- }
-
- int inset = 0;
- switch (gravity) {
- case Gravity.TOP:
- return Math.max(inset, boundingRect.bottom);
- case Gravity.BOTTOM:
- return Math.max(inset, display.getHeight() - boundingRect.top);
- case Gravity.LEFT:
- return Math.max(inset, boundingRect.right);
- case Gravity.RIGHT:
- return Math.max(inset, display.getWidth() - boundingRect.left);
- default:
- throw new IllegalArgumentException("unknown gravity: " + gravity);
- }
- }
-
- static boolean hasNavigationBar(DisplayInfo info, Context context, int displayId) {
- if (displayId == Display.DEFAULT_DISPLAY) {
- // Allow a system property to override this. Used by the emulator.
- final String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
- if ("1".equals(navBarOverride)) {
- return false;
- } else if ("0".equals(navBarOverride)) {
- return true;
- }
- return context.getResources().getBoolean(R.bool.config_showNavigationBar);
- } else {
- boolean isUntrustedVirtualDisplay = info.type == Display.TYPE_VIRTUAL
- && info.ownerUid != SYSTEM_UID;
- final ContentResolver resolver = context.getContentResolver();
- boolean forceDesktopOnExternal = Settings.Global.getInt(resolver,
- DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, 0) != 0;
-
- return ((info.flags & FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0
- || (forceDesktopOnExternal && !isUntrustedVirtualDisplay));
- // TODO(b/142569966): make sure VR2D and DisplayWindowSettings are moved here somehow.
- }
- }
-
- static boolean hasStatusBar(int displayId) {
- return displayId == Display.DEFAULT_DISPLAY;
- }
-
- /** Retrieve navigation bar position from resources based on rotation and size. */
- public static @NavBarPosition int navigationBarPosition(Resources res, int displayWidth,
- int displayHeight, int rotation) {
- boolean navBarCanMove = displayWidth != displayHeight && res.getBoolean(
- com.android.internal.R.bool.config_navBarCanMove);
- if (navBarCanMove && displayWidth > displayHeight) {
- if (rotation == Surface.ROTATION_90) {
- return NAV_BAR_RIGHT;
- } else {
- return NAV_BAR_LEFT;
- }
- }
- return NAV_BAR_BOTTOM;
- }
-
- /** Retrieve navigation bar size from resources based on side/orientation/ui-mode */
- public static int getNavigationBarSize(Resources res, int navBarSide, boolean landscape,
- int uiMode) {
- final boolean carMode = (uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_CAR;
- if (carMode) {
- if (navBarSide == NAV_BAR_BOTTOM) {
- return res.getDimensionPixelSize(landscape
- ? R.dimen.navigation_bar_height_landscape_car_mode
- : R.dimen.navigation_bar_height_car_mode);
- } else {
- return res.getDimensionPixelSize(R.dimen.navigation_bar_width_car_mode);
- }
-
- } else {
- if (navBarSide == NAV_BAR_BOTTOM) {
- return res.getDimensionPixelSize(landscape
- ? R.dimen.navigation_bar_height_landscape
- : R.dimen.navigation_bar_height);
- } else {
- return res.getDimensionPixelSize(R.dimen.navigation_bar_width);
- }
- }
- }
-
- /** @see com.android.server.wm.DisplayPolicy#getNavigationBarFrameHeight */
- public static int getNavigationBarFrameHeight(Resources res, boolean landscape) {
- return res.getDimensionPixelSize(landscape
- ? R.dimen.navigation_bar_frame_height_landscape
- : R.dimen.navigation_bar_frame_height);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java b/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java
deleted file mode 100644
index 21f67ae..0000000
--- a/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * Copyright (C) 2019 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.wm;
-
-import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.util.MergedConfiguration;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.view.Display;
-import android.view.DisplayCutout;
-import android.view.DragEvent;
-import android.view.IScrollCaptureController;
-import android.view.IWindow;
-import android.view.IWindowManager;
-import android.view.IWindowSession;
-import android.view.IWindowSessionCallback;
-import android.view.InsetsSourceControl;
-import android.view.InsetsState;
-import android.view.SurfaceControl;
-import android.view.SurfaceControlViewHost;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.WindowlessWindowManager;
-
-import com.android.internal.os.IResultReceiver;
-
-import java.util.HashMap;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/**
- * Represents the "windowing" layer of the System-UI. This layer allows system-ui components to
- * place and manipulate windows without talking to WindowManager.
- */
-@Singleton
-public class SystemWindows {
- private static final String TAG = "SystemWindows";
-
- private final SparseArray<PerDisplay> mPerDisplay = new SparseArray<>();
- final HashMap<View, SurfaceControlViewHost> mViewRoots = new HashMap<>();
- Context mContext;
- IWindowSession mSession;
- DisplayController mDisplayController;
- IWindowManager mWmService;
-
- private final DisplayController.OnDisplaysChangedListener mDisplayListener =
- new DisplayController.OnDisplaysChangedListener() {
- @Override
- public void onDisplayAdded(int displayId) { }
-
- @Override
- public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
- PerDisplay pd = mPerDisplay.get(displayId);
- if (pd == null) {
- return;
- }
- pd.updateConfiguration(newConfig);
- }
-
- @Override
- public void onDisplayRemoved(int displayId) { }
- };
-
- @Inject
- public SystemWindows(Context context, DisplayController displayController,
- IWindowManager wmService) {
- mContext = context;
- mWmService = wmService;
- mDisplayController = displayController;
- mDisplayController.addDisplayWindowListener(mDisplayListener);
- try {
- mSession = wmService.openSession(
- new IWindowSessionCallback.Stub() {
- @Override
- public void onAnimatorScaleChanged(float scale) {}
- });
- } catch (RemoteException e) {
- Slog.e(TAG, "Unable to create layer", e);
- }
- }
-
- /**
- * Adds a view to system-ui window management.
- */
- public void addView(View view, WindowManager.LayoutParams attrs, int displayId,
- int windowType) {
- PerDisplay pd = mPerDisplay.get(displayId);
- if (pd == null) {
- pd = new PerDisplay(displayId);
- mPerDisplay.put(displayId, pd);
- }
- pd.addView(view, attrs, windowType);
- }
-
- /**
- * Removes a view from system-ui window management.
- * @param view
- */
- public void removeView(View view) {
- SurfaceControlViewHost root = mViewRoots.remove(view);
- root.release();
- }
-
- /**
- * Updates the layout params of a view.
- */
- public void updateViewLayout(@NonNull View view, ViewGroup.LayoutParams params) {
- SurfaceControlViewHost root = mViewRoots.get(view);
- if (root == null || !(params instanceof WindowManager.LayoutParams)) {
- return;
- }
- view.setLayoutParams(params);
- root.relayout((WindowManager.LayoutParams) params);
- }
-
- /**
- * Sets the touchable region of a view's window. This will be cropped to the window size.
- * @param view
- * @param region
- */
- public void setTouchableRegion(@NonNull View view, Region region) {
- SurfaceControlViewHost root = mViewRoots.get(view);
- if (root == null) {
- return;
- }
- WindowlessWindowManager wwm = root.getWindowlessWM();
- if (!(wwm instanceof SysUiWindowManager)) {
- return;
- }
- ((SysUiWindowManager) wwm).setTouchableRegionForWindow(view, region);
- }
-
- /**
- * Adds a root for system-ui window management with no views. Only useful for IME.
- */
- public void addRoot(int displayId, int windowType) {
- PerDisplay pd = mPerDisplay.get(displayId);
- if (pd == null) {
- pd = new PerDisplay(displayId);
- mPerDisplay.put(displayId, pd);
- }
- pd.addRoot(windowType);
- }
-
- /**
- * Get the IWindow token for a specific root.
- *
- * @param windowType A window type from {@link android.view.WindowManager}.
- */
- IWindow getWindow(int displayId, int windowType) {
- PerDisplay pd = mPerDisplay.get(displayId);
- if (pd == null) {
- return null;
- }
- return pd.getWindow(windowType);
- }
-
- /**
- * Gets the SurfaceControl associated with a root view. This is the same surface that backs the
- * ViewRootImpl.
- */
- public SurfaceControl getViewSurface(View rootView) {
- for (int i = 0; i < mPerDisplay.size(); ++i) {
- for (int iWm = 0; iWm < mPerDisplay.valueAt(i).mWwms.size(); ++iWm) {
- SurfaceControl out = mPerDisplay.valueAt(i).mWwms.valueAt(iWm)
- .getSurfaceControlForWindow(rootView);
- if (out != null) {
- return out;
- }
- }
- }
- return null;
- }
-
- private class PerDisplay {
- final int mDisplayId;
- private final SparseArray<SysUiWindowManager> mWwms = new SparseArray<>();
-
- PerDisplay(int displayId) {
- mDisplayId = displayId;
- }
-
- public void addView(View view, WindowManager.LayoutParams attrs, int windowType) {
- SysUiWindowManager wwm = addRoot(windowType);
- if (wwm == null) {
- Slog.e(TAG, "Unable to create systemui root");
- return;
- }
- final Display display = mDisplayController.getDisplay(mDisplayId);
- SurfaceControlViewHost viewRoot =
- new SurfaceControlViewHost(mContext, display, wwm,
- true /* useSfChoreographer */);
- attrs.flags |= FLAG_HARDWARE_ACCELERATED;
- viewRoot.setView(view, attrs);
- mViewRoots.put(view, viewRoot);
-
- try {
- mWmService.setShellRootAccessibilityWindow(mDisplayId, windowType,
- viewRoot.getWindowToken());
- } catch (RemoteException e) {
- Slog.e(TAG, "Error setting accessibility window for " + mDisplayId + ":"
- + windowType, e);
- }
- }
-
- SysUiWindowManager addRoot(int windowType) {
- SysUiWindowManager wwm = mWwms.get(windowType);
- if (wwm != null) {
- return wwm;
- }
- SurfaceControl rootSurface = null;
- ContainerWindow win = new ContainerWindow();
- try {
- rootSurface = mWmService.addShellRoot(mDisplayId, win, windowType);
- } catch (RemoteException e) {
- }
- if (rootSurface == null) {
- Slog.e(TAG, "Unable to get root surfacecontrol for systemui");
- return null;
- }
- Context displayContext = mDisplayController.getDisplayContext(mDisplayId);
- wwm = new SysUiWindowManager(mDisplayId, displayContext, rootSurface, win);
- mWwms.put(windowType, wwm);
- return wwm;
- }
-
- IWindow getWindow(int windowType) {
- SysUiWindowManager wwm = mWwms.get(windowType);
- if (wwm == null) {
- return null;
- }
- return wwm.mContainerWindow;
- }
-
- void updateConfiguration(Configuration configuration) {
- for (int i = 0; i < mWwms.size(); ++i) {
- mWwms.valueAt(i).updateConfiguration(configuration);
- }
- }
- }
-
- /**
- * A subclass of WindowlessWindowManager that provides insets to its viewroots.
- */
- public class SysUiWindowManager extends WindowlessWindowManager {
- final int mDisplayId;
- ContainerWindow mContainerWindow;
- public SysUiWindowManager(int displayId, Context ctx, SurfaceControl rootSurface,
- ContainerWindow container) {
- super(ctx.getResources().getConfiguration(), rootSurface, null /* hostInputToken */);
- mContainerWindow = container;
- mDisplayId = displayId;
- }
-
- @Override
- public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
- int requestedWidth, int requestedHeight, int viewVisibility, int flags,
- long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
- Rect outVisibleInsets, Rect outStableInsets,
- DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration,
- SurfaceControl outSurfaceControl, InsetsState outInsetsState,
- InsetsSourceControl[] outActiveControls, Point outSurfaceSize,
- SurfaceControl outBLASTSurfaceControl) {
- int res = super.relayout(window, seq, attrs, requestedWidth, requestedHeight,
- viewVisibility, flags, frameNumber, outFrame, outOverscanInsets,
- outContentInsets, outVisibleInsets, outStableInsets,
- cutout, mergedConfiguration, outSurfaceControl, outInsetsState,
- outActiveControls, outSurfaceSize, outBLASTSurfaceControl);
- if (res != 0) {
- return res;
- }
- DisplayLayout dl = mDisplayController.getDisplayLayout(mDisplayId);
- outStableInsets.set(dl.stableInsets());
- return 0;
- }
-
- void updateConfiguration(Configuration configuration) {
- setConfiguration(configuration);
- }
-
- SurfaceControl getSurfaceControlForWindow(View rootView) {
- return getSurfaceControl(rootView);
- }
-
- void setTouchableRegionForWindow(View rootView, Region region) {
- IBinder token = rootView.getWindowToken();
- if (token == null) {
- return;
- }
- setTouchRegion(token, region);
- }
- }
-
- class ContainerWindow extends IWindow.Stub {
- ContainerWindow() {}
-
- @Override
- public void resized(Rect frame, Rect contentInsets, Rect visibleInsets, Rect stableInsets,
- boolean reportDraw, MergedConfiguration newMergedConfiguration, Rect backDropFrame,
- boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId,
- DisplayCutout.ParcelableWrapper displayCutout) {}
-
- @Override
- public void locationInParentDisplayChanged(Point offset) {}
-
- @Override
- public void insetsChanged(InsetsState insetsState) {}
-
- @Override
- public void insetsControlChanged(InsetsState insetsState,
- InsetsSourceControl[] activeControls) {}
-
- @Override
- public void showInsets(int types, boolean fromIme) {}
-
- @Override
- public void hideInsets(int types, boolean fromIme) {}
-
- @Override
- public void moved(int newX, int newY) {}
-
- @Override
- public void dispatchAppVisibility(boolean visible) {}
-
- @Override
- public void dispatchGetNewSurface() {}
-
- @Override
- public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) {}
-
- @Override
- public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {}
-
- @Override
- public void closeSystemDialogs(String reason) {}
-
- @Override
- public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
- float zoom, boolean sync) {}
-
- @Override
- public void dispatchWallpaperCommand(String action, int x, int y,
- int z, Bundle extras, boolean sync) {}
-
- /* Drag/drop */
- @Override
- public void dispatchDragEvent(DragEvent event) {}
-
- @Override
- public void updatePointerIcon(float x, float y) {}
-
- @Override
- public void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility,
- int localValue, int localChanges) {}
-
- @Override
- public void dispatchWindowShown() {}
-
- @Override
- public void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId) {}
-
- @Override
- public void dispatchPointerCaptureChanged(boolean hasCapture) {}
-
- @Override
- public void requestScrollCapture(IScrollCaptureController controller) {
- try {
- controller.onClientUnavailable();
- } catch (RemoteException ex) {
- // ignore
- }
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WindowManagerShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WindowManagerShellModule.java
new file mode 100644
index 0000000..bba5ff5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WindowManagerShellModule.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 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.wmshell;
+
+import android.content.Context;
+import android.os.Handler;
+import android.view.IWindowManager;
+
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.SystemWindows;
+import com.android.wm.shell.common.TransactionPool;
+
+import javax.inject.Singleton;
+
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * Provides dependencies from {@link com.android.wm.shell}.
+ */
+@Module
+// TODO(b/161116823) Clean up dependencies after wm shell migration finished.
+public class WindowManagerShellModule {
+ @Singleton
+ @Provides
+ static TransactionPool provideTransactionPool() {
+ return new TransactionPool();
+ }
+
+ @Singleton
+ @Provides
+ static DisplayController provideDisplayController(Context context, @Main Handler handler,
+ IWindowManager wmService) {
+ return new DisplayController(context, handler, wmService);
+ }
+
+ @Singleton
+ @Provides
+ static SystemWindows provideSystemWindows(Context context, DisplayController displayController,
+ IWindowManager wmService) {
+ return new SystemWindows(context, displayController, wmService);
+ }
+
+ @Singleton
+ @Provides
+ static DisplayImeController provideDisplayImeController(
+ SystemWindows syswin, DisplayController displayController,
+ @Main Handler mainHandler, TransactionPool transactionPool) {
+ return new DisplayImeController(syswin, displayController, mainHandler, transactionPool);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizerTest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizerTest.java
index 84a261b6..3231b28 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizerTest.java
@@ -41,7 +41,7 @@
import androidx.test.filters.SmallTest;
-import com.android.systemui.wm.DisplayController;
+import com.android.wm.shell.common.DisplayController;
import org.junit.Before;
import org.junit.Ignore;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java
index 180c450..3b284b14 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java
@@ -33,7 +33,7 @@
import com.android.systemui.model.SysUiState;
import com.android.systemui.statusbar.phone.NavigationModeController;
-import com.android.systemui.wm.DisplayController;
+import com.android.wm.shell.common.DisplayController;
import org.junit.Before;
import org.junit.Test;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedManagerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedManagerImplTest.java
index b6b2217..55bec54 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedManagerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedManagerImplTest.java
@@ -33,7 +33,7 @@
import androidx.test.filters.SmallTest;
import com.android.systemui.model.SysUiState;
-import com.android.systemui.wm.DisplayController;
+import com.android.wm.shell.common.DisplayController;
import org.junit.Before;
import org.junit.Test;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java
index 80fe0f0..3a4ba6a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java
@@ -31,7 +31,7 @@
import com.android.systemui.model.SysUiState;
import com.android.systemui.statusbar.phone.NavigationModeController;
-import com.android.systemui.wm.DisplayController;
+import com.android.wm.shell.common.DisplayController;
import org.junit.Before;
import org.junit.Test;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java
index 70c2bba..e9d2b73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java
@@ -33,7 +33,7 @@
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.wm.DisplayController;
+import com.android.wm.shell.common.DisplayController;
import org.junit.Before;
import org.junit.Test;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wm/DisplayLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/wm/DisplayLayoutTest.java
deleted file mode 100644
index 9596a73..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/wm/DisplayLayoutTest.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2019 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.wm;
-
-import static android.content.res.Configuration.UI_MODE_TYPE_NORMAL;
-import static android.view.Surface.ROTATION_0;
-import static android.view.Surface.ROTATION_270;
-import static android.view.Surface.ROTATION_90;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Insets;
-import android.graphics.Rect;
-import android.view.DisplayCutout;
-import android.view.DisplayInfo;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.R;
-import com.android.systemui.SysuiTestCase;
-
-import org.junit.Test;
-
-@SmallTest
-public class DisplayLayoutTest extends SysuiTestCase {
-
- @Test
- public void testInsets() {
- Resources res = createResources(40, 50, false, 30, 40);
- // Test empty display, no bars or anything
- DisplayInfo info = createDisplayInfo(1000, 1500, 0, ROTATION_0);
- DisplayLayout dl = new DisplayLayout(info, res, false, false);
- assertEquals(new Rect(0, 0, 0, 0), dl.stableInsets());
- assertEquals(new Rect(0, 0, 0, 0), dl.nonDecorInsets());
-
- // Test with bars
- dl = new DisplayLayout(info, res, true, true);
- assertEquals(new Rect(0, 40, 0, 50), dl.stableInsets());
- assertEquals(new Rect(0, 0, 0, 50), dl.nonDecorInsets());
-
- // Test just cutout
- info = createDisplayInfo(1000, 1500, 60, ROTATION_0);
- dl = new DisplayLayout(info, res, false, false);
- assertEquals(new Rect(0, 60, 0, 0), dl.stableInsets());
- assertEquals(new Rect(0, 60, 0, 0), dl.nonDecorInsets());
-
- // Test with bars and cutout
- dl = new DisplayLayout(info, res, true, true);
- assertEquals(new Rect(0, 60, 0, 50), dl.stableInsets());
- assertEquals(new Rect(0, 60, 0, 50), dl.nonDecorInsets());
- }
-
- @Test
- public void testRotate() {
- // Basic rotate utility
- Rect testParent = new Rect(0, 0, 1000, 600);
- Rect testInner = new Rect(40, 20, 120, 80);
- Rect testResult = new Rect(testInner);
- DisplayLayout.rotateBounds(testResult, testParent, 1);
- assertEquals(new Rect(20, 880, 80, 960), testResult);
- testResult.set(testInner);
- DisplayLayout.rotateBounds(testResult, testParent, 2);
- assertEquals(new Rect(880, 20, 960, 80), testResult);
- testResult.set(testInner);
- DisplayLayout.rotateBounds(testResult, testParent, 3);
- assertEquals(new Rect(520, 40, 580, 120), testResult);
-
- Resources res = createResources(40, 50, false, 30, 40);
- DisplayInfo info = createDisplayInfo(1000, 1500, 60, ROTATION_0);
- DisplayLayout dl = new DisplayLayout(info, res, true, true);
- assertEquals(new Rect(0, 60, 0, 50), dl.stableInsets());
- assertEquals(new Rect(0, 60, 0, 50), dl.nonDecorInsets());
-
- // Rotate to 90
- dl.rotateTo(res, ROTATION_90);
- assertEquals(new Rect(60, 30, 0, 40), dl.stableInsets());
- assertEquals(new Rect(60, 0, 0, 40), dl.nonDecorInsets());
-
- // Rotate with moving navbar
- res = createResources(40, 50, true, 30, 40);
- dl = new DisplayLayout(info, res, true, true);
- dl.rotateTo(res, ROTATION_270);
- assertEquals(new Rect(40, 30, 60, 0), dl.stableInsets());
- assertEquals(new Rect(40, 0, 60, 0), dl.nonDecorInsets());
- }
-
- private Resources createResources(
- int navLand, int navPort, boolean navMoves, int statusLand, int statusPort) {
- Configuration cfg = new Configuration();
- cfg.uiMode = UI_MODE_TYPE_NORMAL;
- Resources res = mock(Resources.class);
- doReturn(navLand).when(res).getDimensionPixelSize(
- R.dimen.navigation_bar_height_landscape_car_mode);
- doReturn(navPort).when(res).getDimensionPixelSize(R.dimen.navigation_bar_height_car_mode);
- doReturn(navLand).when(res).getDimensionPixelSize(R.dimen.navigation_bar_width_car_mode);
- doReturn(navLand).when(res).getDimensionPixelSize(R.dimen.navigation_bar_height_landscape);
- doReturn(navPort).when(res).getDimensionPixelSize(R.dimen.navigation_bar_height);
- doReturn(navLand).when(res).getDimensionPixelSize(R.dimen.navigation_bar_width);
- doReturn(navMoves).when(res).getBoolean(R.bool.config_navBarCanMove);
- doReturn(statusLand).when(res).getDimensionPixelSize(R.dimen.status_bar_height_landscape);
- doReturn(statusPort).when(res).getDimensionPixelSize(R.dimen.status_bar_height_portrait);
- doReturn(cfg).when(res).getConfiguration();
- return res;
- }
-
- private DisplayInfo createDisplayInfo(int width, int height, int cutoutHeight, int rotation) {
- DisplayInfo info = new DisplayInfo();
- info.logicalWidth = width;
- info.logicalHeight = height;
- info.rotation = rotation;
- if (cutoutHeight > 0) {
- info.displayCutout = new DisplayCutout(
- Insets.of(0, cutoutHeight, 0, 0) /* safeInsets */, null /* boundLeft */,
- new Rect(width / 2 - cutoutHeight, 0, width / 2 + cutoutHeight,
- cutoutHeight) /* boundTop */, null /* boundRight */,
- null /* boundBottom */);
- } else {
- info.displayCutout = DisplayCutout.NO_CUTOUT;
- }
- info.logicalDensityDpi = 300;
- return info;
- }
-}