diff --git a/cmds/svc/src/com/android/commands/svc/UsbCommand.java b/cmds/svc/src/com/android/commands/svc/UsbCommand.java
index 34f6d7d..adbe9d0 100644
--- a/cmds/svc/src/com/android/commands/svc/UsbCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/UsbCommand.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.hardware.usb.IUsbManager;
-import android.hardware.usb.UsbManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
@@ -39,9 +38,6 @@
                 + "\n"
                 + "usage: svc usb setFunction [function] [usbDataUnlocked=false]\n"
                 + "         Set the current usb function and optionally the data lock state.\n\n"
-                + "       svc usb setScreenUnlockedFunctions [function]\n"
-                + "         Sets the functions which, if the device was charging,"
-                    + " become current on screen unlock.\n"
                 + "       svc usb getFunction\n"
                 + "          Gets the list of currently enabled functions\n";
     }
@@ -66,16 +62,6 @@
             } else if ("getFunction".equals(args[1])) {
                 System.err.println(SystemProperties.get("sys.usb.config"));
                 return;
-            } else if ("setScreenUnlockedFunctions".equals(args[1])) {
-                IUsbManager usbMgr = IUsbManager.Stub.asInterface(ServiceManager.getService(
-                        Context.USB_SERVICE));
-                try {
-                    usbMgr.setScreenUnlockedFunctions((args.length >= 3 ? args[2] :
-                            UsbManager.USB_FUNCTION_NONE));
-                } catch (RemoteException e) {
-                    System.err.println("Error communicating with UsbManager: " + e);
-                }
-                return;
             }
         }
         System.err.println(longHelp());
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index f2160e1..c8d9839 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -268,11 +268,4 @@
      * @param token The IApplicationToken for the activity
      */
     public abstract void setFocusedActivity(IBinder token);
-
-    public interface ScreenObserver {
-        public void onAwakeStateChanged(boolean isAwake);
-        public void onKeyguardStateChanged(boolean isShowing);
-    }
-
-    public abstract void registerScreenObserver(ScreenObserver observer);
 }
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index 4e8c45d..025d46d 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -96,11 +96,6 @@
      */
     void setCurrentFunction(String function, boolean usbDataUnlocked);
 
-    /* Sets the screen unlocked USB function(s), which will be set automatically
-     * when the screen is unlocked.
-     */
-    void setScreenUnlockedFunctions(String function);
-
     /* Allow USB debugging from the attached host. If alwaysAllow is true, add the
      * the public key to list of host keys that the user has approved.
      */
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 48e8d34..d73d3d8 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -590,32 +590,6 @@
     }
 
     /**
-     * Sets the screen unlocked functions, which are persisted and set as the current functions
-     * whenever the screen is unlocked.
-     * <p>
-     * The allowed values are: {@link #USB_FUNCTION_NONE},
-     * {@link #USB_FUNCTION_MIDI}, {@link #USB_FUNCTION_MTP}, {@link #USB_FUNCTION_PTP},
-     * or {@link #USB_FUNCTION_RNDIS}.
-     * {@link #USB_FUNCTION_NONE} has the effect of switching off this feature, so functions
-     * no longer change on screen unlock.
-     * </p><p>
-     * Note: When the screen is on, this method will apply given functions as current functions,
-     * which is asynchronous and may fail silently without applying the requested changes.
-     * </p>
-     *
-     * @param function function to set as default
-     *
-     * {@hide}
-     */
-    public void setScreenUnlockedFunctions(String function) {
-        try {
-            mService.setScreenUnlockedFunctions(function);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Returns a list of physical USB ports on the device.
      * <p>
      * This list is guaranteed to contain all dual-role USB Type C ports but it might
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
index 13617f1..533771a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
@@ -265,9 +265,7 @@
         mStatusBarIconController.getTransitionsController().dump(fd, pw, args);
         pw.println();
         pw.println(" NavigationBarTransitionsController:");
-        if (mNavigationBarController != null) {
-            mNavigationBarController.dump(fd, pw, args);
-        }
+        mNavigationBarController.dump(fd, pw, args);
         pw.println();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index e467903..b08b26d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -49,6 +49,7 @@
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
 import com.android.systemui.SysUiServiceProvider;
+import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.VolumeDialogController;
 import com.android.systemui.qs.tiles.DndTile;
@@ -339,15 +340,11 @@
 
     private boolean shouldShowUI(int flags) {
         updateStatusBar();
-        // if status bar isn't null, check if phone is in AOD, else check flags
-        // since we could be using a different status bar
-        return mStatusBar != null ?
-                mStatusBar.getWakefulnessState() != WakefulnessLifecycle.WAKEFULNESS_ASLEEP
-                && mStatusBar.getWakefulnessState() !=
-                        WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP
+        return mStatusBar != null
+                && mStatusBar.getWakefulnessState() != WakefulnessLifecycle.WAKEFULNESS_ASLEEP
+                && mStatusBar.getWakefulnessState() != WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP
                 && mStatusBar.isDeviceInteractive()
-                && (flags & AudioManager.FLAG_SHOW_UI) != 0
-                : (flags & AudioManager.FLAG_SHOW_UI) != 0;
+                && (flags & AudioManager.FLAG_SHOW_UI) != 0;
     }
 
     boolean onVolumeChangedW(int stream, int flags) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 0cce2d9..3fc4f5e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -201,7 +201,6 @@
 import android.app.ActivityManager.TaskSnapshot;
 import android.app.ActivityManager.TaskThumbnailInfo;
 import android.app.ActivityManagerInternal;
-import android.app.ActivityManagerInternal.ScreenObserver;
 import android.app.ActivityManagerInternal.SleepToken;
 import android.app.ActivityOptions;
 import android.app.ActivityThread;
@@ -1558,8 +1557,6 @@
         }
     }
 
-    final List<ScreenObserver> mScreenObservers = new ArrayList<>();
-
     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
 
@@ -1701,8 +1698,6 @@
     static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
     static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
     static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
-    static final int DISPATCH_SCREEN_AWAKE_MSG = 71;
-    static final int DISPATCH_SCREEN_KEYGUARD_MSG = 72;
     static final int START_USER_SWITCH_FG_MSG = 712;
     static final int NOTIFY_VR_KEYGUARD_MSG = 74;
 
@@ -2426,17 +2421,11 @@
                     }
                 }
             } break;
-            case DISPATCH_SCREEN_AWAKE_MSG: {
-                final boolean isAwake = msg.arg1 != 0;
-                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
-                    mScreenObservers.get(i).onAwakeStateChanged(isAwake);
-                }
+            case NOTIFY_VR_SLEEPING_MSG: {
+                notifyVrManagerOfSleepState(msg.arg1 != 0);
             } break;
-            case DISPATCH_SCREEN_KEYGUARD_MSG: {
-                final boolean isShowing = msg.arg1 != 0;
-                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
-                    mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
-                }
+            case NOTIFY_VR_KEYGUARD_MSG: {
+                notifyVrManagerOfKeyguardState(msg.arg1 != 0);
             } break;
             case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
                 synchronized (ActivityManagerService.this) {
@@ -3280,6 +3269,32 @@
                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
     }
 
+    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
+        mHandler.sendMessage(
+                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
+    }
+
+    private void notifyVrManagerOfSleepState(boolean isSleeping) {
+        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
+        if (vrService == null) {
+            return;
+        }
+        vrService.onSleepStateChanged(isSleeping);
+    }
+
+    private void sendNotifyVrManagerOfKeyguardState(boolean isShowing) {
+        mHandler.sendMessage(
+                mHandler.obtainMessage(NOTIFY_VR_KEYGUARD_MSG, isShowing ? 1 : 0, 0));
+    }
+
+    private void notifyVrManagerOfKeyguardState(boolean isShowing) {
+        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
+        if (vrService == null) {
+            return;
+        }
+        vrService.onKeyguardStateChanged(isShowing);
+    }
+
     final void showAskCompatModeDialogLocked(ActivityRecord r) {
         Message msg = Message.obtain();
         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
@@ -12523,8 +12538,7 @@
             if (wasAwake != isAwake) {
                 // Also update state in a special way for running foreground services UI.
                 mServices.updateScreenStateLocked(isAwake);
-                mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
-                        .sendToTarget();
+                sendNotifyVrManagerOfSleepState(!isAwake);
             }
         }
     }
@@ -12677,9 +12691,7 @@
                 Binder.restoreCallingIdentity(ident);
             }
         }
-
-        mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, showing ? 1 : 0, 0)
-                .sendToTarget();
+        sendNotifyVrManagerOfKeyguardState(showing);
     }
 
     @Override
@@ -24335,11 +24347,6 @@
                 }
             }
         }
-
-        @Override
-        public void registerScreenObserver(ScreenObserver observer) {
-            mScreenObservers.add(observer);
-        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/vr/VrManagerInternal.java b/services/core/java/com/android/server/vr/VrManagerInternal.java
index 35b6ad3..7b1e12e 100644
--- a/services/core/java/com/android/server/vr/VrManagerInternal.java
+++ b/services/core/java/com/android/server/vr/VrManagerInternal.java
@@ -59,6 +59,13 @@
             int userId, int processId, @NonNull ComponentName calling);
 
     /**
+     * Set whether the system has acquired a sleep token.
+     *
+     * @param isAsleep is {@code true} if the device is asleep, or {@code false} otherwise.
+     */
+    public abstract void onSleepStateChanged(boolean isAsleep);
+
+    /**
      * Set whether the display used for VR output is on.
      *
      * @param isScreenOn is {@code true} if the display is on and can receive commands,
@@ -67,6 +74,13 @@
     public abstract void onScreenStateChanged(boolean isScreenOn);
 
     /**
+     * Set whether the keyguard is currently active/showing.
+     *
+     * @param isShowing is {@code true} if the keyguard is active/showing.
+     */
+    public abstract void onKeyguardStateChanged(boolean isShowing);
+
+    /**
      * Return NO_ERROR if the given package is installed on the device and enabled as a
      * VrListenerService for the given current user, or a negative error code indicating a failure.
      *
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index 56cacf4..b0fd248 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -19,7 +19,6 @@
 
 import android.Manifest;
 import android.app.ActivityManagerInternal;
-import android.app.ActivityManagerInternal.ScreenObserver;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.app.INotificationManager;
@@ -105,8 +104,7 @@
  *
  * @hide
  */
