Loading service/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ java_library { static_libs: [ "androidx.annotation_annotation", "androidx.appcompat_appcompat", "modules-utils-shell-command-handler", ], apex_available: [ Loading service/java/com/android/server/bluetooth/BluetoothManagerService.java +10 −1 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.PowerExemptionManager; import android.os.Process; import android.os.RemoteCallbackList; Loading Loading @@ -1019,7 +1020,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { // Check if packageName belongs to callingUid final int callingUid = Binder.getCallingUid(); final boolean isCallerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID; if (!isCallerSystem) { if (!isCallerSystem && callingUid != Process.SHELL_UID) { checkPackage(callingUid, attributionSource.getPackageName()); if (requireForeground && !checkIfCallerIsForegroundUser()) { Loading Loading @@ -3018,6 +3019,14 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { attributionSource, message); } @Override public int handleShellCommand(@NonNull ParcelFileDescriptor in, @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, @NonNull String[] args) { return new BluetoothShellCommand(this, mContext).exec(this, in.getFileDescriptor(), out.getFileDescriptor(), err.getFileDescriptor(), args); } static @NonNull Bundle getTempAllowlistBroadcastOptions() { final long duration = 10_000; final BroadcastOptions bOptions = BroadcastOptions.makeBasic(); Loading service/java/com/android/server/bluetooth/BluetoothShellCommand.java 0 → 100644 +125 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.bluetooth; import android.content.AttributionSource; import android.content.Context; import android.os.Binder; import android.os.Process; import android.os.RemoteException; import android.util.Log; import com.android.modules.utils.BasicShellCommandHandler; import java.io.PrintWriter; class BluetoothShellCommand extends BasicShellCommandHandler { private static final String TAG = "BluetoothShellCommand"; private final BluetoothManagerService mManagerService; private final Context mContext; private final BluetoothCommand[] mBluetoothCommands = { new Enable(), new Disable(), }; private abstract class BluetoothCommand { abstract String getName(); // require root permission by default, can be override in command implementation boolean isPrivileged() { return true; } abstract int exec(PrintWriter pw) throws RemoteException; } private class Enable extends BluetoothCommand { @Override String getName() { return "enable"; } @Override boolean isPrivileged() { return false; } @Override public int exec(PrintWriter pw) throws RemoteException { pw.println("Enabling Bluetooth"); return mManagerService.enable(AttributionSource.myAttributionSource()) ? 0 : -1; } } private class Disable extends BluetoothCommand { @Override String getName() { return "disable"; } @Override boolean isPrivileged() { return false; } @Override public int exec(PrintWriter pw) throws RemoteException { pw.println("Disabling Bluetooth"); return mManagerService.disable(AttributionSource.myAttributionSource(), true) ? 0 : -1; } } BluetoothShellCommand(BluetoothManagerService managerService, Context context) { mManagerService = managerService; mContext = context; } @Override public int onCommand(String cmd) { if (cmd == null) { return handleDefaultCommands(null); } for (BluetoothCommand bt_cmd : mBluetoothCommands) { if (cmd.equals(bt_cmd.getName())) { if (bt_cmd.isPrivileged()) { final int uid = Binder.getCallingUid(); if (uid != Process.ROOT_UID) { throw new SecurityException("Uid " + uid + " does not have access to " + cmd + " bluetooth command (or such command doesn't exist)"); } } try { return bt_cmd.exec(getOutPrintWriter()); } catch (RemoteException e) { Log.w(TAG, cmd + ": error\nException: " + e.getMessage()); getErrPrintWriter().println(cmd + ": error\nException: " + e.getMessage()); e.rethrowFromSystemServer(); } } } return handleDefaultCommands(cmd); } @Override public void onHelp() { PrintWriter pw = getOutPrintWriter(); pw.println("Bluetooth Commands:"); pw.println(" help or -h"); pw.println(" Print this help text."); pw.println(" enable"); pw.println(" Enable Bluetooth on this device."); pw.println(" disable"); pw.println(" Disable Bluetooth on this device."); } } Loading
service/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ java_library { static_libs: [ "androidx.annotation_annotation", "androidx.appcompat_appcompat", "modules-utils-shell-command-handler", ], apex_available: [ Loading
service/java/com/android/server/bluetooth/BluetoothManagerService.java +10 −1 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.PowerExemptionManager; import android.os.Process; import android.os.RemoteCallbackList; Loading Loading @@ -1019,7 +1020,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { // Check if packageName belongs to callingUid final int callingUid = Binder.getCallingUid(); final boolean isCallerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID; if (!isCallerSystem) { if (!isCallerSystem && callingUid != Process.SHELL_UID) { checkPackage(callingUid, attributionSource.getPackageName()); if (requireForeground && !checkIfCallerIsForegroundUser()) { Loading Loading @@ -3018,6 +3019,14 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { attributionSource, message); } @Override public int handleShellCommand(@NonNull ParcelFileDescriptor in, @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, @NonNull String[] args) { return new BluetoothShellCommand(this, mContext).exec(this, in.getFileDescriptor(), out.getFileDescriptor(), err.getFileDescriptor(), args); } static @NonNull Bundle getTempAllowlistBroadcastOptions() { final long duration = 10_000; final BroadcastOptions bOptions = BroadcastOptions.makeBasic(); Loading
service/java/com/android/server/bluetooth/BluetoothShellCommand.java 0 → 100644 +125 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.bluetooth; import android.content.AttributionSource; import android.content.Context; import android.os.Binder; import android.os.Process; import android.os.RemoteException; import android.util.Log; import com.android.modules.utils.BasicShellCommandHandler; import java.io.PrintWriter; class BluetoothShellCommand extends BasicShellCommandHandler { private static final String TAG = "BluetoothShellCommand"; private final BluetoothManagerService mManagerService; private final Context mContext; private final BluetoothCommand[] mBluetoothCommands = { new Enable(), new Disable(), }; private abstract class BluetoothCommand { abstract String getName(); // require root permission by default, can be override in command implementation boolean isPrivileged() { return true; } abstract int exec(PrintWriter pw) throws RemoteException; } private class Enable extends BluetoothCommand { @Override String getName() { return "enable"; } @Override boolean isPrivileged() { return false; } @Override public int exec(PrintWriter pw) throws RemoteException { pw.println("Enabling Bluetooth"); return mManagerService.enable(AttributionSource.myAttributionSource()) ? 0 : -1; } } private class Disable extends BluetoothCommand { @Override String getName() { return "disable"; } @Override boolean isPrivileged() { return false; } @Override public int exec(PrintWriter pw) throws RemoteException { pw.println("Disabling Bluetooth"); return mManagerService.disable(AttributionSource.myAttributionSource(), true) ? 0 : -1; } } BluetoothShellCommand(BluetoothManagerService managerService, Context context) { mManagerService = managerService; mContext = context; } @Override public int onCommand(String cmd) { if (cmd == null) { return handleDefaultCommands(null); } for (BluetoothCommand bt_cmd : mBluetoothCommands) { if (cmd.equals(bt_cmd.getName())) { if (bt_cmd.isPrivileged()) { final int uid = Binder.getCallingUid(); if (uid != Process.ROOT_UID) { throw new SecurityException("Uid " + uid + " does not have access to " + cmd + " bluetooth command (or such command doesn't exist)"); } } try { return bt_cmd.exec(getOutPrintWriter()); } catch (RemoteException e) { Log.w(TAG, cmd + ": error\nException: " + e.getMessage()); getErrPrintWriter().println(cmd + ": error\nException: " + e.getMessage()); e.rethrowFromSystemServer(); } } } return handleDefaultCommands(cmd); } @Override public void onHelp() { PrintWriter pw = getOutPrintWriter(); pw.println("Bluetooth Commands:"); pw.println(" help or -h"); pw.println(" Print this help text."); pw.println(" enable"); pw.println(" Enable Bluetooth on this device."); pw.println(" disable"); pw.println(" Disable Bluetooth on this device."); } }