Merge "health: BatteryService etc. use health AIDL HAL"
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.health;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.hardware.health.HealthInfo;
|
||||
import android.hardware.health.IHealth;
|
||||
import android.hardware.health.IHealthInfoCallback;
|
||||
import android.os.RemoteException;
|
||||
import android.os.Trace;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* On service registration, {@link #onRegistration} is called, which registers {@code this}, an
|
||||
* {@link IHealthInfoCallback}, to the health service.
|
||||
*
|
||||
* <p>When the health service has updates to health info via {@link IHealthInfoCallback}, {@link
|
||||
* HealthInfoCallback#update} is called.
|
||||
*
|
||||
* <p>AIDL variant of {@link HealthHalCallbackHidl}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
// It is made public so Mockito can access this class. It should have been package private if not
|
||||
// for testing.
|
||||
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
|
||||
public class HealthRegCallbackAidl {
|
||||
private static final String TAG = "HealthRegCallbackAidl";
|
||||
private final HealthInfoCallback mServiceInfoCallback;
|
||||
private final IHealthInfoCallback mHalInfoCallback = new HalInfoCallback();
|
||||
|
||||
HealthRegCallbackAidl(@Nullable HealthInfoCallback healthInfoCallback) {
|
||||
mServiceInfoCallback = healthInfoCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the service manager sees {@code newService} replacing {@code oldService}.
|
||||
* This unregisters the health info callback from the old service (ignoring errors), then
|
||||
* registers the health info callback to the new service.
|
||||
*
|
||||
* @param oldService the old IHealth service
|
||||
* @param newService the new IHealth service
|
||||
*/
|
||||
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
|
||||
public void onRegistration(@Nullable IHealth oldService, @NonNull IHealth newService) {
|
||||
if (mServiceInfoCallback == null) return;
|
||||
|
||||
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "HealthUnregisterCallbackAidl");
|
||||
try {
|
||||
unregisterCallback(oldService, mHalInfoCallback);
|
||||
} finally {
|
||||
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
|
||||
}
|
||||
|
||||
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "HealthRegisterCallbackAidl");
|
||||
try {
|
||||
registerCallback(newService, mHalInfoCallback);
|
||||
} finally {
|
||||
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
|
||||
}
|
||||
}
|
||||
|
||||
private static void unregisterCallback(@Nullable IHealth oldService, IHealthInfoCallback cb) {
|
||||
if (oldService == null) return;
|
||||
try {
|
||||
oldService.unregisterCallback(cb);
|
||||
} catch (RemoteException e) {
|
||||
// Ignore errors. The service might have died.
|
||||
Slog.w(
|
||||
TAG,
|
||||
"health: cannot unregister previous callback (transaction error): "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static void registerCallback(@NonNull IHealth newService, IHealthInfoCallback cb) {
|
||||
try {
|
||||
newService.registerCallback(cb);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(
|
||||
TAG,
|
||||
"health: cannot register callback, framework may cease to"
|
||||
+ " receive updates on health / battery info!",
|
||||
e);
|
||||
return;
|
||||
}
|
||||
// registerCallback does NOT guarantee that update is called immediately, so request a
|
||||
// manual update here.
|
||||
try {
|
||||
newService.update();
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "health: cannot update after registering health info callback", e);
|
||||
}
|
||||
}
|
||||
|
||||
private class HalInfoCallback extends IHealthInfoCallback.Stub {
|
||||
@Override
|
||||
public void healthInfoChanged(HealthInfo healthInfo) throws RemoteException {
|
||||
mServiceInfoCallback.update(healthInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,6 +81,8 @@ public abstract class HealthServiceWrapper {
|
||||
public static HealthServiceWrapper create(@Nullable HealthInfoCallback healthInfoCallback)
|
||||
throws RemoteException, NoSuchElementException {
|
||||
return create(
|
||||
healthInfoCallback == null ? null : new HealthRegCallbackAidl(healthInfoCallback),
|
||||
new HealthServiceWrapperAidl.ServiceManagerStub() {},
|
||||
healthInfoCallback == null ? null : new HealthHalCallbackHidl(healthInfoCallback),
|
||||
new HealthServiceWrapperHidl.IServiceManagerSupplier() {},
|
||||
new HealthServiceWrapperHidl.IHealthSupplier() {});
|
||||
@@ -89,6 +91,9 @@ public abstract class HealthServiceWrapper {
|
||||
/**
|
||||
* Create a new HealthServiceWrapper instance for testing.
|
||||
*
|
||||
* @param aidlRegCallback callback for AIDL service registration, or {@code null} if the client
|
||||
* does not care about AIDL service registration notifications
|
||||
* @param aidlServiceManager Stub for AIDL ServiceManager
|
||||
* @param hidlRegCallback callback for HIDL service registration, or {@code null} if the client
|
||||
* does not care about HIDL service registration notifications
|
||||
* @param hidlServiceManagerSupplier supplier of HIDL service manager
|
||||
@@ -97,10 +102,17 @@ public abstract class HealthServiceWrapper {
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static @NonNull HealthServiceWrapper create(
|
||||
@Nullable HealthRegCallbackAidl aidlRegCallback,
|
||||
@NonNull HealthServiceWrapperAidl.ServiceManagerStub aidlServiceManager,
|
||||
@Nullable HealthServiceWrapperHidl.Callback hidlRegCallback,
|
||||
@NonNull HealthServiceWrapperHidl.IServiceManagerSupplier hidlServiceManagerSupplier,
|
||||
@NonNull HealthServiceWrapperHidl.IHealthSupplier hidlHealthSupplier)
|
||||
throws RemoteException, NoSuchElementException {
|
||||
try {
|
||||
return new HealthServiceWrapperAidl(aidlRegCallback, aidlServiceManager);
|
||||
} catch (NoSuchElementException e) {
|
||||
// Ignore, try HIDL
|
||||
}
|
||||
return new HealthServiceWrapperHidl(
|
||||
hidlRegCallback, hidlServiceManagerSupplier, hidlHealthSupplier);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.health;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.hardware.health.HealthInfo;
|
||||
import android.hardware.health.IHealth;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.BatteryProperty;
|
||||
import android.os.Binder;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.os.IServiceCallback;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.ServiceSpecificException;
|
||||
import android.os.Trace;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* Implement {@link HealthServiceWrapper} backed by the AIDL HAL.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
class HealthServiceWrapperAidl extends HealthServiceWrapper {
|
||||
private static final String TAG = "HealthServiceWrapperAidl";
|
||||
@VisibleForTesting static final String SERVICE_NAME = IHealth.DESCRIPTOR + "/default";
|
||||
private final HandlerThread mHandlerThread = new HandlerThread("HealthServiceBinder");
|
||||
private final AtomicReference<IHealth> mLastService = new AtomicReference<>();
|
||||
private final IServiceCallback mServiceCallback = new ServiceCallback();
|
||||
private final HealthRegCallbackAidl mRegCallback;
|
||||
|
||||
/** Stub interface into {@link ServiceManager} for testing. */
|
||||
interface ServiceManagerStub {
|
||||
default @Nullable IHealth waitForDeclaredService(@NonNull String name) {
|
||||
return IHealth.Stub.asInterface(ServiceManager.waitForDeclaredService(name));
|
||||
}
|
||||
|
||||
default void registerForNotifications(
|
||||
@NonNull String name, @NonNull IServiceCallback callback) throws RemoteException {
|
||||
ServiceManager.registerForNotifications(name, callback);
|
||||
}
|
||||
}
|
||||
|
||||
HealthServiceWrapperAidl(
|
||||
@Nullable HealthRegCallbackAidl regCallback, @NonNull ServiceManagerStub serviceManager)
|
||||
throws RemoteException, NoSuchElementException {
|
||||
|
||||
traceBegin("HealthInitGetServiceAidl");
|
||||
IHealth newService;
|
||||
try {
|
||||
newService = serviceManager.waitForDeclaredService(SERVICE_NAME);
|
||||
} finally {
|
||||
traceEnd();
|
||||
}
|
||||
if (newService == null) {
|
||||
throw new NoSuchElementException(
|
||||
"IHealth service instance isn't available. Perhaps no permission?");
|
||||
}
|
||||
mLastService.set(newService);
|
||||
mRegCallback = regCallback;
|
||||
if (mRegCallback != null) {
|
||||
mRegCallback.onRegistration(null /* oldService */, newService);
|
||||
}
|
||||
|
||||
traceBegin("HealthInitRegisterNotificationAidl");
|
||||
mHandlerThread.start();
|
||||
try {
|
||||
serviceManager.registerForNotifications(SERVICE_NAME, mServiceCallback);
|
||||
} finally {
|
||||
traceEnd();
|
||||
}
|
||||
Slog.i(TAG, "health: HealthServiceWrapper listening to AIDL HAL");
|
||||
}
|
||||
|
||||
@Override
|
||||
@VisibleForTesting
|
||||
public HandlerThread getHandlerThread() {
|
||||
return mHandlerThread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProperty(int id, BatteryProperty prop) throws RemoteException {
|
||||
traceBegin("HealthGetPropertyAidl");
|
||||
try {
|
||||
return getPropertyInternal(id, prop);
|
||||
} finally {
|
||||
traceEnd();
|
||||
}
|
||||
}
|
||||
|
||||
private int getPropertyInternal(int id, BatteryProperty prop) throws RemoteException {
|
||||
IHealth service = mLastService.get();
|
||||
if (service == null) throw new RemoteException("no health service");
|
||||
try {
|
||||
switch (id) {
|
||||
case BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER:
|
||||
prop.setLong(service.getChargeCounterUah());
|
||||
break;
|
||||
case BatteryManager.BATTERY_PROPERTY_CURRENT_NOW:
|
||||
prop.setLong(service.getCurrentNowMicroamps());
|
||||
break;
|
||||
case BatteryManager.BATTERY_PROPERTY_CURRENT_AVERAGE:
|
||||
prop.setLong(service.getCurrentAverageMicroamps());
|
||||
break;
|
||||
case BatteryManager.BATTERY_PROPERTY_CAPACITY:
|
||||
prop.setLong(service.getCapacity());
|
||||
break;
|
||||
case BatteryManager.BATTERY_PROPERTY_STATUS:
|
||||
prop.setLong(service.getChargeStatus());
|
||||
break;
|
||||
case BatteryManager.BATTERY_PROPERTY_ENERGY_COUNTER:
|
||||
prop.setLong(service.getEnergyCounterNwh());
|
||||
break;
|
||||
}
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// Leave prop untouched.
|
||||
return -1;
|
||||
} catch (ServiceSpecificException e) {
|
||||
// Leave prop untouched.
|
||||
return -2;
|
||||
}
|
||||
// throws RemoteException as-is. BatteryManager wraps it into a RuntimeException
|
||||
// and throw it to apps.
|
||||
|
||||
// If no error, return 0.
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scheduleUpdate() throws RemoteException {
|
||||
getHandlerThread()
|
||||
.getThreadHandler()
|
||||
.post(
|
||||
() -> {
|
||||
traceBegin("HealthScheduleUpdate");
|
||||
try {
|
||||
IHealth service = mLastService.get();
|
||||
if (service == null) {
|
||||
Slog.e(TAG, "no health service");
|
||||
return;
|
||||
}
|
||||
service.update();
|
||||
} catch (RemoteException | ServiceSpecificException ex) {
|
||||
Slog.e(TAG, "Cannot call update on health AIDL HAL", ex);
|
||||
} finally {
|
||||
traceEnd();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public HealthInfo getHealthInfo() throws RemoteException {
|
||||
IHealth service = mLastService.get();
|
||||
if (service == null) return null;
|
||||
try {
|
||||
return service.getHealthInfo();
|
||||
} catch (UnsupportedOperationException | ServiceSpecificException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void traceBegin(String name) {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, name);
|
||||
}
|
||||
|
||||
private static void traceEnd() {
|
||||
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
|
||||
}
|
||||
|
||||
private class ServiceCallback extends IServiceCallback.Stub {
|
||||
@Override
|
||||
public void onRegistration(String name, @NonNull final IBinder newBinder)
|
||||
throws RemoteException {
|
||||
if (!SERVICE_NAME.equals(name)) return;
|
||||
// This runnable only runs on mHandlerThread and ordering is ensured, hence
|
||||
// no locking is needed inside the runnable.
|
||||
getHandlerThread()
|
||||
.getThreadHandler()
|
||||
.post(
|
||||
() -> {
|
||||
IHealth newService =
|
||||
IHealth.Stub.asInterface(Binder.allowBlocking(newBinder));
|
||||
IHealth oldService = mLastService.getAndSet(newService);
|
||||
IBinder oldBinder =
|
||||
oldService != null ? oldService.asBinder() : null;
|
||||
if (Objects.equals(newBinder, oldBinder)) return;
|
||||
|
||||
Slog.i(TAG, "New health AIDL HAL service registered");
|
||||
mRegCallback.onRegistration(oldService, newService);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,11 +19,12 @@ package com.android.server.health;
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.fail;
|
||||
|
||||
import static org.mockito.AdditionalMatchers.not;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import android.hardware.health.V2_0.IHealth;
|
||||
import android.hidl.manager.V1_0.IServiceManager;
|
||||
import android.hidl.manager.V1_0.IServiceNotification;
|
||||
import android.os.IServiceCallback;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
@@ -44,28 +45,47 @@ import java.util.NoSuchElementException;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class HealthServiceWrapperTest {
|
||||
|
||||
@Mock IServiceManager mMockedManager;
|
||||
@Mock IHealth mMockedHal;
|
||||
@Mock IHealth mMockedHal2;
|
||||
@Mock android.hardware.health.V2_0.IHealth mMockedHal;
|
||||
@Mock android.hardware.health.V2_0.IHealth mMockedHal2;
|
||||
|
||||
@Mock HealthServiceWrapperHidl.Callback mCallback;
|
||||
@Mock HealthServiceWrapperHidl.IServiceManagerSupplier mManagerSupplier;
|
||||
@Mock HealthServiceWrapperHidl.IHealthSupplier mHealthServiceSupplier;
|
||||
|
||||
@Mock android.hardware.health.IHealth.Stub mMockedAidlHal;
|
||||
@Mock android.hardware.health.IHealth.Stub mMockedAidlHal2;
|
||||
@Mock HealthServiceWrapperAidl.ServiceManagerStub mMockedAidlManager;
|
||||
@Mock HealthRegCallbackAidl mRegCallbackAidl;
|
||||
|
||||
HealthServiceWrapper mWrapper;
|
||||
|
||||
private static final String VENDOR = HealthServiceWrapperHidl.INSTANCE_VENDOR;
|
||||
private static final String AIDL_SERVICE_NAME = HealthServiceWrapperAidl.SERVICE_NAME;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
// Mocks the conversion between IHealth and IBinder.
|
||||
when(mMockedAidlHal.asBinder()).thenCallRealMethod(); // returns mMockedAidlHal
|
||||
when(mMockedAidlHal2.asBinder()).thenCallRealMethod(); // returns mMockedAidlHal2
|
||||
when(mMockedAidlHal.queryLocalInterface(android.hardware.health.IHealth.DESCRIPTOR))
|
||||
.thenReturn(mMockedAidlHal);
|
||||
when(mMockedAidlHal2.queryLocalInterface(android.hardware.health.IHealth.DESCRIPTOR))
|
||||
.thenReturn(mMockedAidlHal2);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
validateMockitoUsage();
|
||||
if (mWrapper != null) mWrapper.getHandlerThread().quitSafely();
|
||||
}
|
||||
|
||||
public static <T> ArgumentMatcher<T> isOneOf(T[] collection) {
|
||||
return isOneOf(Arrays.asList(collection));
|
||||
}
|
||||
|
||||
public static <T> ArgumentMatcher<T> isOneOf(Collection<T> collection) {
|
||||
return new ArgumentMatcher<T>() {
|
||||
@Override
|
||||
@@ -75,13 +95,39 @@ public class HealthServiceWrapperTest {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return collection.toString();
|
||||
return "is one of " + collection.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void initForInstances(String... instanceNamesArr) throws Exception {
|
||||
final Collection<String> instanceNames = Arrays.asList(instanceNamesArr);
|
||||
/**
|
||||
* Set up mock objects to pretend that the given AIDL and HIDL instances exists.
|
||||
*
|
||||
* <p>Also, when registering service notifications, the mocked service managers immediately
|
||||
* sends 3 registration notifications, including 2 referring to the original HAL and 1 referring
|
||||
* to the new HAL.
|
||||
*
|
||||
* @param aidlInstances e.g. {"android.hardware.health.IHealth/default"}
|
||||
* @param hidlInstances e.g. {"default", "backup"}
|
||||
* @throws Exception
|
||||
*/
|
||||
private void initForInstances(String[] aidlInstances, String[] hidlInstances) throws Exception {
|
||||
doAnswer(
|
||||
(invocation) -> {
|
||||
sendAidlRegCallback(invocation, mMockedAidlHal);
|
||||
sendAidlRegCallback(invocation, mMockedAidlHal);
|
||||
sendAidlRegCallback(invocation, mMockedAidlHal2);
|
||||
return null;
|
||||
})
|
||||
.when(mMockedAidlManager)
|
||||
.registerForNotifications(
|
||||
argThat(isOneOf(aidlInstances)), any(IServiceCallback.class));
|
||||
when(mMockedAidlManager.waitForDeclaredService(argThat(isOneOf(aidlInstances))))
|
||||
.thenReturn(mMockedAidlHal)
|
||||
.thenThrow(new RuntimeException("waitForDeclaredService called more than once"));
|
||||
when(mMockedAidlManager.waitForDeclaredService(not(argThat(isOneOf(aidlInstances)))))
|
||||
.thenReturn(null);
|
||||
|
||||
doAnswer(
|
||||
(invocation) -> {
|
||||
// technically, preexisting is ignored by
|
||||
@@ -93,8 +139,8 @@ public class HealthServiceWrapperTest {
|
||||
})
|
||||
.when(mMockedManager)
|
||||
.registerForNotifications(
|
||||
eq(IHealth.kInterfaceName),
|
||||
argThat(isOneOf(instanceNames)),
|
||||
eq(android.hardware.health.V2_0.IHealth.kInterfaceName),
|
||||
argThat(isOneOf(hidlInstances)),
|
||||
any(IServiceNotification.class));
|
||||
|
||||
doReturn(mMockedManager).when(mManagerSupplier).get();
|
||||
@@ -104,7 +150,7 @@ public class HealthServiceWrapperTest {
|
||||
.doReturn(mMockedHal2) // notification 3
|
||||
.doThrow(new RuntimeException("Should not call getService for more than 4 times"))
|
||||
.when(mHealthServiceSupplier)
|
||||
.get(argThat(isOneOf(instanceNames)));
|
||||
.get(argThat(isOneOf(hidlInstances)));
|
||||
}
|
||||
|
||||
private void waitHandlerThreadFinish() throws Exception {
|
||||
@@ -121,19 +167,62 @@ public class HealthServiceWrapperTest {
|
||||
throws Exception {
|
||||
((IServiceNotification) invocation.getArguments()[2])
|
||||
.onRegistration(
|
||||
IHealth.kInterfaceName, (String) invocation.getArguments()[1], preexisting);
|
||||
android.hardware.health.V2_0.IHealth.kInterfaceName,
|
||||
(String) invocation.getArguments()[1],
|
||||
preexisting);
|
||||
}
|
||||
|
||||
private static void sendAidlRegCallback(
|
||||
InvocationOnMock invocation, android.hardware.health.IHealth service) throws Exception {
|
||||
((IServiceCallback) invocation.getArguments()[1])
|
||||
.onRegistration((String) invocation.getArguments()[0], service.asBinder());
|
||||
}
|
||||
|
||||
private void createWrapper() throws RemoteException {
|
||||
mWrapper = HealthServiceWrapper.create(mCallback, mManagerSupplier, mHealthServiceSupplier);
|
||||
mWrapper =
|
||||
HealthServiceWrapper.create(
|
||||
mRegCallbackAidl,
|
||||
mMockedAidlManager,
|
||||
mCallback,
|
||||
mManagerSupplier,
|
||||
mHealthServiceSupplier);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
@Test
|
||||
public void testWrapPreferVendor() throws Exception {
|
||||
initForInstances(VENDOR);
|
||||
public void testWrapAidlOnly() throws Exception {
|
||||
initForInstances(new String[] {AIDL_SERVICE_NAME}, new String[0]);
|
||||
createWrapper();
|
||||
waitHandlerThreadFinish();
|
||||
verify(mRegCallbackAidl, times(1)).onRegistration(same(null), same(mMockedAidlHal));
|
||||
verify(mRegCallbackAidl, never())
|
||||
.onRegistration(same(mMockedAidlHal), same(mMockedAidlHal));
|
||||
verify(mRegCallbackAidl, times(1))
|
||||
.onRegistration(same(mMockedAidlHal), same(mMockedAidlHal2));
|
||||
verify(mCallback, never()).onRegistration(any(), any(), anyString());
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
@Test
|
||||
public void testWrapPreferAidl() throws Exception {
|
||||
initForInstances(new String[] {AIDL_SERVICE_NAME}, new String[] {VENDOR});
|
||||
createWrapper();
|
||||
waitHandlerThreadFinish();
|
||||
verify(mRegCallbackAidl, times(1)).onRegistration(same(null), same(mMockedAidlHal));
|
||||
verify(mRegCallbackAidl, never())
|
||||
.onRegistration(same(mMockedAidlHal), same(mMockedAidlHal));
|
||||
verify(mRegCallbackAidl, times(1))
|
||||
.onRegistration(same(mMockedAidlHal), same(mMockedAidlHal2));
|
||||
verify(mCallback, never()).onRegistration(any(), any(), anyString());
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
@Test
|
||||
public void testWrapFallbackHidl() throws Exception {
|
||||
initForInstances(new String[0], new String[] {VENDOR});
|
||||
createWrapper();
|
||||
waitHandlerThreadFinish();
|
||||
verify(mRegCallbackAidl, never()).onRegistration(any(), any());
|
||||
verify(mCallback, times(1)).onRegistration(same(null), same(mMockedHal), eq(VENDOR));
|
||||
verify(mCallback, never()).onRegistration(same(mMockedHal), same(mMockedHal), anyString());
|
||||
verify(mCallback, times(1)).onRegistration(same(mMockedHal), same(mMockedHal2), eq(VENDOR));
|
||||
@@ -142,7 +231,7 @@ public class HealthServiceWrapperTest {
|
||||
@SmallTest
|
||||
@Test
|
||||
public void testNoService() throws Exception {
|
||||
initForInstances("unrelated");
|
||||
initForInstances(new String[0], new String[] {"unrelated"});
|
||||
try {
|
||||
createWrapper();
|
||||
fail("Expect NoSuchElementException");
|
||||
|
||||
Reference in New Issue
Block a user