1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.server.bluetooth 17 18 import android.bluetooth.BluetoothAdapter 19 import android.content.Context 20 import android.content.res.Resources 21 import android.os.HandlerThread 22 import android.os.UserManager 23 import android.provider.Settings 24 import com.android.server.SystemService 25 import com.android.server.SystemService.TargetUser 26 27 class BluetoothService(context: Context) : SystemService(context) { 28 private val mHandlerThread: HandlerThread 29 private val mBluetoothManagerService: BluetoothManagerService 30 private var mInitialized = false 31 32 init { 33 mHandlerThread = HandlerThread("BluetoothManagerService") 34 mHandlerThread.start() 35 mBluetoothManagerService = BluetoothManagerService(context, mHandlerThread.getLooper()) 36 } 37 initializenull38 private fun initialize(user: TargetUser) { 39 if (!mInitialized) { 40 mBluetoothManagerService.handleOnBootPhase(user.userHandle) 41 mInitialized = true 42 } 43 } 44 onStartnull45 override fun onStart() {} 46 onBootPhasenull47 override fun onBootPhase(phase: Int) { 48 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { 49 publishBinderService( 50 BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, 51 mBluetoothManagerService.getBinder(), 52 ) 53 } 54 } 55 shouldInitializeBluetoothnull56 private fun shouldInitializeBluetooth(): Boolean { 57 // Not HSUM, we can initialize Bluetooth on system user 58 if (!UserManager.isHeadlessSystemUserMode()) { 59 return true 60 } 61 62 try { 63 // In HSUM, refer to config_hsumBootStrategy to see if we can boot on system user for 64 // provisioned device 65 val r = Resources.getSystem() 66 if ( 67 r.getInteger(r.getIdentifier("config_hsumBootStrategy", "integer", "android")) == 68 1 && 69 Settings.Global.getInt( 70 context.contentResolver, 71 Settings.Global.DEVICE_PROVISIONED, 72 0, 73 ) == 1 74 ) { 75 return true 76 } 77 } catch (_e: Resources.NotFoundException) { 78 // Config not found, assuming it's 0 so no need to initialize Bluetooth 79 } 80 81 return false 82 } 83 onUserStartingnull84 override fun onUserStarting(user: TargetUser) { 85 if (shouldInitializeBluetooth()) { 86 initialize(user) 87 } 88 } 89 onUserSwitchingnull90 override fun onUserSwitching(_from: TargetUser?, to: TargetUser) { 91 if (!mInitialized) { 92 initialize(to) 93 } else { 94 mBluetoothManagerService.onSwitchUser(to.userHandle) 95 } 96 } 97 onUserUnlockingnull98 override fun onUserUnlocking(user: TargetUser) { 99 mBluetoothManagerService.handleOnUnlockUser(user.userHandle) 100 } 101 } 102