1 package com.android.systemui.qs; 2 3 import static com.android.systemui.Prefs.Key.QS_TILE_SPECS_REVEALED; 4 5 import android.content.Context; 6 import android.os.Handler; 7 import android.util.ArraySet; 8 9 import com.android.systemui.Prefs; 10 import com.android.systemui.plugins.qs.QSTile; 11 import com.android.systemui.qs.customize.QSCustomizerController; 12 import com.android.systemui.qs.dagger.QSScope; 13 import com.android.systemui.shade.ShadeDisplayAware; 14 15 import java.util.Collection; 16 import java.util.Collections; 17 import java.util.Set; 18 19 import javax.inject.Inject; 20 21 /** 22 * Plays a animation to reveal newly added QS tiles. 23 * 24 * The aniumation is played when the user fully opens Quick Settings, and is only shown for 25 * <li> tiles added automatically (not through user customization) 26 * <li> tiles not have been revealed before (memoized via {@code QS_TILE_SPECS_REVEALED} 27 * preference) 28 */ 29 public class QSTileRevealController { 30 private static final long QS_REVEAL_TILES_DELAY = 500L; 31 32 private final Context mContext; 33 private final QSPanelController mQSPanelController; 34 private final PagedTileLayout mPagedTileLayout; 35 private final QSCustomizerController mQsCustomizerController; 36 private final ArraySet<String> mTilesToReveal = new ArraySet<>(); 37 private final Handler mHandler = new Handler(); 38 39 private final Runnable mRevealQsTiles = new Runnable() { 40 @Override 41 public void run() { 42 mPagedTileLayout.startTileReveal(mTilesToReveal, () -> { 43 if (mQSPanelController.isExpanded()) { 44 addTileSpecsToRevealed(mTilesToReveal); 45 mTilesToReveal.clear(); 46 } 47 }); 48 } 49 }; 50 QSTileRevealController(Context context, QSPanelController qsPanelController, PagedTileLayout pagedTileLayout, QSCustomizerController qsCustomizerController)51 QSTileRevealController(Context context, QSPanelController qsPanelController, 52 PagedTileLayout pagedTileLayout, QSCustomizerController qsCustomizerController) { 53 mContext = context; 54 mQSPanelController = qsPanelController; 55 mPagedTileLayout = pagedTileLayout; 56 mQsCustomizerController = qsCustomizerController; 57 } 58 setExpansion(float expansion)59 public void setExpansion(float expansion) { 60 if (expansion == 1f) { 61 mHandler.postDelayed(mRevealQsTiles, QS_REVEAL_TILES_DELAY); 62 } else { 63 mHandler.removeCallbacks(mRevealQsTiles); 64 } 65 } 66 updateRevealedTiles(Collection<QSTile> tiles)67 public void updateRevealedTiles(Collection<QSTile> tiles) { 68 ArraySet<String> tileSpecs = new ArraySet<>(); 69 for (QSTile tile : tiles) { 70 tileSpecs.add(tile.getTileSpec()); 71 } 72 73 final Set<String> revealedTiles = Prefs.getStringSet( 74 mContext, QS_TILE_SPECS_REVEALED, Collections.EMPTY_SET); 75 if (revealedTiles.isEmpty() || mQsCustomizerController.isCustomizing()) { 76 // Do not reveal QS tiles the user has upon first load or those that they directly 77 // added through customization. 78 addTileSpecsToRevealed(tileSpecs); 79 } else { 80 // Animate all tiles that the user has not directly added themselves. 81 tileSpecs.removeAll(revealedTiles); 82 mTilesToReveal.addAll(tileSpecs); 83 } 84 } 85 addTileSpecsToRevealed(ArraySet<String> specs)86 private void addTileSpecsToRevealed(ArraySet<String> specs) { 87 final ArraySet<String> revealedTiles = new ArraySet<>( 88 Prefs.getStringSet(mContext, QS_TILE_SPECS_REVEALED, Collections.EMPTY_SET)); 89 revealedTiles.addAll(specs); 90 Prefs.putStringSet(mContext, QS_TILE_SPECS_REVEALED, revealedTiles); 91 } 92 93 /** TODO(b/168904199): Remove this once QSPanel has its rejection removed. */ 94 @QSScope 95 static class Factory { 96 private final Context mContext; 97 private final QSCustomizerController mQsCustomizerController; 98 99 @Inject Factory(@hadeDisplayAware Context context, QSCustomizerController qsCustomizerController)100 Factory(@ShadeDisplayAware Context context, QSCustomizerController qsCustomizerController) { 101 mContext = context; 102 mQsCustomizerController = qsCustomizerController; 103 } 104 create(QSPanelController qsPanelController, PagedTileLayout pagedTileLayout)105 QSTileRevealController create(QSPanelController qsPanelController, 106 PagedTileLayout pagedTileLayout) { 107 return new QSTileRevealController(mContext, qsPanelController, pagedTileLayout, 108 mQsCustomizerController); 109 } 110 } 111 } 112