Skip to content

Commit fc6baa8

Browse files
Craig MautnerAndroid (Google) Code Review
authored andcommitted
Merge "Fix unprotected variable access by serializing." into jb-mr1-dev
2 parents d5fc86f + 5642a48 commit fc6baa8

File tree

2 files changed

+118
-81
lines changed

2 files changed

+118
-81
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright (C) 2012 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.android.server.wm;
18+
19+
import android.app.admin.DevicePolicyManager;
20+
import android.content.Context;
21+
import android.os.Handler;
22+
import android.os.IBinder;
23+
import android.os.Message;
24+
import android.os.TokenWatcher;
25+
import android.util.Log;
26+
import android.util.Pair;
27+
import android.view.WindowManagerPolicy;
28+
29+
public class KeyguardDisableHandler extends Handler {
30+
private static final String TAG = "KeyguardDisableHandler";
31+
32+
private static final int ALLOW_DISABLE_YES = 1;
33+
private static final int ALLOW_DISABLE_NO = 0;
34+
private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
35+
private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher
36+
37+
// Message.what constants
38+
static final int KEYGUARD_DISABLE = 1;
39+
static final int KEYGUARD_REENABLE = 2;
40+
static final int KEYGUARD_POLICY_CHANGED = 3;
41+
42+
final Context mContext;
43+
final WindowManagerPolicy mPolicy;
44+
KeyguardTokenWatcher mKeyguardTokenWatcher;
45+
46+
public KeyguardDisableHandler(final Context context, final WindowManagerPolicy policy) {
47+
mContext = context;
48+
mPolicy = policy;
49+
}
50+
51+
@SuppressWarnings("unchecked")
52+
@Override
53+
public void handleMessage(Message msg) {
54+
if (mKeyguardTokenWatcher == null) {
55+
mKeyguardTokenWatcher = new KeyguardTokenWatcher(this);
56+
}
57+
58+
switch (msg.what) {
59+
case KEYGUARD_DISABLE:
60+
final Pair<IBinder, String> pair = (Pair<IBinder, String>)msg.obj;
61+
mKeyguardTokenWatcher.acquire(pair.first, pair.second);
62+
break;
63+
64+
case KEYGUARD_REENABLE:
65+
mKeyguardTokenWatcher.release((IBinder)msg.obj);
66+
break;
67+
68+
case KEYGUARD_POLICY_CHANGED:
69+
mPolicy.enableKeyguard(true);
70+
// lazily evaluate this next time we're asked to disable keyguard
71+
mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
72+
break;
73+
}
74+
}
75+
76+
class KeyguardTokenWatcher extends TokenWatcher {
77+
78+
public KeyguardTokenWatcher(final Handler handler) {
79+
super(handler, TAG);
80+
}
81+
82+
@Override
83+
public void acquired() {
84+
// We fail safe and prevent disabling keyguard in the unlikely event this gets
85+
// called before DevicePolicyManagerService has started.
86+
if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
87+
DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
88+
Context.DEVICE_POLICY_SERVICE);
89+
if (dpm != null) {
90+
mAllowDisableKeyguard = dpm.getPasswordQuality(null)
91+
== DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
92+
ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
93+
}
94+
}
95+
if (mAllowDisableKeyguard == ALLOW_DISABLE_YES) {
96+
mPolicy.enableKeyguard(false);
97+
} else {
98+
Log.v(TAG, "Not disabling keyguard since device policy is enforced");
99+
}
100+
}
101+
102+
@Override
103+
public void released() {
104+
mPolicy.enableKeyguard(true);
105+
}
106+
}
107+
}

services/java/com/android/server/wm/WindowManagerService.java

Lines changed: 11 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@
7575
import android.graphics.RectF;
7676
import android.graphics.Region;
7777
import android.hardware.display.DisplayManager;
78-
import android.os.BatteryStats;
7978
import android.os.Binder;
8079
import android.os.Bundle;
8180
import android.os.Debug;
@@ -93,7 +92,6 @@
9392
import android.os.StrictMode;
9493
import android.os.SystemClock;
9594
import android.os.SystemProperties;
96-
import android.os.TokenWatcher;
9795
import android.os.Trace;
9896
import android.os.WorkSource;
9997
import android.provider.Settings;
@@ -279,55 +277,19 @@ public class WindowManagerService extends IWindowManager.Stub
279277
private static final String SYSTEM_SECURE = "ro.secure";
280278
private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
281279

282-
/**
283-
* Condition waited on by {@link #reenableKeyguard} to know the call to
284-
* the window policy has finished.
285-
* This is set to true only if mKeyguardTokenWatcher.acquired() has
286-
* actually disabled the keyguard.
287-
*/
288-
private boolean mKeyguardDisabled = false;
280+
final private KeyguardDisableHandler mKeyguardDisableHandler;
289281

290282
private final boolean mHeadless;
291283

