Notify the change in collection items by passing the old RemoteViews
Also tuning the meta parameter a bit to mitigate the parcel exception Bug: 245950570 Test: Manual Change-Id: I1c34e8cf1b30f8a24dddafeed0eec50415457d0b
This commit is contained in:
@@ -48,9 +48,11 @@ import android.widget.RemoteViews;
|
||||
import com.android.internal.appwidget.IAppWidgetService;
|
||||
import com.android.internal.os.BackgroundThread;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Updates AppWidget state; gets information about installed AppWidget providers and other
|
||||
@@ -785,7 +787,25 @@ public class AppWidgetManager {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mService.notifyAppWidgetViewDataChanged(mPackageName, appWidgetIds, viewId);
|
||||
if (RemoteViews.isAdapterConversionEnabled()) {
|
||||
List<CompletableFuture<Void>> updateFutures = new ArrayList<>();
|
||||
for (int i = 0; i < appWidgetIds.length; i++) {
|
||||
final int widgetId = appWidgetIds[i];
|
||||
updateFutures.add(CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
RemoteViews views = mService.getAppWidgetViews(mPackageName, widgetId);
|
||||
if (views.replaceRemoteCollections(viewId)) {
|
||||
updateAppWidget(widgetId, views);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error notifying changes in RemoteViews", e);
|
||||
}
|
||||
}));
|
||||
}
|
||||
CompletableFuture.allOf(updateFutures.toArray(CompletableFuture[]::new)).join();
|
||||
} else {
|
||||
mService.notifyAppWidgetViewDataChanged(mPackageName, appWidgetIds, viewId);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
@@ -786,6 +786,42 @@ public class RemoteViews implements Parcelable, Filter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @return True if there is a change
|
||||
*/
|
||||
public boolean replaceRemoteCollections(int viewId) {
|
||||
boolean isActionReplaced = false;
|
||||
if (mActions != null) {
|
||||
for (int i = 0; i < mActions.size(); i++) {
|
||||
Action action = mActions.get(i);
|
||||
if (action instanceof SetRemoteCollectionItemListAdapterAction itemsAction
|
||||
&& itemsAction.viewId == viewId
|
||||
&& itemsAction.mServiceIntent != null) {
|
||||
mActions.set(i, new SetRemoteCollectionItemListAdapterAction(itemsAction.viewId,
|
||||
itemsAction.mServiceIntent));
|
||||
isActionReplaced = true;
|
||||
} else if (action instanceof ViewGroupActionAdd groupAction
|
||||
&& groupAction.mNestedViews != null) {
|
||||
isActionReplaced |= groupAction.mNestedViews.replaceRemoteCollections(viewId);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mSizedRemoteViews != null) {
|
||||
for (int i = 0; i < mSizedRemoteViews.size(); i++) {
|
||||
isActionReplaced |= mSizedRemoteViews.get(i).replaceRemoteCollections(viewId);
|
||||
}
|
||||
}
|
||||
if (mLandscape != null) {
|
||||
isActionReplaced |= mLandscape.replaceRemoteCollections(viewId);
|
||||
}
|
||||
if (mPortrait != null) {
|
||||
isActionReplaced |= mPortrait.replaceRemoteCollections(viewId);
|
||||
}
|
||||
|
||||
return isActionReplaced;
|
||||
}
|
||||
|
||||
private static void visitIconUri(Icon icon, @NonNull Consumer<Uri> visitor) {
|
||||
if (icon != null && (icon.getType() == Icon.TYPE_URI
|
||||
|| icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP)) {
|
||||
@@ -1059,18 +1095,21 @@ public class RemoteViews implements Parcelable, Filter {
|
||||
|
||||
private class SetRemoteCollectionItemListAdapterAction extends Action {
|
||||
private @NonNull CompletableFuture<RemoteCollectionItems> mItemsFuture;
|
||||
final Intent mServiceIntent;
|
||||
|
||||
SetRemoteCollectionItemListAdapterAction(@IdRes int id,
|
||||
@NonNull RemoteCollectionItems items) {
|
||||
viewId = id;
|
||||
items.setHierarchyRootData(getHierarchyRootData());
|
||||
mItemsFuture = CompletableFuture.completedFuture(items);
|
||||
mServiceIntent = null;
|
||||
}
|
||||
|
||||
SetRemoteCollectionItemListAdapterAction(@IdRes int id, Intent intent) {
|
||||
viewId = id;
|
||||
mItemsFuture = getItemsFutureFromIntentWithTimeout(intent);
|
||||
setHierarchyRootData(getHierarchyRootData());
|
||||
mServiceIntent = intent;
|
||||
}
|
||||
|
||||
private static CompletableFuture<RemoteCollectionItems> getItemsFutureFromIntentWithTimeout(
|
||||
@@ -1119,6 +1158,7 @@ public class RemoteViews implements Parcelable, Filter {
|
||||
viewId = parcel.readInt();
|
||||
mItemsFuture = CompletableFuture.completedFuture(
|
||||
new RemoteCollectionItems(parcel, getHierarchyRootData()));
|
||||
mServiceIntent = parcel.readTypedObject(Intent.CREATOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1148,6 +1188,7 @@ public class RemoteViews implements Parcelable, Filter {
|
||||
dest.writeInt(viewId);
|
||||
RemoteCollectionItems items = getCollectionItemsFromFuture(mItemsFuture);
|
||||
items.writeToParcel(dest, flags, /* attached= */ true);
|
||||
dest.writeTypedObject(mServiceIntent, flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -4765,15 +4806,23 @@ public class RemoteViews implements Parcelable, Filter {
|
||||
* providing data to the RemoteViewsAdapter
|
||||
*/
|
||||
public void setRemoteAdapter(@IdRes int viewId, Intent intent) {
|
||||
if (AppGlobals.getIntCoreSetting(
|
||||
SystemUiDeviceConfigFlags.REMOTEVIEWS_ADAPTER_CONVERSION,
|
||||
SystemUiDeviceConfigFlags.REMOTEVIEWS_ADAPTER_CONVERSION_DEFAULT ? 1 : 0) == 1) {
|
||||
if (isAdapterConversionEnabled()) {
|
||||
addAction(new SetRemoteCollectionItemListAdapterAction(viewId, intent));
|
||||
return;
|
||||
}
|
||||
addAction(new SetRemoteViewsAdapterIntent(viewId, intent));
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @return True if the remote adapter conversion is enabled
|
||||
*/
|
||||
public static boolean isAdapterConversionEnabled() {
|
||||
return AppGlobals.getIntCoreSetting(
|
||||
SystemUiDeviceConfigFlags.REMOTEVIEWS_ADAPTER_CONVERSION,
|
||||
SystemUiDeviceConfigFlags.REMOTEVIEWS_ADAPTER_CONVERSION_DEFAULT ? 1 : 0) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a simple Adapter for the viewId specified. The viewId must point to an AdapterView,
|
||||
* ie. {@link ListView}, {@link GridView}, {@link StackView} or {@link AdapterViewAnimator}.
|
||||
|
||||
Reference in New Issue
Block a user