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