Skip to content

Commit 9de90c1

Browse files
mikejurkaAndroid (Google) Code Review
authored andcommitted
Merge "Use clock's widget as the default keyguard widget" into jb-mr1-lockscreen-dev
2 parents 324545d + 67a871d commit 9de90c1

File tree

7 files changed

+90
-76
lines changed

7 files changed

+90
-76
lines changed

core/java/com/android/internal/widget/LockPatternUtils.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,11 +1073,7 @@ public int[] getAppWidgets() {
10731073
}
10741074
return appWidgetIds;
10751075
}
1076-
if (appWidgetIdString == null) {
1077-
return new int[] { LockPatternUtils.ID_DEFAULT_STATUS_WIDGET };
1078-
} else {
1079-
return new int[0];
1080-
}
1076+
return new int[0];
10811077
}
10821078

10831079
private static String combineStrings(int[] list, String separator) {

core/res/res/values/config.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,12 @@
404404
-->
405405
<integer name="config_longPressOnPowerBehavior">1</integer>
406406

407+
<!-- Package name for default keyguard appwidget [DO NOT TRANSLATE] -->
408+
<string name="widget_default_package_name"></string>
409+
410+
<!-- Class name for default keyguard appwidget [DO NOT TRANSLATE] -->
411+
<string name="widget_default_class_name"></string>
412+
407413
<!-- Indicate whether the SD card is accessible without removing the battery. -->
408414
<bool name="config_batterySdCardAccessibility">false</bool>
409415

core/res/res/values/strings.xml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,15 +2065,6 @@
20652065
<!-- This can be used in any application wanting to disable the text "Emergency number" -->
20662066
<string name="emergency_call_dialog_number_for_display">Emergency number</string>
20672067

2068-
<!-- String to display if the clock status widget is selected (it is the default) [CHAR LIMIT=22] -->
2069-
<string name="widget_default" msgid="8269383575996003796">Clock</string>
2070-
2071-
<!-- Package name for default widget [DO NOT TRANSLATE] -->
2072-
<string name="widget_default_package_name">com.android.deskclock</string>
2073-
2074-
<!-- Class name for default widget [DO NOT TRANSLATE] -->
2075-
<string name="widget_default_class_name">com.android.deskclock.DeskClock</string>
2076-
20772068
<!--
20782069
*** touch based lock / unlock ***
20792070
--> <skip />

core/res/res/values/symbols.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,6 @@
479479
<java-symbol type="string" name="emailTypeOther" />
480480
<java-symbol type="string" name="emailTypeWork" />
481481
<java-symbol type="string" name="emergency_call_dialog_number_for_display" />
482-
<java-symbol type="string" name="widget_default" />
483482
<java-symbol type="string" name="widget_default_package_name" />
484483
<java-symbol type="string" name="widget_default_class_name" />
485484
<java-symbol type="string" name="emergency_calls_only" />

policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java

Lines changed: 77 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@
2929
import android.content.Context;
3030
import android.content.Intent;
3131
import android.content.IntentSender;
32-
import android.content.pm.ActivityInfo;
33-
import android.content.pm.PackageManager;
3432
import android.content.pm.UserInfo;
3533
import android.content.res.Resources;
3634
import android.graphics.Canvas;
@@ -50,7 +48,6 @@
5048
import android.view.MotionEvent;
5149
import android.view.View;
5250
import android.view.WindowManager;
53-
import android.view.accessibility.AccessibilityNodeInfo;
5451
import android.view.animation.AnimationUtils;
5552
import android.widget.RemoteViews.OnClickHandler;
5653

@@ -59,7 +56,6 @@
5956
import com.android.internal.widget.LockPatternUtils;
6057

6158
import java.io.File;
62-
import java.util.ArrayList;
6359
import java.util.List;
6460

6561
public class KeyguardHostView extends KeyguardViewBase {
@@ -68,10 +64,10 @@ public class KeyguardHostView extends KeyguardViewBase {
6864
// Use this to debug all of keyguard
6965
public static boolean DEBUG = KeyguardViewMediator.DEBUG;
7066

71-
// also referenced in SecuritySettings.java
7267
static final int APPWIDGET_HOST_ID = 0x4B455947;
7368

7469
private AppWidgetHost mAppWidgetHost;
70+
private AppWidgetManager mAppWidgetManager;
7571
private KeyguardWidgetPager mAppWidgetContainer;
7672
private KeyguardSecurityViewFlipper mSecurityViewContainer;
7773
private KeyguardSelectorView mKeyguardSelectorView;
@@ -113,6 +109,7 @@ public KeyguardHostView(Context context, AttributeSet attrs) {
113109
mLockPatternUtils = new LockPatternUtils(context);
114110
mAppWidgetHost = new AppWidgetHost(
115111
context, APPWIDGET_HOST_ID, mOnClickHandler, Looper.myLooper());
112+
mAppWidgetManager = AppWidgetManager.getInstance(mContext);
116113
mSecurityModel = new KeyguardSecurityModel(context);
117114

118115
// The following enables the MENU key to work for testing automation
@@ -158,10 +155,6 @@ protected void onFinishInflate() {
158155
mAppWidgetContainer.setCallbacks(mWidgetCallbacks);
159156
mAppWidgetContainer.setMinScale(0.5f);
160157

161-
addDefaultWidgets();
162-
addWidgetsFromSettings();
163-
mSwitchPageRunnable.run();
164-
165158
SlidingChallengeLayout slider =
166159
(SlidingChallengeLayout) findViewById(R.id.sliding_layout);
167160
if (slider != null) {
@@ -183,8 +176,11 @@ protected void onFinishInflate() {
183176
setSystemUiVisibility(getSystemUiVisibility() | View.STATUS_BAR_DISABLE_BACK);
184177
}
185178

186-
showPrimarySecurityScreen(false);
179+
addDefaultWidgets();
180+
addWidgetsFromSettings();
181+
mSwitchPageRunnable.run();
187182

183+
showPrimarySecurityScreen(false);
188184
updateSecurityViews();
189185
}
190186

@@ -549,8 +545,6 @@ public void run() {
549545
};
550546
};
551547

552-
private KeyguardStatusViewManager mKeyguardStatusViewManager;
553-
554548
// Used to ignore callbacks from methods that are no longer current (e.g. face unlock).
555549
// This avoids unwanted asynchronous events from messing with the state.
556550
private KeyguardSecurityCallback mNullCallback = new KeyguardSecurityCallback() {
@@ -715,6 +709,7 @@ public void onScreenTurnedOff() {
715709
// biometric unlock to start next time keyguard is shown.
716710
KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
717711
saveStickyWidgetIndex();
712+
checkAppWidgetConsistency();
718713
showPrimarySecurityScreen(true);
719714
getSecurityView(mCurrentSecuritySelection).onPause();
720715
CameraWidgetFrame cameraPage = findCameraPage();
@@ -812,15 +807,16 @@ private int getLayoutIdFor(SecurityMode securityMode) {
812807
}
813808
}
814809

815-
private void addWidget(int appId, int pageIndex) {
816-
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mContext);
817-
AppWidgetProviderInfo appWidgetInfo = appWidgetManager.getAppWidgetInfo(appId);
810+
private boolean addWidget(int appId, int pageIndex) {
811+
AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appId);
818812
if (appWidgetInfo != null) {
819813
AppWidgetHostView view = getAppWidgetHost().createView(mContext, appId, appWidgetInfo);
820814
addWidget(view, pageIndex);
815+
return true;
821816
} else {
822817
Log.w(TAG, "AppWidgetInfo for app widget id " + appId + " was null, deleting");
823818
mLockPatternUtils.removeAppWidget(appId);
819+
return false;
824820
}
825821
}
826822

@@ -890,22 +886,7 @@ public void onClick(View v) {
890886

891887
@Override
892888
public void run() {
893-
int defaultIconId = 0;
894-
Resources res = KeyguardHostView.this.getContext().getResources();
895-
ComponentName clock = new ComponentName(
896-
res.getString(R.string.widget_default_package_name),
897-
res.getString(R.string.widget_default_class_name));
898-
try {
899-
ActivityInfo activityInfo =
900-
mContext.getPackageManager().getActivityInfo(clock, 0);
901-
if (activityInfo != null) {
902-
defaultIconId = activityInfo.icon;
903-
}
904-
} catch (PackageManager.NameNotFoundException e) {
905-
defaultIconId = 0;
906-
}
907-
launchPickActivityIntent(R.string.widget_default, defaultIconId, clock,
908-
LockPatternUtils.EXTRA_DEFAULT_WIDGET);
889+
launchPickActivityIntent();
909890
}
910891
});
911892
mCallback.dismiss(false);
@@ -916,8 +897,7 @@ public void run() {
916897
initializeTransportControl();
917898
}
918899

919-
private void launchPickActivityIntent(int defaultLabelId, int defaultIconId,
920-
ComponentName defaultComponentName, String defaultTag) {
900+
private void launchPickActivityIntent() {
921901
// Create intent to pick widget
922902
Intent pickIntent = new Intent(AppWidgetManager.ACTION_KEYGUARD_APPWIDGET_PICK);
923903

@@ -928,22 +908,6 @@ private void launchPickActivityIntent(int defaultLabelId, int defaultIconId,
928908
pickIntent.putExtra(AppWidgetManager.EXTRA_CATEGORY_FILTER,
929909
AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD);
930910

931-
// Add an custom entry for the default
932-
AppWidgetProviderInfo defaultInfo = new AppWidgetProviderInfo();
933-
ArrayList<AppWidgetProviderInfo> extraInfos = new ArrayList<AppWidgetProviderInfo>();
934-
defaultInfo.label = getResources().getString(defaultLabelId);
935-
defaultInfo.icon = defaultIconId;
936-
defaultInfo.provider = defaultComponentName;
937-
extraInfos.add(defaultInfo);
938-
939-
ArrayList<Bundle> extraExtras = new ArrayList<Bundle>();
940-
Bundle b = new Bundle();
941-
b.putBoolean(defaultTag, true);
942-
extraExtras.add(b);
943-
944-
// Launch the widget picker
945-
pickIntent.putExtra(AppWidgetManager.EXTRA_CUSTOM_INFO, extraInfos);
946-
pickIntent.putExtra(AppWidgetManager.EXTRA_CUSTOM_EXTRAS, extraExtras);
947911
pickIntent.putExtra(Intent.EXTRA_INTENT, getBaseIntent());
948912
pickIntent.addFlags(
949913
Intent.FLAG_ACTIVITY_NEW_TASK
@@ -1024,6 +988,22 @@ public void onPlayStateChanged() {
1024988
}
1025989
}
1026990

991+
private int getAddPageIndex() {
992+
View addWidget = mAppWidgetContainer.findViewById(R.id.keyguard_add_widget);
993+
int addPageIndex = mAppWidgetContainer.indexOfChild(addWidget);
994+
// This shouldn't happen, but just to be safe!
995+
if (addPageIndex < 0) {
996+
addPageIndex = 0;
997+
}
998+
return addPageIndex;
999+
}
1000+
1001+
private void addDefaultStatusWidget(int index) {
1002+
LayoutInflater inflater = LayoutInflater.from(mContext);
1003+
View statusWidget = inflater.inflate(R.layout.keyguard_status_view, null, true);
1004+
mAppWidgetContainer.addWidget(statusWidget, index);
1005+
}
1006+
10271007
private void addWidgetsFromSettings() {
10281008
DevicePolicyManager dpm =
10291009
(DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
@@ -1036,23 +1016,17 @@ private void addWidgetsFromSettings() {
10361016
}
10371017
}
10381018

1039-
View addWidget = mAppWidgetContainer.findViewById(R.id.keyguard_add_widget);
1040-
int addPageIndex = mAppWidgetContainer.indexOfChild(addWidget);
1041-
// This shouldn't happen, but just to be safe!
1042-
if (addPageIndex < 0) {
1043-
addPageIndex = 0;
1044-
}
1019+
int addPageIndex = getAddPageIndex();
10451020

10461021
// Add user-selected widget
10471022
final int[] widgets = mLockPatternUtils.getAppWidgets();
1023+
10481024
if (widgets == null) {
10491025
Log.d(TAG, "Problem reading widgets");
10501026
} else {
10511027
for (int i = widgets.length -1; i >= 0; i--) {
10521028
if (widgets[i] == LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
1053-
LayoutInflater inflater = LayoutInflater.from(mContext);
1054-
View statusWidget = inflater.inflate(R.layout.keyguard_status_view, null, true);
1055-
mAppWidgetContainer.addWidget(statusWidget, addPageIndex + 1);
1029+
addDefaultStatusWidget(addPageIndex + 1);
10561030
} else {
10571031
// We add the widgets from left to right, starting after the first page after
10581032
// the add page. We count down, since the order will be persisted from right
@@ -1061,6 +1035,42 @@ private void addWidgetsFromSettings() {
10611035
}
10621036
}
10631037
}
1038+
checkAppWidgetConsistency();
1039+
}
1040+
1041+
public void checkAppWidgetConsistency() {
1042+
final int childCount = mAppWidgetContainer.getChildCount();
1043+
boolean widgetPageExists = false;
1044+
for (int i = 0; i < childCount; i++) {
1045+
if (isWidgetPage(i)) {
1046+
widgetPageExists = true;
1047+
break;
1048+
}
1049+
}
1050+
if (!widgetPageExists) {
1051+
final int addPageIndex = getAddPageIndex();
1052+
1053+
Resources res = getContext().getResources();
1054+
ComponentName defaultAppWidget = new ComponentName(
1055+
res.getString(R.string.widget_default_package_name),
1056+
res.getString(R.string.widget_default_class_name));
1057+
1058+
// Note: we don't support configuring the widget
1059+
int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
1060+
boolean bindSuccessful = false;
1061+
try {
1062+
mAppWidgetManager.bindAppWidgetId(appWidgetId, defaultAppWidget);
1063+
bindSuccessful = true;
1064+
} catch (IllegalArgumentException e) {
1065+
Log.e(TAG, "Error when trying to bind default AppWidget: " + e);
1066+
}
1067+
// Use the built-in status/clock view if we can't inflate the default widget
1068+
if (!(bindSuccessful && addWidget(appWidgetId, addPageIndex + 1))) {
1069+
addDefaultStatusWidget(addPageIndex + 1);
1070+
}
1071+
mAppWidgetContainer.onAddView(
1072+
mAppWidgetContainer.getChildAt(addPageIndex + 1), addPageIndex + 1);
1073+
}
10641074
}
10651075

10661076
Runnable mSwitchPageRunnable = new Runnable() {
@@ -1155,6 +1165,15 @@ private CameraWidgetFrame findCameraPage() {
11551165
return null;
11561166
}
11571167

1168+
private boolean isWidgetPage(int pageIndex) {
1169+
View v = mAppWidgetContainer.getChildAt(pageIndex);
1170+
if (v != null && v instanceof KeyguardWidgetFrame) {
1171+
KeyguardWidgetFrame kwf = (KeyguardWidgetFrame) v;
1172+
return kwf.getContentAppWidgetId() != AppWidgetManager.INVALID_APPWIDGET_ID;
1173+
}
1174+
return false;
1175+
}
1176+
11581177
private boolean isCameraPage(int pageIndex) {
11591178
View v = mAppWidgetContainer.getChildAt(pageIndex);
11601179
return v != null && v instanceof CameraWidgetFrame;

policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import android.animation.ObjectAnimator;
2121
import android.animation.PropertyValuesHolder;
2222
import android.appwidget.AppWidgetHostView;
23+
import android.appwidget.AppWidgetManager;
2324
import android.content.Context;
2425
import android.content.res.Resources;
2526
import android.graphics.Canvas;
@@ -220,8 +221,10 @@ public int getContentAppWidgetId() {
220221
View content = getContent();
221222
if (content instanceof AppWidgetHostView) {
222223
return ((AppWidgetHostView) content).getAppWidgetId();
223-
} else {
224+
} else if (content instanceof KeyguardStatusView) {
224225
return ((KeyguardStatusView) content).getAppWidgetId();
226+
} else {
227+
return AppWidgetManager.INVALID_APPWIDGET_ID;
225228
}
226229
}
227230

services/java/com/android/server/AppWidgetServiceImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -599,15 +599,15 @@ private void bindAppWidgetIdImpl(int appWidgetId, ComponentName provider, Bundle
599599
}
600600

601601
public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options) {
602-
mContext.enforceCallingPermission(android.Manifest.permission.BIND_APPWIDGET,
602+
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BIND_APPWIDGET,
603603
"bindAppWidgetId appWidgetId=" + appWidgetId + " provider=" + provider);
604604
bindAppWidgetIdImpl(appWidgetId, provider, options);
605605
}
606606

607607
public boolean bindAppWidgetIdIfAllowed(
608608
String packageName, int appWidgetId, ComponentName provider, Bundle options) {
609609
try {
610-
mContext.enforceCallingPermission(android.Manifest.permission.BIND_APPWIDGET, null);
610+
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BIND_APPWIDGET, null);
611611
} catch (SecurityException se) {
612612
if (!callerHasBindAppWidgetPermission(packageName)) {
613613
return false;

0 commit comments

Comments
 (0)