Introduce a new user restriction for disallowing Bluetooth.

Only the device owner will be able to set the restriction
and the restriction will prevent usage of Bluetooth on the
entire device - i.e. in all the users.

Test: cts-tradefed run cts -m CtsDevicePolicyManagerTestCases --test com.android.cts.devicepolicy.UserRestrictionsTest
Test: cts-tradefed run cts -m CtsDevicePolicyManagerTestCases --test com.android.cts.devicepolicy.DeviceOwnerTest#testBluetoothRestriction

Bug: 32895300

Merged-In: I2875cf178cb16eca1965d0ba965d1cd3d8db2ad5

Change-Id: I2875cf178cb16eca1965d0ba965d1cd3d8db2ad5
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index aa6afdf..75b2dd4 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -39,6 +39,7 @@
 import android.content.pm.UserInfo;
 import android.database.ContentObserver;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -49,6 +50,8 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.UserManagerInternal;
+import android.os.UserManagerInternal.UserRestrictionsListener;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
 import android.util.Slog;
@@ -172,6 +175,19 @@
         }
     };
 
+    private final UserRestrictionsListener mUserRestrictionsListener =
+            new UserRestrictionsListener() {
+        @Override
+        public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
+                Bundle prevRestrictions) {
+            final boolean bluetoothDisallowed =
+                    newRestrictions.getBoolean(UserManager.DISALLOW_BLUETOOTH);
+            if ((mEnable || mEnableExternal) && bluetoothDisallowed) {
+                disable(true);
+            }
+        }
+    };
+
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -621,6 +637,13 @@
 
     public boolean enableNoAutoConnect()
     {
+        if (isBluetoothDisallowed()) {
+            if (DBG) {
+                Slog.d(TAG, "enableNoAutoConnect(): not enabling - bluetooth disallowed");
+            }
+            return false;
+        }
+
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                                                 "Need BLUETOOTH ADMIN permission");
 
@@ -643,6 +666,13 @@
     }
 
     public boolean enable() {
+        if (isBluetoothDisallowed()) {
+            if (DBG) {
+                Slog.d(TAG,"enable(): not enabling - bluetooth disallowed");
+            }
+            return false;
+        }
+
         if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
             (!checkIfCallerIsForegroundUser())) {
             Slog.w(TAG,"enable(): not allowed for non-active and non system user");
@@ -804,6 +834,12 @@
      */
     public void handleOnBootPhase() {
         if (DBG) Slog.d(TAG, "Bluetooth boot completed");
+        UserManagerInternal userManagerInternal =
+                LocalServices.getService(UserManagerInternal.class);
+        userManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
+        if (isBluetoothDisallowed()) {
+            return;
+        }
         if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) {
             if (DBG) Slog.d(TAG, "Auto-enabling Bluetooth.");
             sendEnableMsg(mQuietEnableExternal);
@@ -1846,6 +1882,16 @@
         }
     }
 
+    private boolean isBluetoothDisallowed() {
+        long callingIdentity = Binder.clearCallingIdentity();
+        try {
+            return mContext.getSystemService(UserManager.class)
+                    .hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM);
+        } finally {
+            Binder.restoreCallingIdentity(callingIdentity);
+        }
+    }
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);