-public class VrManagerService extends SystemService
-        implements EnabledComponentChangeListener, ScreenObserver {
+public class VrManagerService extends SystemService implements EnabledComponentChangeListener{
 
     public static final String TAG = "VrManagerService";
     static final boolean DBG = false;
@@ -233,17 +231,15 @@
         }
     }
 
+    private void setSleepState(boolean isAsleep) {
+        setSystemState(FLAG_AWAKE, !isAsleep);
+    }
+
     private void setScreenOn(boolean isScreenOn) {
         setSystemState(FLAG_SCREEN_ON, isScreenOn);
     }
 
-    @Override
-    public void onAwakeStateChanged(boolean isAwake) {
-        setSystemState(FLAG_AWAKE, isAwake);
-    }
-
-    @Override
-    public void onKeyguardStateChanged(boolean isShowing) {
+    private void setKeyguardShowing(boolean isShowing) {
         setSystemState(FLAG_KEYGUARD_UNLOCKED, !isShowing);
     }
 
@@ -679,11 +675,21 @@
         }
 
         @Override
+        public void onSleepStateChanged(boolean isAsleep) {
+            VrManagerService.this.setSleepState(isAsleep);
+        }
+
+        @Override
         public void onScreenStateChanged(boolean isScreenOn) {
             VrManagerService.this.setScreenOn(isScreenOn);
         }
 
         @Override
+        public void onKeyguardStateChanged(boolean isShowing) {
+            VrManagerService.this.setKeyguardShowing(isShowing);
+        }
+
+        @Override
         public boolean isCurrentVrListener(String packageName, int userId) {
             return VrManagerService.this.isCurrentVrListener(packageName, userId);
         }
@@ -734,9 +740,6 @@
     @Override
     public void onBootPhase(int phase) {
         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
-            LocalServices.getService(ActivityManagerInternal.class)
-                    .registerScreenObserver(this);
-
             mNotificationManager = INotificationManager.Stub.asInterface(
                     ServiceManager.getService(Context.NOTIFICATION_SERVICE));
             synchronized (mLock) {
diff --git a/services/usb/Android.bp b/services/usb/Android.bp
index feb7b76..0cd9ac3 100644
--- a/services/usb/Android.bp
+++ b/services/usb/Android.bp
@@ -10,6 +10,5 @@
     static_libs: [
         "android.hardware.usb-V1.0-java",
         "android.hardware.usb-V1.1-java",
-        "android.hardware.usb.gadget-V1.0-java",
     ],
 }
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index e3e5e3e..1b057f9 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -16,9 +16,6 @@
 
 package com.android.server.usb;
 
-import android.app.ActivityManager;
-import android.app.ActivityManagerInternal;
-import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
@@ -29,7 +26,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.database.ContentObserver;
@@ -41,21 +37,12 @@
 import android.hardware.usb.UsbManager;
 import android.hardware.usb.UsbPort;
 import android.hardware.usb.UsbPortStatus;
-import android.hardware.usb.gadget.V1_0.GadgetFunction;
-import android.hardware.usb.gadget.V1_0.IUsbGadget;
-import android.hardware.usb.gadget.V1_0.IUsbGadgetCallback;
-import android.hardware.usb.gadget.V1_0.Status;
-import android.hidl.manager.V1_0.IServiceManager;
-import android.hidl.manager.V1_0.IServiceNotification;
 import android.os.BatteryManager;
-import android.os.Environment;
 import android.os.FileUtils;
 import android.os.Handler;
-import android.os.HwBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UEventObserver;
@@ -73,7 +60,6 @@
 import com.android.internal.os.SomeArgs;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.FgThread;
-import com.android.server.LocalServices;
 
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -83,24 +69,32 @@
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
-import java.util.NoSuchElementException;
 import java.util.Scanner;
 import java.util.Set;
-import java.util.StringJoiner;
 
 /**
  * UsbDeviceManager manages USB state in device mode.
  */
-public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver {
+public class UsbDeviceManager {
 
     private static final String TAG = "UsbDeviceManager";
     private static final boolean DEBUG = false;
 
     /**
-     * The SharedPreference setting per user that stores the screen unlocked functions between
-     * sessions.
+     * The persistent property which stores whether adb is enabled or not.
+     * May also contain vendor-specific default functions for testing purposes.
      */
-    private static final String UNLOCKED_CONFIG_PREF = "usb-screen-unlocked-config-%d";
+    private static final String USB_PERSISTENT_CONFIG_PROPERTY = "persist.sys.usb.config";
+
+    /**
+     * The non-persistent property which stores the current USB settings.
+     */
+    private static final String USB_CONFIG_PROPERTY = "sys.usb.config";
+
+    /**
+     * The non-persistent property which stores the current USB actual state.
+     */
+    private static final String USB_STATE_PROPERTY = "sys.usb.state";
 
     /**
      * ro.bootmode value when phone boots into usual Android.
@@ -134,12 +128,6 @@
     private static final int MSG_UPDATE_CHARGING_STATE = 9;
     private static final int MSG_UPDATE_HOST_STATE = 10;
     private static final int MSG_LOCALE_CHANGED = 11;
-    private static final int MSG_SET_SCREEN_UNLOCKED_FUNCTIONS = 12;
-    private static final int MSG_UPDATE_SCREEN_LOCK = 13;
-    private static final int MSG_SET_CHARGING_FUNCTIONS = 14;
-    private static final int MSG_SET_FUNCTIONS_TIMEOUT = 15;
-    private static final int MSG_GET_CURRENT_USB_FUNCTIONS = 16;
-    private static final int MSG_FUNCTION_SWITCH_TIMEOUT = 17;
 
     private static final int AUDIO_MODE_SOURCE = 1;
 
@@ -155,9 +143,9 @@
     private static final String BOOT_MODE_PROPERTY = "ro.bootmode";
 
     private static final String ADB_NOTIFICATION_CHANNEL_ID_TV = "usbdevicemanager.adb.tv";
+
     private UsbHandler mHandler;
     private boolean mBootCompleted;
-    private boolean mSystemReady;
 
     private final Object mLock = new Object();
 
@@ -173,6 +161,7 @@
     private boolean mMidiEnabled;
     private int mMidiCard;
     private int mMidiDevice;
+    private HashMap<String, HashMap<String, Pair<String, String>>> mOemModeMap;
     private String[] mAccessoryStrings;
     private UsbDebuggingManager mDebuggingManager;
     private final UsbAlsaManager mUsbAlsaManager;
@@ -180,7 +169,6 @@
     private Intent mBroadcastedIntent;
     private boolean mPendingBootBroadcast;
     private static Set<Integer> sBlackListedInterfaces;
-    private SharedPreferences mSettings;
 
     static {
         sBlackListedInterfaces = new HashSet<>();
@@ -229,31 +217,6 @@
         }
     };
 
-    @Override
-    public void onKeyguardStateChanged(boolean isShowing) {
-        int userHandle = ActivityManager.getCurrentUser();
-        boolean secure = mContext.getSystemService(KeyguardManager.class)
-                .isDeviceSecure(userHandle);
-        boolean unlocking = mContext.getSystemService(UserManager.class)
-                .isUserUnlockingOrUnlocked(userHandle);
-        if (DEBUG) {
-            Slog.v(TAG, "onKeyguardStateChanged: isShowing:" + isShowing + " secure:" + secure
-                    + " unlocking:" + unlocking + " user:" + userHandle);
-        }
-        // We are unlocked when the keyguard is down or non-secure, and user storage is unlocked.
-        mHandler.sendMessage(MSG_UPDATE_SCREEN_LOCK, (isShowing && secure) || !unlocking);
-    }
-
-    @Override
-    public void onAwakeStateChanged(boolean isAwake) {
-        // ignore
-    }
-
-    /** Called when a user is unlocked. */
-    public void onUnlockUser(int userHandle) {
-        onKeyguardStateChanged(false);
-    }
-
     public UsbDeviceManager(Context context, UsbAlsaManager alsaManager,
             UsbSettingsManager settingsManager) {
         mContext = context;
@@ -264,27 +227,9 @@
         mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY);
         initRndisAddress();
 
-        boolean halNotPresent = false;
-        try {
-            IUsbGadget.getService(true);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "USB GADGET HAL present but exception thrown", e);
-        } catch (NoSuchElementException e) {
-            halNotPresent = true;
-            Slog.i(TAG, "USB GADGET HAL not present in the device", e);
-        }
+        readOemUsbOverrideConfig();
 
-        if (halNotPresent) {
-            /**
-             * Initialze the legacy UsbHandler
-             */
-            mHandler = new UsbHandlerLegacy(FgThread.get().getLooper(), mContext);
-        } else {
-            /**
-             * Initialize HAL based UsbHandler
-             */
-            mHandler = new UsbHandlerHal(FgThread.get().getLooper());
-        }
+        mHandler = new UsbHandler(FgThread.get().getLooper());
 
         if (nativeIsStartRequested()) {
             if (DEBUG) Slog.d(TAG, "accessory attached at boot");
@@ -358,8 +303,6 @@
     public void systemReady() {
         if (DEBUG) Slog.d(TAG, "systemReady");
 
-        LocalServices.getService(ActivityManagerInternal.class).registerScreenObserver(this);
-
         mNotificationManager = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
 
@@ -382,6 +325,15 @@
         massStorageSupported = primary != null && primary.allowMassStorage();
         mUseUsbNotification = !massStorageSupported && mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_usbChargingMessage);
+
+        // make sure the ADB_ENABLED setting value matches the current state
+        try {
+            Settings.Global.putInt(mContentResolver,
+                    Settings.Global.ADB_ENABLED, mAdbEnabled ? 1 : 0);
+        } catch (SecurityException e) {
+            // If UserManager.DISALLOW_DEBUGGING_FEATURES is on, that this setting can't be changed.
+            Slog.d(TAG, "ADB_ENABLED is restricted.");
+        }
         mHandler.sendEmptyMessage(MSG_SYSTEM_READY);
     }
 
@@ -455,15 +407,7 @@
         return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
     }
 
-    private SharedPreferences getPinnedSharedPrefs(Context context) {
-        final File prefsFile = new File(new File(
-                Environment.getDataUserCePackageDirectory(StorageManager.UUID_PRIVATE_INTERNAL,
-                        context.getUserId(), context.getPackageName()), "shared_prefs"),
-                UsbDeviceManager.class.getSimpleName() + ".xml");
-        return context.getSharedPreferences(prefsFile, Context.MODE_PRIVATE);
-    }
-
-    private abstract class UsbHandler extends Handler {
+    private final class UsbHandler extends Handler {
 
         // current USB state
         private boolean mConnected;
@@ -471,53 +415,73 @@
         private boolean mSourcePower;
         private boolean mSinkPower;
         private boolean mConfigured;
-        protected boolean mUsbDataUnlocked;
+        private boolean mUsbDataUnlocked;
         private boolean mAudioAccessoryConnected;
         private boolean mAudioAccessorySupported;
-        protected String mCurrentFunctions;
-        protected boolean mCurrentFunctionsApplied;
+        private String mCurrentFunctions;
+        private boolean mCurrentFunctionsApplied;
         private UsbAccessory mCurrentAccessory;
         private int mUsbNotificationId;
         private boolean mAdbNotificationShown;
-        private int mCurrentUser;
+        private int mCurrentUser = UserHandle.USER_NULL;
         private boolean mUsbCharging;
+        private String mCurrentOemFunctions;
         private boolean mHideUsbNotification;
         private boolean mSupportsAllCombinations;
-        private String mScreenUnlockedFunctions = UsbManager.USB_FUNCTION_NONE;
-        private boolean mScreenLocked;
-        protected boolean mCurrentUsbFunctionsRequested;
-        protected boolean mCurrentUsbFunctionsReceived;
-
-        /**
-         * The persistent property which stores whether adb is enabled or not.
-         * May also contain vendor-specific default functions for testing purposes.
-         */
-        protected static final String USB_PERSISTENT_CONFIG_PROPERTY = "persist.sys.usb.config";
 
         public UsbHandler(Looper looper) {
             super(looper);
+            try {
+                // Restore default functions.
 
-            mCurrentUser = ActivityManager.getCurrentUser();
-            mScreenLocked = true;
+                mCurrentOemFunctions = SystemProperties.get(UsbDeviceManager.getPersistProp(false),
+                        UsbManager.USB_FUNCTION_NONE);
+                if (isNormalBoot()) {
+                    mCurrentFunctions = SystemProperties.get(USB_CONFIG_PROPERTY,
+                            UsbManager.USB_FUNCTION_NONE);
+                    mCurrentFunctionsApplied = mCurrentFunctions.equals(
+                            SystemProperties.get(USB_STATE_PROPERTY));
+                } else {
+                    mCurrentFunctions = SystemProperties.get(getPersistProp(true),
+                            UsbManager.USB_FUNCTION_NONE);
+                    mCurrentFunctionsApplied = SystemProperties.get(USB_CONFIG_PROPERTY,
+                            UsbManager.USB_FUNCTION_NONE).equals(
+                            SystemProperties.get(USB_STATE_PROPERTY));
+                }
 
-            /*
-             * Use the normal bootmode persistent prop to maintain state of adb across
-             * all boot modes.
-             */
-            mAdbEnabled = UsbManager.containsFunction(
-                    SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY),
-                    UsbManager.USB_FUNCTION_ADB);
+                /*
+                 * Use the normal bootmode persistent prop to maintain state of adb across
+                 * all boot modes.
+                 */
+                mAdbEnabled = UsbManager.containsFunction(
+                        SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY),
+                        UsbManager.USB_FUNCTION_ADB);
 
-            /*
-             * Previous versions can set persist config to mtp/ptp but it does not
-             * get reset on OTA. Reset the property here instead.
-             */
-            String persisted = SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY);
-            if (UsbManager.containsFunction(persisted, UsbManager.USB_FUNCTION_MTP)
-                    || UsbManager.containsFunction(persisted, UsbManager.USB_FUNCTION_PTP)) {
-                SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY,
-                        UsbManager.removeFunction(UsbManager.removeFunction(persisted,
-                                UsbManager.USB_FUNCTION_MTP), UsbManager.USB_FUNCTION_PTP));
+                /*
+                 * Previous versions can set persist config to mtp/ptp but it does not
+                 * get reset on OTA. Reset the property here instead.
+                 */
+                String persisted = SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY);
+                if (UsbManager.containsFunction(persisted, UsbManager.USB_FUNCTION_MTP)
+                        || UsbManager.containsFunction(persisted, UsbManager.USB_FUNCTION_PTP)) {
+                    SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY,
+                            UsbManager.removeFunction(UsbManager.removeFunction(persisted,
+                                    UsbManager.USB_FUNCTION_MTP), UsbManager.USB_FUNCTION_PTP));
+                }
+
+                String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
+                updateState(state);
+
+                // register observer to listen for settings changes
+                mContentResolver.registerContentObserver(
+                        Settings.Global.getUriFor(Settings.Global.ADB_ENABLED),
+                        false, new AdbSettingsObserver());
+
+                // Watch for USB configuration changes
+                mUEventObserver.startObserving(USB_STATE_MATCH);
+                mUEventObserver.startObserving(ACCESSORY_START_MATCH);
+            } catch (Exception e) {
+                Slog.e(TAG, "Error initializing UsbHandler", e);
             }
         }
 
