@@ -534,6 +534,7 @@ private void bindAppWidgetIdImpl(int appWidgetId, ComponentName provider, Bundle
534534 final long ident = Binder .clearCallingIdentity ();
535535 try {
536536 synchronized (mAppWidgetIds ) {
537+ options = cloneIfLocalBinder (options );
537538 ensureStateLoadedLocked ();
538539 AppWidgetId id = lookupAppWidgetIdLocked (appWidgetId );
539540 if (id == null ) {
@@ -817,7 +818,7 @@ public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) {
817818 ensureStateLoadedLocked ();
818819 AppWidgetId id = lookupAppWidgetIdLocked (appWidgetId );
819820 if (id != null && id .provider != null && !id .provider .zombie ) {
820- return id .provider .info ;
821+ return cloneIfLocalBinder ( id .provider .info ) ;
821822 }
822823 return null ;
823824 }
@@ -828,7 +829,7 @@ public RemoteViews getAppWidgetViews(int appWidgetId) {
828829 ensureStateLoadedLocked ();
829830 AppWidgetId id = lookupAppWidgetIdLocked (appWidgetId );
830831 if (id != null ) {
831- return id .views ;
832+ return cloneIfLocalBinder ( id .views ) ;
832833 }
833834 return null ;
834835 }
@@ -842,7 +843,7 @@ public List<AppWidgetProviderInfo> getInstalledProviders() {
842843 for (int i = 0 ; i < N ; i ++) {
843844 Provider p = mInstalledProviders .get (i );
844845 if (!p .zombie ) {
845- result .add (p .info );
846+ result .add (cloneIfLocalBinder ( p .info ) );
846847 }
847848 }
848849 return result ;
@@ -881,6 +882,7 @@ public void updateAppWidgetIds(int[] appWidgetIds, RemoteViews views) {
881882
882883 public void updateAppWidgetOptions (int appWidgetId , Bundle options ) {
883884 synchronized (mAppWidgetIds ) {
885+ options = cloneIfLocalBinder (options );
884886 ensureStateLoadedLocked ();
885887 AppWidgetId id = lookupAppWidgetIdLocked (appWidgetId );
886888
@@ -907,7 +909,7 @@ public Bundle getAppWidgetOptions(int appWidgetId) {
907909 ensureStateLoadedLocked ();
908910 AppWidgetId id = lookupAppWidgetIdLocked (appWidgetId );
909911 if (id != null && id .options != null ) {
910- return id .options ;
912+ return cloneIfLocalBinder ( id .options ) ;
911913 } else {
912914 return Bundle .EMPTY ;
913915 }
@@ -1062,6 +1064,34 @@ public void onServiceDisconnected(android.content.ComponentName name) {
10621064 }
10631065 }
10641066
1067+ private boolean isLocalBinder () {
1068+ return Process .myPid () == Binder .getCallingPid ();
1069+ }
1070+
1071+ private RemoteViews cloneIfLocalBinder (RemoteViews rv ) {
1072+ if (isLocalBinder () && rv != null ) {
1073+ return rv .clone ();
1074+ }
1075+ return rv ;
1076+ }
1077+
1078+ private AppWidgetProviderInfo cloneIfLocalBinder (AppWidgetProviderInfo info ) {
1079+ if (isLocalBinder () && info != null ) {
1080+ return info .clone ();
1081+ }
1082+ return info ;
1083+ }
1084+
1085+ private Bundle cloneIfLocalBinder (Bundle bundle ) {
1086+ // Note: this is only a shallow copy. For now this will be fine, but it could be problematic
1087+ // if we start adding objects to the options. Further, it would only be an issue if keyguard
1088+ // used such options.
1089+ if (isLocalBinder () && bundle != null ) {
1090+ return (Bundle ) bundle .clone ();
1091+ }
1092+ return bundle ;
1093+ }
1094+
10651095 public int [] startListening (IAppWidgetHost callbacks , String packageName , int hostId ,
10661096 List <RemoteViews > updatedViews ) {
10671097 int callingUid = enforceCallingUid (packageName );
@@ -1078,7 +1108,7 @@ public int[] startListening(IAppWidgetHost callbacks, String packageName, int ho
10781108 for (int i = 0 ; i < N ; i ++) {
10791109 AppWidgetId id = instances .get (i );
10801110 updatedIds [i ] = id .appWidgetId ;
1081- updatedViews .add (id .views );
1111+ updatedViews .add (cloneIfLocalBinder ( id .views ) );
10821112 }
10831113 return updatedIds ;
10841114 }
0 commit comments