Loading core/api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -8371,7 +8371,9 @@ package android.appwidget { method protected android.view.View getDefaultView(); method protected android.view.View getErrorView(); method protected void prepareView(android.view.View); method public void resetColorResources(); method public void setAppWidget(int, android.appwidget.AppWidgetProviderInfo); method public void setColorResources(@NonNull android.util.SparseIntArray); method public void setCurrentSize(@NonNull android.graphics.PointF); method public void setExecutor(java.util.concurrent.Executor); method public void setOnLightBackground(boolean); core/java/android/appwidget/AppWidgetHostView.java +61 −8 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import android.util.AttributeSet; import android.util.Log; import android.util.Pair; import android.util.SparseArray; import android.util.SparseIntArray; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; Loading Loading @@ -92,7 +93,10 @@ public class AppWidgetHostView extends FrameLayout { int mLayoutId = -1; private InteractionHandler mInteractionHandler; private boolean mOnLightBackground; PointF mCurrentSize = null; private PointF mCurrentSize = null; private RemoteViews.ColorResources mColorResources = null; // Stores the last remote views last inflated. private RemoteViews mLastInflatedRemoteViews = null; private Executor mAsyncExecutor; private CancellationSignal mLastExecutionSignal; Loading Loading @@ -358,7 +362,7 @@ public class AppWidgetHostView extends FrameLayout { PointF newSize = new PointF(size.x - xPaddingDips, size.y - yPaddingDips); if (!newSize.equals(mCurrentSize)) { mCurrentSize = newSize; mLayoutId = -1; // Prevents recycling the view. reapplyLastRemoteViews(); } } Loading @@ -368,7 +372,7 @@ public class AppWidgetHostView extends FrameLayout { public void clearCurrentSize() { if (mCurrentSize != null) { mCurrentSize = null; mLayoutId = -1; reapplyLastRemoteViews(); } } Loading Loading @@ -477,9 +481,17 @@ public class AppWidgetHostView extends FrameLayout { * AppWidget provider. Will animate into these new views as needed */ public void updateAppWidget(RemoteViews remoteViews) { this.mLastInflatedRemoteViews = remoteViews; applyRemoteViews(remoteViews, true); } /** * Reapply the last inflated remote views, or the default view is none was inflated. */ private void reapplyLastRemoteViews() { applyRemoteViews(mLastInflatedRemoteViews, true); } /** * @hide */ Loading Loading @@ -518,7 +530,8 @@ public class AppWidgetHostView extends FrameLayout { // layout matches, try recycling it if (content == null && layoutId == mLayoutId) { try { remoteViews.reapply(mContext, mView, mInteractionHandler); remoteViews.reapply(mContext, mView, mInteractionHandler, mCurrentSize, mColorResources); content = mView; recycled = true; if (LOGD) Log.d(TAG, "was able to recycle existing layout"); Loading @@ -530,7 +543,8 @@ public class AppWidgetHostView extends FrameLayout { // Try normal RemoteView inflation if (content == null) { try { content = remoteViews.apply(mContext, this, mInteractionHandler, mCurrentSize); content = remoteViews.apply(mContext, this, mInteractionHandler, mCurrentSize, mColorResources); if (LOGD) Log.d(TAG, "had to inflate new layout"); } catch (RuntimeException e) { exception = e; Loading Loading @@ -583,7 +597,8 @@ public class AppWidgetHostView extends FrameLayout { mAsyncExecutor, new ViewApplyListener(remoteViews, layoutId, true), mInteractionHandler, mCurrentSize); mCurrentSize, mColorResources); } catch (Exception e) { // Reapply failed. Try apply } Loading @@ -594,7 +609,8 @@ public class AppWidgetHostView extends FrameLayout { mAsyncExecutor, new ViewApplyListener(remoteViews, layoutId, false), mInteractionHandler, mCurrentSize); mCurrentSize, mColorResources); } } Loading Loading @@ -662,9 +678,13 @@ public class AppWidgetHostView extends FrameLayout { protected Context getRemoteContext() { try { // Return if cloned successfully, otherwise default return mContext.createApplicationContext( Context newContext = mContext.createApplicationContext( mInfo.providerInfo.applicationInfo, Context.CONTEXT_RESTRICTED); if (mColorResources != null) { mColorResources.apply(newContext); } return newContext; } catch (NameNotFoundException e) { Log.e(TAG, "Package name " + mInfo.providerInfo.packageName + " not found"); return mContext; Loading Loading @@ -819,4 +839,37 @@ public class AppWidgetHostView extends FrameLayout { } }; } /** * Set the dynamically overloaded color resources. * * {@code colorMapping} maps a predefined set of color resources to their ARGB * representation. Any entry not in the predefined set of colors will be ignored. * * Calling this method will trigger a full re-inflation of the App Widget. * * The color resources that can be overloaded are the ones whose name is prefixed with * {@code system_primary_}, {@code system_secondary_} or {@code system_neutral_}, for example * {@link android.R.color#system_primary_500}. */ public void setColorResources(@NonNull SparseIntArray colorMapping) { mColorResources = RemoteViews.ColorResources.create(mContext, colorMapping); mLayoutId = -1; reapplyLastRemoteViews(); } /** * Reset the dynamically overloaded resources, reverting to the default values for * all the colors. * * If colors were defined before, calling this method will trigger a full re-inflation of the * App Widget. */ public void resetColorResources() { if (mColorResources != null) { mColorResources = null; mLayoutId = -1; reapplyLastRemoteViews(); } } } core/java/android/widget/RemoteViews.java +262 −85 File changed.Preview size limit exceeded, changes collapsed. Show changes core/java/android/widget/RemoteViewsListAdapter.java +6 −3 Original line number Diff line number Diff line Loading @@ -31,12 +31,14 @@ public class RemoteViewsListAdapter extends BaseAdapter { private ArrayList<RemoteViews> mRemoteViewsList; private ArrayList<Integer> mViewTypes = new ArrayList<Integer>(); private int mViewTypeCount; private RemoteViews.ColorResources mColorResources; public RemoteViewsListAdapter(Context context, ArrayList<RemoteViews> remoteViews, int viewTypeCount) { int viewTypeCount, RemoteViews.ColorResources colorResources) { mContext = context; mRemoteViewsList = remoteViews; mViewTypeCount = viewTypeCount; mColorResources = colorResources; init(); } Loading Loading @@ -90,9 +92,10 @@ public class RemoteViewsListAdapter extends BaseAdapter { if (convertView != null && rv != null && convertView.getId() == rv.getLayoutId()) { v = convertView; rv.reapply(mContext, v); rv.reapply(mContext, v, null /* handler */, null /* size */, mColorResources); } else { v = rv.apply(mContext, parent); v = rv.apply(mContext, parent, null /* handler */, null /* size */, mColorResources); } return v; } else { Loading core/res/Android.bp +67 −0 Original line number Diff line number Diff line Loading @@ -44,11 +44,73 @@ license { ], } genrule { name: "remote-color-resources-compile-public", tools: ["aapt2"], srcs: [ "remote_color_resources_res/values/public.xml", ], out: ["values_public.arsc.flat"], cmd: "$(location aapt2) compile $(in) -o $(genDir)", } genrule { name: "remote-color-resources-compile-colors", tools: ["aapt2"], srcs: [ "remote_color_resources_res/values/colors.xml", ], out: ["values_colors.arsc.flat"], cmd: "$(location aapt2) compile $(in) -o $(genDir)", } genrule { name: "remote-color-resources-apk", tools: ["aapt2"], // The first input file in the list must be the manifest srcs: [ "RemoteThemeColorsAndroidManifest.xml", ":remote-color-resources-compile-public", ":remote-color-resources-compile-colors", ], out: ["remote-color-resources.apk"], cmd: "$(location aapt2) link -o $(out) --manifest $(in)" } genrule { name: "remote-color-resources-arsc", srcs: [":remote-color-resources-apk"], out: ["res/raw/remote_views_color_resources.arsc"], cmd: "mkdir -p $(genDir)/remote-color-resources-arsc && " + "unzip -x $(in) resources.arsc -d $(genDir)/remote-color-resources-arsc && " + "mkdir -p $$(dirname $(out)) && " + "mv $(genDir)/remote-color-resources-arsc/resources.arsc $(out) && " + "echo 'Created $(out)'" } genrule { name: "remote-color-resources-arsc-zip", tools: ["soong_zip"], srcs: [ ":remote-color-resources-arsc", "remote_color_resources_res/symbols.xml", ], out: ["remote_views_color_resources.zip"], cmd: "INPUTS=($(in)) && " + "RES_DIR=$$(dirname $$(dirname $${INPUTS[0]})) && " + "mkdir -p $$RES_DIR/values && " + "cp $${INPUTS[1]} $$RES_DIR/values && " + "$(location soong_zip) -o $(out) -C $$RES_DIR -D $$RES_DIR && " + "cp $(out) ." } android_app { name: "framework-res", sdk_version: "core_platform", certificate: "platform", srcs: [":remote-color-resources-arsc"], // Disable dexpreopt and verify_uses_libraries check as the app // contains no Java code to be dexpreopted. enforce_uses_libs: false, Loading @@ -72,6 +134,10 @@ android_app { "--auto-add-overlay", ], resource_zips: [ ":remote-color-resources-arsc-zip", ], // Create package-export.apk, which other packages can use to get // PRODUCT-agnostic resource data like IDs and type definitions. export_package_resources: true, Loading @@ -96,6 +162,7 @@ filegroup { srcs: [ "assets/**/*", "res/**/*", ":remote-color-resources-arsc", ], } Loading Loading
core/api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -8371,7 +8371,9 @@ package android.appwidget { method protected android.view.View getDefaultView(); method protected android.view.View getErrorView(); method protected void prepareView(android.view.View); method public void resetColorResources(); method public void setAppWidget(int, android.appwidget.AppWidgetProviderInfo); method public void setColorResources(@NonNull android.util.SparseIntArray); method public void setCurrentSize(@NonNull android.graphics.PointF); method public void setExecutor(java.util.concurrent.Executor); method public void setOnLightBackground(boolean);
core/java/android/appwidget/AppWidgetHostView.java +61 −8 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import android.util.AttributeSet; import android.util.Log; import android.util.Pair; import android.util.SparseArray; import android.util.SparseIntArray; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; Loading Loading @@ -92,7 +93,10 @@ public class AppWidgetHostView extends FrameLayout { int mLayoutId = -1; private InteractionHandler mInteractionHandler; private boolean mOnLightBackground; PointF mCurrentSize = null; private PointF mCurrentSize = null; private RemoteViews.ColorResources mColorResources = null; // Stores the last remote views last inflated. private RemoteViews mLastInflatedRemoteViews = null; private Executor mAsyncExecutor; private CancellationSignal mLastExecutionSignal; Loading Loading @@ -358,7 +362,7 @@ public class AppWidgetHostView extends FrameLayout { PointF newSize = new PointF(size.x - xPaddingDips, size.y - yPaddingDips); if (!newSize.equals(mCurrentSize)) { mCurrentSize = newSize; mLayoutId = -1; // Prevents recycling the view. reapplyLastRemoteViews(); } } Loading @@ -368,7 +372,7 @@ public class AppWidgetHostView extends FrameLayout { public void clearCurrentSize() { if (mCurrentSize != null) { mCurrentSize = null; mLayoutId = -1; reapplyLastRemoteViews(); } } Loading Loading @@ -477,9 +481,17 @@ public class AppWidgetHostView extends FrameLayout { * AppWidget provider. Will animate into these new views as needed */ public void updateAppWidget(RemoteViews remoteViews) { this.mLastInflatedRemoteViews = remoteViews; applyRemoteViews(remoteViews, true); } /** * Reapply the last inflated remote views, or the default view is none was inflated. */ private void reapplyLastRemoteViews() { applyRemoteViews(mLastInflatedRemoteViews, true); } /** * @hide */ Loading Loading @@ -518,7 +530,8 @@ public class AppWidgetHostView extends FrameLayout { // layout matches, try recycling it if (content == null && layoutId == mLayoutId) { try { remoteViews.reapply(mContext, mView, mInteractionHandler); remoteViews.reapply(mContext, mView, mInteractionHandler, mCurrentSize, mColorResources); content = mView; recycled = true; if (LOGD) Log.d(TAG, "was able to recycle existing layout"); Loading @@ -530,7 +543,8 @@ public class AppWidgetHostView extends FrameLayout { // Try normal RemoteView inflation if (content == null) { try { content = remoteViews.apply(mContext, this, mInteractionHandler, mCurrentSize); content = remoteViews.apply(mContext, this, mInteractionHandler, mCurrentSize, mColorResources); if (LOGD) Log.d(TAG, "had to inflate new layout"); } catch (RuntimeException e) { exception = e; Loading Loading @@ -583,7 +597,8 @@ public class AppWidgetHostView extends FrameLayout { mAsyncExecutor, new ViewApplyListener(remoteViews, layoutId, true), mInteractionHandler, mCurrentSize); mCurrentSize, mColorResources); } catch (Exception e) { // Reapply failed. Try apply } Loading @@ -594,7 +609,8 @@ public class AppWidgetHostView extends FrameLayout { mAsyncExecutor, new ViewApplyListener(remoteViews, layoutId, false), mInteractionHandler, mCurrentSize); mCurrentSize, mColorResources); } } Loading Loading @@ -662,9 +678,13 @@ public class AppWidgetHostView extends FrameLayout { protected Context getRemoteContext() { try { // Return if cloned successfully, otherwise default return mContext.createApplicationContext( Context newContext = mContext.createApplicationContext( mInfo.providerInfo.applicationInfo, Context.CONTEXT_RESTRICTED); if (mColorResources != null) { mColorResources.apply(newContext); } return newContext; } catch (NameNotFoundException e) { Log.e(TAG, "Package name " + mInfo.providerInfo.packageName + " not found"); return mContext; Loading Loading @@ -819,4 +839,37 @@ public class AppWidgetHostView extends FrameLayout { } }; } /** * Set the dynamically overloaded color resources. * * {@code colorMapping} maps a predefined set of color resources to their ARGB * representation. Any entry not in the predefined set of colors will be ignored. * * Calling this method will trigger a full re-inflation of the App Widget. * * The color resources that can be overloaded are the ones whose name is prefixed with * {@code system_primary_}, {@code system_secondary_} or {@code system_neutral_}, for example * {@link android.R.color#system_primary_500}. */ public void setColorResources(@NonNull SparseIntArray colorMapping) { mColorResources = RemoteViews.ColorResources.create(mContext, colorMapping); mLayoutId = -1; reapplyLastRemoteViews(); } /** * Reset the dynamically overloaded resources, reverting to the default values for * all the colors. * * If colors were defined before, calling this method will trigger a full re-inflation of the * App Widget. */ public void resetColorResources() { if (mColorResources != null) { mColorResources = null; mLayoutId = -1; reapplyLastRemoteViews(); } } }
core/java/android/widget/RemoteViews.java +262 −85 File changed.Preview size limit exceeded, changes collapsed. Show changes
core/java/android/widget/RemoteViewsListAdapter.java +6 −3 Original line number Diff line number Diff line Loading @@ -31,12 +31,14 @@ public class RemoteViewsListAdapter extends BaseAdapter { private ArrayList<RemoteViews> mRemoteViewsList; private ArrayList<Integer> mViewTypes = new ArrayList<Integer>(); private int mViewTypeCount; private RemoteViews.ColorResources mColorResources; public RemoteViewsListAdapter(Context context, ArrayList<RemoteViews> remoteViews, int viewTypeCount) { int viewTypeCount, RemoteViews.ColorResources colorResources) { mContext = context; mRemoteViewsList = remoteViews; mViewTypeCount = viewTypeCount; mColorResources = colorResources; init(); } Loading Loading @@ -90,9 +92,10 @@ public class RemoteViewsListAdapter extends BaseAdapter { if (convertView != null && rv != null && convertView.getId() == rv.getLayoutId()) { v = convertView; rv.reapply(mContext, v); rv.reapply(mContext, v, null /* handler */, null /* size */, mColorResources); } else { v = rv.apply(mContext, parent); v = rv.apply(mContext, parent, null /* handler */, null /* size */, mColorResources); } return v; } else { Loading
core/res/Android.bp +67 −0 Original line number Diff line number Diff line Loading @@ -44,11 +44,73 @@ license { ], } genrule { name: "remote-color-resources-compile-public", tools: ["aapt2"], srcs: [ "remote_color_resources_res/values/public.xml", ], out: ["values_public.arsc.flat"], cmd: "$(location aapt2) compile $(in) -o $(genDir)", } genrule { name: "remote-color-resources-compile-colors", tools: ["aapt2"], srcs: [ "remote_color_resources_res/values/colors.xml", ], out: ["values_colors.arsc.flat"], cmd: "$(location aapt2) compile $(in) -o $(genDir)", } genrule { name: "remote-color-resources-apk", tools: ["aapt2"], // The first input file in the list must be the manifest srcs: [ "RemoteThemeColorsAndroidManifest.xml", ":remote-color-resources-compile-public", ":remote-color-resources-compile-colors", ], out: ["remote-color-resources.apk"], cmd: "$(location aapt2) link -o $(out) --manifest $(in)" } genrule { name: "remote-color-resources-arsc", srcs: [":remote-color-resources-apk"], out: ["res/raw/remote_views_color_resources.arsc"], cmd: "mkdir -p $(genDir)/remote-color-resources-arsc && " + "unzip -x $(in) resources.arsc -d $(genDir)/remote-color-resources-arsc && " + "mkdir -p $$(dirname $(out)) && " + "mv $(genDir)/remote-color-resources-arsc/resources.arsc $(out) && " + "echo 'Created $(out)'" } genrule { name: "remote-color-resources-arsc-zip", tools: ["soong_zip"], srcs: [ ":remote-color-resources-arsc", "remote_color_resources_res/symbols.xml", ], out: ["remote_views_color_resources.zip"], cmd: "INPUTS=($(in)) && " + "RES_DIR=$$(dirname $$(dirname $${INPUTS[0]})) && " + "mkdir -p $$RES_DIR/values && " + "cp $${INPUTS[1]} $$RES_DIR/values && " + "$(location soong_zip) -o $(out) -C $$RES_DIR -D $$RES_DIR && " + "cp $(out) ." } android_app { name: "framework-res", sdk_version: "core_platform", certificate: "platform", srcs: [":remote-color-resources-arsc"], // Disable dexpreopt and verify_uses_libraries check as the app // contains no Java code to be dexpreopted. enforce_uses_libs: false, Loading @@ -72,6 +134,10 @@ android_app { "--auto-add-overlay", ], resource_zips: [ ":remote-color-resources-arsc-zip", ], // Create package-export.apk, which other packages can use to get // PRODUCT-agnostic resource data like IDs and type definitions. export_package_resources: true, Loading @@ -96,6 +162,7 @@ filegroup { srcs: [ "assets/**/*", "res/**/*", ":remote-color-resources-arsc", ], } Loading