Add support for settings for lock widgets
Change-Id: Iade094c6f32a7653bdbbd4921d345d68f2443ff4
This commit is contained in:
committed by
Michael Jurka
parent
49321ec4fb
commit
f229e4d3eb
@@ -24,8 +24,10 @@ import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
import android.widget.RemoteViews;
|
||||
@@ -115,18 +117,22 @@ public class AppWidgetHost {
|
||||
private OnClickHandler mOnClickHandler;
|
||||
|
||||
public AppWidgetHost(Context context, int hostId) {
|
||||
this(context, hostId, null);
|
||||
this(context, hostId, null, Looper.getMainLooper());
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public AppWidgetHost(Context context, int hostId, OnClickHandler handler) {
|
||||
public AppWidgetHost(Context context, int hostId, OnClickHandler handler, Looper looper) {
|
||||
mContext = context;
|
||||
mHostId = hostId;
|
||||
mOnClickHandler = handler;
|
||||
mHandler = new UpdateHandler(context.getMainLooper());
|
||||
mHandler = new UpdateHandler(looper);
|
||||
mDisplayMetrics = context.getResources().getDisplayMetrics();
|
||||
bindService();
|
||||
}
|
||||
|
||||
private static void bindService() {
|
||||
synchronized (sServiceLock) {
|
||||
if (sService == null) {
|
||||
IBinder b = ServiceManager.getService(Context.APPWIDGET_SERVICE);
|
||||
@@ -189,6 +195,32 @@ public class AppWidgetHost {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a appWidgetId for a host in the calling process.
|
||||
*
|
||||
* @return a appWidgetId
|
||||
* @hide
|
||||
*/
|
||||
public static int allocateAppWidgetIdForHost(String packageName, int hostId) {
|
||||
checkCallerIsSystem();
|
||||
try {
|
||||
if (sService == null) {
|
||||
bindService();
|
||||
}
|
||||
return sService.allocateAppWidgetId(packageName, hostId);
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("system server dead?", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkCallerIsSystem() {
|
||||
int uid = Process.myUid();
|
||||
if (UserHandle.getAppId(uid) == Process.SYSTEM_UID || uid == 0) {
|
||||
return;
|
||||
}
|
||||
throw new SecurityException("Disallowed call for uid " + uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop listening to changes for this AppWidget.
|
||||
*/
|
||||
@@ -204,6 +236,22 @@ public class AppWidgetHost {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop listening to changes for this AppWidget.
|
||||
* @hide
|
||||
*/
|
||||
public static void deleteAppWidgetIdForHost(int appWidgetId) {
|
||||
checkCallerIsSystem();
|
||||
try {
|
||||
if (sService == null) {
|
||||
bindService();
|
||||
}
|
||||
sService.deleteAppWidgetId(appWidgetId);
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("system server dead?", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all records about this host from the AppWidget manager.
|
||||
* <ul>
|
||||
|
||||
@@ -218,17 +218,25 @@ public class AppWidgetManager {
|
||||
/**
|
||||
* An intent extra to pass to the AppWidget picker which allows the picker to filter
|
||||
* the list based on the {@link AppWidgetProviderInfo#widgetCategory}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
/** @hide */
|
||||
public static final String EXTRA_CATEGORY_FILTER = "categoryFilter";
|
||||
|
||||
/**
|
||||
* An intent extra to pass to the AppWidget picker which allows the picker to filter
|
||||
* the list based on the {@link AppWidgetProviderInfo#widgetFeatures}.
|
||||
* @hide
|
||||
*/
|
||||
/** @hide */
|
||||
public static final String EXTRA_FEATURES_FILTER = "featuresFilter";
|
||||
|
||||
/**
|
||||
* An intent extra to pass to the AppWidget picker to specify whether or not to sort
|
||||
* the list of caller-specified extra AppWidgets along with the rest of the AppWidgets
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_CUSTOM_SORT = "customSort";
|
||||
|
||||
/**
|
||||
* A sentiel value that the AppWidget manager will never return as a appWidgetId.
|
||||
*/
|
||||
|
||||
@@ -3200,6 +3200,20 @@ public final class Settings {
|
||||
*/
|
||||
public static final String LOCK_SCREEN_OWNER_INFO = "lock_screen_owner_info";
|
||||
|
||||
/**
|
||||
* Id of the time appwidget on the lockscreen, or -1 if none
|
||||
* @hide
|
||||
*/
|
||||
public static final String LOCK_SCREEN_CLOCK_APPWIDGET_ID =
|
||||
"lock_screen_clock_appwidget_id";
|
||||
|
||||
/**
|
||||
* Id of the user-selected appwidget on the lockscreen, or -1 if none
|
||||
* @hide
|
||||
*/
|
||||
public static final String LOCK_SCREEN_USER_SELECTED_APPWIDGET_ID =
|
||||
"lock_screen_user_selected_appwidget_id";
|
||||
|
||||
/**
|
||||
* This preference enables showing the owner info on LockScren.
|
||||
* @hide
|
||||
|
||||
@@ -1001,6 +1001,17 @@ public class LockPatternUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getUserDefinedWidgets() {
|
||||
int appWidgetId = -1;
|
||||
String appWidgetIdString = Settings.Secure.getString(
|
||||
mContentResolver, Settings.Secure.LOCK_SCREEN_USER_SELECTED_APPWIDGET_ID);
|
||||
if (appWidgetIdString != null) {
|
||||
appWidgetId = (int) Integer.decode(appWidgetIdString);
|
||||
}
|
||||
|
||||
return new int[] { appWidgetId };
|
||||
}
|
||||
|
||||
private long getLong(String secureSettingKey, long defaultValue) {
|
||||
try {
|
||||
return getLockSettings().getLong(secureSettingKey, defaultValue,
|
||||
|
||||
@@ -28,11 +28,11 @@ import android.appwidget.AppWidgetProviderInfo;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentSender;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Looper;
|
||||
import android.os.UserManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
@@ -41,8 +41,6 @@ import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.RemoteViews.OnClickHandler;
|
||||
@@ -61,6 +59,7 @@ public class KeyguardHostView extends KeyguardViewBase {
|
||||
// Use this to debug all of keyguard
|
||||
public static boolean DEBUG;
|
||||
|
||||
// also referenced in SecuritySettings.java
|
||||
static final int APPWIDGET_HOST_ID = 0x4B455947;
|
||||
private static final String KEYGUARD_WIDGET_PREFS = "keyguard_widget_prefs";
|
||||
|
||||
@@ -94,8 +93,9 @@ public class KeyguardHostView extends KeyguardViewBase {
|
||||
public KeyguardHostView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mLockPatternUtils = new LockPatternUtils(context);
|
||||
mAppWidgetHost = new AppWidgetHost(mContext, APPWIDGET_HOST_ID, mOnClickHandler);
|
||||
mSecurityModel = new KeyguardSecurityModel(mContext);
|
||||
mAppWidgetHost = new AppWidgetHost(
|
||||
context, APPWIDGET_HOST_ID, mOnClickHandler, Looper.myLooper());
|
||||
mSecurityModel = new KeyguardSecurityModel(context);
|
||||
|
||||
// The following enables the MENU key to work for testing automation
|
||||
mEnableMenuKey = shouldEnableMenuKey();
|
||||
@@ -212,7 +212,7 @@ public class KeyguardHostView extends KeyguardViewBase {
|
||||
mAppWidgetHost.stopListening();
|
||||
}
|
||||
|
||||
AppWidgetHost getAppWidgetHost() {
|
||||
private AppWidgetHost getAppWidgetHost() {
|
||||
return mAppWidgetHost;
|
||||
}
|
||||
|
||||
@@ -674,15 +674,11 @@ public class KeyguardHostView extends KeyguardViewBase {
|
||||
return;
|
||||
}
|
||||
inflateAndAddUserSelectorWidgetIfNecessary();
|
||||
SharedPreferences prefs = mContext.getSharedPreferences(
|
||||
KEYGUARD_WIDGET_PREFS, Context.MODE_PRIVATE);
|
||||
for (String key : prefs.getAll().keySet()) {
|
||||
int appId = prefs.getInt(key, -1);
|
||||
if (appId != -1) {
|
||||
Log.w(TAG, "populate: adding " + key);
|
||||
addWidget(appId);
|
||||
} else {
|
||||
Log.w(TAG, "populate: can't find " + key);
|
||||
|
||||
final int[] widgets = mLockPatternUtils.getUserDefinedWidgets();
|
||||
for (int i = 0; i < widgets.length; i++) {
|
||||
if (widgets[i] != -1) {
|
||||
addWidget(widgets[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.IBinder;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
@@ -409,7 +410,7 @@ class AppWidgetServiceImpl {
|
||||
}
|
||||
|
||||
public int allocateAppWidgetId(String packageName, int hostId) {
|
||||
int callingUid = enforceCallingUid(packageName);
|
||||
int callingUid = enforceSystemOrCallingUid(packageName);
|
||||
synchronized (mAppWidgetIds) {
|
||||
ensureStateLoadedLocked();
|
||||
int appWidgetId = mNextAppWidgetId++;
|
||||
@@ -1391,6 +1392,15 @@ class AppWidgetServiceImpl {
|
||||
return pkgInfo.applicationInfo.uid;
|
||||
}
|
||||
|
||||
int enforceSystemOrCallingUid(String packageName) throws IllegalArgumentException {
|
||||
int callingUid = Binder.getCallingUid();
|
||||
int uid = Process.myUid();
|
||||
if (UserHandle.getAppId(uid) == Process.SYSTEM_UID || uid == 0) {
|
||||
return callingUid;
|
||||
}
|
||||
return enforceCallingUid(packageName);
|
||||
}
|
||||
|
||||
int enforceCallingUid(String packageName) throws IllegalArgumentException {
|
||||
int callingUid = Binder.getCallingUid();
|
||||
int packageUid;
|
||||
|
||||
Reference in New Issue
Block a user