@@ -543,21 +507,6 @@
             sendMessage(m);
         }
 
-        public void sendMessage(int what, boolean arg1, boolean arg2) {
-            removeMessages(what);
-            Message m = Message.obtain(this, what);
-            m.arg1 = (arg1 ? 1 : 0);
-            m.arg2 = (arg2 ? 1 : 0);
-            sendMessage(m);
-        }
-
-        public void sendMessageDelayed(int what, boolean arg, long delayMillis) {
-            removeMessages(what);
-            Message m = Message.obtain(this, what);
-            m.arg1 = (arg ? 1 : 0);
-            sendMessageDelayed(m, delayMillis);
-        }
-
         public void updateState(String state) {
             int connected, configured;
 
@@ -575,7 +524,6 @@
                 return;
             }
             removeMessages(MSG_UPDATE_STATE);
-            if (connected == 1) removeMessages(MSG_FUNCTION_SWITCH_TIMEOUT);
             Message msg = Message.obtain(this, MSG_UPDATE_STATE);
             msg.arg1 = connected;
             msg.arg2 = configured;
@@ -598,6 +546,28 @@
             sendMessageDelayed(msg, UPDATE_DELAY);
         }
 
+        private boolean waitForState(String state) {
+            // wait for the transition to complete.
+            // give up after 1 second.
+            String value = null;
+            for (int i = 0; i < 20; i++) {
+                // State transition is done when sys.usb.state is set to the new configuration
+                value = SystemProperties.get(USB_STATE_PROPERTY);
+                if (state.equals(value)) return true;
+                SystemClock.sleep(50);
+            }
+            Slog.e(TAG, "waitForState(" + state + ") FAILED: got " + value);
+            return false;
+        }
+
+        private void setUsbConfig(String config) {
+            if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")");
+            // set the new configuration
+            // we always set it due to b/23631400, where adbd was getting killed
+            // and not restarted due to property timeouts on some devices
+            SystemProperties.set(USB_CONFIG_PROPERTY, config);
+        }
+
         private void setAdbEnabled(boolean enable) {
             if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable);
             if (enable != mAdbEnabled) {
@@ -624,7 +594,114 @@
             }
         }
 
