ContextHubService constructor and init cleanup

Bug: 246384988
Test: m && ./vendor/google/tools/flashall
Test: adb shell dumpsys contexthub # normal
Test: adb shell logcat | grep -iE 'CHRE|contexthub' # normal
Test: atest com.android.server.location.contexthub.ContextHubServiceTest
Change-Id: Id00dbad0d8ef94b682ca935a68d1b5f56a3c0d51
This commit is contained in:
Matthew Sedam
2022-10-06 18:56:54 +00:00
parent 31071af467
commit 6b8171f5a9
4 changed files with 385 additions and 178 deletions

View File

@@ -23,6 +23,7 @@ import android.util.Log;
import com.android.internal.util.ConcurrentUtils;
import com.android.server.location.contexthub.ContextHubService;
import com.android.server.location.contexthub.IContextHubWrapper;
import java.util.concurrent.Future;
@@ -35,7 +36,8 @@ class ContextHubSystemService extends SystemService {
public ContextHubSystemService(Context context) {
super(context);
mInit = SystemServerInitThreadPool.submit(() -> {
mContextHubService = new ContextHubService(context);
mContextHubService = new ContextHubService(context,
IContextHubWrapper.getContextHubWrapper());
}, "Init ContextHubSystemService");
}

View File

@@ -122,23 +122,23 @@ public class ContextHubService extends IContextHubService.Stub {
private final Context mContext;
private final Map<Integer, ContextHubInfo> mContextHubIdToInfoMap;
private final List<String> mSupportedContextHubPerms;
private final List<ContextHubInfo> mContextHubInfoList;
private Map<Integer, ContextHubInfo> mContextHubIdToInfoMap;
private List<String> mSupportedContextHubPerms;
private List<ContextHubInfo> mContextHubInfoList;
private final RemoteCallbackList<IContextHubCallback> mCallbacksList =
new RemoteCallbackList<>();
// Proxy object to communicate with the Context Hub HAL
private final IContextHubWrapper mContextHubWrapper;
private IContextHubWrapper mContextHubWrapper;
// The manager for transaction queue
private final ContextHubTransactionManager mTransactionManager;
private ContextHubTransactionManager mTransactionManager;
// The manager for sending messages to/from clients
private final ContextHubClientManager mClientManager;
private ContextHubClientManager mClientManager;
// The default client for old API clients
private final Map<Integer, IContextHubClient> mDefaultClientMap;
private Map<Integer, IContextHubClient> mDefaultClientMap;
// The manager for the internal nanoapp state cache
private final NanoAppStateManager mNanoAppStateManager = new NanoAppStateManager();
@@ -167,7 +167,7 @@ public class ContextHubService extends IContextHubService.Stub {
// Lock object for sendWifiSettingUpdate()
private final Object mSendWifiSettingUpdateLock = new Object();
private final SensorPrivacyManagerInternal mSensorPrivacyManagerInternal;
private SensorPrivacyManagerInternal mSensorPrivacyManagerInternal;
private final Map<Integer, AtomicLong> mLastRestartTimestampMap = new HashMap<>();
@@ -209,156 +209,9 @@ public class ContextHubService extends IContextHubService.Stub {
}
}
public ContextHubService(Context context) {
long startTimeNs = SystemClock.elapsedRealtimeNanos();
public ContextHubService(Context context, IContextHubWrapper contextHubWrapper) {
mContext = context;
mContextHubWrapper = getContextHubWrapper();
if (mContextHubWrapper == null) {
mTransactionManager = null;
mClientManager = null;
mSensorPrivacyManagerInternal = null;
mDefaultClientMap = Collections.emptyMap();
mContextHubIdToInfoMap = Collections.emptyMap();
mSupportedContextHubPerms = Collections.emptyList();
mContextHubInfoList = Collections.emptyList();
return;
}
Pair<List<ContextHubInfo>, List<String>> hubInfo;
try {
hubInfo = mContextHubWrapper.getHubs();
} catch (RemoteException e) {
Log.e(TAG, "RemoteException while getting Context Hub info", e);
hubInfo = new Pair(Collections.emptyList(), Collections.emptyList());
}
long bootTimeNs = SystemClock.elapsedRealtimeNanos() - startTimeNs;
int numContextHubs = hubInfo.first.size();
ContextHubStatsLog.write(ContextHubStatsLog.CONTEXT_HUB_BOOTED, bootTimeNs, numContextHubs);
mContextHubIdToInfoMap = Collections.unmodifiableMap(
ContextHubServiceUtil.createContextHubInfoMap(hubInfo.first));
mSupportedContextHubPerms = hubInfo.second;
mContextHubInfoList = new ArrayList<>(mContextHubIdToInfoMap.values());
mClientManager = new ContextHubClientManager(mContext, mContextHubWrapper);
mTransactionManager = new ContextHubTransactionManager(
mContextHubWrapper, mClientManager, mNanoAppStateManager);
mSensorPrivacyManagerInternal =
LocalServices.getService(SensorPrivacyManagerInternal.class);
HashMap<Integer, IContextHubClient> defaultClientMap = new HashMap<>();
for (int contextHubId : mContextHubIdToInfoMap.keySet()) {
mLastRestartTimestampMap.put(contextHubId,
new AtomicLong(SystemClock.elapsedRealtimeNanos()));
ContextHubInfo contextHubInfo = mContextHubIdToInfoMap.get(contextHubId);
IContextHubClient client = mClientManager.registerClient(
contextHubInfo, createDefaultClientCallback(contextHubId),
null /* attributionTag */, mTransactionManager, mContext.getPackageName());
defaultClientMap.put(contextHubId, client);
try {
mContextHubWrapper.registerCallback(
contextHubId, new ContextHubServiceCallback(contextHubId));
} catch (RemoteException e) {
Log.e(TAG, "RemoteException while registering service callback for hub (ID = "
+ contextHubId + ")", e);
}
// Do a query to initialize the service cache list of nanoapps
// TODO(b/69270990): Remove this when old API is deprecated
queryNanoAppsInternal(contextHubId);
}
mDefaultClientMap = Collections.unmodifiableMap(defaultClientMap);
if (mContextHubWrapper.supportsLocationSettingNotifications()) {
sendLocationSettingUpdate();
mContext.getContentResolver().registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.LOCATION_MODE),
true /* notifyForDescendants */,
new ContentObserver(null /* handler */) {
@Override
public void onChange(boolean selfChange) {
sendLocationSettingUpdate();
}
}, UserHandle.USER_ALL);
}
if (mContextHubWrapper.supportsWifiSettingNotifications()) {
sendWifiSettingUpdate(true /* forceUpdate */);
BroadcastReceiver wifiReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())
|| WifiManager.ACTION_WIFI_SCAN_AVAILABILITY_CHANGED.equals(
intent.getAction())) {
sendWifiSettingUpdate(false /* forceUpdate */);
}
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.ACTION_WIFI_SCAN_AVAILABILITY_CHANGED);
mContext.registerReceiver(wifiReceiver, filter);
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE),
true /* notifyForDescendants */,
new ContentObserver(null /* handler */) {
@Override
public void onChange(boolean selfChange) {
sendWifiSettingUpdate(false /* forceUpdate */);
}
}, UserHandle.USER_ALL);
}
if (mContextHubWrapper.supportsAirplaneModeSettingNotifications()) {
sendAirplaneModeSettingUpdate();
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON),
true /* notifyForDescendants */,
new ContentObserver(null /* handler */) {
@Override
public void onChange(boolean selfChange) {
sendAirplaneModeSettingUpdate();
}
}, UserHandle.USER_ALL);
}
if (mContextHubWrapper.supportsMicrophoneSettingNotifications()) {
sendMicrophoneDisableSettingUpdateForCurrentUser();
mSensorPrivacyManagerInternal.addSensorPrivacyListenerForAllUsers(
SensorPrivacyManager.Sensors.MICROPHONE, (userId, enabled) -> {
if (userId == getCurrentUserId()) {
Log.d(TAG, "User: " + userId + "mic privacy: " + enabled);
sendMicrophoneDisableSettingUpdate(enabled);
}
});
}
if (mContextHubWrapper.supportsBtSettingNotifications()) {
sendBtSettingUpdate(true /* forceUpdate */);
BroadcastReceiver btReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())
|| BluetoothAdapter.ACTION_BLE_STATE_CHANGED.equals(
intent.getAction())) {
sendBtSettingUpdate(false /* forceUpdate */);
}
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothAdapter.ACTION_BLE_STATE_CHANGED);
mContext.registerReceiver(btReceiver, filter);
}
scheduleDailyMetricSnapshot();
init(contextHubWrapper, /* isFirstInit= */ true);
}
/**
@@ -437,21 +290,209 @@ public class ContextHubService extends IContextHubService.Stub {
}
/**
* @return the IContextHubWrapper interface
* Initializes the private state of the ContextHubService
*
* @param startTimeNs the start time when init was called
* @param isFirstInit if true, this is the first time init is called - boot time
*
* @return if mContextHubWrapper is not null and a full state init was done
*/
private IContextHubWrapper getContextHubWrapper() {
IContextHubWrapper wrapper = IContextHubWrapper.maybeConnectToAidl();
if (wrapper == null) {
wrapper = IContextHubWrapper.maybeConnectTo1_2();
}
if (wrapper == null) {
wrapper = IContextHubWrapper.maybeConnectTo1_1();
}
if (wrapper == null) {
wrapper = IContextHubWrapper.maybeConnectTo1_0();
private boolean initContextHubServiceState(long startTimeNs, boolean isFirstInit) {
if (mContextHubWrapper == null) {
mTransactionManager = null;
mClientManager = null;
mSensorPrivacyManagerInternal = null;
mDefaultClientMap = Collections.emptyMap();
mContextHubIdToInfoMap = Collections.emptyMap();
mSupportedContextHubPerms = Collections.emptyList();
mContextHubInfoList = Collections.emptyList();
return false;
}
return wrapper;
Pair<List<ContextHubInfo>, List<String>> hubInfo;
try {
hubInfo = mContextHubWrapper.getHubs();
} catch (RemoteException e) {
Log.e(TAG, "RemoteException while getting Context Hub info", e);
hubInfo = new Pair(Collections.emptyList(), Collections.emptyList());
}
if (isFirstInit) {
long bootTimeNs = SystemClock.elapsedRealtimeNanos() - startTimeNs;
int numContextHubs = hubInfo.first.size();
ContextHubStatsLog.write(ContextHubStatsLog.CONTEXT_HUB_BOOTED, bootTimeNs,
numContextHubs);
}
mContextHubIdToInfoMap = Collections.unmodifiableMap(
ContextHubServiceUtil.createContextHubInfoMap(hubInfo.first));
mSupportedContextHubPerms = hubInfo.second;
mContextHubInfoList = new ArrayList<>(mContextHubIdToInfoMap.values());
mClientManager = new ContextHubClientManager(mContext, mContextHubWrapper);
mTransactionManager = new ContextHubTransactionManager(
mContextHubWrapper, mClientManager, mNanoAppStateManager);
mSensorPrivacyManagerInternal =
LocalServices.getService(SensorPrivacyManagerInternal.class);
return true;
}
/**
* Creates the default client map that maps context hub IDs to the associated
* ClientManager. The client map is unmodifiable
*/
private void initDefaultClientMap() {
HashMap<Integer, IContextHubClient> defaultClientMap = new HashMap<>();
for (int contextHubId : mContextHubIdToInfoMap.keySet()) {
mLastRestartTimestampMap.put(contextHubId,
new AtomicLong(SystemClock.elapsedRealtimeNanos()));
ContextHubInfo contextHubInfo = mContextHubIdToInfoMap.get(contextHubId);
IContextHubClient client = mClientManager.registerClient(
contextHubInfo, createDefaultClientCallback(contextHubId),
/* attributionTag= */ null, mTransactionManager, mContext.getPackageName());
defaultClientMap.put(contextHubId, client);
try {
mContextHubWrapper.registerCallback(contextHubId,
new ContextHubServiceCallback(contextHubId));
} catch (RemoteException e) {
Log.e(TAG, "RemoteException while registering service callback for hub (ID = "
+ contextHubId + ")", e);
}
// Do a query to initialize the service cache list of nanoapps
// TODO(b/194289715): Remove this when old API is deprecated
queryNanoAppsInternal(contextHubId);
}
mDefaultClientMap = Collections.unmodifiableMap(defaultClientMap);
}
/**
* Handles the initialization of location settings notifications
*/
private void initLocationSettingNotifications() {
if (mContextHubWrapper == null
|| !mContextHubWrapper.supportsLocationSettingNotifications()) {
return;
}
sendLocationSettingUpdate();
mContext.getContentResolver().registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.LOCATION_MODE),
/* notifyForDescendants= */ true,
new ContentObserver(/* handler= */ null) {
@Override
public void onChange(boolean selfChange) {
sendLocationSettingUpdate();
}
}, UserHandle.USER_ALL);
}
/**
* Handles the initialization of wifi settings notifications
*/
private void initWifiSettingNotifications() {
if (mContextHubWrapper == null || !mContextHubWrapper.supportsWifiSettingNotifications()) {
return;
}
sendWifiSettingUpdate(/* forceUpdate= */ true);
BroadcastReceiver wifiReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())
|| WifiManager.ACTION_WIFI_SCAN_AVAILABILITY_CHANGED.equals(
intent.getAction())) {
sendWifiSettingUpdate(/* forceUpdate= */ false);
}
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.ACTION_WIFI_SCAN_AVAILABILITY_CHANGED);
mContext.registerReceiver(wifiReceiver, filter);
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE),
/* notifyForDescendants= */ true,
new ContentObserver(/* handler= */ null) {
@Override
public void onChange(boolean selfChange) {
sendWifiSettingUpdate(/* forceUpdate= */ false);
}
}, UserHandle.USER_ALL);
}
/**
* Handles the initialization of airplane mode settings notifications
*/
private void initAirplaneModeSettingNotifications() {
if (mContextHubWrapper == null
|| !mContextHubWrapper.supportsAirplaneModeSettingNotifications()) {
return;
}
sendAirplaneModeSettingUpdate();
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON),
/* notifyForDescendants= */ true,
new ContentObserver(/* handler= */ null) {
@Override
public void onChange(boolean selfChange) {
sendAirplaneModeSettingUpdate();
}
}, UserHandle.USER_ALL);
}
/**
* Handles the initialization of microphone settings notifications
*/
private void initMicrophoneSettingNotifications() {
if (mContextHubWrapper == null
|| !mContextHubWrapper.supportsMicrophoneSettingNotifications()) {
return;
}
sendMicrophoneDisableSettingUpdateForCurrentUser();
if (mSensorPrivacyManagerInternal == null) {
Log.e(TAG, "Unable to add a sensor privacy listener for all users");
return;
}
mSensorPrivacyManagerInternal.addSensorPrivacyListenerForAllUsers(
SensorPrivacyManager.Sensors.MICROPHONE, (userId, enabled) -> {
if (userId == getCurrentUserId()) {
Log.d(TAG, "User: " + userId + "mic privacy: " + enabled);
sendMicrophoneDisableSettingUpdate(enabled);
}
});
}
/**
* Handles the initialization of bluetooth settings notifications
*/
private void initBtSettingNotifications() {
if (mContextHubWrapper == null || !mContextHubWrapper.supportsBtSettingNotifications()) {
return;
}
sendBtSettingUpdate(/* forceUpdate= */ true);
BroadcastReceiver btReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())
|| BluetoothAdapter.ACTION_BLE_STATE_CHANGED.equals(
intent.getAction())) {
sendBtSettingUpdate(/* forceUpdate= */ false);
}
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothAdapter.ACTION_BLE_STATE_CHANGED);
mContext.registerReceiver(btReceiver, filter);
}
@Override
@@ -707,6 +748,31 @@ public class ContextHubService extends IContextHubService.Stub {
return success ? 0 : -1;
}
/**
* Handles a service restart or service init for the first time
*
* @param contextHubWrapper the Context Hub wrapper
* @param isFirstInit if true, this is the first time init is called - boot time
*/
private void init(IContextHubWrapper contextHubWrapper, boolean isFirstInit) {
Log.i(TAG, "Starting Context Hub Service init");
long startTimeNs = SystemClock.elapsedRealtimeNanos();
mContextHubWrapper = contextHubWrapper;
if (!initContextHubServiceState(startTimeNs, isFirstInit)) {
Log.e(TAG, "Failed to initialize the Context Hub Service");
return;
}
initDefaultClientMap();
initLocationSettingNotifications();
initWifiSettingNotifications();
initAirplaneModeSettingNotifications();
initMicrophoneSettingNotifications();
initBtSettingNotifications();
scheduleDailyMetricSnapshot();
}
/**
* Handles a unicast or broadcast message from a nanoapp.
*
@@ -729,7 +795,7 @@ public class ContextHubService extends IContextHubService.Stub {
/**
* A helper function to handle a load response from the Context Hub for the old API.
* TODO(b/69270990): Remove this once the old APIs are obsolete.
* TODO(b/194289715): Remove this once the old APIs are obsolete.
*/
private void handleLoadResponseOldApi(
int contextHubId, int result, NanoAppBinary nanoAppBinary) {
@@ -750,7 +816,7 @@ public class ContextHubService extends IContextHubService.Stub {
/**
* A helper function to handle an unload response from the Context Hub for the old API.
* <p>
* TODO(b/69270990): Remove this once the old APIs are obsolete.
* TODO(b/194289715): Remove this once the old APIs are obsolete.
*/
private void handleUnloadResponseOldApi(int contextHubId, int result) {
byte[] data = new byte[1];
@@ -788,10 +854,10 @@ public class ContextHubService extends IContextHubService.Stub {
ContextHubEventLogger.getInstance().logContextHubRestart(contextHubId);
sendLocationSettingUpdate();
sendWifiSettingUpdate(true /* forceUpdate */);
sendWifiSettingUpdate(/* forceUpdate= */ true);
sendAirplaneModeSettingUpdate();
sendMicrophoneDisableSettingUpdateForCurrentUser();
sendBtSettingUpdate(true /* forceUpdate */);
sendBtSettingUpdate(/* forceUpdate= */ true);
mTransactionManager.onHubReset();
queryNanoAppsInternal(contextHubId);
@@ -1066,8 +1132,8 @@ public class ContextHubService extends IContextHubService.Stub {
mClientManager.forEachClientOfHub(contextHubId, client -> {
if (client.getPackageName().equals(packageName)) {
client.updateNanoAppAuthState(
nanoAppId, Collections.emptyList() /* nanoappPermissions */,
false /* gracePeriodExpired */, true /* forceDenied */);
nanoAppId, /* nanoappPermissions= */ Collections.emptyList(),
/* gracePeriodExpired= */ false, /* forceDenied= */ true);
}
});
}
@@ -1151,7 +1217,7 @@ public class ContextHubService extends IContextHubService.Stub {
}
if (!isValidContextHubId(contextHubId)) {
Log.e(TAG, "Cannot start "
+ ContextHubTransaction.typeToString(transactionType, false /* upperCase */)
+ ContextHubTransaction.typeToString(transactionType, /* upperCase= */ false)
+ " transaction for invalid hub ID " + contextHubId);
try {
callback.onTransactionComplete(ContextHubTransaction.RESULT_FAILED_BAD_PARAMS);
@@ -1260,7 +1326,8 @@ public class ContextHubService extends IContextHubService.Stub {
* Hub.
*/
private void sendMicrophoneDisableSettingUpdateForCurrentUser() {
boolean isEnabled = mSensorPrivacyManagerInternal.isSensorPrivacyEnabled(
boolean isEnabled = mSensorPrivacyManagerInternal == null ? false :
mSensorPrivacyManagerInternal.isSensorPrivacyEnabled(
getCurrentUserId(), SensorPrivacyManager.Sensors.MICROPHONE);
sendMicrophoneDisableSettingUpdate(isEnabled);
}

View File

@@ -94,6 +94,24 @@ public abstract class IContextHubWrapper {
List<String> nanoappPermissions, List<String> messagePermissions);
}
/**
* @return the IContextHubWrapper interface
*/
public static IContextHubWrapper getContextHubWrapper() {
IContextHubWrapper wrapper = maybeConnectToAidl();
if (wrapper == null) {
wrapper = maybeConnectTo1_2();
}
if (wrapper == null) {
wrapper = maybeConnectTo1_1();
}
if (wrapper == null) {
wrapper = maybeConnectTo1_0();
}
return wrapper;
}
/**
* Attempts to connect to the Contexthub HAL 1.0 service, if it exists.
*

View File

@@ -0,0 +1,120 @@
/*
* 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.location.contexthub;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.hardware.location.ContextHubInfo;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.util.Pair;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import java.util.Arrays;
import java.util.List;
@RunWith(AndroidJUnit4.class)
@Presubmit
public class ContextHubServiceTest {
private static final int CONTEXT_HUB_ID = 3;
private static final String CONTEXT_HUB_STRING = "Context Hub Info Test";
private Context mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
@Mock private IContextHubWrapper mMockContextHubWrapper;
@Mock private ContextHubInfo mMockContextHubInfo;
@Rule public final MockitoRule mockito = MockitoJUnit.rule();
@Before
public void setUp() throws RemoteException {
Pair<List<ContextHubInfo>, List<String>> hubInfo =
new Pair<>(Arrays.asList(mMockContextHubInfo), Arrays.asList(""));
when(mMockContextHubInfo.getId()).thenReturn(CONTEXT_HUB_ID);
when(mMockContextHubInfo.toString()).thenReturn(CONTEXT_HUB_STRING);
when(mMockContextHubWrapper.getHubs()).thenReturn(hubInfo);
when(mMockContextHubWrapper.supportsLocationSettingNotifications())
.thenReturn(true);
when(mMockContextHubWrapper.supportsWifiSettingNotifications()).thenReturn(true);
when(mMockContextHubWrapper.supportsAirplaneModeSettingNotifications())
.thenReturn(true);
when(mMockContextHubWrapper.supportsMicrophoneSettingNotifications())
.thenReturn(true);
when(mMockContextHubWrapper.supportsBtSettingNotifications()).thenReturn(true);
}
// TODO (b/254290317): These existing tests are to setup the testing infra for the ContextHub
// service and verify the constructor correctly registers a context hub.
// We need to augment these tests to cover the full behavior of the
// ContextHub service
@Test
public void testConstructorRegistersContextHub() throws RemoteException {
ContextHubService service = new ContextHubService(mContext, mMockContextHubWrapper);
assertThat(service.getContextHubInfo(CONTEXT_HUB_ID)).isEqualTo(mMockContextHubInfo);
}
@Test
public void testConstructorRegistersNotifications() {
new ContextHubService(mContext, mMockContextHubWrapper);
verify(mMockContextHubWrapper).onAirplaneModeSettingChanged(anyBoolean());
verify(mMockContextHubWrapper).onWifiSettingChanged(anyBoolean());
verify(mMockContextHubWrapper).onWifiScanningSettingChanged(anyBoolean());
verify(mMockContextHubWrapper).onWifiMainSettingChanged(anyBoolean());
verify(mMockContextHubWrapper).onAirplaneModeSettingChanged(anyBoolean());
verify(mMockContextHubWrapper).onMicrophoneSettingChanged(anyBoolean());
verify(mMockContextHubWrapper).onBtScanningSettingChanged(anyBoolean());
verify(mMockContextHubWrapper).onBtMainSettingChanged(anyBoolean());
}
@Test
public void testConstructorRegistersNotificationsAndHandlesSettings() {
when(mMockContextHubWrapper.supportsLocationSettingNotifications())
.thenReturn(false);
when(mMockContextHubWrapper.supportsWifiSettingNotifications()).thenReturn(false);
when(mMockContextHubWrapper.supportsAirplaneModeSettingNotifications())
.thenReturn(false);
when(mMockContextHubWrapper.supportsMicrophoneSettingNotifications())
.thenReturn(false);
when(mMockContextHubWrapper.supportsBtSettingNotifications()).thenReturn(false);
new ContextHubService(mContext, mMockContextHubWrapper);
verify(mMockContextHubWrapper, never()).onAirplaneModeSettingChanged(anyBoolean());
verify(mMockContextHubWrapper, never()).onWifiSettingChanged(anyBoolean());
verify(mMockContextHubWrapper, never()).onWifiScanningSettingChanged(anyBoolean());
verify(mMockContextHubWrapper, never()).onWifiMainSettingChanged(anyBoolean());
verify(mMockContextHubWrapper, never()).onAirplaneModeSettingChanged(anyBoolean());
verify(mMockContextHubWrapper, never()).onMicrophoneSettingChanged(anyBoolean());
verify(mMockContextHubWrapper, never()).onBtScanningSettingChanged(anyBoolean());
verify(mMockContextHubWrapper, never()).onBtMainSettingChanged(anyBoolean());
}
}