Reduce the flickering of injected items when package is changed
Root cause: Settings listens to four package-related broadcasts in order to refresh injected items because UI data may change. However, when the system is updating apps on the first boot, it triggers a burst of broadcasts. For each broadcast Settings will reload and then redraw all injected items, which leads to the flickering. Solution: 1. When Settings recieves a broadcast, check if there are already two reloading tasks to avoid redundant updates. 2. In the reloading task, check if any injected item is changed, added, or removed to notify categories changed. 3. Only refresh the UI when any of the changed items belongs to the current page. Bug: 166785977 Bug: 168309941 Test: manual, robotest Change-Id: I77745b60f84510554bff1870a5bb7a8013eab528
This commit is contained in:
@@ -41,6 +41,7 @@ import java.util.Set;
|
||||
public class CategoryManager {
|
||||
|
||||
private static final String TAG = "CategoryManager";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private static CategoryManager sInstance;
|
||||
private final InterestingConfigChanges mInterestingConfigChanges;
|
||||
@@ -92,6 +93,7 @@ public class CategoryManager {
|
||||
public synchronized void updateCategoryFromDenylist(Set<ComponentName> tileDenylist) {
|
||||
if (mCategories == null) {
|
||||
Log.w(TAG, "Category is null, skipping denylist update");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < mCategories.size(); i++) {
|
||||
DashboardCategory category = mCategories.get(i);
|
||||
@@ -104,6 +106,31 @@ public class CategoryManager {
|
||||
}
|
||||
}
|
||||
|
||||
/** Return the current tile map */
|
||||
public synchronized Map<ComponentName, Tile> getTileByComponentMap() {
|
||||
final Map<ComponentName, Tile> result = new ArrayMap<>();
|
||||
if (mCategories == null) {
|
||||
Log.w(TAG, "Category is null, no tiles");
|
||||
return result;
|
||||
}
|
||||
mCategories.forEach(category -> {
|
||||
for (int i = 0; i < category.getTilesCount(); i++) {
|
||||
final Tile tile = category.getTile(i);
|
||||
result.put(tile.getIntent().getComponent(), tile);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
private void logTiles(Context context) {
|
||||
if (DEBUG) {
|
||||
getTileByComponentMap().forEach((component, tile) -> {
|
||||
Log.d(TAG, "Tile: " + tile.getCategory().replace("com.android.settings.", "")
|
||||
+ ": " + tile.getTitle(context) + ", " + component.flattenToShortString());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void tryInitCategories(Context context) {
|
||||
// Keep cached tiles by default. The cache is only invalidated when InterestingConfigChange
|
||||
// happens.
|
||||
@@ -112,6 +139,7 @@ public class CategoryManager {
|
||||
|
||||
private synchronized void tryInitCategories(Context context, boolean forceClearCache) {
|
||||
if (mCategories == null) {
|
||||
final boolean firstLoading = mCategoryByKeyMap.isEmpty();
|
||||
if (forceClearCache) {
|
||||
mTileByComponentCache.clear();
|
||||
}
|
||||
@@ -123,6 +151,9 @@ public class CategoryManager {
|
||||
backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
|
||||
sortCategories(context, mCategoryByKeyMap);
|
||||
filterDuplicateTiles(mCategoryByKeyMap);
|
||||
if (firstLoading) {
|
||||
logTiles(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -56,6 +56,7 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
/**
|
||||
@@ -160,13 +161,21 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCategoriesChanged() {
|
||||
final DashboardCategory category =
|
||||
mDashboardFeatureProvider.getTilesForCategory(getCategoryKey());
|
||||
if (category == null) {
|
||||
public void onCategoriesChanged(Set<String> categories) {
|
||||
final String categoryKey = getCategoryKey();
|
||||
final DashboardCategory dashboardCategory =
|
||||
mDashboardFeatureProvider.getTilesForCategory(categoryKey);
|
||||
if (dashboardCategory == null) {
|
||||
return;
|
||||
}
|
||||
refreshDashboardTiles(getLogTag());
|
||||
|
||||
if (categories == null) {
|
||||
// force refreshing
|
||||
refreshDashboardTiles(getLogTag());
|
||||
} else if (categories.contains(categoryKey)) {
|
||||
Log.i(TAG, "refresh tiles for " + categoryKey);
|
||||
refreshDashboardTiles(getLogTag());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Reference in New Issue
Block a user