-        protected String applyAdbFunction(String functions) {
+        /**
+         * Evaluates USB function policies and applies the change accordingly.
+         */
+        private void setEnabledFunctions(String functions, boolean forceRestart,
+                boolean usbDataUnlocked) {
+            if (DEBUG) {
+                Slog.d(TAG, "setEnabledFunctions functions=" + functions + ", "
+                        + "forceRestart=" + forceRestart + ", usbDataUnlocked=" + usbDataUnlocked);
+            }
+
+            if (usbDataUnlocked != mUsbDataUnlocked) {
+                mUsbDataUnlocked = usbDataUnlocked;
+                updateUsbNotification(false);
+                forceRestart = true;
+            }
+
+            // Try to set the enabled functions.
+            final String oldFunctions = mCurrentFunctions;
+            final boolean oldFunctionsApplied = mCurrentFunctionsApplied;
+            if (trySetEnabledFunctions(functions, forceRestart)) {
+                return;
+            }
+
+            // Didn't work.  Try to revert changes.
+            // We always reapply the policy in case certain constraints changed such as
+            // user restrictions independently of any other new functions we were
+            // trying to activate.
+            if (oldFunctionsApplied && !oldFunctions.equals(functions)) {
+                Slog.e(TAG, "Failsafe 1: Restoring previous USB functions.");
+                if (trySetEnabledFunctions(oldFunctions, false)) {
+                    return;
+                }
+            }
+
+            // Still didn't work.  Try to restore the default functions.
+            Slog.e(TAG, "Failsafe 2: Restoring default USB functions.");
+            if (trySetEnabledFunctions(null, false)) {
+                return;
+            }
+
+            // Now we're desperate.  Ignore the default functions.
+            // Try to get ADB working if enabled.
+            Slog.e(TAG, "Failsafe 3: Restoring empty function list (with ADB if enabled).");
+            if (trySetEnabledFunctions(UsbManager.USB_FUNCTION_NONE, false)) {
+                return;
+            }
+
+            // Ouch.
+            Slog.e(TAG, "Unable to set any USB functions!");
+        }
+
+        private boolean isNormalBoot() {
+            String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown");
+            return bootMode.equals(NORMAL_BOOT) || bootMode.equals("unknown");
+        }
+
+        private boolean trySetEnabledFunctions(String functions, boolean forceRestart) {
+            if (functions == null || applyAdbFunction(functions)
+                    .equals(UsbManager.USB_FUNCTION_NONE)) {
+                functions = getDefaultFunctions();
+            }
+            functions = applyAdbFunction(functions);
+
+            String oemFunctions = applyOemOverrideFunction(functions);
+
+            if (!isNormalBoot() && !mCurrentFunctions.equals(functions)) {
+                SystemProperties.set(getPersistProp(true), functions);
+            }
+
+            if ((!functions.equals(oemFunctions) &&
+                            !mCurrentOemFunctions.equals(oemFunctions))
+                    || !mCurrentFunctions.equals(functions)
+                    || !mCurrentFunctionsApplied
+                    || forceRestart) {
+                Slog.i(TAG, "Setting USB config to " + functions);
+                mCurrentFunctions = functions;
+                mCurrentOemFunctions = oemFunctions;
+                mCurrentFunctionsApplied = false;
+
+                // Kick the USB stack to close existing connections.
+                setUsbConfig(UsbManager.USB_FUNCTION_NONE);
+
+                if (!waitForState(UsbManager.USB_FUNCTION_NONE)) {
+                    Slog.e(TAG, "Failed to kick USB config");
+                    return false;
+                }
+
+                // Set the new USB configuration.
+                setUsbConfig(oemFunctions);
+
+                if (mBootCompleted
+                        && (UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_MTP)
+                        || UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_PTP))) {
+                    // Start up dependent services.
+                    updateUsbStateBroadcastIfNeeded(true);
+                }
+
+                if (!waitForState(oemFunctions)) {
+                    Slog.e(TAG, "Failed to switch USB config to " + functions);
+                    return false;
+                }
+
+                mCurrentFunctionsApplied = true;
+            }
+            return true;
+        }
+
+        private String applyAdbFunction(String functions) {
             // Do not pass null pointer to the UsbManager.
             // There isnt a check there.
             if (functions == null) {
@@ -706,7 +783,7 @@
             return false;
         }
 
-        protected void updateUsbStateBroadcastIfNeeded(boolean configChanged) {
+        private void updateUsbStateBroadcastIfNeeded(boolean configChanged) {
             // send a sticky broadcast containing current USB state
             Intent intent = new Intent(UsbManager.ACTION_USB_STATE);
             intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
@@ -799,14 +876,6 @@
                     mMidiEnabled && mConfigured, mMidiCard, mMidiDevice);
         }
 
-        private void setScreenUnlockedFunctions() {
-            setEnabledFunctions(mScreenUnlockedFunctions, false,
-                    UsbManager.containsFunction(mScreenUnlockedFunctions,
-                            UsbManager.USB_FUNCTION_MTP)
-                            || UsbManager.containsFunction(mScreenUnlockedFunctions,
-                            UsbManager.USB_FUNCTION_PTP));
-        }
-
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
@@ -824,16 +893,9 @@
                         updateCurrentAccessory();
                     }
                     if (mBootCompleted) {
-                        if (!mConnected && !hasMessages(MSG_ACCESSORY_MODE_ENTER_TIMEOUT)
-                                && !hasMessages(MSG_FUNCTION_SWITCH_TIMEOUT)) {
+                        if (!mConnected && !hasMessages(MSG_ACCESSORY_MODE_ENTER_TIMEOUT)) {
                             // restore defaults when USB is disconnected
-                            if (!mScreenLocked
-                                    && !UsbManager.USB_FUNCTION_NONE.equals(
-                                    mScreenUnlockedFunctions)) {
-                                setScreenUnlockedFunctions();
-                            } else {
-                                setEnabledFunctions(null, !mAdbEnabled, false);
-                            }
+                            setEnabledFunctions(null, !mAdbEnabled, false);
                         }
                         updateUsbFunctions();
                     } else {
@@ -916,47 +978,6 @@
                     String functions = (String) msg.obj;
                     setEnabledFunctions(functions, false, msg.arg1 == 1);
                     break;
-                case MSG_SET_SCREEN_UNLOCKED_FUNCTIONS:
-                    mScreenUnlockedFunctions = (String) msg.obj;
-                    SharedPreferences.Editor editor = mSettings.edit();
-                    editor.putString(String.format(Locale.ENGLISH, UNLOCKED_CONFIG_PREF,
-                            mCurrentUser), mScreenUnlockedFunctions);
-                    editor.commit();
-                    if (!mScreenLocked && !UsbManager.USB_FUNCTION_NONE.equals(
-                            mScreenUnlockedFunctions)) {
-                        // If the screen is unlocked, also set current functions.
-                        setScreenUnlockedFunctions();
-                    }
-                    break;
-                case MSG_UPDATE_SCREEN_LOCK:
-                    if (msg.arg1 == 1 == mScreenLocked) {
-                        break;
-                    }
-                    mScreenLocked = msg.arg1 == 1;
-                    if (mSettings == null && !mScreenLocked) {
-                        // Shared preferences aren't accessible until the user has been unlocked.
-                        mSettings = getPinnedSharedPrefs(mContext);
-                        mScreenUnlockedFunctions = mSettings.getString(
-                                String.format(Locale.ENGLISH, UNLOCKED_CONFIG_PREF, mCurrentUser),
-                                UsbManager.USB_FUNCTION_NONE);
-                    }
-                    if (!mBootCompleted) {
-                        break;
-                    }
-                    if (mScreenLocked) {
-                        if (!mConnected) {
-                            setEnabledFunctions(null, false, false);
-                        }
-                    } else {
-                        if (!UsbManager.USB_FUNCTION_NONE.equals(mScreenUnlockedFunctions)
-                                && (UsbManager.USB_FUNCTION_ADB.equals(mCurrentFunctions)
-                                || (UsbManager.USB_FUNCTION_MTP.equals(mCurrentFunctions)
-                                && !mUsbDataUnlocked))) {
-                            // Set the screen unlocked functions if current function is charging.
-                            setScreenUnlockedFunctions();
-                        }
-                    }
-                    break;
                 case MSG_UPDATE_USER_RESTRICTIONS:
                     // Restart the USB stack if USB transfer is enabled but no longer allowed.
                     final boolean forceRestart = mUsbDataUnlocked
@@ -966,8 +987,9 @@
                             mCurrentFunctions, forceRestart, mUsbDataUnlocked && !forceRestart);
                     break;
                 case MSG_SYSTEM_READY:
-                    mSystemReady = true;
-                    finishBoot();
+                    updateUsbNotification(false);
+                    updateAdbNotification(false);
+                    updateUsbFunctions();
                     break;
                 case MSG_LOCALE_CHANGED:
                     updateAdbNotification(true);
@@ -975,19 +997,30 @@
                     break;
                 case MSG_BOOT_COMPLETED:
                     mBootCompleted = true;
-                    finishBoot();
+                    if (mPendingBootBroadcast) {
+                        updateUsbStateBroadcastIfNeeded(false);
+                        mPendingBootBroadcast = false;
+                    }
+                    setEnabledFunctions(null, false, false);
+                    if (mCurrentAccessory != null) {
+                        getCurrentSettings().accessoryAttached(mCurrentAccessory);
+                    }
+                    if (mDebuggingManager != null) {
+                        mDebuggingManager.setAdbEnabled(mAdbEnabled);
+                    }
                     break;
                 case MSG_USER_SWITCHED: {
                     if (mCurrentUser != msg.arg1) {
-                        if (DEBUG) {
-                            Slog.v(TAG, "Current user switched to " + msg.arg1);
+                        // Restart the USB stack and re-apply user restrictions for MTP or PTP.
+                        if (mUsbDataUnlocked
+                                && isUsbDataTransferActive()
+                                && mCurrentUser != UserHandle.USER_NULL) {
+                            Slog.v(TAG, "Current user switched to " + msg.arg1
+                                    + "; resetting USB host stack for MTP or PTP");
+                            // avoid leaking sensitive data from previous user
+                            setEnabledFunctions(null, true, false);
                         }
                         mCurrentUser = msg.arg1;
-                        mScreenLocked = true;
-                        mScreenUnlockedFunctions = mSettings.getString(
-                                String.format(Locale.ENGLISH, UNLOCKED_CONFIG_PREF, mCurrentUser),
-                                UsbManager.USB_FUNCTION_NONE);
-                        setEnabledFunctions(null, false, false);
                     }
                     break;
                 }
@@ -1005,41 +1038,6 @@
             }
         }
 
