diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2022-01-07 21:39:56 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2022-01-07 21:39:56 +0000 |
commit | e5e9acc7a5986436e73b0eac1ecc3481d0c0aa8d (patch) | |
tree | 537dbdff41e96247803ec02e476038a5ba44cbf5 | |
parent | 60de9363f753cb39622b3953268576309299679d (diff) | |
parent | 269f49d9b852fd4ed6762dec16bdf8af9f751b96 (diff) | |
download | base-e5e9acc7a5986436e73b0eac1ecc3481d0c0aa8d.tar.gz |
Merge "Added systemui controller to control system bars." into android11-tests-dev
22 files changed, 1034 insertions, 129 deletions
diff --git a/api/test-current.txt b/api/test-current.txt index 3838bad57aa7..cf97b848e80b 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -34,6 +34,7 @@ package android { public static final class R.bool { field public static final int config_assistantOnTopOfDream = 17891333; // 0x1110005 field public static final int config_perDisplayFocusEnabled = 17891332; // 0x1110004 + field public static final int config_remoteInsetsControllerControlsSystemBars = 17891334; // 0x1110006 } public static final class R.string { diff --git a/core/java/android/view/IDisplayWindowInsetsController.aidl b/core/java/android/view/IDisplayWindowInsetsController.aidl index 429c3aeba9b3..a0d4a6587bcf 100644 --- a/core/java/android/view/IDisplayWindowInsetsController.aidl +++ b/core/java/android/view/IDisplayWindowInsetsController.aidl @@ -27,6 +27,13 @@ import android.view.InsetsState; oneway interface IDisplayWindowInsetsController { /** + * Called when top focused window changes to determine whether or not to take over insets + * control. Won't be called if config_remoteInsetsControllerControlsSystemBars is false. + * @param packageName: Passes the top package name + */ + void topFocusedWindowChanged(String packageName); + + /** * @see IWindow#insetsChanged */ void insetsChanged(in InsetsState insetsState); diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 58597cf3fb6d..00fc67214f75 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -388,16 +388,6 @@ interface IWindowManager oneway void hideTransientBars(int displayId); /** - * When set to {@code true} the system bars will always be shown. This is true even if an app - * requests to be fullscreen by setting the system ui visibility flags. The - * functionality was added for the automotive case as a way to guarantee required content stays - * on screen at all times. - * - * @hide - */ - oneway void setForceShowSystemBars(boolean show); - - /** * Called by System UI to notify of changes to the visibility of Recents. */ oneway void setRecentsVisibility(boolean visible); diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 39d20bbff3ba..2bb63f1ca8df 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -712,10 +712,17 @@ case, this can be disabled (set to false). --> <bool name="config_enableCarDockHomeLaunch">true</bool> - <!-- Control whether to force the display of System UI Bars at all times regardless of - System Ui Flags. This can be useful in the Automotive case if there's a requirement for - a UI element to be on screen at all times. --> - <bool name="config_forceShowSystemBars">false</bool> + <!-- Control whether to force apps to give up control over the display of system bars at all + times regardless of System Ui Flags. + In the Automotive case, this is helpful if there's a requirement for an UI element to be on + screen at all times. Setting this to true also gives System UI the ability to override the + visibility controls for the system through the usage of the + "SYSTEM_BAR_VISIBILITY_OVERRIDE" setting. + Ex: Only setting the config to true will force show system bars for the entire system. + Ex: Setting the config to true and the "SYSTEM_BAR_VISIBILITY_OVERRIDE" setting to + "immersive.status=apps" will force show navigation bar for all apps and force hide status + bar for all apps. --> + <bool name="config_remoteInsetsControllerControlsSystemBars">false</bool> <!-- HDMI behavior --> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index e2fbbf46608f..e00aff1af37b 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -3024,6 +3024,8 @@ <!-- @hide @TestApi --> <public type="bool" name="config_assistantOnTopOfDream" id="0x01110005" /> + <!-- @hide @TestApi --> + <public type="bool" name="config_remoteInsetsControllerControlsSystemBars" id="0x01110006" /> <!-- =============================================================== Resources added in version S of the platform diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 871924255e66..bfb6802a2b80 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1669,7 +1669,7 @@ <java-symbol type="bool" name="config_enableCarDockHomeLaunch" /> <java-symbol type="bool" name="config_enableLockBeforeUnlockScreen" /> <java-symbol type="bool" name="config_enableLockScreenRotation" /> - <java-symbol type="bool" name="config_forceShowSystemBars" /> + <java-symbol type="bool" name="config_remoteInsetsControllerControlsSystemBars" /> <java-symbol type="bool" name="config_lidControlsScreenLock" /> <java-symbol type="bool" name="config_lidControlsSleep" /> <java-symbol type="bool" name="config_lockDayNightMode" /> diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java index fe2be1df44be..ca7e9ee4050b 100644 --- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java +++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java @@ -66,6 +66,8 @@ import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.volume.VolumeDialogComponent; +import com.android.systemui.wm.DisplayImeController; +import com.android.systemui.wm.DisplaySystemBarsController; import javax.inject.Named; import javax.inject.Singleton; @@ -96,6 +98,10 @@ public abstract class CarSystemUIModule { groupManager, configurationController); } + @Binds + abstract DisplayImeController bindDisplayImeController( + DisplaySystemBarsController displaySystemBarsController); + @Singleton @Provides @Named(LEAK_REPORT_EMAIL_NAME) diff --git a/packages/CarSystemUI/src/com/android/systemui/wm/BarControlPolicy.java b/packages/CarSystemUI/src/com/android/systemui/wm/BarControlPolicy.java new file mode 100644 index 000000000000..5f9665ff7632 --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/wm/BarControlPolicy.java @@ -0,0 +1,250 @@ +/* + * 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.wm; + +import android.car.settings.CarSettings; +import android.content.Context; +import android.database.ContentObserver; +import android.os.Handler; +import android.os.UserHandle; +import android.provider.Settings; +import android.util.ArraySet; +import android.util.Slog; +import android.view.WindowInsets; + +import androidx.annotation.VisibleForTesting; + +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * Util class to load PolicyControl and allow for querying if a package matches immersive filters. + * Similar to {@link com.android.server.wm.PolicyControl}, but separate due to CarSystemUI needing + * to set its own policies for system bar visibilities. + * + * This forces immersive mode behavior for one or both system bars (based on a package + * list). + * + * Control by setting {@link Settings.Global#POLICY_CONTROL_AUTO} to one or more name-value pairs. + * e.g. + * to force immersive mode everywhere: + * "immersive.full=*" + * to force hide status bars for com.package1 but not com.package2: + * "immersive.status=com.package1,-com.package2" + * + * Separate multiple name-value pairs with ':' + * e.g. "immersive.status=com.package:immersive.navigation=*" + */ +public class BarControlPolicy { + + private static final String TAG = "BarControlPolicy"; + private static final boolean DEBUG = false; + + private static final String NAME_IMMERSIVE_FULL = "immersive.full"; + private static final String NAME_IMMERSIVE_STATUS = "immersive.status"; + private static final String NAME_IMMERSIVE_NAVIGATION = "immersive.navigation"; + + @VisibleForTesting + static String sSettingValue; + @VisibleForTesting + static Filter sImmersiveStatusFilter; + private static Filter sImmersiveNavigationFilter; + + /** Loads values from the POLICY_CONTROL setting to set filters. */ + static boolean reloadFromSetting(Context context) { + if (DEBUG) Slog.d(TAG, "reloadFromSetting()"); + String value = null; + try { + value = Settings.Global.getStringForUser(context.getContentResolver(), + CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE, + UserHandle.USER_CURRENT); + if (sSettingValue == value || sSettingValue != null && sSettingValue.equals(value)) { + return false; + } + setFilters(value); + sSettingValue = value; + } catch (Throwable t) { + Slog.w(TAG, "Error loading policy control, value=" + value, t); + return false; + } + return true; + } + + /** Used in testing to reset BarControlPolicy. */ + @VisibleForTesting + static void reset() { + sSettingValue = null; + sImmersiveStatusFilter = null; + sImmersiveNavigationFilter = null; + } + + /** + * Registers a content observer to listen to updates to the SYSTEM_BAR_VISIBILITY_OVERRIDE flag. + */ + static void registerContentObserver(Context context, Handler handler, FilterListener listener) { + context.getContentResolver().registerContentObserver( + Settings.Global.getUriFor(CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE), false, + new ContentObserver(handler) { + @Override + public void onChange(boolean selfChange) { + if (reloadFromSetting(context)) { + listener.onFilterUpdated(); + } + } + }, UserHandle.USER_ALL); + } + + /** + * Returns bar visibilities based on POLICY_CONTROL_AUTO filters and window policies. + * @return int[], where the first value is the inset types that should be shown, and the second + * is the inset types that should be hidden. + */ + @WindowInsets.Type.InsetsType + static int[] getBarVisibilities(String packageName) { + int hideTypes = 0; + int showTypes = 0; + if (matchesStatusFilter(packageName)) { + hideTypes |= WindowInsets.Type.statusBars(); + } else { + showTypes |= WindowInsets.Type.statusBars(); + } + if (matchesNavigationFilter(packageName)) { + hideTypes |= WindowInsets.Type.navigationBars(); + } else { + showTypes |= WindowInsets.Type.navigationBars(); + } + + return new int[] {showTypes, hideTypes}; + } + + private static boolean matchesStatusFilter(String packageName) { + return sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(packageName); + } + + private static boolean matchesNavigationFilter(String packageName) { + return sImmersiveNavigationFilter != null + && sImmersiveNavigationFilter.matches(packageName); + } + + private static void setFilters(String value) { + if (DEBUG) Slog.d(TAG, "setFilters: " + value); + sImmersiveStatusFilter = null; + sImmersiveNavigationFilter = null; + if (value != null) { + String[] nvps = value.split(":"); + for (String nvp : nvps) { + int i = nvp.indexOf('='); + if (i == -1) continue; + String n = nvp.substring(0, i); + String v = nvp.substring(i + 1); + if (n.equals(NAME_IMMERSIVE_FULL)) { + Filter f = Filter.parse(v); + sImmersiveStatusFilter = sImmersiveNavigationFilter = f; + } else if (n.equals(NAME_IMMERSIVE_STATUS)) { + Filter f = Filter.parse(v); + sImmersiveStatusFilter = f; + } else if (n.equals(NAME_IMMERSIVE_NAVIGATION)) { + Filter f = Filter.parse(v); + sImmersiveNavigationFilter = f; + } + } + } + if (DEBUG) { + Slog.d(TAG, "immersiveStatusFilter: " + sImmersiveStatusFilter); + Slog.d(TAG, "immersiveNavigationFilter: " + sImmersiveNavigationFilter); + } + } + + private static class Filter { + private static final String ALL = "*"; + + private final ArraySet<String> mWhitelist; + private final ArraySet<String> mBlacklist; + + private Filter(ArraySet<String> whitelist, ArraySet<String> blacklist) { + mWhitelist = whitelist; + mBlacklist = blacklist; + } + + boolean matches(String packageName) { + if (packageName == null) return false; + if (onBlacklist(packageName)) return false; + return onWhitelist(packageName); + } + + private boolean onBlacklist(String packageName) { + return mBlacklist.contains(packageName) || mBlacklist.contains(ALL); + } + + private boolean onWhitelist(String packageName) { + return mWhitelist.contains(ALL) || mWhitelist.contains(packageName); + } + + void dump(PrintWriter pw) { + pw.print("Filter["); + dump("whitelist", mWhitelist, pw); pw.print(','); + dump("blacklist", mBlacklist, pw); pw.print(']'); + } + + private void dump(String name, ArraySet<String> set, PrintWriter pw) { + pw.print(name); pw.print("=("); + int n = set.size(); + for (int i = 0; i < n; i++) { + if (i > 0) pw.print(','); + pw.print(set.valueAt(i)); + } + pw.print(')'); + } + + @Override + public String toString() { + StringWriter sw = new StringWriter(); + dump(new PrintWriter(sw, true)); + return sw.toString(); + } + + // value = comma-delimited list of tokens, where token = (package name|*) + // e.g. "com.package1", or "com.android.systemui, com.android.keyguard" or "*" + static Filter parse(String value) { + if (value == null) return null; + ArraySet<String> whitelist = new ArraySet<String>(); + ArraySet<String> blacklist = new ArraySet<String>(); + for (String token : value.split(",")) { + token = token.trim(); + if (token.startsWith("-") && token.length() > 1) { + token = token.substring(1); + blacklist.add(token); + } else { + whitelist.add(token); + } + } + return new Filter(whitelist, blacklist); + } + } + + /** + * Interface to listen for updates to the filter triggered by the content observer listening to + * the SYSTEM_BAR_VISIBILITY_OVERRIDE flag. + */ + interface FilterListener { + + /** Callback triggered when the content observer updates the filter. */ + void onFilterUpdated(); + } + + private BarControlPolicy() {} +} diff --git a/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java b/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java new file mode 100644 index 000000000000..a831464e7987 --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsController.java @@ -0,0 +1,168 @@ +/* + * 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.wm; + +import android.os.Handler; +import android.os.RemoteException; +import android.util.ArraySet; +import android.util.Slog; +import android.util.SparseArray; +import android.view.IDisplayWindowInsetsController; +import android.view.InsetsController; +import android.view.InsetsSourceControl; +import android.view.InsetsState; +import android.view.WindowInsets; + +import androidx.annotation.VisibleForTesting; + +import com.android.systemui.TransactionPool; +import com.android.systemui.dagger.qualifiers.Main; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * Controller that maps between displays and {@link IDisplayWindowInsetsController} in order to + * give system bar control to SystemUI. + * {@link R.bool#config_remoteInsetsControllerControlsSystemBars} determines whether this controller + * takes control or not. + */ +@Singleton +public class DisplaySystemBarsController extends DisplayImeController { + + private static final String TAG = "DisplaySystemBarsController"; + + private SparseArray<PerDisplay> mPerDisplaySparseArray; + + @Inject + public DisplaySystemBarsController( + SystemWindows syswin, + DisplayController displayController, + @Main Handler mainHandler, + TransactionPool transactionPool) { + super(syswin, displayController, mainHandler, transactionPool); + } + + @Override + public void onDisplayAdded(int displayId) { + PerDisplay pd = new PerDisplay(displayId); + try { + mSystemWindows.mWmService.setDisplayWindowInsetsController(displayId, pd); + } catch (RemoteException e) { + Slog.w(TAG, "Unable to set insets controller on display " + displayId); + } + // Lazy loading policy control filters instead of during boot. + if (mPerDisplaySparseArray == null) { + mPerDisplaySparseArray = new SparseArray<>(); + BarControlPolicy.reloadFromSetting(mSystemWindows.mContext); + BarControlPolicy.registerContentObserver(mSystemWindows.mContext, mHandler, () -> { + int size = mPerDisplaySparseArray.size(); + for (int i = 0; i < size; i++) { + mPerDisplaySparseArray.valueAt(i).modifyDisplayWindowInsets(); + } + }); + } + mPerDisplaySparseArray.put(displayId, pd); + } + + @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); + } + mPerDisplaySparseArray.remove(displayId); + } + + @VisibleForTesting + class PerDisplay extends IDisplayWindowInsetsController.Stub { + + int mDisplayId; + InsetsController mInsetsController; + InsetsState mInsetsState = new InsetsState(); + String mPackageName; + + PerDisplay(int displayId) { + mDisplayId = displayId; + mInsetsController = new InsetsController( + new DisplaySystemBarsInsetsControllerHost(mHandler, this)); + } + + @Override + public void insetsChanged(InsetsState insetsState) { + if (mInsetsState.equals(insetsState)) { + return; + } + mInsetsState.set(insetsState, true /* copySources */); + mInsetsController.onStateChanged(insetsState); + if (mPackageName != null) { + modifyDisplayWindowInsets(); + } + } + + @Override + public void insetsControlChanged(InsetsState insetsState, + InsetsSourceControl[] activeControls) { + mInsetsController.onControlsChanged(activeControls); + } + + @Override + public void hideInsets(@WindowInsets.Type.InsetsType int types, boolean fromIme) { + mInsetsController.hide(types); + } + + @Override + public void showInsets(@WindowInsets.Type.InsetsType int types, boolean fromIme) { + mInsetsController.show(types); + } + + @Override + public void topFocusedWindowChanged(String packageName) { + // If both package names are null or both package names are equal, return. + if (mPackageName == packageName + || (mPackageName != null && mPackageName.equals(packageName))) { + return; + } + mPackageName = packageName; + modifyDisplayWindowInsets(); + } + + private void modifyDisplayWindowInsets() { + if (mPackageName == null) { + return; + } + int[] barVisibilities = BarControlPolicy.getBarVisibilities(mPackageName); + updateInsetsState(barVisibilities[0], /* visible= */ true); + updateInsetsState(barVisibilities[1], /* visible= */ false); + showInsets(barVisibilities[0], /* fromIme= */ false); + hideInsets(barVisibilities[1], /* fromIme= */ false); + try { + mSystemWindows.mWmService.modifyDisplayWindowInsets(mDisplayId, mInsetsState); + } catch (RemoteException e) { + Slog.w(TAG, "Unable to update window manager service."); + } + } + + private void updateInsetsState(@WindowInsets.Type.InsetsType int types, boolean visible) { + ArraySet<Integer> internalTypes = InsetsState.toInternalType(types); + for (int i = internalTypes.size() - 1; i >= 0; i--) { + mInsetsState.getSource(internalTypes.valueAt(i)).setVisible(visible); + } + } + } +} diff --git a/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsInsetsControllerHost.java b/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsInsetsControllerHost.java new file mode 100644 index 000000000000..2f8da44ba851 --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/wm/DisplaySystemBarsInsetsControllerHost.java @@ -0,0 +1,173 @@ +/* + * 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.wm; + +import android.annotation.NonNull; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Log; +import android.view.IDisplayWindowInsetsController; +import android.view.InsetsController; +import android.view.InsetsState; +import android.view.SurfaceControl; +import android.view.SyncRtSurfaceTransactionApplier; +import android.view.WindowInsets; +import android.view.WindowInsetsAnimation; +import android.view.WindowInsetsController; +import android.view.inputmethod.InputMethodManager; + +import java.util.List; + +/** + * Implements {@link InsetsController.Host} for usage by + * {@link DisplaySystemBarsController.PerDisplay} instances in {@link DisplaySystemBarsController}. + * @hide + */ +public class DisplaySystemBarsInsetsControllerHost implements InsetsController.Host { + + private static final String TAG = DisplaySystemBarsInsetsControllerHost.class.getSimpleName(); + + private final Handler mHandler; + private final IDisplayWindowInsetsController mController; + private final float[] mTmpFloat9 = new float[9]; + + public DisplaySystemBarsInsetsControllerHost( + Handler handler, IDisplayWindowInsetsController controller) { + mHandler = handler; + mController = controller; + } + + @Override + public Handler getHandler() { + return mHandler; + } + + @Override + public void notifyInsetsChanged() { + // no-op + } + + @Override + public void dispatchWindowInsetsAnimationPrepare(@NonNull WindowInsetsAnimation animation) { + // no-op + } + + @Override + public WindowInsetsAnimation.Bounds dispatchWindowInsetsAnimationStart( + @NonNull WindowInsetsAnimation animation, + @NonNull WindowInsetsAnimation.Bounds bounds) { + return null; + } + + @Override + public WindowInsets dispatchWindowInsetsAnimationProgress(@NonNull WindowInsets insets, + @NonNull List<WindowInsetsAnimation> runningAnimations) { + return null; + } + + @Override + public void dispatchWindowInsetsAnimationEnd(@NonNull WindowInsetsAnimation animation) { + // no-op + } + + @Override + public void applySurfaceParams(final SyncRtSurfaceTransactionApplier.SurfaceParams... params) { + for (int i = params.length - 1; i >= 0; i--) { + SyncRtSurfaceTransactionApplier.applyParams( + new SurfaceControl.Transaction(), params[i], mTmpFloat9); + } + + } + + @Override + public void updateCompatSysUiVisibility( + @InsetsState.InternalInsetsType int type, boolean visible, boolean hasControl) { + // no-op + } + + @Override + public void onInsetsModified(InsetsState insetsState) { + try { + mController.insetsChanged(insetsState); + } catch (RemoteException e) { + Log.e(TAG, "Failed to send insets to controller"); + } + } + + @Override + public boolean hasAnimationCallbacks() { + return false; + } + + @Override + public void setSystemBarsAppearance( + @WindowInsetsController.Appearance int appearance, + @WindowInsetsController.Appearance int mask) { + // no-op + } + + @Override + public @WindowInsetsController.Appearance int getSystemBarsAppearance() { + return 0; + } + + @Override + public void setSystemBarsBehavior(@WindowInsetsController.Behavior int behavior) { + // no-op + } + + @Override + public @WindowInsetsController.Behavior int getSystemBarsBehavior() { + return 0; + } + + @Override + public void releaseSurfaceControlFromRt(SurfaceControl surfaceControl) { + surfaceControl.release(); + } + + @Override + public void addOnPreDrawRunnable(Runnable r) { + mHandler.post(r); + } + + @Override + public void postInsetsAnimationCallback(Runnable r) { + mHandler.post(r); + } + + @Override + public InputMethodManager getInputMethodManager() { + return null; + } + + @Override + public String getRootViewTitle() { + return null; + } + + @Override + public int dipToPx(int dips) { + return 0; + } + + @Override + public IBinder getWindowToken() { + return null; + } +} diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/wm/BarControlPolicyTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/wm/BarControlPolicyTest.java new file mode 100644 index 000000000000..da7cb8e4f6ac --- /dev/null +++ b/packages/CarSystemUI/tests/src/com/android/systemui/wm/BarControlPolicyTest.java @@ -0,0 +1,195 @@ +/* + * 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.wm; + +import static android.view.WindowInsets.Type.navigationBars; +import static android.view.WindowInsets.Type.statusBars; + +import static com.google.common.truth.Truth.assertThat; + +import android.car.settings.CarSettings; +import android.provider.Settings; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.SysuiTestCase; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +@SmallTest +public class BarControlPolicyTest extends SysuiTestCase { + + private static final String PACKAGE_NAME = "sample.app"; + + @Before + public void setUp() { + BarControlPolicy.reset(); + } + + @After + public void tearDown() { + Settings.Global.clearProviderForTest(); + } + + @Test + public void reloadFromSetting_notSet_doesNotSetFilters() { + BarControlPolicy.reloadFromSetting(mContext); + + assertThat(BarControlPolicy.sImmersiveStatusFilter).isNull(); + } + + @Test + public void reloadFromSetting_invalidPolicyControlString_doesNotSetFilters() { + String text = "sample text"; + Settings.Global.putString( + mContext.getContentResolver(), + CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE, + text + ); + + BarControlPolicy.reloadFromSetting(mContext); + + assertThat(BarControlPolicy.sImmersiveStatusFilter).isNull(); + } + + @Test + public void reloadFromSetting_validPolicyControlString_setsFilters() { + String text = "immersive.status=" + PACKAGE_NAME; + Settings.Global.putString( + mContext.getContentResolver(), + CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE, + text + ); + + BarControlPolicy.reloadFromSetting(mContext); + + assertThat(BarControlPolicy.sImmersiveStatusFilter).isNotNull(); + } + + @Test + public void reloadFromSetting_filtersSet_doesNotSetFiltersAgain() { + String text = "immersive.status=" + PACKAGE_NAME; + Settings.Global.putString( + mContext.getContentResolver(), + CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE, + text + ); + + BarControlPolicy.reloadFromSetting(mContext); + + assertThat(BarControlPolicy.reloadFromSetting(mContext)).isFalse(); + } + + @Test + public void getBarVisibilities_policyControlNotSet_showsSystemBars() { + int[] visibilities = BarControlPolicy.getBarVisibilities(PACKAGE_NAME); + + assertThat(visibilities[0]).isEqualTo(statusBars() | navigationBars()); + assertThat(visibilities[1]).isEqualTo(0); + } + + @Test + public void getBarVisibilities_immersiveStatusForAppAndMatchingApp_hidesStatusBar() { + Settings.Global.putString( + mContext.getContentResolver(), + CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE, + "immersive.status=" + PACKAGE_NAME); + BarControlPolicy.reloadFromSetting(mContext); + + int[] visibilities = BarControlPolicy.getBarVisibilities(PACKAGE_NAME); + + assertThat(visibilities[0]).isEqualTo(navigationBars()); + assertThat(visibilities[1]).isEqualTo(statusBars()); + } + + @Test + public void getBarVisibilities_immersiveStatusForAppAndNonMatchingApp_showsSystemBars() { + Settings.Global.putString( + mContext.getContentResolver(), + CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE, + "immersive.status=" + PACKAGE_NAME); + BarControlPolicy.reloadFromSetting(mContext); + + int[] visibilities = BarControlPolicy.getBarVisibilities("sample2.app"); + + assertThat(visibilities[0]).isEqualTo(statusBars() | navigationBars()); + assertThat(visibilities[1]).isEqualTo(0); + } + + @Test + public void getBarVisibilities_immersiveStatusForAppsAndNonApp_showsSystemBars() { + Settings.Global.putString( + mContext.getContentResolver(), + CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE, + "immersive.status=apps"); + BarControlPolicy.reloadFromSetting(mContext); + + int[] visibilities = BarControlPolicy.getBarVisibilities(PACKAGE_NAME); + + assertThat(visibilities[0]).isEqualTo(statusBars() | navigationBars()); + assertThat(visibilities[1]).isEqualTo(0); + } + + @Test + public void getBarVisibilities_immersiveFullForAppAndMatchingApp_hidesSystemBars() { + Settings.Global.putString( + mContext.getContentResolver(), + CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE, + "immersive.full=" + PACKAGE_NAME); + BarControlPolicy.reloadFromSetting(mContext); + + int[] visibilities = BarControlPolicy.getBarVisibilities(PACKAGE_NAME); + + assertThat(visibilities[0]).isEqualTo(0); + assertThat(visibilities[1]).isEqualTo(statusBars() | navigationBars()); + } + + @Test + public void getBarVisibilities_immersiveFullForAppAndNonMatchingApp_showsSystemBars() { + Settings.Global.putString( + mContext.getContentResolver(), + CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE, + "immersive.full=" + PACKAGE_NAME); + BarControlPolicy.reloadFromSetting(mContext); + + int[] visibilities = BarControlPolicy.getBarVisibilities("sample2.app"); + + assertThat(visibilities[0]).isEqualTo(statusBars() | navigationBars()); + assertThat(visibilities[1]).isEqualTo(0); + } + + @Test + public void getBarVisibilities_immersiveFullForAppsAndNonApp_showsSystemBars() { + Settings.Global.putString( + mContext.getContentResolver(), + CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE, + "immersive.full=apps"); + BarControlPolicy.reloadFromSetting(mContext); + + int[] visibilities = BarControlPolicy.getBarVisibilities(PACKAGE_NAME); + + assertThat(visibilities[0]).isEqualTo(statusBars() | navigationBars()); + assertThat(visibilities[1]).isEqualTo(0); + } +} diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/wm/DisplaySystemBarsControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/wm/DisplaySystemBarsControllerTest.java new file mode 100644 index 000000000000..29cc8eec4bc3 --- /dev/null +++ b/packages/CarSystemUI/tests/src/com/android/systemui/wm/DisplaySystemBarsControllerTest.java @@ -0,0 +1,111 @@ +/* + * 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.wm; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.verify; + +import android.car.settings.CarSettings; +import android.os.Handler; +import android.os.RemoteException; +import android.provider.Settings; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.view.IWindowManager; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.TransactionPool; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +@SmallTest +public class DisplaySystemBarsControllerTest extends SysuiTestCase { + + private DisplaySystemBarsController mController; + + private static final int DISPLAY_ID = 1; + + @Mock + private SystemWindows mSystemWindows; + @Mock + private IWindowManager mIWindowManager; + @Mock + private DisplayController mDisplayController; + @Mock + private Handler mHandler; + @Mock + private TransactionPool mTransactionPool; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mSystemWindows.mContext = mContext; + mSystemWindows.mWmService = mIWindowManager; + + mController = new DisplaySystemBarsController( + mSystemWindows, + mDisplayController, + mHandler, + mTransactionPool + ); + } + + @Test + public void onDisplayAdded_setsDisplayWindowInsetsControllerOnWMService() + throws RemoteException { + mController.onDisplayAdded(DISPLAY_ID); + + verify(mIWindowManager).setDisplayWindowInsetsController( + eq(DISPLAY_ID), any(DisplaySystemBarsController.PerDisplay.class)); + } + + @Test + public void onDisplayAdded_loadsBarControlPolicyFilters() { + String text = "sample text"; + Settings.Global.putString( + mContext.getContentResolver(), + CarSettings.Global.SYSTEM_BAR_VISIBILITY_OVERRIDE, + text + ); + + mController.onDisplayAdded(DISPLAY_ID); + + assertThat(BarControlPolicy.sSettingValue).isEqualTo(text); + } + + @Test + public void onDisplayRemoved_unsetsDisplayWindowInsetsControllerInWMService() + throws RemoteException { + mController.onDisplayAdded(DISPLAY_ID); + + mController.onDisplayRemoved(DISPLAY_ID); + + verify(mIWindowManager).setDisplayWindowInsetsController( + DISPLAY_ID, /* displayWindowInsetsController= */ null); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java index 926f653153ee..89f469a438a9 100644 --- a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java +++ b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java @@ -259,6 +259,11 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged 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. */ diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 5d3f3c0401ef..cdbc7d2f4861 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -5774,6 +5774,19 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mRemoteInsetsController = controller; } + /** + * Notifies the remote insets controller that the top focused window has changed. + * + * @param packageName The name of the package that is open in the top focused window. + */ + void topFocusedWindowChanged(String packageName) { + try { + mRemoteInsetsController.topFocusedWindowChanged(packageName); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to deliver package in top focused window change", e); + } + } + void notifyInsetsChanged() { try { mRemoteInsetsController.insetsChanged( diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 0d467c50aa11..20f9bf3f6709 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -386,11 +386,6 @@ public class DisplayPolicy { private int mForcingShowNavBarLayer; private boolean mForceShowSystemBars; - /** - * Force the display of system bars regardless of other settings. - */ - private boolean mForceShowSystemBarsFromExternal; - private boolean mShowingDream; private boolean mLastShowingDream; private boolean mDreamingLockscreen; @@ -480,7 +475,6 @@ public class DisplayPolicy { final Resources r = mContext.getResources(); mCarDockEnablesAccelerometer = r.getBoolean(R.bool.config_carDockEnablesAccelerometer); mDeskDockEnablesAccelerometer = r.getBoolean(R.bool.config_deskDockEnablesAccelerometer); - mForceShowSystemBarsFromExternal = r.getBoolean(R.bool.config_forceShowSystemBars); mAccessibilityManager = (AccessibilityManager) mContext.getSystemService( Context.ACCESSIBILITY_SERVICE); @@ -698,17 +692,6 @@ public class DisplayPolicy { return mDockMode; } - /** - * @see WindowManagerService.setForceShowSystemBars - */ - void setForceShowSystemBars(boolean forceShowSystemBars) { - mForceShowSystemBarsFromExternal = forceShowSystemBars; - } - - boolean getForceShowSystemBars() { - return mForceShowSystemBarsFromExternal; - } - public boolean hasNavigationBar() { return mHasNavigationBar; } @@ -3547,8 +3530,7 @@ public class DisplayPolicy { // We need to force system bars when the docked stack is visible, when the freeform stack // is focused but also when we are resizing for the transitions when docked stack // visibility changes. - mForceShowSystemBars = dockedStackVisible || win.inFreeformWindowingMode() || resizing - || mForceShowSystemBarsFromExternal; + mForceShowSystemBars = dockedStackVisible || win.inFreeformWindowingMode() || resizing; final boolean forceOpaqueStatusBar = mForceShowSystemBars && !isKeyguardShowing(); // apply translucent bar vis flags @@ -3923,8 +3905,8 @@ public class DisplayPolicy { } pw.print(prefix); pw.print("mTopIsFullscreen="); pw.println(mTopIsFullscreen); pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar); - pw.print(prefix); pw.print("mForceShowSystemBarsFromExternal="); - pw.print(mForceShowSystemBarsFromExternal); + pw.print(prefix); pw.print("mRemoteInsetsControllerControlsSystemBars"); + pw.print(mDisplayContent.getInsetsPolicy().getRemoteInsetsControllerControlsSystemBars()); pw.print(" mAllowLockscreenWhenOn="); pw.println(mAllowLockscreenWhenOn); mStatusBarController.dump(pw, prefix); mNavigationBarController.dump(pw, prefix); diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index 254356d673e3..82e7555c62ac 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -46,7 +46,9 @@ import android.view.WindowInsets.Type.InsetsType; import android.view.WindowInsetsAnimation; import android.view.WindowInsetsAnimation.Bounds; import android.view.WindowInsetsAnimationControlListener; +import android.view.WindowManager; +import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.server.DisplayThread; @@ -97,12 +99,31 @@ class InsetsPolicy { private BarWindow mStatusBar = new BarWindow(StatusBarManager.WINDOW_STATUS_BAR); private BarWindow mNavBar = new BarWindow(StatusBarManager.WINDOW_NAVIGATION_BAR); private boolean mAnimatingShown; + + /** + * Let remote insets controller control system bars regardless of other settings. + */ + private boolean mRemoteInsetsControllerControlsSystemBars; private final float[] mTmpFloat9 = new float[9]; InsetsPolicy(InsetsStateController stateController, DisplayContent displayContent) { mStateController = stateController; mDisplayContent = displayContent; mPolicy = displayContent.getDisplayPolicy(); + mRemoteInsetsControllerControlsSystemBars = mPolicy.getContext().getResources().getBoolean( + R.bool.config_remoteInsetsControllerControlsSystemBars); + } + + boolean getRemoteInsetsControllerControlsSystemBars() { + return mRemoteInsetsControllerControlsSystemBars; + } + + /** + * Used only for testing. + */ + @VisibleForTesting + void setRemoteInsetsControllerControlsSystemBars(boolean controlsSystemBars) { + mRemoteInsetsControllerControlsSystemBars = controlsSystemBars; } /** Updates the target which can control system bars. */ @@ -256,6 +277,11 @@ class InsetsPolicy { // Notification shade has control anyways, no reason to force anything. return focusedWin; } + if (remoteInsetsControllerControlsSystemBars(focusedWin)) { + mDisplayContent.mRemoteInsetsControlTarget.topFocusedWindowChanged( + focusedWin.mAttrs.packageName); + return mDisplayContent.mRemoteInsetsControlTarget; + } if (forceShowsSystemBarsForWindowingMode) { // Status bar is forcibly shown for the windowing mode which is a steady state. // We don't want the client to control the status bar, and we will dispatch the real @@ -285,6 +311,11 @@ class InsetsPolicy { // Notification shade has control anyways, no reason to force anything. return focusedWin; } + if (remoteInsetsControllerControlsSystemBars(focusedWin)) { + mDisplayContent.mRemoteInsetsControlTarget.topFocusedWindowChanged( + focusedWin.mAttrs.packageName); + return mDisplayContent.mRemoteInsetsControlTarget; + } if (forceShowsSystemBarsForWindowingMode) { // Navigation bar is forcibly shown for the windowing mode which is a steady state. // We don't want the client to control the navigation bar, and we will dispatch the real @@ -300,6 +331,28 @@ class InsetsPolicy { return focusedWin; } + /** + * Determines whether the remote insets controller should take control of system bars for all + * windows. + */ + boolean remoteInsetsControllerControlsSystemBars(@Nullable WindowState focusedWin) { + if (focusedWin == null) { + return false; + } + if (!mRemoteInsetsControllerControlsSystemBars) { + return false; + } + if (mDisplayContent == null || mDisplayContent.mRemoteInsetsControlTarget == null) { + // No remote insets control target to take control of insets. + return false; + } + // If necessary, auto can control application windows when + // config_remoteInsetsControllerControlsSystemBars is set to true. This is useful in cases + // where we want to dictate system bar inset state for applications. + return focusedWin.getAttrs().type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW + && focusedWin.getAttrs().type <= WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; + } + private boolean forceShowsStatusBarTransiently() { final WindowState win = mPolicy.getStatusBar(); return win != null && (win.mAttrs.privateFlags & PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR) != 0; @@ -321,10 +374,7 @@ class InsetsPolicy { // We need to force system bars when the docked stack is visible, when the freeform stack // is visible but also when we are resizing for the transitions when docked stack // visibility changes. - return isDockedStackVisible - || isFreeformStackVisible - || isResizing - || mPolicy.getForceShowSystemBars(); + return isDockedStackVisible || isFreeformStackVisible || isResizing; } @VisibleForTesting diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index ef81c0a5d206..371d6b56f687 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -5827,27 +5827,6 @@ public class WindowManagerService extends IWindowManager.Stub } } - @Override - public void setForceShowSystemBars(boolean show) { - boolean isAutomotive = mContext.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_AUTOMOTIVE); - if (!isAutomotive) { - throw new UnsupportedOperationException("Force showing system bars is only supported" - + "for Automotive use cases."); - } - if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR) - != PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("Caller does not hold permission " - + android.Manifest.permission.STATUS_BAR); - } - synchronized (mGlobalLock) { - final PooledConsumer c = PooledLambda.obtainConsumer( - DisplayPolicy::setForceShowSystemBars, PooledLambda.__(), show); - mRoot.forAllDisplayPolicies(c); - c.recycle(); - } - } - public void setNavBarVirtualKeyHapticFeedbackEnabled(boolean enabled) { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR) != PackageManager.PERMISSION_GRANTED) { diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index d6e038d8d027..85736ab11e65 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -96,13 +96,10 @@ import android.platform.test.annotations.Presubmit; import android.util.DisplayMetrics; import android.view.DisplayCutout; import android.view.Gravity; -import android.view.IDisplayWindowInsetsController; import android.view.IDisplayWindowRotationCallback; import android.view.IDisplayWindowRotationController; import android.view.ISystemGestureExclusionListener; import android.view.IWindowManager; -import android.view.InsetsSourceControl; -import android.view.InsetsState; import android.view.MotionEvent; import android.view.Surface; import android.view.SurfaceControl.Transaction; @@ -954,28 +951,6 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(mAppWindow, mDisplayContent.computeImeControlTarget()); } - private IDisplayWindowInsetsController createDisplayWindowInsetsController() { - return new IDisplayWindowInsetsController.Stub() { - - @Override - public void insetsChanged(InsetsState insetsState) throws RemoteException { - } - - @Override - public void insetsControlChanged(InsetsState insetsState, - InsetsSourceControl[] insetsSourceControls) throws RemoteException { - } - - @Override - public void showInsets(int i, boolean b) throws RemoteException { - } - - @Override - public void hideInsets(int i, boolean b) throws RemoteException { - } - }; - } - @Test public void testUpdateSystemGestureExclusion() throws Exception { final DisplayContent dc = createNewDisplay(); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java index 1922351ac1eb..278de56dfea0 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java @@ -67,7 +67,6 @@ import android.view.WindowManager; import androidx.test.filters.SmallTest; -import com.android.server.policy.WindowManagerPolicy; import com.android.server.wm.utils.WmDisplayCutout; import org.junit.Before; @@ -807,27 +806,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase { } @Test - public void forceShowSystemBars_clearsSystemUIFlags() { - mDisplayPolicy.mLastSystemUiFlags |= SYSTEM_UI_FLAG_FULLSCREEN; - mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; - mWindow.mAttrs.flags = - FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; - mWindow.mSystemUiVisibility = SYSTEM_UI_FLAG_FULLSCREEN; - mDisplayPolicy.setForceShowSystemBars(true); - addWindow(mWindow); - - mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); - mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); - // triggers updateSystemUiVisibilityLw which will reset the flags as needed - int finishPostLayoutPolicyLw = mDisplayPolicy.focusChangedLw(mWindow, mWindow); - - assertEquals(WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT, finishPostLayoutPolicyLw); - assertEquals(0, mDisplayPolicy.mLastSystemUiFlags); - assertEquals(0, mWindow.mAttrs.systemUiVisibility); - assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); - } - - @Test public void testScreenDecorWindows() { final WindowState decorWindow = createWindow(null, TYPE_APPLICATION_OVERLAY, "decorWindow"); mWindow.mAttrs.flags = FLAG_NOT_FOCUSABLE | FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java index c794e1a3b328..87bc7f1bf781 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java @@ -172,8 +172,9 @@ public class InsetsPolicyTest extends WindowTestsBase { } @Test - public void testControlsForDispatch_forceShowSystemBarsFromExternal_appHasNoControl() { - mDisplayContent.getDisplayPolicy().setForceShowSystemBars(true); + public void testControlsForDispatch_remoteInsetsControllerControlsBars_appHasNoControl() { + mDisplayContent.setRemoteInsetsController(createDisplayWindowInsetsController()); + mDisplayContent.getInsetsPolicy().setRemoteInsetsControllerControlsSystemBars(true); addWindow(TYPE_STATUS_BAR, "statusBar"); addWindow(TYPE_NAVIGATION_BAR, "navBar"); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java index f52905ef6ae9..499bf668decf 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java @@ -60,24 +60,6 @@ public class WindowManagerServiceTests extends WindowTestsBase { @Rule public ExpectedException mExpectedException = ExpectedException.none(); - @Test - public void testForceShowSystemBarsThrowsExceptionForNonAutomotive() { - if (!isAutomotive()) { - mExpectedException.expect(UnsupportedOperationException.class); - - mWm.setForceShowSystemBars(true); - } - } - - @Test - public void testForceShowSystemBarsDoesNotThrowExceptionForAutomotiveWithStatusBarPermission() { - if (isAutomotive()) { - mExpectedException.none(); - - mWm.setForceShowSystemBars(true); - } - } - private boolean isAutomotive() { return getInstrumentation().getTargetContext().getPackageManager().hasSystemFeature( PackageManager.FEATURE_AUTOMOTIVE); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java index a1e5b80eb2ed..156298c86d41 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -41,11 +41,15 @@ import static org.mockito.Mockito.mock; import android.content.Context; import android.content.Intent; +import android.os.RemoteException; import android.os.UserHandle; import android.util.Log; import android.view.Display; import android.view.DisplayInfo; +import android.view.IDisplayWindowInsetsController; import android.view.IWindow; +import android.view.InsetsSourceControl; +import android.view.InsetsState; import android.view.SurfaceControl.Transaction; import android.view.View; import android.view.WindowManager; @@ -123,7 +127,7 @@ class WindowTestsBase extends SystemServiceTestsBase { mChildAppWindowBelow = createCommonWindow(mAppWindow, TYPE_APPLICATION_MEDIA_OVERLAY, "mChildAppWindowBelow"); - mDisplayContent.getDisplayPolicy().setForceShowSystemBars(false); + mDisplayContent.getInsetsPolicy().setRemoteInsetsControllerControlsSystemBars(false); // Adding a display will cause freezing the display. Make sure to wait until it's // unfrozen to not run into race conditions with the tests. @@ -344,6 +348,32 @@ class WindowTestsBase extends SystemServiceTestsBase { return createNewDisplay(displayInfo, false /* supportIme */); } + IDisplayWindowInsetsController createDisplayWindowInsetsController() { + return new IDisplayWindowInsetsController.Stub() { + + @Override + public void insetsChanged(InsetsState insetsState) throws RemoteException { + } + + @Override + public void insetsControlChanged(InsetsState insetsState, + InsetsSourceControl[] insetsSourceControls) throws RemoteException { + } + + @Override + public void showInsets(int i, boolean b) throws RemoteException { + } + + @Override + public void hideInsets(int i, boolean b) throws RemoteException { + } + + @Override + public void topFocusedWindowChanged(String packageName) { + } + }; + } + /** Sets the default minimum task size to 1 so that tests can use small task sizes */ void removeGlobalMinSizeRestriction() { mWm.mAtmService.mRootWindowContainer.mDefaultMinSizeOfResizeableTaskDp = 1; |