2929import android .content .Context ;
3030import android .content .Intent ;
3131import android .content .IntentSender ;
32- import android .content .pm .ActivityInfo ;
33- import android .content .pm .PackageManager ;
3432import android .content .pm .UserInfo ;
3533import android .content .res .Resources ;
3634import android .graphics .Canvas ;
5048import android .view .MotionEvent ;
5149import android .view .View ;
5250import android .view .WindowManager ;
53- import android .view .accessibility .AccessibilityNodeInfo ;
5451import android .view .animation .AnimationUtils ;
5552import android .widget .RemoteViews .OnClickHandler ;
5653
5956import com .android .internal .widget .LockPatternUtils ;
6057
6158import java .io .File ;
62- import java .util .ArrayList ;
6359import java .util .List ;
6460
6561public 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 ;
0 commit comments