-        protected void finishBoot() {
-            if (mBootCompleted && mCurrentUsbFunctionsReceived && mSystemReady) {
-                if (mPendingBootBroadcast) {
-                    updateUsbStateBroadcastIfNeeded(false);
-                    mPendingBootBroadcast = false;
-                }
-                if (!mScreenLocked
-                        && !UsbManager.USB_FUNCTION_NONE.equals(mScreenUnlockedFunctions)) {
-                    setScreenUnlockedFunctions();
-                } else {
-                    setEnabledFunctions(null, false, false);
-                }
-                if (mCurrentAccessory != null) {
-                    getCurrentSettings().accessoryAttached(mCurrentAccessory);
-                }
-                if (mDebuggingManager != null) {
-                    mDebuggingManager.setAdbEnabled(mAdbEnabled);
-                }
-
-                // make sure the ADB_ENABLED setting value matches the current state
-                try {
-                    Settings.Global.putInt(mContentResolver,
-                            Settings.Global.ADB_ENABLED, mAdbEnabled ? 1 : 0);
-                } catch (SecurityException e) {
-                    // If UserManager.DISALLOW_DEBUGGING_FEATURES is on, that this setting can't
-                    // be changed.
-                    Slog.d(TAG, "ADB_ENABLED is restricted.");
-                }
-
-                updateUsbNotification(false);
-                updateAdbNotification(false);
-                updateUsbFunctions();
-            }
-        }
-
         private boolean isUsbDataTransferActive() {
             return UsbManager.containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP)
                     || UsbManager.containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_PTP);
@@ -1049,7 +1047,7 @@
             return mCurrentAccessory;
         }
 
