Skip to content

Commit 487bb6e

Browse files
author
Jeff Brown
committed
Ensure Binder in-calls to UiModeManagerService are guarded.
Fixed a couple of problems where locks were not being taken or where the calling identity was being clear deep in the call stack whereas it should be cleared as close to the entry point possible to ensure code correctness. Bug: 7328545 Change-Id: I8ff646a772cd7f4025d5604bc35c6372c3d2428e
1 parent a2f7ca7 commit 487bb6e

1 file changed

Lines changed: 146 additions & 129 deletions

File tree

services/java/com/android/server/UiModeManagerService.java

Lines changed: 146 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
import com.android.internal.app.DisableCarModeActivity;
5252
import com.android.server.TwilightService.TwilightState;
5353

54-
class UiModeManagerService extends IUiModeManager.Stub {
54+
final class UiModeManagerService extends IUiModeManager.Stub {
5555
private static final String TAG = UiModeManager.class.getSimpleName();
5656
private static final boolean LOG = false;
5757

@@ -186,57 +186,79 @@ public UiModeManagerService(Context context, TwilightService twilight) {
186186
mTwilightService.registerListener(mTwilightListener, mHandler);
187187
}
188188

189+
@Override // Binder call
189190
public void disableCarMode(int flags) {
190-
synchronized (mLock) {
191-
setCarModeLocked(false);
192-
if (mSystemReady) {
193-
updateLocked(0, flags);
191+
final long ident = Binder.clearCallingIdentity();
192+
try {
193+
synchronized (mLock) {
194+
setCarModeLocked(false);
195+
if (mSystemReady) {
196+
updateLocked(0, flags);
197+
}
194198
}
199+
} finally {
200+
Binder.restoreCallingIdentity(ident);
195201
}
196202
}
197203

204+
@Override // Binder call
198205
public void enableCarMode(int flags) {
199-
synchronized (mLock) {
200-
setCarModeLocked(true);
201-
if (mSystemReady) {
202-
updateLocked(flags, 0);
206+
final long ident = Binder.clearCallingIdentity();
207+
try {
208+
synchronized (mLock) {
209+
setCarModeLocked(true);
210+
if (mSystemReady) {
211+
updateLocked(flags, 0);
212+
}
203213
}
214+
} finally {
215+
Binder.restoreCallingIdentity(ident);
204216
}
205217
}
206218

219+
@Override // Binder call
207220
public int getCurrentModeType() {
208-
synchronized (mLock) {
209-
return mCurUiMode & Configuration.UI_MODE_TYPE_MASK;
221+
final long ident = Binder.clearCallingIdentity();
222+
try {
223+
synchronized (mLock) {
224+
return mCurUiMode & Configuration.UI_MODE_TYPE_MASK;
225+
}
226+
} finally {
227+
Binder.restoreCallingIdentity(ident);
210228
}
211229
}
212230

213-
public void setNightMode(int mode) throws RemoteException {
214-
synchronized (mLock) {
215-
switch (mode) {
216-
case UiModeManager.MODE_NIGHT_NO:
217-
case UiModeManager.MODE_NIGHT_YES:
218-
case UiModeManager.MODE_NIGHT_AUTO:
219-
break;
220-
default:
221-
throw new IllegalArgumentException("Unknown mode: " + mode);
222-
}
223-
if (!isDoingNightMode()) {
224-
return;
225-
}
231+
@Override // Binder call
232+
public void setNightMode(int mode) {
233+
switch (mode) {
234+
case UiModeManager.MODE_NIGHT_NO:
235+
case UiModeManager.MODE_NIGHT_YES:
236+
case UiModeManager.MODE_NIGHT_AUTO:
237+
break;
238+
default:
239+
throw new IllegalArgumentException("Unknown mode: " + mode);
240+
}
226241

227-
if (mNightMode != mode) {
228-
long ident = Binder.clearCallingIdentity();
229-
Settings.Secure.putInt(mContext.getContentResolver(),
230-
Settings.Secure.UI_NIGHT_MODE, mode);
231-
Binder.restoreCallingIdentity(ident);
232-
mNightMode = mode;
233-
updateLocked(0, 0);
242+
final long ident = Binder.clearCallingIdentity();
243+
try {
244+
synchronized (mLock) {
245+
if (isDoingNightModeLocked() && mNightMode != mode) {
246+
Settings.Secure.putInt(mContext.getContentResolver(),
247+
Settings.Secure.UI_NIGHT_MODE, mode);
248+
mNightMode = mode;
249+
updateLocked(0, 0);
250+
}
234251
}
252+
} finally {
253+
Binder.restoreCallingIdentity(ident);
235254
}
236255
}
237256

238-
public int getNightMode() throws RemoteException {
239-
return mNightMode;
257+
@Override // Binder call
258+
public int getNightMode() {
259+
synchronized (mLock) {
260+
return mNightMode;
261+
}
240262
}
241263

242264
void systemReady() {
@@ -248,17 +270,17 @@ void systemReady() {
248270
}
249271
}
250272

251-
boolean isDoingNightMode() {
273+
private boolean isDoingNightModeLocked() {
252274
return mCarModeEnabled || mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED;
253275
}
254276

255-
void setCarModeLocked(boolean enabled) {
277+
private void setCarModeLocked(boolean enabled) {
256278
if (mCarModeEnabled != enabled) {
257279
mCarModeEnabled = enabled;
258280
}
259281
}
260282

261-
void updateDockState(int newState) {
283+
private void updateDockState(int newState) {
262284
synchronized (mLock) {
263285
if (newState != mDockState) {
264286
mDockState = newState;
@@ -270,7 +292,7 @@ void updateDockState(int newState) {
270292
}
271293
}
272294

273-
final static boolean isDeskDockState(int state) {
295+
private static boolean isDeskDockState(int state) {
274296
switch (state) {
275297
case Intent.EXTRA_DOCK_STATE_DESK:
276298
case Intent.EXTRA_DOCK_STATE_LE_DESK:
@@ -281,7 +303,7 @@ final static boolean isDeskDockState(int state) {
281303
}
282304
}
283305

284-
final void updateConfigurationLocked() {
306+
private void updateConfigurationLocked() {
285307
int uiMode = mTelevision ? Configuration.UI_MODE_TYPE_TELEVISION : mDefaultUiModeType;
286308
if (mCarModeEnabled) {
287309
uiMode = Configuration.UI_MODE_TYPE_CAR;
@@ -315,7 +337,7 @@ final void updateConfigurationLocked() {
315337
}
316338
}
317339

318-
final void sendConfigurationLocked() {
340+
private void sendConfigurationLocked() {
319341
if (mSetUiMode != mConfiguration.uiMode) {
320342
mSetUiMode = mConfiguration.uiMode;
321343

@@ -327,105 +349,99 @@ final void sendConfigurationLocked() {
327349
}
328350
}
329351

330-
final void updateLocked(int enableFlags, int disableFlags) {
331-
long ident = Binder.clearCallingIdentity();
352+
private void updateLocked(int enableFlags, int disableFlags) {
353+
String action = null;
354+
String oldAction = null;
355+
if (mLastBroadcastState == Intent.EXTRA_DOCK_STATE_CAR) {
356+
adjustStatusBarCarModeLocked();
357+
oldAction = UiModeManager.ACTION_EXIT_CAR_MODE;
358+
} else if (isDeskDockState(mLastBroadcastState)) {
359+
oldAction = UiModeManager.ACTION_EXIT_DESK_MODE;
360+
}
332361

333-
try {
334-
String action = null;
335-
String oldAction = null;
336-
if (mLastBroadcastState == Intent.EXTRA_DOCK_STATE_CAR) {
362+
if (mCarModeEnabled) {
363+
if (mLastBroadcastState != Intent.EXTRA_DOCK_STATE_CAR) {
337364
adjustStatusBarCarModeLocked();
338-
oldAction = UiModeManager.ACTION_EXIT_CAR_MODE;
339-
} else if (isDeskDockState(mLastBroadcastState)) {
340-
oldAction = UiModeManager.ACTION_EXIT_DESK_MODE;
341-
}
342365

343-
if (mCarModeEnabled) {
344-
if (mLastBroadcastState != Intent.EXTRA_DOCK_STATE_CAR) {
345-
adjustStatusBarCarModeLocked();
346-
347-
if (oldAction != null) {
348-
mContext.sendBroadcastAsUser(new Intent(oldAction), UserHandle.ALL);
349-
}
350-
mLastBroadcastState = Intent.EXTRA_DOCK_STATE_CAR;
351-
action = UiModeManager.ACTION_ENTER_CAR_MODE;
366+
if (oldAction != null) {
367+
mContext.sendBroadcastAsUser(new Intent(oldAction), UserHandle.ALL);
352368
}
353-
} else if (isDeskDockState(mDockState)) {
354-
if (!isDeskDockState(mLastBroadcastState)) {
355-
if (oldAction != null) {
356-
mContext.sendBroadcastAsUser(new Intent(oldAction), UserHandle.ALL);
357-
}
358-
mLastBroadcastState = mDockState;
359-
action = UiModeManager.ACTION_ENTER_DESK_MODE;
369+
mLastBroadcastState = Intent.EXTRA_DOCK_STATE_CAR;
370+
action = UiModeManager.ACTION_ENTER_CAR_MODE;
371+
}
372+
} else if (isDeskDockState(mDockState)) {
373+
if (!isDeskDockState(mLastBroadcastState)) {
374+
if (oldAction != null) {
375+
mContext.sendBroadcastAsUser(new Intent(oldAction), UserHandle.ALL);
360376
}
361-
} else {
362-
mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
363-
action = oldAction;
377+
mLastBroadcastState = mDockState;
378+
action = UiModeManager.ACTION_ENTER_DESK_MODE;
364379
}
380+
} else {
381+
mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
382+
action = oldAction;
383+
}
365384

366-
if (action != null) {
367-
if (LOG) {
368-
Slog.v(TAG, String.format(
369-
"updateLocked: preparing broadcast: action=%s enable=0x%08x disable=0x%08x",
370-
action, enableFlags, disableFlags));
371-
}
385+
if (action != null) {
386+
if (LOG) {
387+
Slog.v(TAG, String.format(
388+
"updateLocked: preparing broadcast: action=%s enable=0x%08x disable=0x%08x",
389+
action, enableFlags, disableFlags));
390+
}
372391

373-
// Send the ordered broadcast; the result receiver will receive after all
374-
// broadcasts have been sent. If any broadcast receiver changes the result
375-
// code from the initial value of RESULT_OK, then the result receiver will
376-
// not launch the corresponding dock application. This gives apps a chance
377-
// to override the behavior and stay in their app even when the device is
378-
// placed into a dock.
379-
Intent intent = new Intent(action);
380-
intent.putExtra("enableFlags", enableFlags);
381-
intent.putExtra("disableFlags", disableFlags);
382-
mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
383-
mResultReceiver, null, Activity.RESULT_OK, null, null);
384-
385-
// Attempting to make this transition a little more clean, we are going
386-
// to hold off on doing a configuration change until we have finished
387-
// the broadcast and started the home activity.
388-
mHoldingConfiguration = true;
389-
updateConfigurationLocked();
390-
} else {
391-
String category = null;
392-
if (mCarModeEnabled) {
393-
if (ENABLE_LAUNCH_CAR_DOCK_APP
394-
&& (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
395-
category = Intent.CATEGORY_CAR_DOCK;
396-
}
397-
} else if (isDeskDockState(mDockState)) {
398-
if (ENABLE_LAUNCH_DESK_DOCK_APP
399-
&& (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
400-
category = Intent.CATEGORY_DESK_DOCK;
401-
}
402-
} else {
403-
if ((disableFlags & UiModeManager.DISABLE_CAR_MODE_GO_HOME) != 0) {
404-
category = Intent.CATEGORY_HOME;
405-
}
392+
// Send the ordered broadcast; the result receiver will receive after all
393+
// broadcasts have been sent. If any broadcast receiver changes the result
394+
// code from the initial value of RESULT_OK, then the result receiver will
395+
// not launch the corresponding dock application. This gives apps a chance
396+
// to override the behavior and stay in their app even when the device is
397+
// placed into a dock.
398+
Intent intent = new Intent(action);
399+
intent.putExtra("enableFlags", enableFlags);
400+
intent.putExtra("disableFlags", disableFlags);
401+
mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
402+
mResultReceiver, null, Activity.RESULT_OK, null, null);
403+
404+
// Attempting to make this transition a little more clean, we are going
405+
// to hold off on doing a configuration change until we have finished
406+
// the broadcast and started the home activity.
407+
mHoldingConfiguration = true;
408+
updateConfigurationLocked();
409+
} else {
410+
String category = null;
411+
if (mCarModeEnabled) {
412+
if (ENABLE_LAUNCH_CAR_DOCK_APP
413+
&& (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
414+
category = Intent.CATEGORY_CAR_DOCK;
406415
}
407-
408-
if (LOG) {
409-
Slog.v(TAG, "updateLocked: null action, mDockState="
410-
+ mDockState +", category=" + category);
416+
} else if (isDeskDockState(mDockState)) {
417+
if (ENABLE_LAUNCH_DESK_DOCK_APP
418+
&& (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
419+
category = Intent.CATEGORY_DESK_DOCK;
420+
}
421+
} else {
422+
if ((disableFlags & UiModeManager.DISABLE_CAR_MODE_GO_HOME) != 0) {
423+
category = Intent.CATEGORY_HOME;
411424
}
425+
}
412426

413-
sendConfigurationAndStartDreamOrDockAppLocked(category);
427+
if (LOG) {
428+
Slog.v(TAG, "updateLocked: null action, mDockState="
429+
+ mDockState +", category=" + category);
414430
}
415431

416-
// keep screen on when charging and in car mode
417-
boolean keepScreenOn = mCharging &&
418-
((mCarModeEnabled && mCarModeKeepsScreenOn) ||
419-
(mCurUiMode == Configuration.UI_MODE_TYPE_DESK && mDeskModeKeepsScreenOn));
420-
if (keepScreenOn != mWakeLock.isHeld()) {
421-
if (keepScreenOn) {
422-
mWakeLock.acquire();
423-
} else {
424-
mWakeLock.release();
425-
}
432+
sendConfigurationAndStartDreamOrDockAppLocked(category);
433+
}
434+
435+
// keep screen on when charging and in car mode
436+
boolean keepScreenOn = mCharging &&
437+
((mCarModeEnabled && mCarModeKeepsScreenOn) ||
438+
(mCurUiMode == Configuration.UI_MODE_TYPE_DESK && mDeskModeKeepsScreenOn));
439+
if (keepScreenOn != mWakeLock.isHeld()) {
440+
if (keepScreenOn) {
441+
mWakeLock.acquire();
442+
} else {
443+
mWakeLock.release();
426444
}
427-
} finally {
428-
Binder.restoreCallingIdentity(ident);
429445
}
430446
}
431447

@@ -500,7 +516,7 @@ private void sendConfigurationAndStartDreamOrDockAppLocked(String category) {
500516

501517
// If we did not start a dock app, then start dreaming if supported.
502518
if (category != null && !dockAppStarted
503-
&& isScreenSaverEnabled() && isScreenSaverActivatedOnDock()) {
519+
&& isScreenSaverEnabledLocked() && isScreenSaverActivatedOnDockLocked()) {
504520
Slog.i(TAG, "Activating dream while docked.");
505521
try {
506522
IDreamManager dreamManagerService = IDreamManager.Stub.asInterface(
@@ -522,21 +538,22 @@ && isScreenSaverEnabled() && isScreenSaverActivatedOnDock()) {
522538
}
523539
}
524540

525-
private boolean isScreenSaverEnabled() {
541+
private boolean isScreenSaverEnabledLocked() {
526542
return Settings.Secure.getIntForUser(mContext.getContentResolver(),
527543
Settings.Secure.SCREENSAVER_ENABLED, DEFAULT_SCREENSAVER_ENABLED,
528544
UserHandle.USER_CURRENT) != 0;
529545
}
530546

531-
private boolean isScreenSaverActivatedOnDock() {
547+
private boolean isScreenSaverActivatedOnDockLocked() {
532548
return Settings.Secure.getIntForUser(mContext.getContentResolver(),
533549
Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
534550
DEFAULT_SCREENSAVER_ACTIVATED_ON_DOCK, UserHandle.USER_CURRENT) != 0;
535551
}
536552

537553
private void adjustStatusBarCarModeLocked() {
538554
if (mStatusBarManager == null) {
539-
mStatusBarManager = (StatusBarManager) mContext.getSystemService(Context.STATUS_BAR_SERVICE);
555+
mStatusBarManager = (StatusBarManager)
556+
mContext.getSystemService(Context.STATUS_BAR_SERVICE);
540557
}
541558

542559
// Fear not: StatusBarManagerService manages a list of requests to disable
@@ -581,7 +598,7 @@ private void adjustStatusBarCarModeLocked() {
581598

582599
private void updateTwilight() {
583600
synchronized (mLock) {
584-
if (isDoingNightMode() && mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
601+
if (isDoingNightModeLocked() && mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
585602
updateComputedNightModeLocked();
586603
updateLocked(0, 0);
587604
}

0 commit comments

Comments
 (0)