Merge "Add keyguard background scrim and protection around keyguard APIs"
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 2ab981b3..83d6061 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2209,6 +2209,13 @@
android:label="@string/permlab_access_keyguard_secure_storage"
android:description="@string/permdesc_access_keyguard_secure_storage" />
+ <!-- Allows an application to control keyguard. Only allowed for system processes.
+ @hide -->
+ <permission android:name="android.permission.CONTROL_KEYGUARD"
+ android:protectionLevel="signature"
+ android:label="@string/permlab_control_keyguard"
+ android:description="@string/permdesc_control_keyguard" />
+
<!-- Must be required by an {@link
android.service.notification.NotificationListenerService},
to ensure that only the system can bind to it. -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index b832bbe..09be719 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3474,6 +3474,11 @@
<!-- Description of an application permission that lets an application access keyguard secure storage. -->
<string name="permdesc_access_keyguard_secure_storage">Allows an application to access keguard secure storage.</string>
+ <!-- Title of an application permission that lets it control keyguard. -->
+ <string name="permlab_control_keyguard">Control displaying and hiding keyguard</string>
+ <!-- Description of an application permission that lets it control keyguard. -->
+ <string name="permdesc_control_keyguard">Allows an application to control keguard.</string>
+
<!-- Shown in the tutorial for tap twice for zoom control. -->
<string name="tutorial_double_tap_to_zoom_message_short">Touch twice for zoom control</string>
diff --git a/packages/Keyguard/Android.mk b/packages/Keyguard/Android.mk
index 2f8edad..bc86a44 100644
--- a/packages/Keyguard/Android.mk
+++ b/packages/Keyguard/Android.mk
@@ -16,7 +16,7 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-subdir-java-files) $(call all-subdir-Iaidl-files)
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-subdir-Iaidl-files)
LOCAL_JAVA_LIBRARIES := services
@@ -28,4 +28,4 @@
include $(BUILD_PACKAGE)
-include $(call all-makefiles-under,$(LOCAL_PATH))
+#include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/Keyguard/AndroidManifest.xml b/packages/Keyguard/AndroidManifest.xml
index 38e764a..7a40a9e7 100644
--- a/packages/Keyguard/AndroidManifest.xml
+++ b/packages/Keyguard/AndroidManifest.xml
@@ -38,7 +38,7 @@
<uses-permission android:name="android.permission.BIND_DEVICE_ADMIN" />
<uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
- <application android:label="@string/app_name" android:icon="@drawable/app_icon"
+ <application android:label="@string/app_name"
android:process="com.android.systemui.keyguard"
android:persistent="true" >
diff --git a/packages/Keyguard/res/drawable-nodpi/app_icon.png b/packages/Keyguard/res/drawable-nodpi/app_icon.png
deleted file mode 100644
index ea31bd8..0000000
--- a/packages/Keyguard/res/drawable-nodpi/app_icon.png
+++ /dev/null
Binary files differ
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardService.java b/packages/Keyguard/src/com/android/keyguard/KeyguardService.java
index 9fa4790..f89ad65 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardService.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardService.java
@@ -21,7 +21,11 @@
import android.app.Service;
import android.content.Intent;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
+import android.os.Binder;
import android.os.Bundle;
+import android.os.Debug;
import android.os.IBinder;
import android.util.Log;
@@ -32,6 +36,7 @@
public class KeyguardService extends Service {
static final String TAG = "KeyguardService";
+ static final String PERMISSION = android.Manifest.permission.CONTROL_KEYGUARD;
private KeyguardViewMediator mKeyguardViewMediator;
@Override
@@ -53,6 +58,14 @@
// TODO
}
+ void checkPermission() {
+ if (getBaseContext().checkCallingOrSelfPermission(PERMISSION) != PERMISSION_GRANTED) {
+ Log.w(TAG, "Caller needs permission '" + PERMISSION + "' to call " + Debug.getCaller());
+ throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
+ + ", must have permission " + PERMISSION);
+ }
+ }
+
private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() {
public boolean isShowing() {
return mKeyguardViewMediator.isShowing();
@@ -70,48 +83,61 @@
mKeyguardViewMediator.verifyUnlock(callback);
}
public void keyguardDone(boolean authenticated, boolean wakeup) {
+ checkPermission();
mKeyguardViewMediator.keyguardDone(authenticated, wakeup);
}
public void setHidden(boolean isHidden) {
+ checkPermission();
mKeyguardViewMediator.setHidden(isHidden);
}
public void dismiss() {
mKeyguardViewMediator.dismiss();
}
public void onWakeKeyWhenKeyguardShowing(int keyCode) {
+ checkPermission();
mKeyguardViewMediator.onWakeKeyWhenKeyguardShowing(keyCode);
}
public void onWakeMotionWhenKeyguardShowing() {
+ checkPermission();
mKeyguardViewMediator.onWakeMotionWhenKeyguardShowing();
}
public void onDreamingStarted() {
+ checkPermission();
mKeyguardViewMediator.onDreamingStarted();
}
public void onDreamingStopped() {
+ checkPermission();
mKeyguardViewMediator.onDreamingStopped();
}
public void onScreenTurnedOff(int reason) {
+ checkPermission();
mKeyguardViewMediator.onScreenTurnedOff(reason);
}
public void onScreenTurnedOn(IKeyguardShowCallback callback) {
+ checkPermission();
mKeyguardViewMediator.onScreenTurnedOn(callback);
}
public void setKeyguardEnabled(boolean enabled) {
+ checkPermission();
mKeyguardViewMediator.setKeyguardEnabled(enabled);
}
public boolean isDismissable() {
return mKeyguardViewMediator.isDismissable();
}
public void onSystemReady() {
+ checkPermission();
mKeyguardViewMediator.onSystemReady();
}
public void doKeyguardTimeout(Bundle options) {
+ checkPermission();
mKeyguardViewMediator.doKeyguardTimeout(options);
}
public void setCurrentUser(int userId) {
+ checkPermission();
mKeyguardViewMediator.setCurrentUser(userId);
}
public void showAssistant() {
+ checkPermission();
mKeyguardViewMediator.showAssistant();
}
};
diff --git a/packages/Keyguard/test/Android.mk b/packages/Keyguard/test/Android.mk
new file mode 100644
index 0000000..d011df4
--- /dev/null
+++ b/packages/Keyguard/test/Android.mk
@@ -0,0 +1,28 @@
+# Copyright (C) 2013 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := KeyguardTest
+
+# Remove this to verify permission checks are working correctly
+LOCAL_CERTIFICATE := platform
+
+# LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+
+include $(BUILD_PACKAGE)
diff --git a/packages/Keyguard/test/AndroidManifest.xml b/packages/Keyguard/test/AndroidManifest.xml
new file mode 100644
index 0000000..b801e4b
--- /dev/null
+++ b/packages/Keyguard/test/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2013, 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.
+*/
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.keyguard.test">
+ <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="17"/>
+ <uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
+ <application android:label="@string/app_name" android:icon="@drawable/app_icon">
+ <activity android:name=".KeyguardTestActivity"
+ android:label="@string/app_name"
+ android:theme="@android:style/Theme.Holo">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/packages/Keyguard/test/res/drawable-hdpi/app_icon.png b/packages/Keyguard/test/res/drawable-hdpi/app_icon.png
new file mode 100644
index 0000000..732133c
--- /dev/null
+++ b/packages/Keyguard/test/res/drawable-hdpi/app_icon.png
Binary files differ
diff --git a/packages/Keyguard/test/res/drawable-mdpi/app_icon.png b/packages/Keyguard/test/res/drawable-mdpi/app_icon.png
new file mode 100644
index 0000000..30eb974
--- /dev/null
+++ b/packages/Keyguard/test/res/drawable-mdpi/app_icon.png
Binary files differ
diff --git a/packages/Keyguard/test/res/drawable-xhdpi/app_icon.png b/packages/Keyguard/test/res/drawable-xhdpi/app_icon.png
new file mode 100644
index 0000000..c44a330
--- /dev/null
+++ b/packages/Keyguard/test/res/drawable-xhdpi/app_icon.png
Binary files differ
diff --git a/packages/Keyguard/res/layout/keyguard_test_activity.xml b/packages/Keyguard/test/res/layout/keyguard_test_activity.xml
similarity index 96%
rename from packages/Keyguard/res/layout/keyguard_test_activity.xml
rename to packages/Keyguard/test/res/layout/keyguard_test_activity.xml
index a3b75b0..dab1088 100644
--- a/packages/Keyguard/res/layout/keyguard_test_activity.xml
+++ b/packages/Keyguard/test/res/layout/keyguard_test_activity.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
-** Copyright 2012, The Android Open Source Project
+** Copyright 2013, 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.
diff --git a/packages/Keyguard/res/menu/optionmenu.xml b/packages/Keyguard/test/res/menu/optionmenu.xml
similarity index 100%
rename from packages/Keyguard/res/menu/optionmenu.xml
rename to packages/Keyguard/test/res/menu/optionmenu.xml
diff --git a/packages/Keyguard/res/values/activitystrings.xml b/packages/Keyguard/test/res/values/strings.xml
similarity index 96%
rename from packages/Keyguard/res/values/activitystrings.xml
rename to packages/Keyguard/test/res/values/strings.xml
index 5af9dea..129204b 100644
--- a/packages/Keyguard/res/values/activitystrings.xml
+++ b/packages/Keyguard/test/res/values/strings.xml
@@ -2,7 +2,7 @@
<!--
/* //device/apps/common/assets/res/any/strings.xml
**
-** Copyright 2006, The Android Open Source Project
+** Copyright 2013, 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.
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardTestActivity.java b/packages/Keyguard/test/src/com/android/keyguard/test/KeyguardTestActivity.java
similarity index 88%
rename from packages/Keyguard/src/com/android/keyguard/KeyguardTestActivity.java
rename to packages/Keyguard/test/src/com/android/keyguard/test/KeyguardTestActivity.java
index 0ff00e3..e89c10e 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardTestActivity.java
+++ b/packages/Keyguard/test/src/com/android/keyguard/test/KeyguardTestActivity.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.keyguard;
+package com.android.keyguard.test;
import com.android.internal.policy.IKeyguardShowCallback;
import com.android.internal.policy.IKeyguardExitCallback;
@@ -28,6 +28,7 @@
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
+import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -56,6 +57,7 @@
private static final int MODE_SIM_PIN = 4;
private static final int MODE_SIM_PUK = 5;
private static final String SECURITY_MODE = "security_mode";
+ Handler mHandler = new Handler();
IKeyguardService mService = null;
@@ -76,13 +78,17 @@
class KeyguardExitCallback extends IKeyguardExitCallback.Stub {
@Override
- public void onKeyguardExitResult(boolean success) throws RemoteException {
- new AlertDialog.Builder(KeyguardTestActivity.this)
- .setMessage("Result: " + success)
- .setPositiveButton("OK", null)
- .show();
+ public void onKeyguardExitResult(final boolean success) throws RemoteException {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ new AlertDialog.Builder(KeyguardTestActivity.this)
+ .setMessage("Result: " + success)
+ .setPositiveButton("OK", null)
+ .show();
+ }
+ });
}
-
};
private class RemoteServiceConnection implements ServiceConnection {
@@ -158,12 +164,13 @@
setMode(savedInstanceState.getInt(SECURITY_MODE));
}
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.optionmenu, menu);
- return true;
- }
+// TODO: Find a secure way to inject mock into keyguard...
+// @Override
+// public boolean onCreateOptionsMenu(Menu menu) {
+// MenuInflater inflater = getMenuInflater();
+// inflater.inflate(R.menu.optionmenu, menu);
+// return true;
+// }
private void setMode(int mode) {
mTestSimPin = false;
@@ -255,12 +262,22 @@
mService.doKeyguardTimeout(null);
break;
case R.id.verify_unlock:
- mService.verifyUnlock(mKeyguardExitCallback);
+ mService.doKeyguardTimeout(null);
+ // Wait for keyguard to lock and then try this...
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ mService.verifyUnlock(mKeyguardExitCallback);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed verifyUnlock()", e);
+ }
+ }
+ }, 5000);
break;
}
} catch (RemoteException e) {
- Log.e(TAG, "Remote service died");
- e.printStackTrace();
+ Log.e(TAG, "onClick(): Failed due to remote exeption", e);
}
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 63584ac..41efaa5 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1722,7 +1722,6 @@
return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
}
mKeyguard = win;
- hideKeyguardScrim();
break;
case TYPE_KEYGUARD_SCRIM:
if (mKeyguardScrim != null) {
@@ -1742,7 +1741,7 @@
} else if (mKeyguard == win) {
Log.v(TAG, "Removing keyguard window (Did it crash?)");
mKeyguard = null;
- showKeyguardScrimLw();
+ mKeyguardDelegate.showScrim();
} else if (mKeyguardScrim == win) {
Log.v(TAG, "Removing keyguard scrim");
mKeyguardScrim = null;
@@ -1751,14 +1750,6 @@
}
}
- private void showKeyguardScrimLw() {
- Log.v(TAG, "*** SHOWING KEYGUARD SCRIM ***");
- }
-
- private void hideKeyguardScrim() {
- Log.v(TAG, "*** HIDING KEYGUARD SCRIM ***");
- }
-
static final boolean PRINT_ANIM = false;
/** {@inheritDoc} */
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
index bf18b99..2bb94be 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
@@ -4,12 +4,17 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.content.pm.ActivityInfo;
+import android.graphics.PixelFormat;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
import android.view.WindowManagerPolicy.OnKeyguardExitResult;
import com.android.internal.policy.IKeyguardExitCallback;
@@ -29,6 +34,7 @@
private static final String TAG = "KeyguardServiceDelegate";
private static final boolean DEBUG = true;
protected KeyguardServiceWrapper mKeyguardService;
+ private View mScrim; // shown if keyguard crashes
private KeyguardState mKeyguardState = new KeyguardState();
/* package */ static final class KeyguardState {
@@ -64,6 +70,7 @@
if (mShowListener != null) {
mShowListener.onShown(windowToken);
}
+ hideScrim();
}
};
@@ -87,6 +94,7 @@
public KeyguardServiceDelegate(Context context, LockPatternUtils lockPatternUtils) {
Intent intent = new Intent();
intent.setClassName(KEYGUARD_PACKAGE, KEYGUARD_CLASS);
+ mScrim = createScrim(context);
if (!context.bindServiceAsUser(intent, mKeyguardConnection,
Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
if (DEBUG) Log.v(TAG, "*** Keyguard: can't bind to " + KEYGUARD_CLASS);
@@ -102,7 +110,10 @@
mKeyguardService = new KeyguardServiceWrapper(
IKeyguardService.Stub.asInterface(service));
if (mKeyguardState.systemIsReady) {
+ // If the system is ready, it means keyguard crashed and restarted.
mKeyguardService.onSystemReady();
+ // This is used to hide the scrim once keyguard displays.
+ mKeyguardService.onScreenTurnedOn(new KeyguardShowDelegate(null));
}
}
@@ -257,4 +268,51 @@
mKeyguardState.currentUser = newUserId;
}
+ private static final View createScrim(Context context) {
+ View view = new View(context);
+
+ int flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+ | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
+ | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN
+ | WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER
+ ;
+
+ final int stretch = ViewGroup.LayoutParams.MATCH_PARENT;
+ final int type = WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM;
+ WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+ stretch, stretch, type, flags, PixelFormat.TRANSLUCENT);
+ lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
+ lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+ lp.setTitle("KeyguardScrim");
+ WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ wm.addView(view, lp);
+ view.setVisibility(View.GONE);
+ // Disable pretty much everything in statusbar until keyguard comes back and we know
+ // the state of the world.
+ view.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME
+ | View.STATUS_BAR_DISABLE_BACK
+ | View.STATUS_BAR_DISABLE_RECENT
+ | View.STATUS_BAR_DISABLE_EXPAND
+ | View.STATUS_BAR_DISABLE_SEARCH);
+ return view;
+ }
+
+ public void showScrim() {
+ mScrim.post(new Runnable() {
+ @Override
+ public void run() {
+ mScrim.setVisibility(View.VISIBLE);
+ }
+ });
+ }
+
+ public void hideScrim() {
+ mScrim.post(new Runnable() {
+ @Override
+ public void run() {
+ mScrim.setVisibility(View.GONE);
+ }
+ });
+ }
+
}