From 3ee13ce4d6533831c67a76b17e1dd2352e083c08 Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Thu, 18 Jun 2020 03:03:35 +0800 Subject: [PATCH] Fix homepage cards show up problem after first launch ContextualCardLoader was waiting for eligible card checkers with a 300 ms timeout one by one in a loop. So if more than four checkers expire, the total waiting time will exceed the 1 sec homepage content loading timeout, which causes no card shows up. The solution is to leverage all the checkers' timeout starting time, and increase the timeout for all checkers. So that ContextualCardLoader just needs to wait for all checkers for at most 400 ms and then can get the results. Bug: 159236069 Test: robotest Change-Id: I601ac4151bf8be68b30eaabdb45a4e1ace95653f --- .../contextualcards/ContextualCardLoader.java | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java b/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java index 4d1a1d476bf..d30fe59a51d 100644 --- a/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java +++ b/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java @@ -38,14 +38,14 @@ import com.android.settings.homepage.contextualcards.logging.ContextualCardLogUt import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.utils.AsyncLoaderCompat; -import com.android.settingslib.utils.ThreadUtils; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; public class ContextualCardLoader extends AsyncLoaderCompat> { @@ -56,7 +56,7 @@ public class ContextualCardLoader extends AsyncLoaderCompat static final int CARD_CONTENT_LOADER_ID = 1; private static final String TAG = "ContextualCardLoader"; - private static final long ELIGIBILITY_CHECKER_TIMEOUT_MS = 300; + private static final long ELIGIBILITY_CHECKER_TIMEOUT_MS = 400; private final ContentObserver mObserver = new ContentObserver( new Handler(Looper.getMainLooper())) { @@ -184,23 +184,37 @@ public class ContextualCardLoader extends AsyncLoaderCompat @VisibleForTesting List filterEligibleCards(List candidates) { + final ExecutorService executor = Executors.newFixedThreadPool(candidates.size()); final List cards = new ArrayList<>(); - final List> eligibleCards = new ArrayList<>(); + List> eligibleCards = new ArrayList<>(); - for (ContextualCard card : candidates) { - final EligibleCardChecker checker = new EligibleCardChecker(mContext, card); - eligibleCards.add(ThreadUtils.postOnBackgroundThread(checker)); + final List checkers = candidates.stream() + .map(card -> new EligibleCardChecker(mContext, card)) + .collect(Collectors.toList()); + try { + eligibleCards = executor.invokeAll(checkers, ELIGIBILITY_CHECKER_TIMEOUT_MS, + TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + Log.w(TAG, "Failed to get eligible states for all cards", e); } + executor.shutdown(); + // Collect future and eligible cards - for (Future cardFuture : eligibleCards) { + for (int i = 0; i < eligibleCards.size(); i++) { + final Future cardFuture = eligibleCards.get(i); + if (cardFuture.isCancelled()) { + Log.w(TAG, "Timeout getting eligible state for card: " + + candidates.get(i).getSliceUri()); + continue; + } + try { - final ContextualCard card = cardFuture.get(ELIGIBILITY_CHECKER_TIMEOUT_MS, - TimeUnit.MILLISECONDS); + final ContextualCard card = cardFuture.get(); if (card != null) { cards.add(card); } - } catch (ExecutionException | InterruptedException | TimeoutException e) { - Log.w(TAG, "Failed to get eligible state for card: " + e.toString()); + } catch (Exception e) { + Log.w(TAG, "Failed to get eligible state for card", e); } } return cards;