summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server/AppWidgetServiceImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com/android/server/AppWidgetServiceImpl.java')
-rw-r--r--services/java/com/android/server/AppWidgetServiceImpl.java40
1 files changed, 35 insertions, 5 deletions
diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java
index 8ec67c4..e77f8cf 100644
--- a/services/java/com/android/server/AppWidgetServiceImpl.java
+++ b/services/java/com/android/server/AppWidgetServiceImpl.java
@@ -534,6 +534,7 @@ class AppWidgetServiceImpl {
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mAppWidgetIds) {
+ options = cloneIfLocalBinder(options);
ensureStateLoadedLocked();
AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
if (id == null) {
@@ -817,7 +818,7 @@ class AppWidgetServiceImpl {
ensureStateLoadedLocked();
AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
if (id != null && id.provider != null && !id.provider.zombie) {
- return id.provider.info;
+ return cloneIfLocalBinder(id.provider.info);
}
return null;
}
@@ -828,7 +829,7 @@ class AppWidgetServiceImpl {
ensureStateLoadedLocked();
AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
if (id != null) {
- return id.views;
+ return cloneIfLocalBinder(id.views);
}
return null;
}
@@ -842,7 +843,7 @@ class AppWidgetServiceImpl {
for (int i = 0; i < N; i++) {
Provider p = mInstalledProviders.get(i);
if (!p.zombie) {
- result.add(p.info);
+ result.add(cloneIfLocalBinder(p.info));
}
}
return result;
@@ -881,6 +882,7 @@ class AppWidgetServiceImpl {
public void updateAppWidgetOptions(int appWidgetId, Bundle options) {
synchronized (mAppWidgetIds) {
+ options = cloneIfLocalBinder(options);
ensureStateLoadedLocked();
AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
@@ -907,7 +909,7 @@ class AppWidgetServiceImpl {
ensureStateLoadedLocked();
AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
if (id != null && id.options != null) {
- return id.options;
+ return cloneIfLocalBinder(id.options);
} else {
return Bundle.EMPTY;
}
@@ -1062,6 +1064,34 @@ class AppWidgetServiceImpl {
}
}
+ private boolean isLocalBinder() {
+ return Process.myPid() == Binder.getCallingPid();
+ }
+
+ private RemoteViews cloneIfLocalBinder(RemoteViews rv) {
+ if (isLocalBinder() && rv != null) {
+ return rv.clone();
+ }
+ return rv;
+ }
+
+ private AppWidgetProviderInfo cloneIfLocalBinder(AppWidgetProviderInfo info) {
+ if (isLocalBinder() && info != null) {
+ return info.clone();
+ }
+ return info;
+ }
+
+ private Bundle cloneIfLocalBinder(Bundle bundle) {
+ // Note: this is only a shallow copy. For now this will be fine, but it could be problematic
+ // if we start adding objects to the options. Further, it would only be an issue if keyguard
+ // used such options.
+ if (isLocalBinder() && bundle != null) {
+ return (Bundle) bundle.clone();
+ }
+ return bundle;
+ }
+
public int[] startListening(IAppWidgetHost callbacks, String packageName, int hostId,
List<RemoteViews> updatedViews) {
int callingUid = enforceCallingUid(packageName);
@@ -1078,7 +1108,7 @@ class AppWidgetServiceImpl {
for (int i = 0; i < N; i++) {
AppWidgetId id = instances.get(i);
updatedIds[i] = id.appWidgetId;
- updatedViews.add(id.views);
+ updatedViews.add(cloneIfLocalBinder(id.views));
}
return updatedIds;
}