Don't report device state until hardware state is known.
The previous implementation of DeviceStateProviderImpl would report the current device state as soon as a listener was registered leading to a series of device state changes on boot as the state of the hardware becomes known. This changes the implementation to await callbacks before notifying the listener of a change in device state. Fixes: 181671216 Test: atest DeviceStateProviderImplTest Test: atest DeviceStateManagerServiceTest Test: atest DeviceStateManagerGlobalTest Change-Id: I3f133b6d7135b829b79c9f225ae52c71061faa3e
This commit is contained in:
@@ -179,8 +179,6 @@ public final class DeviceStateManagerGlobal {
|
||||
@VisibleForTesting(visibility = Visibility.PACKAGE)
|
||||
public void registerDeviceStateCallback(@NonNull DeviceStateCallback callback,
|
||||
@NonNull Executor executor) {
|
||||
DeviceStateCallbackWrapper wrapper;
|
||||
DeviceStateInfo currentInfo;
|
||||
synchronized (mLock) {
|
||||
int index = findCallbackLocked(callback);
|
||||
if (index != -1) {
|
||||
@@ -189,25 +187,22 @@ public final class DeviceStateManagerGlobal {
|
||||
}
|
||||
|
||||
registerCallbackIfNeededLocked();
|
||||
if (mLastReceivedInfo == null) {
|
||||
// Initialize the last received info with the current info if this is the first
|
||||
// callback being registered.
|
||||
try {
|
||||
mLastReceivedInfo = mDeviceStateManager.getDeviceStateInfo();
|
||||
} catch (RemoteException ex) {
|
||||
throw ex.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
currentInfo = new DeviceStateInfo(mLastReceivedInfo);
|
||||
|
||||
wrapper = new DeviceStateCallbackWrapper(callback, executor);
|
||||
// Add the callback wrapper to the mCallbacks array after registering the callback as
|
||||
// the callback could be triggered immediately if the mDeviceStateManager IBinder is in
|
||||
// the same process as this instance.
|
||||
DeviceStateCallbackWrapper wrapper = new DeviceStateCallbackWrapper(callback, executor);
|
||||
mCallbacks.add(wrapper);
|
||||
}
|
||||
|
||||
wrapper.notifySupportedStatesChanged(currentInfo.supportedStates);
|
||||
wrapper.notifyBaseStateChanged(currentInfo.baseState);
|
||||
wrapper.notifyStateChanged(currentInfo.currentState);
|
||||
if (mLastReceivedInfo != null) {
|
||||
// Copy the array to prevent the callback from modifying the internal state.
|
||||
final int[] supportedStates = Arrays.copyOf(mLastReceivedInfo.supportedStates,
|
||||
mLastReceivedInfo.supportedStates.length);
|
||||
wrapper.notifySupportedStatesChanged(supportedStates);
|
||||
wrapper.notifyBaseStateChanged(mLastReceivedInfo.baseState);
|
||||
wrapper.notifyStateChanged(mLastReceivedInfo.currentState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -267,7 +262,7 @@ public final class DeviceStateManagerGlobal {
|
||||
callbacks = new ArrayList<>(mCallbacks);
|
||||
}
|
||||
|
||||
final int diff = oldInfo == null ? 1 : info.diff(oldInfo);
|
||||
final int diff = oldInfo == null ? ~0 : info.diff(oldInfo);
|
||||
if ((diff & DeviceStateInfo.CHANGED_SUPPORTED_STATES) > 0) {
|
||||
for (int i = 0; i < callbacks.size(); i++) {
|
||||
// Copy the array to prevent callbacks from modifying the internal state.
|
||||
|
||||
@@ -21,7 +21,8 @@ import android.hardware.devicestate.DeviceStateInfo;
|
||||
/** @hide */
|
||||
interface IDeviceStateManagerCallback {
|
||||
/**
|
||||
* Called in response to a change in {@link DeviceStateInfo}.
|
||||
* Called in response to a change in {@link DeviceStateInfo}. Guaranteed to be called once
|
||||
* after successful registration of the callback with the initial value.
|
||||
*
|
||||
* @param info the new device state info.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user