1 /* 2 * Copyright 2020 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 17 package com.android.server; 18 19 import android.annotation.RequiresPermission; 20 import android.bluetooth.BluetoothA2dp; 21 import android.bluetooth.BluetoothAdapter; 22 import android.bluetooth.BluetoothHearingAid; 23 import android.bluetooth.BluetoothProfile; 24 import android.bluetooth.BluetoothProfile.ServiceListener; 25 import android.content.Context; 26 import android.content.res.Resources; 27 import android.provider.Settings; 28 import android.widget.Toast; 29 30 import com.android.internal.R; 31 import com.android.internal.annotations.VisibleForTesting; 32 33 /** 34 * Helper class that handles callout and callback methods without 35 * complex logic. 36 */ 37 public class BluetoothModeChangeHelper { 38 private volatile BluetoothA2dp mA2dp; 39 private volatile BluetoothHearingAid mHearingAid; 40 private final BluetoothAdapter mAdapter; 41 private final Context mContext; 42 BluetoothModeChangeHelper(Context context)43 BluetoothModeChangeHelper(Context context) { 44 mAdapter = BluetoothAdapter.getDefaultAdapter(); 45 mContext = context; 46 47 mAdapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.A2DP); 48 mAdapter.getProfileProxy(mContext, mProfileServiceListener, 49 BluetoothProfile.HEARING_AID); 50 } 51 52 private final ServiceListener mProfileServiceListener = new ServiceListener() { 53 @Override 54 public void onServiceConnected(int profile, BluetoothProfile proxy) { 55 // Setup Bluetooth profile proxies 56 switch (profile) { 57 case BluetoothProfile.A2DP: 58 mA2dp = (BluetoothA2dp) proxy; 59 break; 60 case BluetoothProfile.HEARING_AID: 61 mHearingAid = (BluetoothHearingAid) proxy; 62 break; 63 default: 64 break; 65 } 66 } 67 68 @Override 69 public void onServiceDisconnected(int profile) { 70 // Clear Bluetooth profile proxies 71 switch (profile) { 72 case BluetoothProfile.A2DP: 73 mA2dp = null; 74 break; 75 case BluetoothProfile.HEARING_AID: 76 mHearingAid = null; 77 break; 78 default: 79 break; 80 } 81 } 82 }; 83 84 @VisibleForTesting isA2dpOrHearingAidConnected()85 public boolean isA2dpOrHearingAidConnected() { 86 return isA2dpConnected() || isHearingAidConnected(); 87 } 88 89 @VisibleForTesting isBluetoothOn()90 public boolean isBluetoothOn() { 91 final BluetoothAdapter adapter = mAdapter; 92 if (adapter == null) { 93 return false; 94 } 95 return adapter.getLeState() == BluetoothAdapter.STATE_ON; 96 } 97 98 @VisibleForTesting isAirplaneModeOn()99 public boolean isAirplaneModeOn() { 100 return Settings.Global.getInt(mContext.getContentResolver(), 101 Settings.Global.AIRPLANE_MODE_ON, 0) == 1; 102 } 103 104 @VisibleForTesting 105 @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) onAirplaneModeChanged(BluetoothManagerService managerService)106 public void onAirplaneModeChanged(BluetoothManagerService managerService) { 107 managerService.onAirplaneModeChanged(); 108 } 109 110 @VisibleForTesting getSettingsInt(String name)111 public int getSettingsInt(String name) { 112 return Settings.Global.getInt(mContext.getContentResolver(), 113 name, 0); 114 } 115 116 @VisibleForTesting setSettingsInt(String name, int value)117 public void setSettingsInt(String name, int value) { 118 Settings.Global.putInt(mContext.getContentResolver(), 119 name, value); 120 } 121 122 @VisibleForTesting showToastMessage()123 public void showToastMessage() { 124 Resources r = mContext.getResources(); 125 final CharSequence text = r.getString( 126 R.string.bluetooth_airplane_mode_toast, 0); 127 Toast.makeText(mContext, text, Toast.LENGTH_LONG).show(); 128 } 129 isA2dpConnected()130 private boolean isA2dpConnected() { 131 final BluetoothA2dp a2dp = mA2dp; 132 if (a2dp == null) { 133 return false; 134 } 135 return a2dp.getConnectedDevices().size() > 0; 136 } 137 isHearingAidConnected()138 private boolean isHearingAidConnected() { 139 final BluetoothHearingAid hearingAid = mHearingAid; 140 if (hearingAid == null) { 141 return false; 142 } 143 return hearingAid.getConnectedDevices().size() > 0; 144 } 145 } 146