Loading core/java/android/widget/RemoteViews.java +23 −8 Original line number Diff line number Diff line Loading @@ -42,11 +42,13 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.net.Uri; import android.os.AsyncTask; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.CancellationSignal; import android.os.Parcel; import android.os.Parcelable; import android.os.Process; import android.os.StrictMode; import android.os.UserHandle; import android.text.TextUtils; Loading Loading @@ -91,6 +93,12 @@ public class RemoteViews implements Parcelable, Filter { */ static final String EXTRA_REMOTEADAPTER_APPWIDGET_ID = "remoteAdapterAppWidgetId"; /** * Maximum depth of nested views calls from {@link #addView(int, RemoteViews)} and * {@link #RemoteViews(RemoteViews, RemoteViews)}. */ private static final int MAX_NESTED_VIEWS = 10; /** * Application that hosts the remote views. * Loading Loading @@ -1538,11 +1546,11 @@ public class RemoteViews implements Parcelable, Filter { } } ViewGroupAction(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info) { ViewGroupAction(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info, int depth) { viewId = parcel.readInt(); boolean nestedViewsNull = parcel.readInt() == 0; if (!nestedViewsNull) { nestedViews = new RemoteViews(parcel, bitmapCache, info); nestedViews = new RemoteViews(parcel, bitmapCache, info, depth); } else { nestedViews = null; } Loading Loading @@ -2209,10 +2217,16 @@ public class RemoteViews implements Parcelable, Filter { * @param parcel */ public RemoteViews(Parcel parcel) { this(parcel, null, null); this(parcel, null, null, 0); } private RemoteViews(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info, int depth) { if (depth > MAX_NESTED_VIEWS && (UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID)) { throw new IllegalArgumentException("Too many nested views."); } depth++; private RemoteViews(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info) { int mode = parcel.readInt(); // We only store a bitmap cache in the root of the RemoteViews. Loading Loading @@ -2245,7 +2259,8 @@ public class RemoteViews implements Parcelable, Filter { mActions.add(new ReflectionAction(parcel)); break; case ViewGroupAction.TAG: mActions.add(new ViewGroupAction(parcel, mBitmapCache, mApplication)); mActions.add(new ViewGroupAction(parcel, mBitmapCache, mApplication, depth)); break; case ReflectionActionWithoutParams.TAG: mActions.add(new ReflectionActionWithoutParams(parcel)); Loading Loading @@ -2293,8 +2308,8 @@ public class RemoteViews implements Parcelable, Filter { } } else { // MODE_HAS_LANDSCAPE_AND_PORTRAIT mLandscape = new RemoteViews(parcel, mBitmapCache, info); mPortrait = new RemoteViews(parcel, mBitmapCache, mLandscape.mApplication); mLandscape = new RemoteViews(parcel, mBitmapCache, info, depth); mPortrait = new RemoteViews(parcel, mBitmapCache, mLandscape.mApplication, depth); mApplication = mPortrait.mApplication; mLayoutId = mPortrait.getLayoutId(); } Loading @@ -2318,7 +2333,7 @@ public class RemoteViews implements Parcelable, Filter { p.setDataPosition(0); mIsRoot = true; RemoteViews rv = new RemoteViews(p, mBitmapCache.clone(), mApplication); RemoteViews rv = new RemoteViews(p, mBitmapCache.clone(), mApplication, 0); rv.mIsRoot = true; p.recycle(); Loading core/tests/coretests/src/android/widget/RemoteViewsTest.java +41 −7 Original line number Diff line number Diff line Loading @@ -179,13 +179,8 @@ public class RemoteViewsTest { ViewAppliedListener listener = new ViewAppliedListener(); views.applyAsync(mContext, mContainer, AsyncTask.THREAD_POOL_EXECUTOR, listener); boolean exceptionThrown = false; try { exception.expect(Exception.class); listener.waitAndGetView(); } catch (Exception e) { exceptionThrown = true; } assertTrue(exceptionThrown); } @Test Loading Loading @@ -332,4 +327,43 @@ public class RemoteViewsTest { return mView; } } @Test public void nestedAddViews() { RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_test); for (int i = 0; i < 10; i++) { RemoteViews parent = new RemoteViews(mPackage, R.layout.remote_views_test); parent.addView(R.id.layout, views); views = parent; } views.clone(); views = new RemoteViews(mPackage, R.layout.remote_views_test); for (int i = 0; i < 11; i++) { RemoteViews parent = new RemoteViews(mPackage, R.layout.remote_views_test); parent.addView(R.id.layout, views); views = parent; } exception.expect(IllegalArgumentException.class); views.clone(); } @Test public void nestedLandscapeViews() { RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_test); for (int i = 0; i < 10; i++) { views = new RemoteViews(views, new RemoteViews(mPackage, R.layout.remote_views_test)); } views.clone(); views = new RemoteViews(mPackage, R.layout.remote_views_test); for (int i = 0; i < 11; i++) { RemoteViews parent = new RemoteViews(mPackage, R.layout.remote_views_test); parent.addView(R.id.layout, views); views = parent; } exception.expect(IllegalArgumentException.class); views.clone(); } } Loading
core/java/android/widget/RemoteViews.java +23 −8 Original line number Diff line number Diff line Loading @@ -42,11 +42,13 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.net.Uri; import android.os.AsyncTask; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.CancellationSignal; import android.os.Parcel; import android.os.Parcelable; import android.os.Process; import android.os.StrictMode; import android.os.UserHandle; import android.text.TextUtils; Loading Loading @@ -91,6 +93,12 @@ public class RemoteViews implements Parcelable, Filter { */ static final String EXTRA_REMOTEADAPTER_APPWIDGET_ID = "remoteAdapterAppWidgetId"; /** * Maximum depth of nested views calls from {@link #addView(int, RemoteViews)} and * {@link #RemoteViews(RemoteViews, RemoteViews)}. */ private static final int MAX_NESTED_VIEWS = 10; /** * Application that hosts the remote views. * Loading Loading @@ -1538,11 +1546,11 @@ public class RemoteViews implements Parcelable, Filter { } } ViewGroupAction(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info) { ViewGroupAction(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info, int depth) { viewId = parcel.readInt(); boolean nestedViewsNull = parcel.readInt() == 0; if (!nestedViewsNull) { nestedViews = new RemoteViews(parcel, bitmapCache, info); nestedViews = new RemoteViews(parcel, bitmapCache, info, depth); } else { nestedViews = null; } Loading Loading @@ -2209,10 +2217,16 @@ public class RemoteViews implements Parcelable, Filter { * @param parcel */ public RemoteViews(Parcel parcel) { this(parcel, null, null); this(parcel, null, null, 0); } private RemoteViews(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info, int depth) { if (depth > MAX_NESTED_VIEWS && (UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID)) { throw new IllegalArgumentException("Too many nested views."); } depth++; private RemoteViews(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info) { int mode = parcel.readInt(); // We only store a bitmap cache in the root of the RemoteViews. Loading Loading @@ -2245,7 +2259,8 @@ public class RemoteViews implements Parcelable, Filter { mActions.add(new ReflectionAction(parcel)); break; case ViewGroupAction.TAG: mActions.add(new ViewGroupAction(parcel, mBitmapCache, mApplication)); mActions.add(new ViewGroupAction(parcel, mBitmapCache, mApplication, depth)); break; case ReflectionActionWithoutParams.TAG: mActions.add(new ReflectionActionWithoutParams(parcel)); Loading Loading @@ -2293,8 +2308,8 @@ public class RemoteViews implements Parcelable, Filter { } } else { // MODE_HAS_LANDSCAPE_AND_PORTRAIT mLandscape = new RemoteViews(parcel, mBitmapCache, info); mPortrait = new RemoteViews(parcel, mBitmapCache, mLandscape.mApplication); mLandscape = new RemoteViews(parcel, mBitmapCache, info, depth); mPortrait = new RemoteViews(parcel, mBitmapCache, mLandscape.mApplication, depth); mApplication = mPortrait.mApplication; mLayoutId = mPortrait.getLayoutId(); } Loading @@ -2318,7 +2333,7 @@ public class RemoteViews implements Parcelable, Filter { p.setDataPosition(0); mIsRoot = true; RemoteViews rv = new RemoteViews(p, mBitmapCache.clone(), mApplication); RemoteViews rv = new RemoteViews(p, mBitmapCache.clone(), mApplication, 0); rv.mIsRoot = true; p.recycle(); Loading
core/tests/coretests/src/android/widget/RemoteViewsTest.java +41 −7 Original line number Diff line number Diff line Loading @@ -179,13 +179,8 @@ public class RemoteViewsTest { ViewAppliedListener listener = new ViewAppliedListener(); views.applyAsync(mContext, mContainer, AsyncTask.THREAD_POOL_EXECUTOR, listener); boolean exceptionThrown = false; try { exception.expect(Exception.class); listener.waitAndGetView(); } catch (Exception e) { exceptionThrown = true; } assertTrue(exceptionThrown); } @Test Loading Loading @@ -332,4 +327,43 @@ public class RemoteViewsTest { return mView; } } @Test public void nestedAddViews() { RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_test); for (int i = 0; i < 10; i++) { RemoteViews parent = new RemoteViews(mPackage, R.layout.remote_views_test); parent.addView(R.id.layout, views); views = parent; } views.clone(); views = new RemoteViews(mPackage, R.layout.remote_views_test); for (int i = 0; i < 11; i++) { RemoteViews parent = new RemoteViews(mPackage, R.layout.remote_views_test); parent.addView(R.id.layout, views); views = parent; } exception.expect(IllegalArgumentException.class); views.clone(); } @Test public void nestedLandscapeViews() { RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_test); for (int i = 0; i < 10; i++) { views = new RemoteViews(views, new RemoteViews(mPackage, R.layout.remote_views_test)); } views.clone(); views = new RemoteViews(mPackage, R.layout.remote_views_test); for (int i = 0; i < 11; i++) { RemoteViews parent = new RemoteViews(mPackage, R.layout.remote_views_test); parent.addView(R.id.layout, views); views = parent; } exception.expect(IllegalArgumentException.class); views.clone(); } }