Moving NavigationMode to display controller

Navigation mode affects display properties like bounds and
most listeners already had a similar display listener. This
will remove race conditions when managing the two events.

Bug: 221961069
Test: Presubmit
Change-Id: If7a22e006e6b969ecddf075001066809aa72995c
This commit is contained in:
Sunny Goyal
2022-03-04 10:49:01 -08:00
parent 1ffc81c7ba
commit 4403d078a6
31 changed files with 317 additions and 462 deletions

View File

@@ -15,11 +15,17 @@
*/
package com.android.launcher3.util;
import static android.content.Intent.ACTION_CONFIGURATION_CHANGED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static com.android.launcher3.ResourceUtils.INVALID_RESOURCE_HANDLE;
import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_2_BUTTON;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_3_BUTTON;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
import static com.android.launcher3.util.WindowManagerCompat.MIN_TABLET_WIDTH;
import static java.util.Collections.emptyMap;
@@ -29,7 +35,6 @@ import android.annotation.TargetApi;
import android.content.ComponentCallbacks;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
@@ -43,9 +48,12 @@ import android.view.Display;
import androidx.annotation.AnyThread;
import androidx.annotation.UiThread;
import com.android.launcher3.ResourceUtils;
import com.android.launcher3.Utilities;
import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
import com.android.launcher3.uioverrides.ApiWrapper;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Map;
import java.util.Objects;
@@ -66,9 +74,14 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
public static final int CHANGE_ROTATION = 1 << 1;
public static final int CHANGE_DENSITY = 1 << 2;
public static final int CHANGE_SUPPORTED_BOUNDS = 1 << 3;
public static final int CHANGE_NAVIGATION_MODE = 1 << 4;
public static final int CHANGE_ALL = CHANGE_ACTIVE_SCREEN | CHANGE_ROTATION
| CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS;
| CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS | CHANGE_NAVIGATION_MODE;
private static final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";
private static final String NAV_BAR_INTERACTION_MODE_RES_NAME = "config_navBarInteractionMode";
private static final String TARGET_OVERLAY_PACKAGE = "android";
private final Context mContext;
private final DisplayManager mDM;
@@ -79,6 +92,8 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
private DisplayInfoChangeListener mPriorityListener;
private final ArrayList<DisplayInfoChangeListener> mListeners = new ArrayList<>();
private final SimpleBroadcastReceiver mReceiver = new SimpleBroadcastReceiver(this::onIntent);
private Info mInfo;
private boolean mDestroyed = false;
@@ -92,11 +107,13 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
mWindowContext.registerComponentCallbacks(this);
} else {
mWindowContext = null;
SimpleBroadcastReceiver configChangeReceiver =
new SimpleBroadcastReceiver(this::onConfigChanged);
mContext.registerReceiver(configChangeReceiver,
new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED));
mReceiver.register(mContext, ACTION_CONFIGURATION_CHANGED);
}
// Initialize navigation mode change listener
mContext.registerReceiver(mReceiver,
getPackageFilter(TARGET_OVERLAY_PACKAGE, ACTION_OVERLAY_CHANGED));
mInfo = new Info(getDisplayInfoContext(display), display,
getInternalDisplays(mDM), emptyMap());
}
@@ -116,6 +133,13 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
return internalDisplays;
}
/**
* Returns the current navigation mode
*/
public static NavigationMode getNavigationMode(Context context) {
return INSTANCE.get(context).getInfo().navigationMode;
}
@Override
public void close() {
mDestroyed = true;
@@ -140,15 +164,20 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
void onDisplayInfoChanged(Context context, Info info, int flags);
}
/**
* Only used for pre-S
*/
private void onConfigChanged(Intent intent) {
private void onIntent(Intent intent) {
if (mDestroyed) {
return;
}
Configuration config = mContext.getResources().getConfiguration();
if (mInfo.fontScale != config.fontScale || mInfo.densityDpi != config.densityDpi) {
boolean reconfigure = false;
if (ACTION_OVERLAY_CHANGED.equals(intent.getAction())) {
reconfigure = true;
} else if (ACTION_CONFIGURATION_CHANGED.equals(intent.getAction())) {
Configuration config = mContext.getResources().getConfiguration();
reconfigure = mInfo.fontScale != config.fontScale
|| mInfo.densityDpi != config.densityDpi;
}
if (reconfigure) {
Log.d(TAG, "Configuration changed, notifying listeners");
Display display = mDM.getDisplay(DEFAULT_DISPLAY);
if (display != null) {
@@ -202,7 +231,8 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
Info newInfo = new Info(displayContext, display,
oldInfo.mInternalDisplays, oldInfo.mPerDisplayBounds);
if (newInfo.densityDpi != oldInfo.densityDpi || newInfo.fontScale != oldInfo.fontScale) {
if (newInfo.densityDpi != oldInfo.densityDpi || newInfo.fontScale != oldInfo.fontScale
|| newInfo.navigationMode != oldInfo.navigationMode) {
// Cache may not be valid anymore, recreate without cache
newInfo = new Info(displayContext, display, getInternalDisplays(mDM), emptyMap());
}
@@ -217,6 +247,9 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
if (newInfo.densityDpi != oldInfo.densityDpi || newInfo.fontScale != oldInfo.fontScale) {
change |= CHANGE_DENSITY;
}
if (newInfo.navigationMode != oldInfo.navigationMode) {
change |= CHANGE_NAVIGATION_MODE;
}
if (!newInfo.supportedBounds.equals(oldInfo.supportedBounds)) {
change |= CHANGE_SUPPORTED_BOUNDS;
@@ -247,7 +280,9 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
if (mPriorityListener != null) {
mPriorityListener.onDisplayInfoChanged(context, mInfo, flags);
}
for (int i = mListeners.size() - 1; i >= 0; i--) {
int count = mListeners.size();
for (int i = 0; i < count; i++) {
mListeners.get(i).onDisplayInfoChanged(context, mInfo, flags);
}
}
@@ -258,6 +293,7 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
public final int rotation;
public final float fontScale;
public final int densityDpi;
public final NavigationMode navigationMode;
private final PortraitSize mScreenSizeDp;
@@ -282,6 +318,7 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
fontScale = config.fontScale;
densityDpi = config.densityDpi;
mScreenSizeDp = new PortraitSize(config.screenHeightDp, config.screenWidthDp);
navigationMode = parseNavigationMode(context);
currentSize = new Point();
display.getRealSize(currentSize);
@@ -340,6 +377,21 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
}
}
/**
* Dumps the current state information
*/
public void dump(PrintWriter pw) {
Info info = mInfo;
pw.println("DisplayController.Info:");
pw.println(" id=" + info.displayId);
pw.println(" rotation=" + info.rotation);
pw.println(" fontScale=" + info.fontScale);
pw.println(" densityDpi=" + info.displayId);
pw.println(" navigationMode=" + info.navigationMode.name());
pw.println(" currentSize=" + info.currentSize);
pw.println(" supportedBounds=" + info.supportedBounds);
}
/**
* Utility class to hold a size information in an orientation independent way
*/
@@ -364,4 +416,36 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
return Objects.hash(width, height);
}
}
public enum NavigationMode {
THREE_BUTTONS(false, 0, LAUNCHER_NAVIGATION_MODE_3_BUTTON),
TWO_BUTTONS(true, 1, LAUNCHER_NAVIGATION_MODE_2_BUTTON),
NO_BUTTON(true, 2, LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON);
public final boolean hasGestures;
public final int resValue;
public final LauncherEvent launcherEvent;
NavigationMode(boolean hasGestures, int resValue, LauncherEvent launcherEvent) {
this.hasGestures = hasGestures;
this.resValue = resValue;
this.launcherEvent = launcherEvent;
}
}
private static NavigationMode parseNavigationMode(Context context) {
int modeInt = ResourceUtils.getIntegerByName(NAV_BAR_INTERACTION_MODE_RES_NAME,
context.getResources(), INVALID_RESOURCE_HANDLE);
if (modeInt == INVALID_RESOURCE_HANDLE) {
Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?");
} else {
for (NavigationMode m : NavigationMode.values()) {
if (m.resValue == modeInt) {
return m;
}
}
}
return Utilities.ATLEAST_S ? NavigationMode.NO_BUTTON : NavigationMode.THREE_BUTTONS;
}
}