Home | History | Annotate | Download | only in qs
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.systemui.qs;
     18 
     19 import android.content.Context;
     20 import android.content.res.Configuration;
     21 import android.util.AttributeSet;
     22 import android.view.Gravity;
     23 import android.view.View;
     24 import android.widget.LinearLayout;
     25 import android.widget.Space;
     26 
     27 import com.android.systemui.R;
     28 import com.android.systemui.qs.QSTile.SignalState;
     29 import com.android.systemui.qs.QSTile.State;
     30 import com.android.systemui.qs.customize.QSCustomizer;
     31 import com.android.systemui.statusbar.phone.QSTileHost;
     32 import com.android.systemui.tuner.TunerService;
     33 import com.android.systemui.tuner.TunerService.Tunable;
     34 
     35 import java.util.ArrayList;
     36 import java.util.Collection;
     37 
     38 /**
     39  * Version of QSPanel that only shows N Quick Tiles in the QS Header.
     40  */
     41 public class QuickQSPanel extends QSPanel {
     42 
     43     public static final String NUM_QUICK_TILES = "sysui_qqs_count";
     44 
     45     private int mMaxTiles;
     46     private QSPanel mFullPanel;
     47     private View mHeader;
     48 
     49     public QuickQSPanel(Context context, AttributeSet attrs) {
     50         super(context, attrs);
     51         if (mTileLayout != null) {
     52             for (int i = 0; i < mRecords.size(); i++) {
     53                 mTileLayout.removeTile(mRecords.get(i));
     54             }
     55             removeView((View) mTileLayout);
     56         }
     57         mTileLayout = new HeaderTileLayout(context);
     58         mTileLayout.setListening(mListening);
     59         addView((View) mTileLayout, 1 /* Between brightness and footer */);
     60     }
     61 
     62     @Override
     63     protected void onAttachedToWindow() {
     64         super.onAttachedToWindow();
     65         TunerService.get(mContext).addTunable(mNumTiles, NUM_QUICK_TILES);
     66     }
     67 
     68     @Override
     69     protected void onDetachedFromWindow() {
     70         super.onDetachedFromWindow();
     71         TunerService.get(mContext).removeTunable(mNumTiles);
     72     }
     73 
     74     public void setQSPanelAndHeader(QSPanel fullPanel, View header) {
     75         mFullPanel = fullPanel;
     76         mHeader = header;
     77     }
     78 
     79     @Override
     80     protected boolean shouldShowDetail() {
     81         return !mExpanded;
     82     }
     83 
     84     @Override
     85     protected void drawTile(TileRecord r, State state) {
     86         if (state instanceof SignalState) {
     87             State copy = r.tile.newTileState();
     88             state.copyTo(copy);
     89             // No activity shown in the quick panel.
     90             ((SignalState) copy).activityIn = false;
     91             ((SignalState) copy).activityOut = false;
     92             state = copy;
     93         }
     94         super.drawTile(r, state);
     95     }
     96 
     97     @Override
     98     protected QSTileBaseView createTileView(QSTile<?> tile, boolean collapsedView) {
     99         return new QSTileBaseView(mContext, tile.createTileView(mContext), collapsedView);
    100     }
    101 
    102     @Override
    103     public void setHost(QSTileHost host, QSCustomizer customizer) {
    104         super.setHost(host, customizer);
    105         setTiles(mHost.getTiles());
    106     }
    107 
    108     public void setMaxTiles(int maxTiles) {
    109         mMaxTiles = maxTiles;
    110         if (mHost != null) {
    111             setTiles(mHost.getTiles());
    112         }
    113     }
    114 
    115     @Override
    116     protected void onTileClick(QSTile<?> tile) {
    117         tile.secondaryClick();
    118     }
    119 
    120     @Override
    121     public void onTuningChanged(String key, String newValue) {
    122         // No tunings for you.
    123         if (key.equals(QS_SHOW_BRIGHTNESS)) {
    124             // No Brightness for you.
    125             super.onTuningChanged(key, "0");
    126         }
    127     }
    128 
    129     @Override
    130     public void setTiles(Collection<QSTile<?>> tiles) {
    131         ArrayList<QSTile<?>> quickTiles = new ArrayList<>();
    132         for (QSTile<?> tile : tiles) {
    133             quickTiles.add(tile);
    134             if (quickTiles.size() == mMaxTiles) {
    135                 break;
    136             }
    137         }
    138         super.setTiles(quickTiles, true);
    139     }
    140 
    141     private final Tunable mNumTiles = new Tunable() {
    142         @Override
    143         public void onTuningChanged(String key, String newValue) {
    144             setMaxTiles(getNumQuickTiles(mContext));
    145         }
    146     };
    147 
    148     public int getNumQuickTiles(Context context) {
    149         return TunerService.get(context).getValue(NUM_QUICK_TILES, 6);
    150     }
    151 
    152     private static class HeaderTileLayout extends LinearLayout implements QSTileLayout {
    153 
    154         protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
    155         private boolean mListening;
    156 
    157         public HeaderTileLayout(Context context) {
    158             super(context);
    159             setClipChildren(false);
    160             setClipToPadding(false);
    161             setGravity(Gravity.CENTER_VERTICAL);
    162             setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    163         }
    164 
    165         @Override
    166         public void setListening(boolean listening) {
    167             if (mListening == listening) return;
    168             mListening = listening;
    169             for (TileRecord record : mRecords) {
    170                 record.tile.setListening(this, mListening);
    171             }
    172         }
    173 
    174         @Override
    175         public void addTile(TileRecord tile) {
    176             if (getChildCount() != 0) {
    177                 // Add a spacer.
    178                 addView(new Space(mContext), getChildCount(), generateSpaceParams());
    179             }
    180             addView(tile.tileView, getChildCount(), generateLayoutParams());
    181             mRecords.add(tile);
    182             tile.tile.setListening(this, mListening);
    183         }
    184 
    185         private LayoutParams generateSpaceParams() {
    186             int size = mContext.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_size);
    187             LayoutParams lp = new LayoutParams(0, size);
    188             lp.weight = 1;
    189             lp.gravity = Gravity.CENTER;
    190             return lp;
    191         }
    192 
    193         private LayoutParams generateLayoutParams() {
    194             int size = mContext.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_size);
    195             LayoutParams lp = new LayoutParams(size, size);
    196             lp.gravity = Gravity.CENTER;
    197             return lp;
    198         }
    199 
    200         @Override
    201         public void removeTile(TileRecord tile) {
    202             int childIndex = getChildIndex(tile.tileView);
    203             // Remove the tile.
    204             removeViewAt(childIndex);
    205             if (getChildCount() != 0) {
    206                 // Remove its spacer as well.
    207                 removeViewAt(childIndex);
    208             }
    209             mRecords.remove(tile);
    210             tile.tile.setListening(this, false);
    211         }
    212 
    213         private int getChildIndex(QSTileBaseView tileView) {
    214             final int N = getChildCount();
    215             for (int i = 0; i < N; i++) {
    216                 if (getChildAt(i) == tileView) {
    217                     return i;
    218                 }
    219             }
    220             return -1;
    221         }
    222 
    223         @Override
    224         public int getOffsetTop(TileRecord tile) {
    225             return 0;
    226         }
    227 
    228         @Override
    229         public boolean updateResources() {
    230             // No resources here.
    231             return false;
    232         }
    233 
    234         @Override
    235         public boolean hasOverlappingRendering() {
    236             return false;
    237         }
    238 
    239         @Override
    240         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    241             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    242             if (mRecords != null && mRecords.size() > 0) {
    243                 View previousView = this;
    244                 for (TileRecord record : mRecords) {
    245                     if (record.tileView.getVisibility() == GONE) continue;
    246                     previousView = record.tileView.updateAccessibilityOrder(previousView);
    247                 }
    248                 mRecords.get(0).tileView.setAccessibilityTraversalAfter(
    249                         R.id.alarm_status_collapsed);
    250                 mRecords.get(mRecords.size() - 1).tileView.setAccessibilityTraversalBefore(
    251                         R.id.expand_indicator);
    252             }
    253         }
    254     }
    255 }
    256