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