-        protected void updateUsbNotification(boolean force) {
+        private void updateUsbNotification(boolean force) {
             if (mNotificationManager == null || !mUseUsbNotification
                     || ("0".equals(SystemProperties.get("persist.charging.notify")))) {
                 return;
@@ -1074,12 +1072,20 @@
                 titleRes = com.android.internal.R.string.usb_unsupported_audio_accessory_title;
                 id = SystemMessage.NOTE_USB_AUDIO_ACCESSORY_NOT_SUPPORTED;
             } else if (mConnected) {
-                if (UsbManager.containsFunction(mCurrentFunctions,
-                        UsbManager.USB_FUNCTION_MTP) && mUsbDataUnlocked) {
+                if (!mUsbDataUnlocked) {
+                    if (mSourcePower) {
+                        titleRes = com.android.internal.R.string.usb_supplying_notification_title;
+                        id = SystemMessage.NOTE_USB_SUPPLYING;
+                    } else {
+                        titleRes = com.android.internal.R.string.usb_charging_notification_title;
+                        id = SystemMessage.NOTE_USB_CHARGING;
+                    }
+                } else if (UsbManager.containsFunction(mCurrentFunctions,
+                        UsbManager.USB_FUNCTION_MTP)) {
                     titleRes = com.android.internal.R.string.usb_mtp_notification_title;
                     id = SystemMessage.NOTE_USB_MTP;
                 } else if (UsbManager.containsFunction(mCurrentFunctions,
-                        UsbManager.USB_FUNCTION_PTP) && mUsbDataUnlocked) {
+                        UsbManager.USB_FUNCTION_PTP)) {
                     titleRes = com.android.internal.R.string.usb_ptp_notification_title;
                     id = SystemMessage.NOTE_USB_PTP;
                 } else if (UsbManager.containsFunction(mCurrentFunctions,
@@ -1149,18 +1155,18 @@
                     }
 
                     Notification.Builder builder = new Notification.Builder(mContext, channel)
-                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
-                            .setWhen(0)
-                            .setOngoing(true)
-                            .setTicker(title)
-                            .setDefaults(0)  // please be quiet
-                            .setColor(mContext.getColor(
-                                    com.android.internal.R.color
-                                            .system_notification_accent_color))
-                            .setContentTitle(title)
-                            .setContentText(message)
-                            .setContentIntent(pi)
-                            .setVisibility(Notification.VISIBILITY_PUBLIC);
+                                    .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
+                                    .setWhen(0)
+                                    .setOngoing(true)
+                                    .setTicker(title)
+                                    .setDefaults(0)  // please be quiet
+                                    .setColor(mContext.getColor(
+                                            com.android.internal.R.color
+                                                    .system_notification_accent_color))
+                                    .setContentTitle(title)
+                                    .setContentText(message)
+                                    .setContentIntent(pi)
+                                    .setVisibility(Notification.VISIBILITY_PUBLIC);
 
                     if (titleRes
                             == com.android.internal.R.string
@@ -1178,7 +1184,7 @@
             }
         }
 
-        protected void updateAdbNotification(boolean force) {
+        private void updateAdbNotification(boolean force) {
             if (mNotificationManager == null) return;
             final int id = SystemMessage.NOTE_ADB_ACTIVE;
             final int titleRes = com.android.internal.R.string.adb_active_notification_title;
@@ -1230,26 +1236,23 @@
             }
         }
 
-        protected String getChargingFunctions() {
+        private String getDefaultFunctions() {
+            String func = SystemProperties.get(getPersistProp(true),
+                    UsbManager.USB_FUNCTION_NONE);
             // if ADB is enabled, reset functions to ADB
             // else enable MTP as usual.
-            if (mAdbEnabled) {
+            if (UsbManager.containsFunction(func, UsbManager.USB_FUNCTION_ADB)) {
                 return UsbManager.USB_FUNCTION_ADB;
             } else {
                 return UsbManager.USB_FUNCTION_MTP;
             }
         }
 
-        public boolean isFunctionEnabled(String function) {
-            return UsbManager.containsFunction(mCurrentFunctions, function);
-        }
-
         public void dump(IndentingPrintWriter pw) {
             pw.println("USB Device State:");
             pw.println("  mCurrentFunctions: " + mCurrentFunctions);
+            pw.println("  mCurrentOemFunctions: " + mCurrentOemFunctions);
             pw.println("  mCurrentFunctionsApplied: " + mCurrentFunctionsApplied);
-            pw.println("  mScreenUnlockedFunctions: " + mScreenUnlockedFunctions);
-            pw.println("  mScreenLocked: " + mScreenLocked);
             pw.println("  mConnected: " + mConnected);
             pw.println("  mConfigured: " + mConfigured);
             pw.println("  mUsbDataUnlocked: " + mUsbDataUnlocked);
@@ -1260,7 +1263,6 @@
             pw.println("  mUsbCharging: " + mUsbCharging);
             pw.println("  mHideUsbNotification: " + mHideUsbNotification);
             pw.println("  mAudioAccessoryConnected: " + mAudioAccessoryConnected);
-            pw.println("  mAdbEnabled: " + mAdbEnabled);
 
             try {
                 pw.println("  Kernel state: "
@@ -1271,675 +1273,6 @@
                 pw.println("IOException: " + e);
             }
         }
-
-        /**
-         * Evaluates USB function policies and applies the change accordingly.
-         */
-        protected abstract void setEnabledFunctions(String functions, boolean forceRestart,
-                boolean usbDataUnlocked);
-
-    }
-
-    private final class UsbHandlerLegacy extends UsbHandler {
-        /**
-         * The non-persistent property which stores the current USB settings.
-         */
-        private static final String USB_CONFIG_PROPERTY = "sys.usb.config";
-
-        /**
-         * The non-persistent property which stores the current USB actual state.
-         */
-        private static final String USB_STATE_PROPERTY = "sys.usb.state";
-
-        private HashMap<String, HashMap<String, Pair<String, String>>> mOemModeMap;
-        private String mCurrentOemFunctions;
-
-        UsbHandlerLegacy(Looper looper, Context context) {
-            super(looper);
-            try {
-                readOemUsbOverrideConfig(context);
-                // Restore default functions.
-                mCurrentOemFunctions = SystemProperties.get(getPersistProp(false),
-                        UsbManager.USB_FUNCTION_NONE);
-                if (isNormalBoot()) {
-                    mCurrentFunctions = SystemProperties.get(USB_CONFIG_PROPERTY,
-                            UsbManager.USB_FUNCTION_NONE);
-                    mCurrentFunctionsApplied = mCurrentFunctions.equals(
-                            SystemProperties.get(USB_STATE_PROPERTY));
-                } else {
-                    mCurrentFunctions = SystemProperties.get(getPersistProp(true),
-                            UsbManager.USB_FUNCTION_NONE);
-                    mCurrentFunctionsApplied = SystemProperties.get(USB_CONFIG_PROPERTY,
-                            UsbManager.USB_FUNCTION_NONE).equals(
-                            SystemProperties.get(USB_STATE_PROPERTY));
-                }
-                mCurrentUsbFunctionsReceived = true;
-
-                String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
-                updateState(state);
-
-                // register observer to listen for settings changes
-                mContentResolver.registerContentObserver(
-                        Settings.Global.getUriFor(Settings.Global.ADB_ENABLED),
-                        false, new AdbSettingsObserver());
-
-                // Watch for USB configuration changes
-                mUEventObserver.startObserving(USB_STATE_MATCH);
-                mUEventObserver.startObserving(ACCESSORY_START_MATCH);
-            } catch (Exception e) {
-                Slog.e(TAG, "Error initializing UsbHandler", e);
-            }
-        }
-
-        private void readOemUsbOverrideConfig(Context context) {
-            String[] configList = mContext.getResources().getStringArray(
-                    com.android.internal.R.array.config_oemUsbModeOverride);
-
-            if (configList != null) {
-                for (String config : configList) {
-                    String[] items = config.split(":");
-                    if (items.length == 3 || items.length == 4) {
-                        if (mOemModeMap == null) {
-                            mOemModeMap = new HashMap<>();
-                        }
-                        HashMap<String, Pair<String, String>> overrideMap =
-                                mOemModeMap.get(items[0]);
-                        if (overrideMap == null) {
-                            overrideMap = new HashMap<>();
-                            mOemModeMap.put(items[0], overrideMap);
-                        }
-
-                        // Favoring the first combination if duplicate exists
-                        if (!overrideMap.containsKey(items[1])) {
-                            if (items.length == 3) {
-                                overrideMap.put(items[1], new Pair<>(items[2], ""));
-                            } else {
-                                overrideMap.put(items[1], new Pair<>(items[2], items[3]));
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        private String applyOemOverrideFunction(String usbFunctions) {
-            if ((usbFunctions == null) || (mOemModeMap == null)) {
-                return usbFunctions;
-            }
-
-            String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown");
-            Slog.d(TAG, "applyOemOverride usbfunctions=" + usbFunctions + " bootmode=" + bootMode);
-
-            Map<String, Pair<String, String>> overridesMap =
-                    mOemModeMap.get(bootMode);
-            // Check to ensure that the oem is not overriding in the normal
-            // boot mode
-            if (overridesMap != null && !(bootMode.equals(NORMAL_BOOT)
-                    || bootMode.equals("unknown"))) {
-                Pair<String, String> overrideFunctions =
-                        overridesMap.get(usbFunctions);
-                if (overrideFunctions != null) {
-                    Slog.d(TAG, "OEM USB override: " + usbFunctions
-                            + " ==> " + overrideFunctions.first
-                            + " persist across reboot "
-                            + overrideFunctions.second);
-                    if (!overrideFunctions.second.equals("")) {
-                        String newFunction;
-                        if (mAdbEnabled) {
-                            newFunction = UsbManager.addFunction(overrideFunctions.second,
-                                    UsbManager.USB_FUNCTION_ADB);
-                        } else {
-                            newFunction = overrideFunctions.second;
-                        }
-                        Slog.d(TAG, "OEM USB override persisting: " + newFunction + "in prop: "
-                                + getPersistProp(false));
-                        SystemProperties.set(getPersistProp(false),
-                                newFunction);
-                    }
-                    return overrideFunctions.first;
-                } else if (mAdbEnabled) {
-                    String newFunction = UsbManager.addFunction(UsbManager.USB_FUNCTION_NONE,
-                            UsbManager.USB_FUNCTION_ADB);
-                    SystemProperties.set(getPersistProp(false),
-                            newFunction);
-                } else {
-                    SystemProperties.set(getPersistProp(false),
-                            UsbManager.USB_FUNCTION_NONE);
-                }
-            }
-            // return passed in functions as is.
-            return usbFunctions;
-        }
-
-        private boolean waitForState(String state) {
-            // wait for the transition to complete.
-            // give up after 1 second.
-            String value = null;
-            for (int i = 0; i < 20; i++) {
-                // State transition is done when sys.usb.state is set to the new configuration
-                value = SystemProperties.get(USB_STATE_PROPERTY);
-                if (state.equals(value)) return true;
-                SystemClock.sleep(50);
-            }
-            Slog.e(TAG, "waitForState(" + state + ") FAILED: got " + value);
-            return false;
-        }
-
-        private void setUsbConfig(String config) {
-            if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")");
-            /**
-             * set the new configuration
-             * we always set it due to b/23631400, where adbd was getting killed
-             * and not restarted due to property timeouts on some devices
-             */
-            SystemProperties.set(USB_CONFIG_PROPERTY, config);
-        }
-
-        @Override
-        protected void setEnabledFunctions(String functions, boolean forceRestart,
-                boolean usbDataUnlocked) {
-            if (DEBUG) {
-                Slog.d(TAG, "setEnabledFunctions functions=" + functions + ", "
-                        + "forceRestart=" + forceRestart + ", usbDataUnlocked=" + usbDataUnlocked);
-            }
-
-            if (usbDataUnlocked != mUsbDataUnlocked) {
-                mUsbDataUnlocked = usbDataUnlocked;
-                updateUsbNotification(false);
-                forceRestart = true;
-            }
-
-            /**
-             * Try to set the enabled functions.
-             */
-            final String oldFunctions = mCurrentFunctions;
-            final boolean oldFunctionsApplied = mCurrentFunctionsApplied;
-            if (trySetEnabledFunctions(functions, forceRestart)) {
-                return;
-            }
-
-            /**
-             * Didn't work.  Try to revert changes.
-             * We always reapply the policy in case certain constraints changed such as
-             * user restrictions independently of any other new functions we were
-             * trying to activate.
-             */
-            if (oldFunctionsApplied && !oldFunctions.equals(functions)) {
-                Slog.e(TAG, "Failsafe 1: Restoring previous USB functions.");
-                if (trySetEnabledFunctions(oldFunctions, false)) {
-                    return;
-                }
-            }
-
-            /**
-             * Still didn't work.  Try to restore the default functions.
-             */
-            Slog.e(TAG, "Failsafe 2: Restoring default USB functions.");
-            if (trySetEnabledFunctions(null, false)) {
-                return;
-            }
-
-            /**
-             * Now we're desperate.  Ignore the default functions.
-             * Try to get ADB working if enabled.
-             */
-            Slog.e(TAG, "Failsafe 3: Restoring empty function list (with ADB if enabled).");
-            if (trySetEnabledFunctions(UsbManager.USB_FUNCTION_NONE, false)) {
-                return;
-            }
-
-            /**
-             * Ouch.
-             */
-            Slog.e(TAG, "Unable to set any USB functions!");
-        }
-
-        private boolean isNormalBoot() {
-            String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown");
-            return bootMode.equals(NORMAL_BOOT) || bootMode.equals("unknown");
-        }
-
-        private boolean trySetEnabledFunctions(String functions, boolean forceRestart) {
-            if (functions == null || applyAdbFunction(functions)
-                    .equals(UsbManager.USB_FUNCTION_NONE)) {
-                functions = getChargingFunctions();
-            }
-            functions = applyAdbFunction(functions);
-
-            String oemFunctions = applyOemOverrideFunction(functions);
-
-            if (!isNormalBoot() && !mCurrentFunctions.equals(functions)) {
-                SystemProperties.set(getPersistProp(true), functions);
-            }
-
-            if ((!functions.equals(oemFunctions)
-                    && !mCurrentOemFunctions.equals(oemFunctions))
-                    || !mCurrentFunctions.equals(functions)
-                    || !mCurrentFunctionsApplied
-                    || forceRestart) {
-                Slog.i(TAG, "Setting USB config to " + functions);
-                mCurrentFunctions = functions;
-                mCurrentOemFunctions = oemFunctions;
-                mCurrentFunctionsApplied = false;
-
-                /**
-                 * Kick the USB stack to close existing connections.
-                 */
-                setUsbConfig(UsbManager.USB_FUNCTION_NONE);
-
-                if (!waitForState(UsbManager.USB_FUNCTION_NONE)) {
-                    Slog.e(TAG, "Failed to kick USB config");
-                    return false;
-                }
-
-                /**
-                 * Set the new USB configuration.
-                 */
-                setUsbConfig(oemFunctions);
-
-                if (mBootCompleted
-                        && (UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_MTP)
-                        || UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_PTP))) {
-                    /**
-                     * Start up dependent services.
-                     */
-                    updateUsbStateBroadcastIfNeeded(true);
-                }
-
-                if (!waitForState(oemFunctions)) {
-                    Slog.e(TAG, "Failed to switch USB config to " + functions);
-                    return false;
-                }
-
-                mCurrentFunctionsApplied = true;
-            }
-            return true;
-        }
-
-        private String getPersistProp(boolean functions) {
-            String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown");
-            String persistProp = USB_PERSISTENT_CONFIG_PROPERTY;
-            if (!(bootMode.equals(NORMAL_BOOT) || bootMode.equals("unknown"))) {
-                if (functions) {
-                    persistProp = "persist.sys.usb." + bootMode + ".func";
-                } else {
-                    persistProp = "persist.sys.usb." + bootMode + ".config";
-                }
-            }
-            return persistProp;
-        }
-    }
-
-    private final class UsbHandlerHal extends UsbHandler {
-
-        /**
-         * Proxy object for the usb gadget hal daemon.
-         */
-        @GuardedBy("mGadgetProxyLock")
-        private IUsbGadget mGadgetProxy;
-
-        private final Object mGadgetProxyLock = new Object();
-
-        /**
-         * Cookie sent for usb gadget hal death notification.
-         */
-        private static final int USB_GADGET_HAL_DEATH_COOKIE = 2000;
-
-        /**
-         * Keeps track of the latest setCurrentUsbFunctions request number.
-         */
-        private int mCurrentRequest = 0;
-
-        /**
-         * The maximum time for which the UsbDeviceManager would wait once
-         * setCurrentUsbFunctions is called.
-         */
-        private static final int SET_FUNCTIONS_TIMEOUT_MS = 3000;
-
-        /**
-         * Conseration leeway to make sure that the hal callback arrives before
-         * SET_FUNCTIONS_TIMEOUT_MS expires. If the callback does not arrive
-         * within SET_FUNCTIONS_TIMEOUT_MS, UsbDeviceManager retries enabling
-         * default functions.
-         */
-        private static final int SET_FUNCTIONS_LEEWAY_MS = 500;
-
-        /**
-         * While switching functions, a disconnect is excpect as the usb gadget
-         * us torn down and brought back up. Wait for SET_FUNCTIONS_TIMEOUT_MS +
-         * ENUMERATION_TIME_OUT_MS before switching back to default fumctions when
-         * switching functions.
-         */
-        private static final int ENUMERATION_TIME_OUT_MS = 2000;
-
-        /**
-         * Command to start native service.
-         */
-        protected static final String CTL_START = "ctl.start";
-
-        /**
-         * Command to start native service.
-         */
-        protected static final String CTL_STOP = "ctl.stop";
-
-        /**
-         * Adb natvie daemon
-         */
-        protected static final String ADBD = "adbd";
-
-
-        UsbHandlerHal(Looper looper) {
-            super(looper);
-            try {
-                ServiceNotification serviceNotification = new ServiceNotification();
-
-                boolean ret = IServiceManager.getService()
-                        .registerForNotifications("android.hardware.usb.gadget@1.0::IUsbGadget",
-                                "", serviceNotification);
-                if (!ret) {
-                    Slog.e(TAG, "Failed to register usb gadget service start notification");
-                    return;
-                }
-
-                synchronized (mGadgetProxyLock) {
-                    mGadgetProxy = IUsbGadget.getService(true);
-                    mGadgetProxy.linkToDeath(new UsbGadgetDeathRecipient(),
-                            USB_GADGET_HAL_DEATH_COOKIE);
-                    mCurrentFunctions = UsbManager.USB_FUNCTION_NONE;
-                    mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback());
-                    mCurrentUsbFunctionsRequested = true;
-                }
-                String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
-                updateState(state);
-
-                /**
-                 * Register observer to listen for settings changes.
-                 */
-                mContentResolver.registerContentObserver(
-                        Settings.Global.getUriFor(Settings.Global.ADB_ENABLED),
-                        false, new AdbSettingsObserver());
-
-                /**
-                 * Watch for USB configuration changes.
-                 */
-                mUEventObserver.startObserving(USB_STATE_MATCH);
-                mUEventObserver.startObserving(ACCESSORY_START_MATCH);
-            } catch (NoSuchElementException e) {
-                Slog.e(TAG, "Usb gadget hal not found", e);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Usb Gadget hal not responding", e);
-            } catch (Exception e) {
-                Slog.e(TAG, "Error initializing UsbHandler", e);
-            }
-        }
-
-
-        final class UsbGadgetDeathRecipient implements HwBinder.DeathRecipient {
-            @Override
-            public void serviceDied(long cookie) {
-                if (cookie == USB_GADGET_HAL_DEATH_COOKIE) {
-                    Slog.e(TAG, "Usb Gadget hal service died cookie: " + cookie);
-                    synchronized (mGadgetProxyLock) {
-                        mGadgetProxy = null;
-                    }
-                }
-            }
-        }
-
-        final class ServiceNotification extends IServiceNotification.Stub {
-            @Override
-            public void onRegistration(String fqName, String name, boolean preexisting) {
-                Slog.i(TAG, "Usb gadget hal service started " + fqName + " " + name);
-                synchronized (mGadgetProxyLock) {
-                    try {
-                        mGadgetProxy = IUsbGadget.getService();
-                        mGadgetProxy.linkToDeath(new UsbGadgetDeathRecipient(),
-                                USB_GADGET_HAL_DEATH_COOKIE);
-                        if (!mCurrentFunctionsApplied) {
-                            setCurrentFunctions(mCurrentFunctions, mUsbDataUnlocked);
-                        }
-                    } catch (NoSuchElementException e) {
-                        Slog.e(TAG, "Usb gadget hal not found", e);
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "Usb Gadget hal not responding", e);
-                    }
-                }
-            }
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_SET_CHARGING_FUNCTIONS:
-                    setEnabledFunctions(null, false, mUsbDataUnlocked);
-                    break;
-                case MSG_SET_FUNCTIONS_TIMEOUT:
-                    Slog.e(TAG, "Set functions timed out! no reply from usb hal");
-                    if (msg.arg1 != 1) {
-                        setEnabledFunctions(null, false, mUsbDataUnlocked);
-                    }
-                    break;
-                case MSG_GET_CURRENT_USB_FUNCTIONS:
-                    Slog.e(TAG, "prcessing MSG_GET_CURRENT_USB_FUNCTIONS");
-                    mCurrentUsbFunctionsReceived = true;
-
-                    if (mCurrentUsbFunctionsRequested) {
-                        Slog.e(TAG, "updating mCurrentFunctions");
-                        mCurrentFunctions = functionListToString((Long) msg.obj);
-                        Slog.e(TAG,
-                                "mCurrentFunctions:" + mCurrentFunctions + "applied:" + msg.arg1);
-                        mCurrentFunctionsApplied = msg.arg1 == 1;
-                    }
-                    finishBoot();
-                    break;
-                case MSG_FUNCTION_SWITCH_TIMEOUT:
-                    /**
-                     * Dont force to default when the configuration is already set to default.
-                     */
-                    if (msg.arg1 != 1) {
-                        setEnabledFunctions(null, !mAdbEnabled, false);
-                    }
-                    break;
-                default:
-                    super.handleMessage(msg);
-            }
-        }
-
-        private class UsbGadgetCallback extends IUsbGadgetCallback.Stub {
-            int mRequest;
-            long mFunctions;
-            boolean mChargingFunctions;
-
-            UsbGadgetCallback() {
-            }
-
-            UsbGadgetCallback(int request, long functions,
-                    boolean chargingFunctions) {
-                mRequest = request;
-                mFunctions = functions;
-                mChargingFunctions = chargingFunctions;
-            }
-
-            @Override
-            public void setCurrentUsbFunctionsCb(long functions,
-                    int status) {
-                /**
-                 * Callback called for a previous setCurrenUsbFunction
-                 */
-                if ((mCurrentRequest != mRequest) || !hasMessages(MSG_SET_FUNCTIONS_TIMEOUT)
-                        || (mFunctions != functions)) {
-                    return;
-                }
-
-                removeMessages(MSG_SET_FUNCTIONS_TIMEOUT);
-                Slog.e(TAG, "notifyCurrentFunction request:" + mRequest + " status:" + status);
-                if (status == Status.SUCCESS) {
-                    mCurrentFunctionsApplied = true;
-                } else if (!mChargingFunctions) {
-                    Slog.e(TAG, "Setting default fuctions");
-                    sendEmptyMessage(MSG_SET_CHARGING_FUNCTIONS);
-                }
-            }
-
-            @Override
-            public void getCurrentUsbFunctionsCb(long functions,
-                    int status) {
-                sendMessage(MSG_GET_CURRENT_USB_FUNCTIONS, functions,
-                        status == Status.FUNCTIONS_APPLIED);
-            }
-        }
-
-        private long stringToFunctionList(String config) {
-            long functionsMask = 0;
-            String[] functions = config.split(",");
-            for (int i = 0; i < functions.length; i++) {
-                switch (functions[i]) {
-                    case "none":
-                        functionsMask |= GadgetFunction.NONE;
-                        break;
-                    case "adb":
-                        functionsMask |= GadgetFunction.ADB;
-                        break;
-                    case "mtp":
-                        functionsMask |= GadgetFunction.MTP;
-                        break;
-                    case "ptp":
-                        functionsMask |= GadgetFunction.PTP;
-                        break;
-                    case "midi":
-                        functionsMask |= GadgetFunction.MIDI;
-                        break;
-                    case "accessory":
-                        functionsMask |= GadgetFunction.ACCESSORY;
-                        break;
-                    case "rndis":
-                        functionsMask |= GadgetFunction.RNDIS;
-                        break;
-                }
-            }
-            return functionsMask;
-        }
-
-        private String functionListToString(Long functionList) {
-            StringJoiner functions = new StringJoiner(",");
-            if (functionList == GadgetFunction.NONE) {
-                functions.add("none");
-                return functions.toString();
-            }
-            if ((functionList & GadgetFunction.ADB) != 0) {
-                functions.add("adb");
-            }
-            if ((functionList & GadgetFunction.MTP) != 0) {
-                functions.add("mtp");
-            }
-            if ((functionList & GadgetFunction.PTP) != 0) {
-                functions.add("ptp");
-            }
-            if ((functionList & GadgetFunction.MIDI) != 0) {
-                functions.add("midi");
-            }
-            if ((functionList & GadgetFunction.ACCESSORY) != 0) {
-                functions.add("accessory");
-            }
-            if ((functionList & GadgetFunction.RNDIS) != 0) {
-                functions.add("rndis");
-            }
-            /**
-             * Remove the trailing comma.
-             */
-            return functions.toString();
-        }
-
-
-        private void setUsbConfig(String config, boolean chargingFunctions) {
-            Long functions = stringToFunctionList(config);
-            if (true) Slog.d(TAG, "setUsbConfig(" + config + ") request:" + ++mCurrentRequest);
-            /**
-             * Cancel any ongoing requests, if present.
-             */
-            removeMessages(MSG_FUNCTION_SWITCH_TIMEOUT);
-            removeMessages(MSG_SET_FUNCTIONS_TIMEOUT);
-            removeMessages(MSG_SET_CHARGING_FUNCTIONS);
-
-            synchronized (mGadgetProxyLock) {
-                if (mGadgetProxy == null) {
-                    Slog.e(TAG, "setUsbConfig mGadgetProxy is null");
-                    return;
-                }
-                try {
-                    if ((functions & GadgetFunction.ADB) != 0) {
-                        /**
-                         * Start adbd if ADB function is included in the configuration.
-                         */
-                        SystemProperties.set(CTL_START, ADBD);
-                    } else {
-                        /**
-                         * Stop adbd otherwise.
-                         */
-                        SystemProperties.set(CTL_STOP, ADBD);
-                    }
-                    UsbGadgetCallback usbGadgetCallback = new UsbGadgetCallback(mCurrentRequest,
-                            functions, chargingFunctions);
-                    mGadgetProxy.setCurrentUsbFunctions(functions, usbGadgetCallback,
-                            SET_FUNCTIONS_TIMEOUT_MS - SET_FUNCTIONS_LEEWAY_MS);
-                    sendMessageDelayed(MSG_SET_FUNCTIONS_TIMEOUT, chargingFunctions,
-                            SET_FUNCTIONS_TIMEOUT_MS);
-                    sendMessageDelayed(MSG_FUNCTION_SWITCH_TIMEOUT, chargingFunctions,
-                            SET_FUNCTIONS_TIMEOUT_MS + ENUMERATION_TIME_OUT_MS);
-                    if (DEBUG) Slog.d(TAG, "timeout message queued");
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Remoteexception while calling setCurrentUsbFunctions", e);
-                }
-            }
-        }
-
-        @Override
-        protected void setEnabledFunctions(String functions, boolean forceRestart,
-                boolean usbDataUnlocked) {
-            if (DEBUG) {
-                Slog.d(TAG, "setEnabledFunctions functions=" + functions + ", "
-                        + "forceRestart=" + forceRestart + ", usbDataUnlocked=" + usbDataUnlocked);
-            }
-
-            if (usbDataUnlocked != mUsbDataUnlocked) {
-                mUsbDataUnlocked = usbDataUnlocked;
-                updateUsbNotification(false);
-                forceRestart = true;
-            }
-
-            trySetEnabledFunctions(functions, forceRestart);
-        }
-
-        private void trySetEnabledFunctions(String functions, boolean forceRestart) {
-            boolean chargingFunctions = false;
-
-            if (functions == null || applyAdbFunction(functions)
-                    .equals(UsbManager.USB_FUNCTION_NONE)) {
-                functions = getChargingFunctions();
-                chargingFunctions = true;
-            }
-            functions = applyAdbFunction(functions);
-
-            if (!mCurrentFunctions.equals(functions)
-                    || !mCurrentFunctionsApplied
-                    || forceRestart) {
-                Slog.i(TAG, "Setting USB config to " + functions);
-                mCurrentFunctions = functions;
-                mCurrentFunctionsApplied = false;
-                // set the flag to false as that would be stale value
-                mCurrentUsbFunctionsRequested = false;
-
-                // Set the new USB configuration.
-                setUsbConfig(mCurrentFunctions, chargingFunctions);
-
-                if (mBootCompleted
-                        && (UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_MTP)
-                        || UsbManager.containsFunction(functions, UsbManager.USB_FUNCTION_PTP))) {
-                    // Start up dependent services.
-                    updateUsbStateBroadcastIfNeeded(true);
-                }
-            }
-        }
     }
 
     /* returns the currently attached USB accessory */
@@ -1947,11 +1280,7 @@
         return mHandler.getCurrentAccessory();
     }
 
-    /**
-     * opens the currently attached USB accessory.
-     *
-     * @param accessory accessory to be openened.
-     */
+    /* opens the currently attached USB accessory */
     public ParcelFileDescriptor openAccessory(UsbAccessory accessory,
             UsbUserSettingsManager settings) {
         UsbAccessory currentAccessory = mHandler.getCurrentAccessory();
@@ -1968,41 +1297,113 @@
         return nativeOpenAccessory();
     }
 
-    /**
-     * Checks whether the function is present in the USB configuration.
-     *
-     * @param function function to be checked.
-     */
     public boolean isFunctionEnabled(String function) {
-        return mHandler.isFunctionEnabled(function);
+        return UsbManager.containsFunction(SystemProperties.get(USB_CONFIG_PROPERTY), function);
     }
 
-    /**
-     * Adds function to the current USB configuration.
-     *
-     * @param functions name of the USB function, or null to restore the default function.
-     * @param usbDataUnlocked whether user data is accessible.
-     */
     public void setCurrentFunctions(String functions, boolean usbDataUnlocked) {
         if (DEBUG) {
-            Slog.d(TAG, "setCurrentFunctions(" + functions + ", "
-                    + usbDataUnlocked + ")");
+            Slog.d(TAG, "setCurrentFunctions(" + functions + ", " +
+                    usbDataUnlocked + ")");
         }
         mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, usbDataUnlocked);
     }
 
-    /**
-     * Sets the functions which are set when the screen is unlocked.
-     *
-     * @param functions Functions to set.
-     */
-    public void setScreenUnlockedFunctions(String functions) {
-        if (DEBUG) {
-            Slog.d(TAG, "setScreenUnlockedFunctions(" + functions + ")");
+    private void readOemUsbOverrideConfig() {
+        String[] configList = mContext.getResources().getStringArray(
+                com.android.internal.R.array.config_oemUsbModeOverride);
+
+        if (configList != null) {
+            for (String config : configList) {
+                String[] items = config.split(":");
+                if (items.length == 3 || items.length == 4) {
+                    if (mOemModeMap == null) {
+                        mOemModeMap = new HashMap<>();
+                    }
+                    HashMap<String, Pair<String, String>> overrideMap
+                            = mOemModeMap.get(items[0]);
+                    if (overrideMap == null) {
+                        overrideMap = new HashMap<>();
+                        mOemModeMap.put(items[0], overrideMap);
+                    }
+
+                    // Favoring the first combination if duplicate exists
+                    if (!overrideMap.containsKey(items[1])) {
+                        if (items.length == 3) {
+                            overrideMap.put(items[1], new Pair<>(items[2], ""));
+                        } else {
+                            overrideMap.put(items[1], new Pair<>(items[2], items[3]));
+                        }
+                    }
+                }
+            }
         }
-        mHandler.sendMessage(MSG_SET_SCREEN_UNLOCKED_FUNCTIONS, functions);
     }
 
+    private String applyOemOverrideFunction(String usbFunctions) {
+        if ((usbFunctions == null) || (mOemModeMap == null)) {
+            return usbFunctions;
+        }
+
+        String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown");
+        Slog.d(TAG, "applyOemOverride usbfunctions=" + usbFunctions + " bootmode=" + bootMode);
+
+        Map<String, Pair<String, String>> overridesMap =
+                mOemModeMap.get(bootMode);
+        // Check to ensure that the oem is not overriding in the normal
+        // boot mode
+        if (overridesMap != null && !(bootMode.equals(NORMAL_BOOT) ||
+                bootMode.equals("unknown"))) {
+            Pair<String, String> overrideFunctions =
+                    overridesMap.get(usbFunctions);
+            if (overrideFunctions != null) {
+                Slog.d(TAG, "OEM USB override: " + usbFunctions
+                        + " ==> " + overrideFunctions.first
+                        + " persist across reboot "
+                        + overrideFunctions.second);
+                if (!overrideFunctions.second.equals("")) {
+                    String newFunction;
+                    if (mAdbEnabled) {
+                        newFunction = UsbManager.addFunction(overrideFunctions.second,
+                                UsbManager.USB_FUNCTION_ADB);
+                    } else {
+                        newFunction = overrideFunctions.second;
+                    }
+                    Slog.d(TAG, "OEM USB override persisting: " + newFunction + "in prop: "
+                            + UsbDeviceManager.getPersistProp(false));
+                    SystemProperties.set(UsbDeviceManager.getPersistProp(false),
+                            newFunction);
+                }
+                return overrideFunctions.first;
+            } else if (mAdbEnabled) {
+                String newFunction = UsbManager.addFunction(UsbManager.USB_FUNCTION_NONE,
+                        UsbManager.USB_FUNCTION_ADB);
+                SystemProperties.set(UsbDeviceManager.getPersistProp(false),
+                        newFunction);
+            } else {
+                SystemProperties.set(UsbDeviceManager.getPersistProp(false),
+                        UsbManager.USB_FUNCTION_NONE);
+            }
+        }
+        // return passed in functions as is.
+        return usbFunctions;
+    }
+
+    public static String getPersistProp(boolean functions) {
+        String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown");
+        String persistProp = USB_PERSISTENT_CONFIG_PROPERTY;
+        if (!(bootMode.equals(NORMAL_BOOT) || bootMode.equals("unknown"))) {
+            if (functions) {
+                persistProp = "persist.sys.usb." + bootMode + ".func";
+            } else {
+                persistProp = "persist.sys.usb." + bootMode + ".config";
+            }
+        }
+
+        return persistProp;
+    }
+
+
     public void allowUsbDebugging(boolean alwaysAllow, String publicKey) {
         if (mDebuggingManager != null) {
             mDebuggingManager.allowUsbDebugging(alwaysAllow, publicKey);
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index 039597c..e4fcea7 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -87,11 +87,6 @@
         public void onStopUser(int userHandle) {
             mUsbService.onStopUser(UserHandle.of(userHandle));
         }
-
-        @Override
-        public void onUnlockUser(int userHandle) {
-            mUsbService.onUnlockUser(userHandle);
-        }
     }
 
     private static final String TAG = "UsbService";
@@ -210,13 +205,6 @@
         }
     }
 
-    /** Called when a user is unlocked. */
-    public void onUnlockUser(int user) {
-        if (mDeviceManager != null) {
-            mDeviceManager.onUnlockUser(user);
-        }
-    }
-
     /* Returns a list of all currently attached USB devices (host mdoe) */
     @Override
     public void getDeviceList(Bundle devices) {
@@ -401,23 +389,6 @@
         }
     }
 
-    @Override
-    public void setScreenUnlockedFunctions(String function) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
-
-        if (!isSupportedCurrentFunction(function)) {
-            Slog.w(TAG, "Caller of setScreenUnlockedFunctions() requested unsupported USB function:"
-                    + function);
-            function = UsbManager.USB_FUNCTION_NONE;
-        }
-
-        if (mDeviceManager != null) {
-            mDeviceManager.setScreenUnlockedFunctions(function);
-        } else {
-            throw new IllegalStateException("USB device mode not supported");
-        }
-    }
-
     private static boolean isSupportedCurrentFunction(String function) {
         if (function == null) return true;
 
