QuickQSPanel.java revision 8fb7787cf9628284c75d873850a41b660b568348
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
17package com.android.systemui.qs;
18
19import android.content.Context;
20import android.content.res.Configuration;
21import android.util.AttributeSet;
22import android.view.Gravity;
23import android.view.View;
24import android.widget.LinearLayout;
25import android.widget.Space;
26import com.android.systemui.R;
27import com.android.systemui.qs.QSTile.SignalState;
28import com.android.systemui.qs.QSTile.State;
29import com.android.systemui.tuner.TunerService;
30import com.android.systemui.tuner.TunerService.Tunable;
31
32import java.util.ArrayList;
33import java.util.Collection;
34
35/**
36 * Version of QSPanel that only shows N Quick Tiles in the QS Header.
37 */
38public class QuickQSPanel extends QSPanel {
39
40    public static final String NUM_QUICK_TILES = "sysui_qqs_count";
41
42    private int mMaxTiles;
43    private QSPanel mFullPanel;
44    private View mHeader;
45
46    public QuickQSPanel(Context context, AttributeSet attrs) {
47        super(context, attrs);
48        if (mTileLayout != null) {
49            for (int i = 0; i < mRecords.size(); i++) {
50                mTileLayout.removeTile(mRecords.get(i));
51            }
52            removeView((View) mTileLayout);
53        }
54        mTileLayout = new HeaderTileLayout(context);
55        addView((View) mTileLayout, 1 /* Between brightness and footer */);
56    }
57
58    @Override
59    protected void onAttachedToWindow() {
60        super.onAttachedToWindow();
61        TunerService.get(mContext).addTunable(mNumTiles, NUM_QUICK_TILES);
62    }
63
64    @Override
65    protected void onDetachedFromWindow() {
66        super.onDetachedFromWindow();
67        TunerService.get(mContext).removeTunable(mNumTiles);
68    }
69
70    @Override
71    protected void createCustomizePanel() {
72        // No customizing from the header.
73    }
74
75    public void setQSPanelAndHeader(QSPanel fullPanel, View header) {
76        mFullPanel = fullPanel;
77        mHeader = header;
78    }
79
80    @Override
81    protected void drawTile(TileRecord r, State state) {
82        if (state instanceof SignalState) {
83            State copy = r.tile.newTileState();
84            state.copyTo(copy);
85            // No activity shown in the quick panel.
86            ((SignalState) copy).activityIn = false;
87            ((SignalState) copy).activityOut = false;
88            state = copy;
89        }
90        super.drawTile(r, state);
91    }
92
93    @Override
94    protected void showDetail(boolean show, Record r) {
95        // Do nothing, will be handled by the QSPanel.
96    }
97
98    @Override
99    protected QSTileBaseView createTileView(QSTile<?> tile) {
100        return new QSTileBaseView(mContext, tile.createTileView(mContext));
101    }
102
103    public void setMaxTiles(int maxTiles) {
104        mMaxTiles = maxTiles;
105        setTiles(mHost.getTiles());
106    }
107
108    @Override
109    protected void onTileClick(QSTile<?> tile) {
110        tile.secondaryClick();
111    }
112
113    @Override
114    public void onTuningChanged(String key, String newValue) {
115        // No tunings for you.
116        if (key.equals(QS_SHOW_BRIGHTNESS)) {
117            // No Brightness for you.
118            super.onTuningChanged(key, "0");
119        }
120    }
121
122    @Override
123    public void setTiles(Collection<QSTile<?>> tiles) {
124        ArrayList<QSTile<?>> quickTiles = new ArrayList<>();
125        for (QSTile<?> tile : tiles) {
126            quickTiles.add(tile);
127            if (quickTiles.size() == mMaxTiles) {
128                break;
129            }
130        }
131        super.setTiles(quickTiles);
132    }
133
134    private final Tunable mNumTiles = new Tunable() {
135        @Override
136        public void onTuningChanged(String key, String newValue) {
137            setMaxTiles(getNumQuickTiles(mContext));
138        }
139    };
140
141    public static int getNumQuickTiles(Context context) {
142        return TunerService.get(context).getValue(NUM_QUICK_TILES, 5);
143    }
144
145    private static class HeaderTileLayout extends LinearLayout implements QSTileLayout {
146
147        private final Space mEndSpacer;
148
149        public HeaderTileLayout(Context context) {
150            super(context);
151            setClipChildren(false);
152            setClipToPadding(false);
153            setGravity(Gravity.CENTER_VERTICAL);
154            setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
155
156            mEndSpacer = new Space(context);
157            mEndSpacer.setLayoutParams(generateLayoutParams());
158            updateDownArrowMargin();
159            addView(mEndSpacer);
160            setOrientation(LinearLayout.HORIZONTAL);
161        }
162
163        @Override
164        protected void onConfigurationChanged(Configuration newConfig) {
165            super.onConfigurationChanged(newConfig);
166            updateDownArrowMargin();
167        }
168
169        private void updateDownArrowMargin() {
170            LayoutParams params = (LayoutParams) mEndSpacer.getLayoutParams();
171            params.setMarginStart(mContext.getResources().getDimensionPixelSize(
172                    R.dimen.qs_expand_margin));
173            mEndSpacer.setLayoutParams(params);
174        }
175
176        @Override
177        public void addTile(TileRecord tile) {
178            addView(tile.tileView, getChildCount() - 1 /* Leave icon at end */,
179                    generateLayoutParams());
180            // Add a spacer.
181            addView(new Space(mContext), getChildCount() - 1 /* Leave icon at end */,
182                    generateSpaceParams());
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            // Remove its spacer as well.
206            removeViewAt(childIndex);
207        }
208
209        private int getChildIndex(QSTileBaseView tileView) {
210            final int N = getChildCount();
211            for (int i = 0; i < N; i++) {
212                if (getChildAt(i) == tileView) {
213                    return i;
214                }
215            }
216            return -1;
217        }
218
219        @Override
220        public int getOffsetTop(TileRecord tile) {
221            return 0;
222        }
223
224        @Override
225        public boolean updateResources() {
226            // No resources here.
227            return false;
228        }
229
230        @Override
231        public boolean hasOverlappingRendering() {
232            return false;
233        }
234    }
235}
236