Loading core/java/android/widget/RemoteViews.java +12 −5 Original line number Diff line number Diff line Loading @@ -131,7 +131,7 @@ public class RemoteViews implements Parcelable, Filter { * * @hide */ private ApplicationInfo mApplication; public ApplicationInfo mApplication; /** * The resource ID of the layout file. (Added to the parcel) Loading Loading @@ -1519,8 +1519,7 @@ public class RemoteViews implements Parcelable, Filter { @Override public boolean hasSameAppInfo(ApplicationInfo parentInfo) { return mNestedViews.mApplication.packageName.equals(parentInfo.packageName) && mNestedViews.mApplication.uid == parentInfo.uid; return mNestedViews.hasSameAppInfo(parentInfo); } @Override Loading Loading @@ -2138,8 +2137,7 @@ public class RemoteViews implements Parcelable, Filter { if (landscape == null || portrait == null) { throw new RuntimeException("Both RemoteViews must be non-null"); } if (landscape.mApplication.uid != portrait.mApplication.uid || !landscape.mApplication.packageName.equals(portrait.mApplication.packageName)) { if (!landscape.hasSameAppInfo(portrait.mApplication)) { throw new RuntimeException("Both RemoteViews must share the same package and user"); } mApplication = portrait.mApplication; Loading Loading @@ -3554,6 +3552,15 @@ public class RemoteViews implements Parcelable, Filter { return applicationInfo; } /** * Returns true if the {@link #mApplication} is same as the provided info. * * @hide */ public boolean hasSameAppInfo(ApplicationInfo info) { return mApplication.packageName.equals(info.packageName) && mApplication.uid == info.uid; } /** * Parcelable.Creator that instantiates RemoteViews objects */ Loading core/java/android/widget/RemoteViewsAdapter.java +39 −30 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetManager; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; Loading Loading @@ -114,6 +115,12 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback // construction (happens when we have a cached FixedSizeRemoteViewsCache). private boolean mDataReady = false; /** * USed to dedupe {@link RemoteViews#mApplication} so that we do not hold on to * multiple copies of the same ApplicationInfo object. */ private ApplicationInfo mLastRemoteViewAppInfo; /** * An interface for the RemoteAdapter to notify other classes when adapters * are actually connected to/disconnected from their actual services. Loading Loading @@ -309,6 +316,8 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback static class RemoteViewsFrameLayout extends AppWidgetHostView { private final FixedSizeRemoteViewsCache mCache; public int cacheIndex = -1; public RemoteViewsFrameLayout(Context context, FixedSizeRemoteViewsCache cache) { super(context); mCache = cache; Loading Loading @@ -359,26 +368,23 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback * Stores the references of all the RemoteViewsFrameLayouts that have been returned by the * adapter that have not yet had their RemoteViews loaded. */ private class RemoteViewsFrameLayoutRefSet { private final SparseArray<LinkedList<RemoteViewsFrameLayout>> mReferences = new SparseArray<>(); private final HashMap<RemoteViewsFrameLayout, LinkedList<RemoteViewsFrameLayout>> mViewToLinkedList = new HashMap<>(); private class RemoteViewsFrameLayoutRefSet extends SparseArray<LinkedList<RemoteViewsFrameLayout>> { /** * Adds a new reference to a RemoteViewsFrameLayout returned by the adapter. */ public void add(int position, RemoteViewsFrameLayout layout) { LinkedList<RemoteViewsFrameLayout> refs = mReferences.get(position); LinkedList<RemoteViewsFrameLayout> refs = get(position); // Create the list if necessary if (refs == null) { refs = new LinkedList<RemoteViewsFrameLayout>(); mReferences.put(position, refs); refs = new LinkedList<>(); put(position, refs); } mViewToLinkedList.put(layout, refs); // Add the references to the list layout.cacheIndex = position; refs.add(layout); } Loading @@ -389,18 +395,13 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback public void notifyOnRemoteViewsLoaded(int position, RemoteViews view) { if (view == null) return; final LinkedList<RemoteViewsFrameLayout> refs = mReferences.get(position); // Remove this set from the original mapping final LinkedList<RemoteViewsFrameLayout> refs = removeReturnOld(position); if (refs != null) { // Notify all the references for that position of the newly loaded RemoteViews for (final RemoteViewsFrameLayout ref : refs) { ref.onRemoteViewsLoaded(view, mRemoteViewsOnClickHandler, true); if (mViewToLinkedList.containsKey(ref)) { mViewToLinkedList.remove(ref); } } refs.clear(); // Remove this set from the original mapping mReferences.remove(position); } } Loading @@ -408,20 +409,14 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback * We need to remove views from this set if they have been recycled by the AdapterView. */ public void removeView(RemoteViewsFrameLayout rvfl) { if (mViewToLinkedList.containsKey(rvfl)) { mViewToLinkedList.get(rvfl).remove(rvfl); mViewToLinkedList.remove(rvfl); if (rvfl.cacheIndex < 0) { return; } final LinkedList<RemoteViewsFrameLayout> refs = get(rvfl.cacheIndex); if (refs != null) { refs.remove(rvfl); } /** * Removes all references to all RemoteViewsFrameLayouts returned by the adapter. */ public void clear() { // We currently just clear the references, and leave all the previous layouts returned // in their default state of the loading view. mReferences.clear(); mViewToLinkedList.clear(); rvfl.cacheIndex = -1; } } Loading Loading @@ -534,7 +529,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback // too much memory. private final SparseArray<RemoteViews> mIndexRemoteViews = new SparseArray<>(); // An array of indices to load, Indices which are explicitely requested are set to true, // An array of indices to load, Indices which are explicitly requested are set to true, // and those determined by the preloading algorithm to prefetch are set to false. private final SparseBooleanArray mIndicesToLoad = new SparseBooleanArray(); Loading Loading @@ -994,6 +989,20 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback return; } if (remoteViews.mApplication != null) { // We keep track of last application info. This helps when all the remoteViews have // same applicationInfo, which should be the case for a typical adapter. But if every // view has different application info, there will not be any optimization. if (mLastRemoteViewAppInfo != null && remoteViews.hasSameAppInfo(mLastRemoteViewAppInfo)) { // We should probably also update the remoteViews for nested ViewActions. // Hopefully, RemoteViews in an adapter would be less complicated. remoteViews.mApplication = mLastRemoteViewAppInfo; } else { mLastRemoteViewAppInfo = remoteViews.mApplication; } } int layoutId = remoteViews.getLayoutId(); RemoteViewsMetaData metaData = mCache.getMetaData(); boolean viewTypeInRange; Loading Loading
core/java/android/widget/RemoteViews.java +12 −5 Original line number Diff line number Diff line Loading @@ -131,7 +131,7 @@ public class RemoteViews implements Parcelable, Filter { * * @hide */ private ApplicationInfo mApplication; public ApplicationInfo mApplication; /** * The resource ID of the layout file. (Added to the parcel) Loading Loading @@ -1519,8 +1519,7 @@ public class RemoteViews implements Parcelable, Filter { @Override public boolean hasSameAppInfo(ApplicationInfo parentInfo) { return mNestedViews.mApplication.packageName.equals(parentInfo.packageName) && mNestedViews.mApplication.uid == parentInfo.uid; return mNestedViews.hasSameAppInfo(parentInfo); } @Override Loading Loading @@ -2138,8 +2137,7 @@ public class RemoteViews implements Parcelable, Filter { if (landscape == null || portrait == null) { throw new RuntimeException("Both RemoteViews must be non-null"); } if (landscape.mApplication.uid != portrait.mApplication.uid || !landscape.mApplication.packageName.equals(portrait.mApplication.packageName)) { if (!landscape.hasSameAppInfo(portrait.mApplication)) { throw new RuntimeException("Both RemoteViews must share the same package and user"); } mApplication = portrait.mApplication; Loading Loading @@ -3554,6 +3552,15 @@ public class RemoteViews implements Parcelable, Filter { return applicationInfo; } /** * Returns true if the {@link #mApplication} is same as the provided info. * * @hide */ public boolean hasSameAppInfo(ApplicationInfo info) { return mApplication.packageName.equals(info.packageName) && mApplication.uid == info.uid; } /** * Parcelable.Creator that instantiates RemoteViews objects */ Loading
core/java/android/widget/RemoteViewsAdapter.java +39 −30 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetManager; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; Loading Loading @@ -114,6 +115,12 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback // construction (happens when we have a cached FixedSizeRemoteViewsCache). private boolean mDataReady = false; /** * USed to dedupe {@link RemoteViews#mApplication} so that we do not hold on to * multiple copies of the same ApplicationInfo object. */ private ApplicationInfo mLastRemoteViewAppInfo; /** * An interface for the RemoteAdapter to notify other classes when adapters * are actually connected to/disconnected from their actual services. Loading Loading @@ -309,6 +316,8 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback static class RemoteViewsFrameLayout extends AppWidgetHostView { private final FixedSizeRemoteViewsCache mCache; public int cacheIndex = -1; public RemoteViewsFrameLayout(Context context, FixedSizeRemoteViewsCache cache) { super(context); mCache = cache; Loading Loading @@ -359,26 +368,23 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback * Stores the references of all the RemoteViewsFrameLayouts that have been returned by the * adapter that have not yet had their RemoteViews loaded. */ private class RemoteViewsFrameLayoutRefSet { private final SparseArray<LinkedList<RemoteViewsFrameLayout>> mReferences = new SparseArray<>(); private final HashMap<RemoteViewsFrameLayout, LinkedList<RemoteViewsFrameLayout>> mViewToLinkedList = new HashMap<>(); private class RemoteViewsFrameLayoutRefSet extends SparseArray<LinkedList<RemoteViewsFrameLayout>> { /** * Adds a new reference to a RemoteViewsFrameLayout returned by the adapter. */ public void add(int position, RemoteViewsFrameLayout layout) { LinkedList<RemoteViewsFrameLayout> refs = mReferences.get(position); LinkedList<RemoteViewsFrameLayout> refs = get(position); // Create the list if necessary if (refs == null) { refs = new LinkedList<RemoteViewsFrameLayout>(); mReferences.put(position, refs); refs = new LinkedList<>(); put(position, refs); } mViewToLinkedList.put(layout, refs); // Add the references to the list layout.cacheIndex = position; refs.add(layout); } Loading @@ -389,18 +395,13 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback public void notifyOnRemoteViewsLoaded(int position, RemoteViews view) { if (view == null) return; final LinkedList<RemoteViewsFrameLayout> refs = mReferences.get(position); // Remove this set from the original mapping final LinkedList<RemoteViewsFrameLayout> refs = removeReturnOld(position); if (refs != null) { // Notify all the references for that position of the newly loaded RemoteViews for (final RemoteViewsFrameLayout ref : refs) { ref.onRemoteViewsLoaded(view, mRemoteViewsOnClickHandler, true); if (mViewToLinkedList.containsKey(ref)) { mViewToLinkedList.remove(ref); } } refs.clear(); // Remove this set from the original mapping mReferences.remove(position); } } Loading @@ -408,20 +409,14 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback * We need to remove views from this set if they have been recycled by the AdapterView. */ public void removeView(RemoteViewsFrameLayout rvfl) { if (mViewToLinkedList.containsKey(rvfl)) { mViewToLinkedList.get(rvfl).remove(rvfl); mViewToLinkedList.remove(rvfl); if (rvfl.cacheIndex < 0) { return; } final LinkedList<RemoteViewsFrameLayout> refs = get(rvfl.cacheIndex); if (refs != null) { refs.remove(rvfl); } /** * Removes all references to all RemoteViewsFrameLayouts returned by the adapter. */ public void clear() { // We currently just clear the references, and leave all the previous layouts returned // in their default state of the loading view. mReferences.clear(); mViewToLinkedList.clear(); rvfl.cacheIndex = -1; } } Loading Loading @@ -534,7 +529,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback // too much memory. private final SparseArray<RemoteViews> mIndexRemoteViews = new SparseArray<>(); // An array of indices to load, Indices which are explicitely requested are set to true, // An array of indices to load, Indices which are explicitly requested are set to true, // and those determined by the preloading algorithm to prefetch are set to false. private final SparseBooleanArray mIndicesToLoad = new SparseBooleanArray(); Loading Loading @@ -994,6 +989,20 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback return; } if (remoteViews.mApplication != null) { // We keep track of last application info. This helps when all the remoteViews have // same applicationInfo, which should be the case for a typical adapter. But if every // view has different application info, there will not be any optimization. if (mLastRemoteViewAppInfo != null && remoteViews.hasSameAppInfo(mLastRemoteViewAppInfo)) { // We should probably also update the remoteViews for nested ViewActions. // Hopefully, RemoteViews in an adapter would be less complicated. remoteViews.mApplication = mLastRemoteViewAppInfo; } else { mLastRemoteViewAppInfo = remoteViews.mApplication; } } int layoutId = remoteViews.getLayoutId(); RemoteViewsMetaData metaData = mCache.getMetaData(); boolean viewTypeInRange; Loading