Merge changes from topic "p4_default_gestural_nav" into qt-dev
* changes: Defer applying gestural nav until the device is provisioned and user is setup Exposing default theme overlays to system callers
This commit is contained in:
@@ -152,4 +152,9 @@ interface IOverlayManager {
|
||||
* @param userId The user for which to change the overlay.
|
||||
*/
|
||||
boolean setLowestPriority(in String packageName, in int userId);
|
||||
|
||||
/**
|
||||
* Returns the list of default overlay packages, or an empty array if there are none.
|
||||
*/
|
||||
String[] getDefaultOverlayPackages();
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ import com.android.systemui.util.NotificationChannels;
|
||||
*/
|
||||
public class PipNotification {
|
||||
private static final String TAG = "PipNotification";
|
||||
private static final String NOTIFICATION_TAG = PipNotification.class.getName();
|
||||
private static final String NOTIFICATION_TAG = PipNotification.class.getSimpleName();
|
||||
private static final boolean DEBUG = PipManager.DEBUG;
|
||||
|
||||
private static final String ACTION_MENU = "PipNotification.menu";
|
||||
|
||||
@@ -53,7 +53,7 @@ import javax.inject.Singleton;
|
||||
@Singleton
|
||||
public class NavigationBarController implements Callbacks {
|
||||
|
||||
private static final String TAG = NavigationBarController.class.getName();
|
||||
private static final String TAG = NavigationBarController.class.getSimpleName();
|
||||
|
||||
private final Context mContext;
|
||||
private final Handler mHandler;
|
||||
|
||||
@@ -17,8 +17,10 @@
|
||||
package com.android.systemui.statusbar.phone;
|
||||
|
||||
import static android.content.Intent.ACTION_OVERLAY_CHANGED;
|
||||
import static android.content.Intent.ACTION_USER_SWITCHED;
|
||||
import static android.os.UserHandle.USER_CURRENT;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
@@ -28,16 +30,21 @@ import android.content.om.IOverlayManager;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.ApkAssets;
|
||||
import android.os.PatternMatcher;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.util.SparseBooleanArray;
|
||||
|
||||
import com.android.systemui.Dumpable;
|
||||
import com.android.systemui.UiOffloadThread;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@@ -48,7 +55,7 @@ import javax.inject.Singleton;
|
||||
@Singleton
|
||||
public class NavigationModeController implements Dumpable {
|
||||
|
||||
private static final String TAG = NavigationModeController.class.getName();
|
||||
private static final String TAG = NavigationModeController.class.getSimpleName();
|
||||
private static final boolean DEBUG = true;
|
||||
|
||||
public interface ModeChangedListener {
|
||||
@@ -57,6 +64,10 @@ public class NavigationModeController implements Dumpable {
|
||||
|
||||
private final Context mContext;
|
||||
private final IOverlayManager mOverlayManager;
|
||||
private final DeviceProvisionedController mDeviceProvisionedController;
|
||||
private final UiOffloadThread mUiOffloadThread;
|
||||
|
||||
private SparseBooleanArray mRestoreGesturalNavBarMode = new SparseBooleanArray();
|
||||
|
||||
private int mMode = NAV_BAR_MODE_3BUTTON;
|
||||
private ArrayList<ModeChangedListener> mListeners = new ArrayList<>();
|
||||
@@ -64,36 +75,90 @@ public class NavigationModeController implements Dumpable {
|
||||
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
context = getCurrentUserContext();
|
||||
int mode = getCurrentInteractionMode(context);
|
||||
mMode = mode;
|
||||
if (DEBUG) {
|
||||
Log.e(TAG, "ACTION_OVERLAY_CHANGED: mode=" + mMode
|
||||
+ " contextUser=" + context.getUserId());
|
||||
dumpAssetPaths(context);
|
||||
}
|
||||
|
||||
for (int i = 0; i < mListeners.size(); i++) {
|
||||
mListeners.get(i).onNavigationModeChanged(mode);
|
||||
if (intent.getAction().equals(ACTION_OVERLAY_CHANGED)) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "ACTION_OVERLAY_CHANGED");
|
||||
}
|
||||
updateCurrentInteractionMode(true /* notify */);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final DeviceProvisionedController.DeviceProvisionedListener mDeviceProvisionedCallback =
|
||||
new DeviceProvisionedController.DeviceProvisionedListener() {
|
||||
@Override
|
||||
public void onDeviceProvisionedChanged() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onDeviceProvisionedChanged: "
|
||||
+ mDeviceProvisionedController.isDeviceProvisioned());
|
||||
}
|
||||
// Once the device has been provisioned, check if we can restore gestural nav
|
||||
restoreGesturalNavOverlayIfNecessary();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserSetupChanged() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onUserSetupChanged: "
|
||||
+ mDeviceProvisionedController.isCurrentUserSetup());
|
||||
}
|
||||
// Once the user has been setup, check if we can restore gestural nav
|
||||
restoreGesturalNavOverlayIfNecessary();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserSwitched() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onUserSwitched: "
|
||||
+ ActivityManagerWrapper.getInstance().getCurrentUserId());
|
||||
}
|
||||
|
||||
// Update the nav mode for the current user
|
||||
updateCurrentInteractionMode(true /* notify */);
|
||||
|
||||
// When switching users, defer enabling the gestural nav overlay until the user
|
||||
// is all set up
|
||||
deferGesturalNavOverlayIfNecessary();
|
||||
}
|
||||
};
|
||||
|
||||
@Inject
|
||||
public NavigationModeController(Context context) {
|
||||
public NavigationModeController(Context context,
|
||||
DeviceProvisionedController deviceProvisionedController,
|
||||
UiOffloadThread uiOffloadThread) {
|
||||
mContext = context;
|
||||
mOverlayManager = IOverlayManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.OVERLAY_SERVICE));
|
||||
mUiOffloadThread = uiOffloadThread;
|
||||
mDeviceProvisionedController = deviceProvisionedController;
|
||||
mDeviceProvisionedController.addCallback(mDeviceProvisionedCallback);
|
||||
|
||||
IntentFilter overlayFilter = new IntentFilter(ACTION_OVERLAY_CHANGED);
|
||||
overlayFilter.addDataScheme("package");
|
||||
overlayFilter.addDataSchemeSpecificPart("android", PatternMatcher.PATTERN_LITERAL);
|
||||
mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, overlayFilter, null, null);
|
||||
|
||||
IntentFilter userFilter = new IntentFilter(ACTION_USER_SWITCHED);
|
||||
mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, userFilter, null, null);
|
||||
updateCurrentInteractionMode(false /* notify */);
|
||||
|
||||
mMode = getCurrentInteractionMode(getCurrentUserContext());
|
||||
// Check if we need to defer enabling gestural nav
|
||||
deferGesturalNavOverlayIfNecessary();
|
||||
}
|
||||
|
||||
public void updateCurrentInteractionMode(boolean notify) {
|
||||
Context context = getCurrentUserContext();
|
||||
int mode = getCurrentInteractionMode(context);
|
||||
mMode = mode;
|
||||
if (DEBUG) {
|
||||
Log.e(TAG, "updateCurrentInteractionMode: mode=" + mMode
|
||||
+ " contextUser=" + context.getUserId());
|
||||
dumpAssetPaths(context);
|
||||
}
|
||||
|
||||
if (notify) {
|
||||
for (int i = 0; i < mListeners.size(); i++) {
|
||||
mListeners.get(i).onNavigationModeChanged(mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int addListener(ModeChangedListener listener) {
|
||||
@@ -129,10 +194,77 @@ public class NavigationModeController implements Dumpable {
|
||||
}
|
||||
}
|
||||
|
||||
private void deferGesturalNavOverlayIfNecessary() {
|
||||
final int userId = mDeviceProvisionedController.getCurrentUser();
|
||||
mRestoreGesturalNavBarMode.put(userId, false);
|
||||
if (mDeviceProvisionedController.isDeviceProvisioned()
|
||||
&& mDeviceProvisionedController.isCurrentUserSetup()) {
|
||||
// User is already setup and device is provisioned, nothing to do
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "deferGesturalNavOverlayIfNecessary: device is provisioned and user is "
|
||||
+ "setup");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<String> defaultOverlays = new ArrayList<>();
|
||||
try {
|
||||
defaultOverlays.addAll(Arrays.asList(mOverlayManager.getDefaultOverlayPackages()));
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "deferGesturalNavOverlayIfNecessary: failed to fetch default overlays");
|
||||
}
|
||||
if (!defaultOverlays.contains(NAV_BAR_MODE_GESTURAL_OVERLAY)) {
|
||||
// No default gesture nav overlay
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "deferGesturalNavOverlayIfNecessary: no default gestural overlay, "
|
||||
+ "default=" + defaultOverlays);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If the default is gestural, force-enable three button mode until the device is
|
||||
// provisioned
|
||||
setModeOverlay(NAV_BAR_MODE_3BUTTON_OVERLAY, USER_CURRENT);
|
||||
mRestoreGesturalNavBarMode.put(userId, true);
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "deferGesturalNavOverlayIfNecessary: setting to 3 button mode");
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreGesturalNavOverlayIfNecessary() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "restoreGesturalNavOverlayIfNecessary: needs restore="
|
||||
+ mRestoreGesturalNavBarMode);
|
||||
}
|
||||
final int userId = mDeviceProvisionedController.getCurrentUser();
|
||||
if (mRestoreGesturalNavBarMode.get(userId)) {
|
||||
// Restore the gestural state if necessary
|
||||
setModeOverlay(NAV_BAR_MODE_GESTURAL_OVERLAY, USER_CURRENT);
|
||||
mRestoreGesturalNavBarMode.put(userId, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void setModeOverlay(String overlayPkg, int userId) {
|
||||
mUiOffloadThread.submit(() -> {
|
||||
try {
|
||||
mOverlayManager.setEnabledExclusiveInCategory(overlayPkg, userId);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to enable overlay " + overlayPkg + " for user " + userId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
pw.println("NavigationModeController:");
|
||||
pw.println(" mode=" + mMode);
|
||||
String defaultOverlays = "";
|
||||
try {
|
||||
defaultOverlays = String.join(", ", mOverlayManager.getDefaultOverlayPackages());
|
||||
} catch (RemoteException e) {
|
||||
defaultOverlays = "failed_to_fetch";
|
||||
}
|
||||
pw.println(" defaultOverlays=" + defaultOverlays);
|
||||
dumpAssetPaths(getCurrentUserContext());
|
||||
}
|
||||
|
||||
|
||||
@@ -719,6 +719,26 @@ public final class OverlayManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDefaultOverlayPackages() throws RemoteException {
|
||||
try {
|
||||
traceBegin(TRACE_TAG_RRO, "OMS#getDefaultOverlayPackages");
|
||||
getContext().enforceCallingOrSelfPermission(
|
||||
android.Manifest.permission.MODIFY_THEME_OVERLAY, null);
|
||||
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
return mImpl.getDefaultOverlayPackages();
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
} finally {
|
||||
traceEnd(TRACE_TAG_RRO);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShellCommand(@NonNull final FileDescriptor in,
|
||||
@NonNull final FileDescriptor out, @NonNull final FileDescriptor err,
|
||||
|
||||
@@ -641,6 +641,10 @@ final class OverlayManagerServiceImpl {
|
||||
pw.println("Default overlays: " + TextUtils.join(";", mDefaultOverlays));
|
||||
}
|
||||
|
||||
@NonNull String[] getDefaultOverlayPackages() {
|
||||
return mDefaultOverlays;
|
||||
}
|
||||
|
||||
List<String> getEnabledOverlayPackageNames(@NonNull final String targetPackageName,
|
||||
final int userId) {
|
||||
final List<OverlayInfo> overlays = mSettings.getOverlaysForTarget(targetPackageName,
|
||||
|
||||
Reference in New Issue
Block a user