am 259e3121: am 51117262: Handle DevicePolicyManagement and safe mode when inflating widgets

* commit '259e3121d301c29112dad028931d9d477264be96':
  Handle DevicePolicyManagement and safe mode when inflating widgets
This commit is contained in:
Jim Miller
2012-11-07 11:17:33 -08:00
committed by Android Git Automerger
5 changed files with 206 additions and 98 deletions

View File

@@ -3228,6 +3228,13 @@ public final class Settings {
public static final String LOCK_SCREEN_APPWIDGET_IDS =
"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

View File

@@ -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;
}
}

View File

@@ -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();
mSwitchPageRunnable.run();
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();
final int insertPageIndex = getInsertPageIndex();
Resources res = getContext().getResources();
ComponentName defaultAppWidget = new ComponentName(
res.getString(R.string.widget_default_package_name),
res.getString(R.string.widget_default_class_name));
final boolean userAddedWidgetsEnabled = !widgetsDisabledByDpm();
boolean addedDefaultAppWidget = false;
// 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);
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.

View File

@@ -260,4 +260,5 @@ public abstract class KeyguardViewBase extends FrameLayout {
KeyguardViewMediator.ViewMediatorCallback viewMediatorCallback) {
mViewMediatorCallback = viewMediatorCallback;
}
}

View File

@@ -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());
@@ -502,35 +495,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()) {
// Remove non-widget pages from the range
while (range[1] > range[0] && !isWidgetPage(range[1])) {
range[1]--;
}
while (range[0] < range[1] && !isWidgetPage(range[0])) {
range[0]++;
}
if (isMusicWidgetVisible()) {
range[1]--;
}
if (isCameraWidgetVisible()) {
range[1]--;
}
}
}
/*
* 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();
}
@@ -785,7 +774,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) {