Merge "Fix IllegalStateException in DeviceStateManagerService" into udc-dev

This commit is contained in:
Jiaming Liu
2023-05-12 18:08:07 +00:00
committed by Android (Google) Code Review
2 changed files with 49 additions and 17 deletions

View File

@@ -205,7 +205,7 @@ public final class DeviceStateManagerService extends SystemService {
@VisibleForTesting @VisibleForTesting
DeviceStateManagerService(@NonNull Context context, @NonNull DeviceStatePolicy policy, DeviceStateManagerService(@NonNull Context context, @NonNull DeviceStatePolicy policy,
@NonNull SystemPropertySetter systemPropertySetter) { @NonNull SystemPropertySetter systemPropertySetter) {
super(context); super(context);
mSystemPropertySetter = systemPropertySetter; mSystemPropertySetter = systemPropertySetter;
// We use the DisplayThread because this service indirectly drives // We use the DisplayThread because this service indirectly drives
@@ -391,12 +391,7 @@ public final class DeviceStateManagerService extends SystemService {
setRearDisplayStateLocked(); setRearDisplayStateLocked();
if (!mPendingState.isPresent()) { notifyDeviceStateInfoChangedAsync();
// If the change in the supported states didn't result in a change of the pending
// state commitPendingState() will never be called and the callbacks will never be
// notified of the change.
notifyDeviceStateInfoChangedAsync();
}
mHandler.post(this::notifyPolicyIfNeeded); mHandler.post(this::notifyPolicyIfNeeded);
} }
@@ -460,12 +455,7 @@ public final class DeviceStateManagerService extends SystemService {
mOverrideRequestController.handleBaseStateChanged(identifier); mOverrideRequestController.handleBaseStateChanged(identifier);
updatePendingStateLocked(); updatePendingStateLocked();
if (!mPendingState.isPresent()) { notifyDeviceStateInfoChangedAsync();
// If the change in base state didn't result in a change of the pending state
// commitPendingState() will never be called and the callbacks will never be
// notified of the change.
notifyDeviceStateInfoChangedAsync();
}
mHandler.post(this::notifyPolicyIfNeeded); mHandler.post(this::notifyPolicyIfNeeded);
} }
@@ -593,6 +583,18 @@ public final class DeviceStateManagerService extends SystemService {
private void notifyDeviceStateInfoChangedAsync() { private void notifyDeviceStateInfoChangedAsync() {
synchronized (mLock) { synchronized (mLock) {
if (mPendingState.isPresent()) {
Slog.i(TAG,
"Cannot notify device state info change when pending state is present.");
return;
}
if (!mBaseState.isPresent() || !mCommittedState.isPresent()) {
Slog.e(TAG, "Cannot notify device state info change before the initial state has"
+ " been committed.");
return;
}
if (mProcessRecords.size() == 0) { if (mProcessRecords.size() == 0) {
return; return;
} }
@@ -658,7 +660,7 @@ public final class DeviceStateManagerService extends SystemService {
} }
} else { } else {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Unknown OverrideRest type: " + request.getRequestType()); "Unknown OverrideRest type: " + request.getRequestType());
} }
boolean updatedPendingState = updatePendingStateLocked(); boolean updatedPendingState = updatePendingStateLocked();

View File

@@ -88,6 +88,11 @@ public final class DeviceStateManagerServiceTest {
mProvider = new TestDeviceStateProvider(); mProvider = new TestDeviceStateProvider();
mPolicy = new TestDeviceStatePolicy(mProvider); mPolicy = new TestDeviceStatePolicy(mProvider);
mSysPropSetter = new TestSystemPropertySetter(); mSysPropSetter = new TestSystemPropertySetter();
setupDeviceStateManagerService();
flushHandler(); // Flush the handler to ensure the initial values are committed.
}
private void setupDeviceStateManagerService() {
mService = new DeviceStateManagerService(InstrumentationRegistry.getContext(), mPolicy, mService = new DeviceStateManagerService(InstrumentationRegistry.getContext(), mPolicy,
mSysPropSetter); mSysPropSetter);
@@ -97,8 +102,6 @@ public final class DeviceStateManagerServiceTest {
when(mService.mActivityTaskManagerInternal.getTopApp()) when(mService.mActivityTaskManagerInternal.getTopApp())
.thenReturn(mWindowProcessController); .thenReturn(mWindowProcessController);
when(mWindowProcessController.getPid()).thenReturn(FAKE_PROCESS_ID); when(mWindowProcessController.getPid()).thenReturn(FAKE_PROCESS_ID);
flushHandler(); // Flush the handler to ensure the initial values are committed.
} }
private void flushHandler() { private void flushHandler() {
@@ -324,6 +327,21 @@ public final class DeviceStateManagerServiceTest {
DEFAULT_DEVICE_STATE.getIdentifier()); DEFAULT_DEVICE_STATE.getIdentifier());
} }
@Test
public void registerCallback_initialValueUnavailable() throws RemoteException {
// Create a provider and a service without an initial base state.
mProvider = new TestDeviceStateProvider(null /* initialState */);
mPolicy = new TestDeviceStatePolicy(mProvider);
setupDeviceStateManagerService();
flushHandler(); // Flush the handler to ensure the initial values are committed.
TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
mService.getBinderService().registerCallback(callback);
flushHandler();
// The callback should never be called when the base state is not set yet.
assertNull(callback.getLastNotifiedInfo());
}
@Test @Test
public void requestState() throws RemoteException { public void requestState() throws RemoteException {
TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback(); TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
@@ -939,8 +957,18 @@ public final class DeviceStateManagerServiceTest {
DEFAULT_DEVICE_STATE, DEFAULT_DEVICE_STATE,
OTHER_DEVICE_STATE, OTHER_DEVICE_STATE,
DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP}; DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP};
@Nullable private final DeviceState mInitialState;
private Listener mListener; private Listener mListener;
private TestDeviceStateProvider() {
this(DEFAULT_DEVICE_STATE);
}
private TestDeviceStateProvider(@Nullable DeviceState initialState) {
mInitialState = initialState;
}
@Override @Override
public void setListener(Listener listener) { public void setListener(Listener listener) {
if (mListener != null) { if (mListener != null) {
@@ -950,7 +978,9 @@ public final class DeviceStateManagerServiceTest {
mListener = listener; mListener = listener;
mListener.onSupportedDeviceStatesChanged(mSupportedDeviceStates, mListener.onSupportedDeviceStatesChanged(mSupportedDeviceStates,
SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED); SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED);
mListener.onStateChanged(mSupportedDeviceStates[0].getIdentifier()); if (mInitialState != null) {
mListener.onStateChanged(mInitialState.getIdentifier());
}
} }
public void notifySupportedDeviceStates(DeviceState[] supportedDeviceStates) { public void notifySupportedDeviceStates(DeviceState[] supportedDeviceStates) {