292-
private static final int ALLOW_DISABLE_YES = 1;
293-
private static final int ALLOW_DISABLE_NO = 0;
294-
private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
295-
private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher
296-
297284
private static final float THUMBNAIL_ANIMATION_DECELERATE_FACTOR = 1.5f;
298285

299-
final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
300-
new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
301-
@Override
302-
public void acquired() {
303-
if (shouldAllowDisableKeyguard()) {
304-
mPolicy.enableKeyguard(false);
305-
mKeyguardDisabled = true;
306-
} else {
307-
Log.v(TAG, "Not disabling keyguard since device policy is enforced");
308-
}
309-
}
310-
@Override
311-
public void released() {
312-
mPolicy.enableKeyguard(true);
313-
synchronized (mKeyguardTokenWatcher) {
314-
mKeyguardDisabled = false;
315-
mKeyguardTokenWatcher.notifyAll();
316-
}
317-
}
318-
};
319-
320286
final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
321287
@Override
322288
public void onReceive(Context context, Intent intent) {
323289
final String action = intent.getAction();
324290
if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
325-
mPolicy.enableKeyguard(true);
326-
synchronized(mKeyguardTokenWatcher) {
327-
// lazily evaluate this next time we're asked to disable keyguard
328-
mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
329-
mKeyguardDisabled = false;
330-
}
291+
mKeyguardDisableHandler.sendEmptyMessage(
292+
KeyguardDisableHandler.KEYGUARD_POLICY_CHANGED);
331293
} else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
332294
final int newUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
333295
Slog.v(TAG, "Switching user from " + mCurrentUserId + " to " + newUserId);
@@ -898,6 +860,8 @@ private WindowManagerService(Context context, PowerManagerService pm,
898860
mDisplayManager = DisplayManager.getInstance();
899861
mHeadless = displayManager.isHeadless();
900862

863+
mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);
864+
901865
mPowerManager = pm;
902866
mPowerManager.setPolicy(mPolicy);
903867
PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
@@ -5062,59 +5026,26 @@ public void moveAppTokensToBottom(List<IBinder> tokens) {
50625026
// Misc IWindowSession methods
50635027
// -------------------------------------------------------------
50645028

5065-
private boolean shouldAllowDisableKeyguard()
5066-
{
5067-
// We fail safe and prevent disabling keyguard in the unlikely event this gets
5068-
// called before DevicePolicyManagerService has started.
5069-
if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
5070-
DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
5071-
Context.DEVICE_POLICY_SERVICE);
5072-
if (dpm != null) {
5073-
mAllowDisableKeyguard = dpm.getPasswordQuality(null)
5074-
== DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
5075-
ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
5076-
}
5077-
}
5078-
return mAllowDisableKeyguard == ALLOW_DISABLE_YES;
5079-
}
5080-
5029+
@Override
50815030
public void disableKeyguard(IBinder token, String tag) {
50825031
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
50835032
!= PackageManager.PERMISSION_GRANTED) {
50845033
throw new SecurityException("Requires DISABLE_KEYGUARD permission");
50855034
}
50865035

5087-
synchronized (mKeyguardTokenWatcher) {
5088-
mKeyguardTokenWatcher.acquire(token, tag);
5089-
}
5036+
mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
5037+
KeyguardDisableHandler.KEYGUARD_DISABLE, new Pair<IBinder, String>(token, tag)));
50905038
}
50915039

5040+
@Override
50925041
public void reenableKeyguard(IBinder token) {
50935042
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
50945043
!= PackageManager.PERMISSION_GRANTED) {
50955044
throw new SecurityException("Requires DISABLE_KEYGUARD permission");
50965045
}
50975046

5098-
synchronized (mKeyguardTokenWatcher) {
5099-
mKeyguardTokenWatcher.release(token);
5100-
5101-
if (!mKeyguardTokenWatcher.isAcquired()) {
5102-
// If we are the last one to reenable the keyguard wait until
5103-
// we have actually finished reenabling until returning.
5104-
// It is possible that reenableKeyguard() can be called before
5105-
// the previous disableKeyguard() is handled, in which case
5106-
// neither mKeyguardTokenWatcher.acquired() or released() would
5107-
// be called. In that case mKeyguardDisabled will be false here
5108-
// and we have nothing to wait for.
5109-
while (mKeyguardDisabled) {
5110-
try {
5111-
mKeyguardTokenWatcher.wait();
5112-
} catch (InterruptedException e) {
5113-
Thread.currentThread().interrupt();
5114-
}
5115-
}
5116-
}
5117-
}
5047+
mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
5048+
KeyguardDisableHandler.KEYGUARD_REENABLE, token));
51185049
}
51195050

51205051
/**
@@ -10416,7 +10347,6 @@ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1041610347
// Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
1041710348
public void monitor() {
1041810349
synchronized (mWindowMap) { }
10419-
synchronized (mKeyguardTokenWatcher) { }
1042010350
}
1042110351

1042210352
public interface OnHardKeyboardStatusChangeListener {

0 commit comments

Comments
 (0)