你现在是一名资深的蓝牙工程师,请你详细讲解下面的BluetoothServiceBinder.java的代码:
package com.android.server.bluetooth;
18
19 import static android.Manifest.permission.BLUETOOTH_CONNECT;
20 import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
21 import static android.Manifest.permission.DUMP;
22 import static android.Manifest.permission.LOCAL_MAC_ADDRESS;
23 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
24
25 import static com.android.server.bluetooth.BtPermissionUtils.checkConnectPermissionForDataDelivery;
26 import static com.android.server.bluetooth.BtPermissionUtils.getCallingAppId;
27 import static com.android.server.bluetooth.BtPermissionUtils.isCallerSystem;
28
29 import static java.util.Objects.requireNonNull;
30
31 import android.annotation.NonNull;
32 import android.annotation.Nullable;
33 import android.annotation.RequiresPermission;
34 import android.app.AppOpsManager;
35 import android.bluetooth.BluetoothAdapter;
36 import android.bluetooth.IBluetooth;
37 import android.bluetooth.IBluetoothManager;
38 import android.bluetooth.IBluetoothManagerCallback;
39 import android.content.AttributionSource;
40 import android.content.Context;
41 import android.os.Build;
42 import android.os.IBinder;
43 import android.os.Looper;
44 import android.os.ParcelFileDescriptor;
45 import android.os.UserManager;
46 import android.permission.PermissionManager;
47
48 import androidx.annotation.RequiresApi;
49
50 import java.io.FileDescriptor;
51 import java.io.PrintWriter;
52
53 class BluetoothServiceBinder extends IBluetoothManager.Stub {
54 private static final String TAG = BluetoothServiceBinder.class.getSimpleName();
55
56 private final BluetoothManagerService mBluetoothManagerService;
57 private final Context mContext;
58 private final UserManager mUserManager;
59 private final AppOpsManager mAppOpsManager;
60 private final PermissionManager mPermissionManager;
61 private final BtPermissionUtils mPermissionUtils;
62 private final Looper unusedmLooper;
63
64 BluetoothServiceBinder(
65 BluetoothManagerService bms, Looper looper, Context ctx, UserManager userManager) {
66 mBluetoothManagerService = bms;
67 unusedmLooper = looper;
68 mContext = ctx;
69 mUserManager = userManager;
70 mAppOpsManager =
71 requireNonNull(
72 ctx.getSystemService(AppOpsManager.class),
73 "AppOpsManager system service cannot be null");
74 mPermissionManager =
75 requireNonNull(
76 ctx.getSystemService(PermissionManager.class),
77 "PermissionManager system service cannot be null");
78 mPermissionUtils = new BtPermissionUtils(ctx);
79 }
80
81 @Override
82 @Nullable
83 public IBinder registerAdapter(@NonNull IBluetoothManagerCallback callback) {
84 requireNonNull(callback, "Callback cannot be null in registerAdapter");
85 IBluetooth bluetooth = mBluetoothManagerService.registerAdapter(callback);
86 if (bluetooth == null) {
87 return null;
88 }
89 return bluetooth.asBinder();
90 }
91
92 @Override
93 public void unregisterAdapter(@NonNull IBluetoothManagerCallback callback) {
94 requireNonNull(callback, "Callback cannot be null in unregisterAdapter");
95 mBluetoothManagerService.unregisterAdapter(callback);
96 }
97
98 @Override
99 public boolean enable(@NonNull AttributionSource source) {
100 requireNonNull(source, "AttributionSource cannot be null in enable");
101
102 final String errorMsg =
103 mPermissionUtils.callerCanToggle(
104 mContext,
105 source,
106 mUserManager,
107 mAppOpsManager,
108 mPermissionManager,
109 "enable",
110 true);
111 if (!errorMsg.isEmpty()) {
112 Log.d(TAG, "enable(): FAILED: " + errorMsg);
113 return false;
114 }
115
116 return mBluetoothManagerService.enable(source.getPackageName());
117 }
118
119 @Override
120 public boolean enableNoAutoConnect(AttributionSource source) {
121 requireNonNull(source, "AttributionSource cannot be null in enableNoAutoConnect");
122
123 final String errorMsg =
124 mPermissionUtils.callerCanToggle(
125 mContext,
126 source,
127 mUserManager,
128 mAppOpsManager,
129 mPermissionManager,
130 "enableNoAutoConnect",
131 false);
132 if (!errorMsg.isEmpty()) {
133 Log.d(TAG, "enableNoAutoConnect(): FAILED: " + errorMsg);
134 return false;
135 }
136
137 if (!BtPermissionUtils.isCallerNfc(getCallingAppId())) {
138 throw new SecurityException("No permission to enable Bluetooth quietly");
139 }
140
141 return mBluetoothManagerService.enableNoAutoConnect(source.getPackageName());
142 }
143
144 @Override
145 public boolean disable(AttributionSource source, boolean persist) {
146 requireNonNull(source, "AttributionSource cannot be null in disable");
147
148 if (!persist) {
149 BtPermissionUtils.enforcePrivileged(mContext);
150 }
151
152 final String errorMsg =
153 mPermissionUtils.callerCanToggle(
154 mContext,
155 source,
156 mUserManager,
157 mAppOpsManager,
158 mPermissionManager,
159 "disable",
160 true);
161 if (!errorMsg.isEmpty()) {
162 Log.d(TAG, "disable(): FAILED: " + errorMsg);
163 return false;
164 }
165
166 return mBluetoothManagerService.disable(source.getPackageName(), persist);
167 }
168
169 @Override
170 public int getState() {
171 if (!isCallerSystem(getCallingAppId())
172 && !mPermissionUtils.checkIfCallerIsForegroundUser(mUserManager)) {
173 Log.w(TAG, "getState(): UNAUTHORIZED. Report OFF for non-active and non system user");
174 return BluetoothAdapter.STATE_OFF;
175 }
176
177 return mBluetoothManagerService.getState();
178 }
179
180 @Override
181 @RequiresPermission(allOf = {BLUETOOTH_CONNECT, LOCAL_MAC_ADDRESS})
182 public String getAddress(AttributionSource source) {
183 requireNonNull(source, "AttributionSource cannot be null in getAddress");
184
185 if (!checkConnectPermissionForDataDelivery(
186 mContext, mPermissionManager, source, "getAddress")) {
187 return null;
188 }
189
190 if (!isCallerSystem(getCallingAppId())
191 && !mPermissionUtils.checkIfCallerIsForegroundUser(mUserManager)) {
192 Log.w(TAG, "getAddress(): Not allowed for non-active and non system user");
193 return null;
194 }
195
196 if (mContext.checkCallingOrSelfPermission(LOCAL_MAC_ADDRESS) != PERMISSION_GRANTED) {
197 // TODO(b/280890575): Throws a SecurityException instead
198 Log.w(TAG, "getAddress(): Client does not have LOCAL_MAC_ADDRESS permission");
199 return BluetoothAdapter.DEFAULT_MAC_ADDRESS;
200 }
201
202 return mBluetoothManagerService.getAddress();
203 }
204
205 @Override
206 @RequiresPermission(BLUETOOTH_CONNECT)
207 public String getName(AttributionSource source) {
208 requireNonNull(source, "AttributionSource cannot be null in getName");
209
210 if (!checkConnectPermissionForDataDelivery(
211 mContext, mPermissionManager, source, "getName")) {
212 return null;
213 }
214
215 if (!isCallerSystem(getCallingAppId())
216 && !mPermissionUtils.checkIfCallerIsForegroundUser(mUserManager)) {
217 Log.w(TAG, "getName(): not allowed for non-active and non system user");
218 return null;
219 }
220
221 return mBluetoothManagerService.getName();
222 }
223
224 @Override
225 @RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
226 public boolean onFactoryReset(AttributionSource source) {
227 requireNonNull(source, "AttributionSource cannot be null in onFactoryReset");
228
229 BtPermissionUtils.enforcePrivileged(mContext);
230
231 if (!checkConnectPermissionForDataDelivery(
232 mContext, mPermissionManager, source, "onFactoryReset")) {
233 return false;
234 }
235
236 return mBluetoothManagerService.onFactoryReset();
237 }
238
239 @Override
240 public boolean factoryReset() {
241 return true;
242 }
243
244 public boolean isBleScanAvailable() {
245 return mBluetoothManagerService.isBleScanAvailable();
246 }
247
248 @Override
249 @RequiresPermission(BLUETOOTH_CONNECT)
250 public boolean enableBle(AttributionSource source, IBinder token) {
251 requireNonNull(source, "AttributionSource cannot be null in enableBle");
252 requireNonNull(token, "IBinder cannot be null in enableBle");
253
254 final String errorMsg =
255 mPermissionUtils.callerCanToggle(
256 mContext,
257 source,
258 mUserManager,
259 mAppOpsManager,
260 mPermissionManager,
261 "enableBle",
262 false);
263 if (!errorMsg.isEmpty()) {
264 Log.d(TAG, "enableBle(): FAILED: " + errorMsg);
265 return false;
266 }
267
268 return mBluetoothManagerService.enableBle(source.getPackageName(), token);
269 }
270
271 @Override
272 @RequiresPermission(BLUETOOTH_CONNECT)
273 public boolean disableBle(AttributionSource source, IBinder token) {
274 requireNonNull(source, "AttributionSource cannot be null in disableBle");
275 requireNonNull(token, "IBinder cannot be null in disableBle");
276
277 final String errorMsg =
278 mPermissionUtils.callerCanToggle(
279 mContext,
280 source,
281 mUserManager,
282 mAppOpsManager,
283 mPermissionManager,
284 "disableBle",
285 false);
286 if (!errorMsg.isEmpty()) {
287 Log.d(TAG, "disableBle(): FAILED: " + errorMsg);
288 return false;
289 }
290
291 return mBluetoothManagerService.disableBle(source.getPackageName(), token);
292 }
293
294 @Override
295 public boolean isHearingAidProfileSupported() {
296 return mBluetoothManagerService.isHearingAidProfileSupported();
297 }
298
299 @Override
300 @RequiresPermission(BLUETOOTH_PRIVILEGED)
301 public int setBtHciSnoopLogMode(int mode) {
302 BtPermissionUtils.enforcePrivileged(mContext);
303
304 return mBluetoothManagerService.setBtHciSnoopLogMode(mode);
305 }
306
307 @Override
308 @RequiresPermission(BLUETOOTH_PRIVILEGED)
309 public int getBtHciSnoopLogMode() {
310 BtPermissionUtils.enforcePrivileged(mContext);
311
312 return mBluetoothManagerService.getBtHciSnoopLogMode();
313 }
314
315 @Override
316 public int handleShellCommand(
317 @NonNull ParcelFileDescriptor in,
318 @NonNull ParcelFileDescriptor out,
319 @NonNull ParcelFileDescriptor err,
320 @NonNull String[] args) {
321 return new BluetoothShellCommand(mBluetoothManagerService)
322 .exec(
323 this,
324 in.getFileDescriptor(),
325 out.getFileDescriptor(),
326 err.getFileDescriptor(),
327 args);
328 }
329
330 @Override
331 @RequiresPermission(BLUETOOTH_PRIVILEGED)
332 public boolean isAutoOnSupported() {
333 BtPermissionUtils.enforcePrivileged(mContext);
334 return mBluetoothManagerService.isAutoOnSupported();
335 }
336
337 @Override
338 @RequiresPermission(BLUETOOTH_PRIVILEGED)
339 public boolean isAutoOnEnabled() {
340 BtPermissionUtils.enforcePrivileged(mContext);
341 return mBluetoothManagerService.isAutoOnEnabled();
342 }
343
344 @Override
345 @RequiresPermission(BLUETOOTH_PRIVILEGED)
346 @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
347 public void setAutoOnEnabled(boolean status) {
348 BtPermissionUtils.enforcePrivileged(mContext);
349 mBluetoothManagerService.setAutoOnEnabled(status);
350 }
351
352 @Override
353 @RequiresPermission(DUMP)
354 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
355 if (mContext.checkCallingOrSelfPermission(DUMP) != PERMISSION_GRANTED) {
356 // TODO(b/280890575): Throws SecurityException instead
357 Log.w(TAG, "dump(): Client does not have DUMP permission");
358 return;
359 }
360
361 mBluetoothManagerService.dump(fd, writer, args);
362 }
363 }
最新发布