From 2b575a40f3646a3061316e28ac198597051cd004 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Thu, 16 Aug 2018 10:41:08 -0700 Subject: [PATCH] Check condition displayable state in parallel. This speeds up condition display by about 40 ms. Bug: 112485407 Test: robotests still passes Change-Id: Iac66354492496a9ece9178c438db6506e6fe7be5 --- .../conditional/v2/ConditionManager.java | 48 +++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/homepage/conditional/v2/ConditionManager.java b/src/com/android/settings/homepage/conditional/v2/ConditionManager.java index ff5d20a868f..c67b255d4f0 100644 --- a/src/com/android/settings/homepage/conditional/v2/ConditionManager.java +++ b/src/com/android/settings/homepage/conditional/v2/ConditionManager.java @@ -28,6 +28,13 @@ import com.android.settings.homepage.conditional.ConditionListener; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.Callable; +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; public class ConditionManager { private static final String TAG = "ConditionManager"; @@ -37,6 +44,9 @@ public class ConditionManager { @VisibleForTesting final List mCardControllers; + private static final long DISPLAYABLE_CHECKER_TIMEOUT_MS = 20; + + private final ExecutorService mExecutorService; private final Context mAppContext; private final ConditionListener mListener; @@ -51,6 +61,7 @@ public class ConditionManager { public ConditionManager(Context context, ConditionListener listener) { mAppContext = context.getApplicationContext(); + mExecutorService = Executors.newCachedThreadPool(); mCandidates = new ArrayList<>(); mCardControllers = new ArrayList<>(); mListener = listener; @@ -62,9 +73,23 @@ public class ConditionManager { */ public List getDisplayableCards() { final List cards = new ArrayList<>(); + final List> displayableCards = new ArrayList<>(); + // Check displayable future for (ConditionalCard card : mCandidates) { - if (getController(card.getId()).isDisplayable()) { - cards.add(card); + final DisplayableChecker future = new DisplayableChecker( + card, getController(card.getId())); + displayableCards.add(mExecutorService.submit(future)); + } + // Collect future and add displayable cards + for (Future cardFuture : displayableCards) { + try { + final ConditionalCard card = cardFuture.get(DISPLAYABLE_CHECKER_TIMEOUT_MS, + TimeUnit.MILLISECONDS); + if (card != null) { + cards.add(card); + } + } catch (InterruptedException | ExecutionException | TimeoutException e) { + Log.w(TAG, "Failed to get displayable state for card, likely timeout. Skipping", e); } } return cards; @@ -89,7 +114,6 @@ public class ConditionManager { onConditionChanged(); } - /** * Start monitoring state change for all conditions */ @@ -163,6 +187,24 @@ public class ConditionManager { mCandidates.add(new RingerMutedConditionCard(mAppContext)); mCandidates.add(new RingerVibrateConditionCard(mAppContext)); mCandidates.add(new WorkModeConditionCard(mAppContext)); + } + /** + * Returns card if controller says it's displayable. Otherwise returns null. + */ + public static class DisplayableChecker implements Callable { + + private final ConditionalCard mCard; + private final ConditionalCardController mController; + + private DisplayableChecker(ConditionalCard card, ConditionalCardController controller) { + mCard = card; + mController = controller; + } + + @Override + public ConditionalCard call() throws Exception { + return mController.isDisplayable() ? mCard : null; + } } }