Merge changes I93fa880a,Ib036852a,Ic5ab3c04,I4452eacf am: 20909a93b0 am: 1d4cea45d6
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1462704 Change-Id: Ic68afbf39ea2ec8a00fca543676f415debe351b9
This commit is contained in:
@@ -16,22 +16,14 @@
|
|||||||
|
|
||||||
package com.android.server;
|
package com.android.server;
|
||||||
|
|
||||||
import android.bluetooth.BluetoothA2dp;
|
|
||||||
import android.bluetooth.BluetoothAdapter;
|
|
||||||
import android.bluetooth.BluetoothHearingAid;
|
|
||||||
import android.bluetooth.BluetoothProfile;
|
|
||||||
import android.bluetooth.BluetoothProfile.ServiceListener;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.android.internal.R;
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,7 +45,7 @@ class BluetoothAirplaneModeListener {
|
|||||||
|
|
||||||
private final BluetoothManagerService mBluetoothManager;
|
private final BluetoothManagerService mBluetoothManager;
|
||||||
private final BluetoothAirplaneModeHandler mHandler;
|
private final BluetoothAirplaneModeHandler mHandler;
|
||||||
private AirplaneModeHelper mAirplaneHelper;
|
private BluetoothModeChangeHelper mAirplaneHelper;
|
||||||
|
|
||||||
@VisibleForTesting int mToastCount = 0;
|
@VisibleForTesting int mToastCount = 0;
|
||||||
|
|
||||||
@@ -97,7 +89,7 @@ class BluetoothAirplaneModeListener {
|
|||||||
* Call after boot complete
|
* Call after boot complete
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void start(AirplaneModeHelper helper) {
|
void start(BluetoothModeChangeHelper helper) {
|
||||||
Log.i(TAG, "start");
|
Log.i(TAG, "start");
|
||||||
mAirplaneHelper = helper;
|
mAirplaneHelper = helper;
|
||||||
mToastCount = mAirplaneHelper.getSettingsInt(TOAST_COUNT);
|
mToastCount = mAirplaneHelper.getSettingsInt(TOAST_COUNT);
|
||||||
@@ -141,118 +133,4 @@ class BluetoothAirplaneModeListener {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper class that handles callout and callback methods without
|
|
||||||
* complex logic.
|
|
||||||
*/
|
|
||||||
@VisibleForTesting
|
|
||||||
public static class AirplaneModeHelper {
|
|
||||||
private volatile BluetoothA2dp mA2dp;
|
|
||||||
private volatile BluetoothHearingAid mHearingAid;
|
|
||||||
private final BluetoothAdapter mAdapter;
|
|
||||||
private final Context mContext;
|
|
||||||
|
|
||||||
AirplaneModeHelper(Context context) {
|
|
||||||
mAdapter = BluetoothAdapter.getDefaultAdapter();
|
|
||||||
mContext = context;
|
|
||||||
|
|
||||||
mAdapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.A2DP);
|
|
||||||
mAdapter.getProfileProxy(mContext, mProfileServiceListener,
|
|
||||||
BluetoothProfile.HEARING_AID);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final ServiceListener mProfileServiceListener = new ServiceListener() {
|
|
||||||
@Override
|
|
||||||
public void onServiceConnected(int profile, BluetoothProfile proxy) {
|
|
||||||
// Setup Bluetooth profile proxies
|
|
||||||
switch (profile) {
|
|
||||||
case BluetoothProfile.A2DP:
|
|
||||||
mA2dp = (BluetoothA2dp) proxy;
|
|
||||||
break;
|
|
||||||
case BluetoothProfile.HEARING_AID:
|
|
||||||
mHearingAid = (BluetoothHearingAid) proxy;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onServiceDisconnected(int profile) {
|
|
||||||
// Clear Bluetooth profile proxies
|
|
||||||
switch (profile) {
|
|
||||||
case BluetoothProfile.A2DP:
|
|
||||||
mA2dp = null;
|
|
||||||
break;
|
|
||||||
case BluetoothProfile.HEARING_AID:
|
|
||||||
mHearingAid = null;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public boolean isA2dpOrHearingAidConnected() {
|
|
||||||
return isA2dpConnected() || isHearingAidConnected();
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public boolean isBluetoothOn() {
|
|
||||||
final BluetoothAdapter adapter = mAdapter;
|
|
||||||
if (adapter == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return adapter.getLeState() == BluetoothAdapter.STATE_ON;
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public boolean isAirplaneModeOn() {
|
|
||||||
return Settings.Global.getInt(mContext.getContentResolver(),
|
|
||||||
Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public void onAirplaneModeChanged(BluetoothManagerService managerService) {
|
|
||||||
managerService.onAirplaneModeChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public int getSettingsInt(String name) {
|
|
||||||
return Settings.Global.getInt(mContext.getContentResolver(),
|
|
||||||
name, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public void setSettingsInt(String name, int value) {
|
|
||||||
Settings.Global.putInt(mContext.getContentResolver(),
|
|
||||||
name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public void showToastMessage() {
|
|
||||||
Resources r = mContext.getResources();
|
|
||||||
final CharSequence text = r.getString(
|
|
||||||
R.string.bluetooth_airplane_mode_toast, 0);
|
|
||||||
Toast.makeText(mContext, text, Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isA2dpConnected() {
|
|
||||||
final BluetoothA2dp a2dp = mA2dp;
|
|
||||||
if (a2dp == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return a2dp.getConnectedDevices().size() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isHearingAidConnected() {
|
|
||||||
final BluetoothHearingAid hearingAid = mHearingAid;
|
|
||||||
if (hearingAid == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return hearingAid.getConnectedDevices().size() > 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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;
|
||||||
|
|
||||||
|
import android.provider.DeviceConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The BluetoothDeviceConfigListener handles system device config change callback and checks
|
||||||
|
* whether we need to inform BluetoothManagerService on this change.
|
||||||
|
*
|
||||||
|
* The information of device config change would not be passed to the BluetoothManagerService
|
||||||
|
* when Bluetooth is on and Bluetooth is in one of the following situations:
|
||||||
|
* 1. Bluetooth A2DP is connected.
|
||||||
|
* 2. Bluetooth Hearing Aid profile is connected.
|
||||||
|
*/
|
||||||
|
class BluetoothDeviceConfigListener {
|
||||||
|
private static final String TAG = "BluetoothDeviceConfigListener";
|
||||||
|
|
||||||
|
BluetoothManagerService mService;
|
||||||
|
|
||||||
|
BluetoothDeviceConfigListener(BluetoothManagerService service) {
|
||||||
|
mService = service;
|
||||||
|
DeviceConfig.addOnPropertiesChangedListener(
|
||||||
|
DeviceConfig.NAMESPACE_BLUETOOTH,
|
||||||
|
(Runnable r) -> r.run(),
|
||||||
|
mDeviceConfigChangedListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final DeviceConfig.OnPropertiesChangedListener mDeviceConfigChangedListener =
|
||||||
|
new DeviceConfig.OnPropertiesChangedListener() {
|
||||||
|
@Override
|
||||||
|
public void onPropertiesChanged(DeviceConfig.Properties properties) {
|
||||||
|
if (!properties.getNamespace().equals(DeviceConfig.NAMESPACE_BLUETOOTH)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean foundInit = false;
|
||||||
|
for (String name : properties.getKeyset()) {
|
||||||
|
if (name.startsWith("INIT_")) {
|
||||||
|
foundInit = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundInit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mService.onInitFlagsChanged();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -23,7 +23,9 @@ import android.Manifest;
|
|||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.AppGlobals;
|
import android.app.AppGlobals;
|
||||||
import android.app.AppOpsManager;
|
import android.app.AppOpsManager;
|
||||||
|
import android.bluetooth.BluetoothA2dp;
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.bluetooth.BluetoothHearingAid;
|
||||||
import android.bluetooth.BluetoothProfile;
|
import android.bluetooth.BluetoothProfile;
|
||||||
import android.bluetooth.BluetoothProtoEnums;
|
import android.bluetooth.BluetoothProtoEnums;
|
||||||
import android.bluetooth.IBluetooth;
|
import android.bluetooth.IBluetooth;
|
||||||
@@ -63,7 +65,6 @@ import android.os.UserHandle;
|
|||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.os.UserManagerInternal;
|
import android.os.UserManagerInternal;
|
||||||
import android.os.UserManagerInternal.UserRestrictionsListener;
|
import android.os.UserManagerInternal.UserRestrictionsListener;
|
||||||
import android.provider.DeviceConfig;
|
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.provider.Settings.SettingNotFoundException;
|
import android.provider.Settings.SettingNotFoundException;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@@ -116,6 +117,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
|||||||
// Delay for retrying enable and disable in msec
|
// Delay for retrying enable and disable in msec
|
||||||
private static final int ENABLE_DISABLE_DELAY_MS = 300;
|
private static final int ENABLE_DISABLE_DELAY_MS = 300;
|
||||||
private static final int DELAY_BEFORE_RESTART_DUE_TO_INIT_FLAGS_CHANGED_MS = 300;
|
private static final int DELAY_BEFORE_RESTART_DUE_TO_INIT_FLAGS_CHANGED_MS = 300;
|
||||||
|
private static final int DELAY_FOR_RETRY_INIT_FLAG_CHECK_MS = 86400;
|
||||||
|
|
||||||
private static final int MESSAGE_ENABLE = 1;
|
private static final int MESSAGE_ENABLE = 1;
|
||||||
private static final int MESSAGE_DISABLE = 2;
|
private static final int MESSAGE_DISABLE = 2;
|
||||||
@@ -175,8 +177,12 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
|||||||
private int mWaitForEnableRetry;
|
private int mWaitForEnableRetry;
|
||||||
private int mWaitForDisableRetry;
|
private int mWaitForDisableRetry;
|
||||||
|
|
||||||
|
private BluetoothModeChangeHelper mBluetoothModeChangeHelper;
|
||||||
|
|
||||||
private BluetoothAirplaneModeListener mBluetoothAirplaneModeListener;
|
private BluetoothAirplaneModeListener mBluetoothAirplaneModeListener;
|
||||||
|
|
||||||
|
private BluetoothDeviceConfigListener mBluetoothDeviceConfigListener;
|
||||||
|
|
||||||
// used inside handler thread
|
// used inside handler thread
|
||||||
private boolean mQuietEnable = false;
|
private boolean mQuietEnable = false;
|
||||||
private boolean mEnable;
|
private boolean mEnable;
|
||||||
@@ -281,29 +287,13 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final DeviceConfig.OnPropertiesChangedListener mDeviceConfigChangedListener =
|
@VisibleForTesting
|
||||||
new DeviceConfig.OnPropertiesChangedListener() {
|
public void onInitFlagsChanged() {
|
||||||
@Override
|
mHandler.removeMessages(MESSAGE_INIT_FLAGS_CHANGED);
|
||||||
public void onPropertiesChanged(DeviceConfig.Properties properties) {
|
mHandler.sendEmptyMessageDelayed(
|
||||||
if (!properties.getNamespace().equals(DeviceConfig.NAMESPACE_BLUETOOTH)) {
|
MESSAGE_INIT_FLAGS_CHANGED,
|
||||||
return;
|
DELAY_BEFORE_RESTART_DUE_TO_INIT_FLAGS_CHANGED_MS);
|
||||||
}
|
}
|
||||||
boolean foundInit = false;
|
|
||||||
for (String name : properties.getKeyset()) {
|
|
||||||
if (name.startsWith("INIT_")) {
|
|
||||||
foundInit = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!foundInit) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mHandler.removeMessages(MESSAGE_INIT_FLAGS_CHANGED);
|
|
||||||
mHandler.sendEmptyMessageDelayed(
|
|
||||||
MESSAGE_INIT_FLAGS_CHANGED,
|
|
||||||
DELAY_BEFORE_RESTART_DUE_TO_INIT_FLAGS_CHANGED_MS);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public boolean onFactoryReset() {
|
public boolean onFactoryReset() {
|
||||||
// Wait for stable state if bluetooth is temporary state.
|
// Wait for stable state if bluetooth is temporary state.
|
||||||
@@ -451,6 +441,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
|||||||
mHandler.sendMessage(msg);
|
mHandler.sendMessage(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(action)
|
||||||
|
|| BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
|
||||||
|
final int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
|
||||||
|
BluetoothProfile.STATE_CONNECTED);
|
||||||
|
if (mHandler.hasMessages(MESSAGE_INIT_FLAGS_CHANGED)
|
||||||
|
&& state == BluetoothProfile.STATE_DISCONNECTED
|
||||||
|
&& !mBluetoothModeChangeHelper.isA2dpOrHearingAidConnected()) {
|
||||||
|
onInitFlagsChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -501,6 +500,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
|||||||
filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
|
filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
|
||||||
filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
|
filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
|
||||||
filter.addAction(Intent.ACTION_SETTING_RESTORED);
|
filter.addAction(Intent.ACTION_SETTING_RESTORED);
|
||||||
|
filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
|
||||||
|
filter.addAction(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
|
||||||
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
|
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
|
||||||
mContext.registerReceiver(mReceiver, filter);
|
mContext.registerReceiver(mReceiver, filter);
|
||||||
|
|
||||||
@@ -535,10 +536,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
|||||||
Slog.w(TAG, "Unable to resolve SystemUI's UID.");
|
Slog.w(TAG, "Unable to resolve SystemUI's UID.");
|
||||||
}
|
}
|
||||||
mSystemUiUid = systemUiUid;
|
mSystemUiUid = systemUiUid;
|
||||||
DeviceConfig.addOnPropertiesChangedListener(
|
|
||||||
DeviceConfig.NAMESPACE_BLUETOOTH,
|
|
||||||
(Runnable r) -> r.run(),
|
|
||||||
mDeviceConfigChangedListener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1368,10 +1365,12 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
|||||||
Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
|
Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
|
||||||
mHandler.sendMessage(getMsg);
|
mHandler.sendMessage(getMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mBluetoothModeChangeHelper = new BluetoothModeChangeHelper(mContext);
|
||||||
if (mBluetoothAirplaneModeListener != null) {
|
if (mBluetoothAirplaneModeListener != null) {
|
||||||
mBluetoothAirplaneModeListener.start(
|
mBluetoothAirplaneModeListener.start(mBluetoothModeChangeHelper);
|
||||||
new BluetoothAirplaneModeListener.AirplaneModeHelper(mContext));
|
|
||||||
}
|
}
|
||||||
|
mBluetoothDeviceConfigListener = new BluetoothDeviceConfigListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2214,6 +2213,12 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
|||||||
Slog.d(TAG, "MESSAGE_INIT_FLAGS_CHANGED");
|
Slog.d(TAG, "MESSAGE_INIT_FLAGS_CHANGED");
|
||||||
}
|
}
|
||||||
mHandler.removeMessages(MESSAGE_INIT_FLAGS_CHANGED);
|
mHandler.removeMessages(MESSAGE_INIT_FLAGS_CHANGED);
|
||||||
|
if (mBluetoothModeChangeHelper.isA2dpOrHearingAidConnected()) {
|
||||||
|
mHandler.sendEmptyMessageDelayed(
|
||||||
|
MESSAGE_INIT_FLAGS_CHANGED,
|
||||||
|
DELAY_FOR_RETRY_INIT_FLAG_CHECK_MS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (mBluetooth != null && isEnabled()) {
|
if (mBluetooth != null && isEnabled()) {
|
||||||
restartForReason(
|
restartForReason(
|
||||||
BluetoothProtoEnums.ENABLE_DISABLE_REASON_INIT_FLAGS_CHANGED);
|
BluetoothProtoEnums.ENABLE_DISABLE_REASON_INIT_FLAGS_CHANGED);
|
||||||
|
|||||||
@@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothA2dp;
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.bluetooth.BluetoothHearingAid;
|
||||||
|
import android.bluetooth.BluetoothProfile;
|
||||||
|
import android.bluetooth.BluetoothProfile.ServiceListener;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.android.internal.R;
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class that handles callout and callback methods without
|
||||||
|
* complex logic.
|
||||||
|
*/
|
||||||
|
public class BluetoothModeChangeHelper {
|
||||||
|
private volatile BluetoothA2dp mA2dp;
|
||||||
|
private volatile BluetoothHearingAid mHearingAid;
|
||||||
|
private final BluetoothAdapter mAdapter;
|
||||||
|
private final Context mContext;
|
||||||
|
|
||||||
|
BluetoothModeChangeHelper(Context context) {
|
||||||
|
mAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||||
|
mContext = context;
|
||||||
|
|
||||||
|
mAdapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.A2DP);
|
||||||
|
mAdapter.getProfileProxy(mContext, mProfileServiceListener,
|
||||||
|
BluetoothProfile.HEARING_AID);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ServiceListener mProfileServiceListener = new ServiceListener() {
|
||||||
|
@Override
|
||||||
|
public void onServiceConnected(int profile, BluetoothProfile proxy) {
|
||||||
|
// Setup Bluetooth profile proxies
|
||||||
|
switch (profile) {
|
||||||
|
case BluetoothProfile.A2DP:
|
||||||
|
mA2dp = (BluetoothA2dp) proxy;
|
||||||
|
break;
|
||||||
|
case BluetoothProfile.HEARING_AID:
|
||||||
|
mHearingAid = (BluetoothHearingAid) proxy;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceDisconnected(int profile) {
|
||||||
|
// Clear Bluetooth profile proxies
|
||||||
|
switch (profile) {
|
||||||
|
case BluetoothProfile.A2DP:
|
||||||
|
mA2dp = null;
|
||||||
|
break;
|
||||||
|
case BluetoothProfile.HEARING_AID:
|
||||||
|
mHearingAid = null;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public boolean isA2dpOrHearingAidConnected() {
|
||||||
|
return isA2dpConnected() || isHearingAidConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public boolean isBluetoothOn() {
|
||||||
|
final BluetoothAdapter adapter = mAdapter;
|
||||||
|
if (adapter == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return adapter.getLeState() == BluetoothAdapter.STATE_ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public boolean isAirplaneModeOn() {
|
||||||
|
return Settings.Global.getInt(mContext.getContentResolver(),
|
||||||
|
Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public void onAirplaneModeChanged(BluetoothManagerService managerService) {
|
||||||
|
managerService.onAirplaneModeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public int getSettingsInt(String name) {
|
||||||
|
return Settings.Global.getInt(mContext.getContentResolver(),
|
||||||
|
name, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public void setSettingsInt(String name, int value) {
|
||||||
|
Settings.Global.putInt(mContext.getContentResolver(),
|
||||||
|
name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public void showToastMessage() {
|
||||||
|
Resources r = mContext.getResources();
|
||||||
|
final CharSequence text = r.getString(
|
||||||
|
R.string.bluetooth_airplane_mode_toast, 0);
|
||||||
|
Toast.makeText(mContext, text, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isA2dpConnected() {
|
||||||
|
final BluetoothA2dp a2dp = mA2dp;
|
||||||
|
if (a2dp == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return a2dp.getConnectedDevices().size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isHearingAidConnected() {
|
||||||
|
final BluetoothHearingAid hearingAid = mHearingAid;
|
||||||
|
if (hearingAid == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return hearingAid.getConnectedDevices().size() > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,8 +27,6 @@ import androidx.test.InstrumentationRegistry;
|
|||||||
import androidx.test.filters.MediumTest;
|
import androidx.test.filters.MediumTest;
|
||||||
import androidx.test.runner.AndroidJUnit4;
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
import com.android.server.BluetoothAirplaneModeListener.AirplaneModeHelper;
|
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -41,7 +39,7 @@ public class BluetoothAirplaneModeListenerTest {
|
|||||||
private Context mContext;
|
private Context mContext;
|
||||||
private BluetoothAirplaneModeListener mBluetoothAirplaneModeListener;
|
private BluetoothAirplaneModeListener mBluetoothAirplaneModeListener;
|
||||||
private BluetoothAdapter mBluetoothAdapter;
|
private BluetoothAdapter mBluetoothAdapter;
|
||||||
private AirplaneModeHelper mHelper;
|
private BluetoothModeChangeHelper mHelper;
|
||||||
|
|
||||||
@Mock BluetoothManagerService mBluetoothManagerService;
|
@Mock BluetoothManagerService mBluetoothManagerService;
|
||||||
|
|
||||||
@@ -49,7 +47,7 @@ public class BluetoothAirplaneModeListenerTest {
|
|||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
mContext = InstrumentationRegistry.getTargetContext();
|
mContext = InstrumentationRegistry.getTargetContext();
|
||||||
|
|
||||||
mHelper = mock(AirplaneModeHelper.class);
|
mHelper = mock(BluetoothModeChangeHelper.class);
|
||||||
when(mHelper.getSettingsInt(BluetoothAirplaneModeListener.TOAST_COUNT))
|
when(mHelper.getSettingsInt(BluetoothAirplaneModeListener.TOAST_COUNT))
|
||||||
.thenReturn(BluetoothAirplaneModeListener.MAX_TOAST_COUNT);
|
.thenReturn(BluetoothAirplaneModeListener.MAX_TOAST_COUNT);
|
||||||
doNothing().when(mHelper).setSettingsInt(anyString(), anyInt());
|
doNothing().when(mHelper).setSettingsInt(anyString(), anyInt());
|
||||||
|
|||||||
Reference in New Issue
Block a user