summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/provider/Settings.java7
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java31
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java218
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewBase.java1
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java47
5 files changed, 206 insertions, 98 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f482335..b94f0b9 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3229,6 +3229,13 @@ public final class Settings {
"lock_screen_appwidget_ids";
/**
+ * Id of the appwidget shown on the lock screen when appwidgets are disabled.
+ * @hide
+ */
+ public static final String LOCK_SCREEN_FALLBACK_APPWIDGET_ID =
+ "lock_screen_fallback_appwidget_id";
+
+ /**
* Index of the lockscreen appwidget to restore, -1 if none.
* @hide
*/
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index e5e1a2b..47d501c 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -18,6 +18,7 @@ package com.android.internal.widget;
import android.app.ActivityManagerNative;
import android.app.admin.DevicePolicyManager;
+import android.appwidget.AppWidgetManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -35,6 +36,7 @@ import android.security.KeyStore;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
+import android.view.IWindowManager;
import android.view.View;
import android.widget.Button;
@@ -1112,6 +1114,25 @@ public class LockPatternUtils {
return sb.toString();
}
+ // appwidget used when appwidgets are disabled (we make an exception for
+ // default clock widget)
+ public void writeFallbackAppWidgetId(int appWidgetId) {
+ Settings.Secure.putIntForUser(mContentResolver,
+ Settings.Secure.LOCK_SCREEN_FALLBACK_APPWIDGET_ID,
+ appWidgetId,
+ UserHandle.USER_CURRENT);
+ }
+
+ // appwidget used when appwidgets are disabled (we make an exception for
+ // default clock widget)
+ public int getFallbackAppWidgetId() {
+ return Settings.Secure.getIntForUser(
+ mContentResolver,
+ Settings.Secure.LOCK_SCREEN_FALLBACK_APPWIDGET_ID,
+ AppWidgetManager.INVALID_APPWIDGET_ID,
+ UserHandle.USER_CURRENT);
+ }
+
private void writeAppWidgets(int[] appWidgetIds) {
Settings.Secure.putStringForUser(mContentResolver,
Settings.Secure.LOCK_SCREEN_APPWIDGET_IDS,
@@ -1325,5 +1346,15 @@ public class LockPatternUtils {
public boolean getPowerButtonInstantlyLocks() {
return getBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, true);
}
+
+ public static boolean isSafeModeEnabled() {
+ try {
+ return IWindowManager.Stub.asInterface(
+ ServiceManager.getService("window")).isSafeModeEnabled();
+ } catch (RemoteException e) {
+ // Shouldn't happen!
+ }
+ return false;
+ }
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
index 9fe3144..68783c3 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -37,6 +37,8 @@ import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.UserHandle;
import android.os.UserManager;
import android.util.AttributeSet;
import android.util.Log;
@@ -57,7 +59,7 @@ import java.io.File;
import java.util.List;
public class KeyguardHostView extends KeyguardViewBase {
- private static final String TAG = "KeyguardViewHost";
+ private static final String TAG = "KeyguardHostView";
// Use this to debug all of keyguard
public static boolean DEBUG = KeyguardViewMediator.DEBUG;
@@ -87,6 +89,12 @@ public class KeyguardHostView extends KeyguardViewBase {
private Rect mTempRect = new Rect();
+ private int mDisabledFeatures;
+
+ private boolean mCameraDisabled;
+
+ private boolean mSafeModeEnabled;
+
/*package*/ interface TransportCallback {
void onListenerDetached();
void onListenerAttached();
@@ -113,6 +121,25 @@ public class KeyguardHostView extends KeyguardViewBase {
mSecurityModel = new KeyguardSecurityModel(context);
mViewStateManager = new KeyguardViewStateManager(this);
+
+ DevicePolicyManager dpm =
+ (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ if (dpm != null) {
+ mDisabledFeatures = getDisabledFeatures(dpm);
+ mCameraDisabled = dpm.getCameraDisabled(null);
+ }
+
+ mSafeModeEnabled = LockPatternUtils.isSafeModeEnabled();
+
+ if (mSafeModeEnabled) {
+ Log.v(TAG, "Keyguard widgets disabled by safe mode");
+ }
+ if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0) {
+ Log.v(TAG, "Keyguard widgets disabled by DPM");
+ }
+ if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0) {
+ Log.v(TAG, "Keyguard secure camera disabled by DPM");
+ }
}
@Override
@@ -177,9 +204,10 @@ public class KeyguardHostView extends KeyguardViewBase {
}
addDefaultWidgets();
+
addWidgetsFromSettings();
+ checkAppWidgetConsistency();
mSwitchPageRunnable.run();
-
// This needs to be called after the pages are all added.
mViewStateManager.showUsabilityHints();
@@ -187,6 +215,24 @@ public class KeyguardHostView extends KeyguardViewBase {
updateSecurityViews();
}
+ private int getDisabledFeatures(DevicePolicyManager dpm) {
+ int disabledFeatures = DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
+ if (dpm != null) {
+ final int currentUser = mLockPatternUtils.getCurrentUser();
+ disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUser);
+ }
+ return disabledFeatures;
+ }
+
+ private boolean widgetsDisabledByDpm() {
+ return (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0;
+ }
+
+ private boolean cameraDisabledByDpm() {
+ return mCameraDisabled
+ || (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0;
+ }
+
private void updateSecurityViews() {
int children = mSecurityViewContainer.getChildCount();
for (int i = 0; i < children; i++) {
@@ -821,15 +867,18 @@ public class KeyguardHostView extends KeyguardViewBase {
}
}
- private boolean addWidget(int appId, int pageIndex) {
+ private boolean addWidget(int appId, int pageIndex, boolean updateDbIfFailed) {
AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appId);
if (appWidgetInfo != null) {
AppWidgetHostView view = getAppWidgetHost().createView(mContext, appId, appWidgetInfo);
addWidget(view, pageIndex);
return true;
} else {
- Log.w(TAG, "AppWidgetInfo for app widget id " + appId + " was null, deleting");
- mLockPatternUtils.removeAppWidget(appId);
+ if (updateDbIfFailed) {
+ Log.w(TAG, "AppWidgetInfo for app widget id " + appId + " was null, deleting");
+ mAppWidgetHost.deleteAppWidgetId(appId);
+ mLockPatternUtils.removeAppWidget(appId);
+ }
return false;
}
}
@@ -885,9 +934,28 @@ public class KeyguardHostView extends KeyguardViewBase {
LayoutInflater inflater = LayoutInflater.from(mContext);
inflater.inflate(R.layout.keyguard_transport_control_view, this, true);
- View addWidget = inflater.inflate(R.layout.keyguard_add_widget, null, true);
- mAppWidgetContainer.addWidget(addWidget);
- if (mContext.getResources().getBoolean(R.bool.kg_enable_camera_default_widget)) {
+ if (!mSafeModeEnabled && !widgetsDisabledByDpm()) {
+ View addWidget = inflater.inflate(R.layout.keyguard_add_widget, this, false);
+ mAppWidgetContainer.addWidget(addWidget);
+ View addWidgetButton = addWidget.findViewById(R.id.keyguard_add_widget_view);
+ addWidgetButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
+ if (appWidgetId != -1) {
+ mActivityLauncher.launchWidgetPicker(appWidgetId);
+ } else {
+ Log.e(TAG, "Unable to allocate an AppWidget id in lock screen");
+ }
+ }
+ });
+ }
+
+ // We currently disable cameras in safe mode because we support loading 3rd party
+ // cameras we can't trust. TODO: plumb safe mode into camera creation code and only
+ // inflate system-provided camera?
+ if (!mSafeModeEnabled && !cameraDisabledByDpm()
+ && mContext.getResources().getBoolean(R.bool.kg_enable_camera_default_widget)) {
View cameraWidget =
CameraWidgetFrame.create(mContext, mCameraWidgetCallbacks, mActivityLauncher);
if (cameraWidget != null) {
@@ -895,19 +963,6 @@ public class KeyguardHostView extends KeyguardViewBase {
}
}
- View addWidgetButton = addWidget.findViewById(R.id.keyguard_add_widget_view);
- addWidgetButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
- if (appWidgetId != -1) {
- mActivityLauncher.launchWidgetPicker(appWidgetId);
- } else {
- Log.e(TAG, "Unable to allocate an AppWidget id in lock screen");
- }
- }
- });
-
enableUserSelectorIfNecessary();
initializeTransportControl();
}
@@ -969,14 +1024,15 @@ public class KeyguardHostView extends KeyguardViewBase {
}
}
- private int getAddPageIndex() {
+ private int getInsertPageIndex() {
View addWidget = mAppWidgetContainer.findViewById(R.id.keyguard_add_widget);
- int addPageIndex = mAppWidgetContainer.indexOfChild(addWidget);
- // This shouldn't happen, but just to be safe!
- if (addPageIndex < 0) {
- addPageIndex = 0;
+ int insertionIndex = mAppWidgetContainer.indexOfChild(addWidget);
+ if (insertionIndex < 0) {
+ insertionIndex = 0; // no add widget page found
+ } else {
+ insertionIndex++; // place after add widget
}
- return addPageIndex;
+ return insertionIndex;
}
private void addDefaultStatusWidget(int index) {
@@ -986,18 +1042,11 @@ public class KeyguardHostView extends KeyguardViewBase {
}
private void addWidgetsFromSettings() {
- DevicePolicyManager dpm =
- (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
- if (dpm != null) {
- final int currentUser = mLockPatternUtils.getCurrentUser();
- final int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUser);
- if ((disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0) {
- Log.v(TAG, "Keyguard widgets disabled because of device policy admin");
- return;
- }
+ if (mSafeModeEnabled || widgetsDisabledByDpm()) {
+ return;
}
- int addPageIndex = getAddPageIndex();
+ int insertionIndex = getInsertPageIndex();
// Add user-selected widget
final int[] widgets = mLockPatternUtils.getAppWidgets();
@@ -1007,50 +1056,90 @@ public class KeyguardHostView extends KeyguardViewBase {
} else {
for (int i = widgets.length -1; i >= 0; i--) {
if (widgets[i] == LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
- addDefaultStatusWidget(addPageIndex + 1);
+ addDefaultStatusWidget(insertionIndex);
} else {
// We add the widgets from left to right, starting after the first page after
// the add page. We count down, since the order will be persisted from right
// to left, starting after camera.
- addWidget(widgets[i], addPageIndex + 1);
+ addWidget(widgets[i], insertionIndex, true);
}
}
}
- checkAppWidgetConsistency();
+ }
+
+ private int allocateIdForDefaultAppWidget() {
+ int appWidgetId;
+ Resources res = getContext().getResources();
+ ComponentName defaultAppWidget = new ComponentName(
+ res.getString(R.string.widget_default_package_name),
+ res.getString(R.string.widget_default_class_name));
+
+ // Note: we don't support configuring the widget
+ appWidgetId = mAppWidgetHost.allocateAppWidgetId();
+
+ try {
+ mAppWidgetManager.bindAppWidgetId(appWidgetId, defaultAppWidget);
+
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Error when trying to bind default AppWidget: " + e);
+ mAppWidgetHost.deleteAppWidgetId(appWidgetId);
+ appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
+ }
+ return appWidgetId;
}
public void checkAppWidgetConsistency() {
final int childCount = mAppWidgetContainer.getChildCount();
boolean widgetPageExists = false;
for (int i = 0; i < childCount; i++) {
- if (isWidgetPage(i)) {
+ if (mAppWidgetContainer.isWidgetPage(i)) {
widgetPageExists = true;
break;
}
}
if (!widgetPageExists) {
- final int addPageIndex = getAddPageIndex();
-
- Resources res = getContext().getResources();
- ComponentName defaultAppWidget = new ComponentName(
- res.getString(R.string.widget_default_package_name),
- res.getString(R.string.widget_default_class_name));
-
- // Note: we don't support configuring the widget
- int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
- boolean bindSuccessful = false;
- try {
- mAppWidgetManager.bindAppWidgetId(appWidgetId, defaultAppWidget);
- bindSuccessful = true;
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Error when trying to bind default AppWidget: " + e);
+ final int insertPageIndex = getInsertPageIndex();
+
+ final boolean userAddedWidgetsEnabled = !widgetsDisabledByDpm();
+ boolean addedDefaultAppWidget = false;
+
+ if (!mSafeModeEnabled) {
+ if (userAddedWidgetsEnabled) {
+ int appWidgetId = allocateIdForDefaultAppWidget();
+ if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
+ addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, true);
+ }
+ } else {
+ // note: even if widgetsDisabledByDpm() returns true, we still bind/create
+ // the default appwidget if possible
+ int appWidgetId = mLockPatternUtils.getFallbackAppWidgetId();
+ if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
+ appWidgetId = allocateIdForDefaultAppWidget();
+ if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
+ mLockPatternUtils.writeFallbackAppWidgetId(appWidgetId);
+ }
+ }
+ if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
+ addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, false);
+ if (!addedDefaultAppWidget) {
+ mAppWidgetHost.deleteAppWidgetId(appWidgetId);
+ mLockPatternUtils.writeFallbackAppWidgetId(
+ AppWidgetManager.INVALID_APPWIDGET_ID);
+ }
+ }
+ }
}
+
// Use the built-in status/clock view if we can't inflate the default widget
- if (!(bindSuccessful && addWidget(appWidgetId, addPageIndex + 1))) {
- addDefaultStatusWidget(addPageIndex + 1);
+ if (!addedDefaultAppWidget) {
+ addDefaultStatusWidget(insertPageIndex);
+ }
+
+ // trigger DB updates only if user-added widgets are enabled
+ if (!mSafeModeEnabled && userAddedWidgetsEnabled) {
+ mAppWidgetContainer.onAddView(
+ mAppWidgetContainer.getChildAt(insertPageIndex), insertPageIndex);
}
- mAppWidgetContainer.onAddView(
- mAppWidgetContainer.getChildAt(addPageIndex + 1), addPageIndex + 1);
}
}
@@ -1154,15 +1243,6 @@ public class KeyguardHostView extends KeyguardViewBase {
return null;
}
- private boolean isWidgetPage(int pageIndex) {
- View v = mAppWidgetContainer.getChildAt(pageIndex);
- if (v != null && v instanceof KeyguardWidgetFrame) {
- KeyguardWidgetFrame kwf = (KeyguardWidgetFrame) v;
- return kwf.getContentAppWidgetId() != AppWidgetManager.INVALID_APPWIDGET_ID;
- }
- return false;
- }
-
private int getStickyWidget() {
// The first time we query the persistent state. From that point, we use a locally updated
// notion of the sticky widget page.
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewBase.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewBase.java
index 9e3424d..6fcacd3 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewBase.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewBase.java
@@ -260,4 +260,5 @@ public abstract class KeyguardViewBase extends FrameLayout {
KeyguardViewMediator.ViewMediatorCallback viewMediatorCallback) {
mViewMediatorCallback = viewMediatorCallback;
}
+
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
index c930ecc..9caeb0d 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
@@ -22,9 +22,9 @@ import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.TimeInterpolator;
import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
-import android.content.res.Resources;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.AttributeSet;
@@ -38,7 +38,6 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
-import com.android.internal.R;
import com.android.internal.widget.LockPatternUtils;
import java.util.ArrayList;
@@ -69,8 +68,6 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
private int mPage = 0;
private Callbacks mCallbacks;
- private boolean mCameraWidgetEnabled;
-
private int mWidgetToResetAfterFadeOut;
// Bouncer
@@ -97,10 +94,6 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
setPageSwitchListener(this);
- Resources r = getResources();
- mCameraWidgetEnabled = r.getBoolean(R.bool.kg_enable_camera_default_widget);
- mCenterSmallWidgetsVertically =
- r.getBoolean(com.android.internal.R.bool.kg_center_small_widgets_vertically);
mBackgroundWorkerThread = new HandlerThread("KeyguardWidgetPager Worker");
mBackgroundWorkerThread.start();
mBackgroundWorkerHandler = new Handler(mBackgroundWorkerThread.getLooper());
@@ -485,35 +478,31 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
}
}
+ public boolean isWidgetPage(int pageIndex) {
+ if (pageIndex < 0 || pageIndex >= getChildCount()) {
+ return false;
+ }
+ View v = getChildAt(pageIndex);
+ if (v != null && v instanceof KeyguardWidgetFrame) {
+ KeyguardWidgetFrame kwf = (KeyguardWidgetFrame) v;
+ return kwf.getContentAppWidgetId() != AppWidgetManager.INVALID_APPWIDGET_ID;
+ }
+ return false;
+ }
+
@Override
void boundByReorderablePages(boolean isReordering, int[] range) {
if (isReordering) {
- if (isAddWidgetPageVisible()) {
- range[0]++;
- }
- if (isMusicWidgetVisible()) {
+ // Remove non-widget pages from the range
+ while (range[1] > range[0] && !isWidgetPage(range[1])) {
range[1]--;
}
- if (isCameraWidgetVisible()) {
- range[1]--;
+ while (range[0] < range[1] && !isWidgetPage(range[0])) {
+ range[0]++;
}
}
}
- /*
- * Special widgets
- */
- boolean isAddWidgetPageVisible() {
- // TODO: Make proper test once we decide whether the add-page is always showing
- return true;
- }
- boolean isMusicWidgetVisible() {
- return mViewStateManager.getTransportState() != KeyguardViewStateManager.TRANSPORT_GONE;
- }
- boolean isCameraWidgetVisible() {
- return mCameraWidgetEnabled;
- }
-
protected void reorderStarting() {
showOutlinesAndSidePages();
}
@@ -761,7 +750,7 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
boolean isAddPage(int pageIndex) {
View v = getChildAt(pageIndex);
- return v != null && v.getId() == R.id.keyguard_add_widget;
+ return v != null && v.getId() == com.android.internal.R.id.keyguard_add_widget;
}
boolean isCameraPage(int pageIndex) {