CellularTile.java revision e17c4b49a41ec9de5c1d7f229273fc4677ec24b1
1/*
2 * Copyright (C) 2014 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.tiles;
18
19import android.content.ComponentName;
20import android.content.Context;
21import android.content.Intent;
22import android.content.res.Resources;
23import android.view.LayoutInflater;
24import android.view.View;
25import android.view.ViewGroup;
26import android.widget.TextView;
27
28import com.android.systemui.R;
29import com.android.systemui.qs.DataUsageGraph;
30import com.android.systemui.qs.QSTile;
31import com.android.systemui.qs.QSTileView;
32import com.android.systemui.qs.SignalTileView;
33import com.android.systemui.statusbar.policy.NetworkController;
34import com.android.systemui.statusbar.policy.NetworkController.DataUsageInfo;
35import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
36
37import java.text.DecimalFormat;
38
39/** Quick settings tile: Cellular **/
40public class CellularTile extends QSTile<QSTile.SignalState> {
41    private static final Intent CELLULAR_SETTINGS = new Intent().setComponent(new ComponentName(
42            "com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity"));
43
44    private final NetworkController mController;
45    private final CellularDetailAdapter mDetailAdapter;
46
47    public CellularTile(Host host) {
48        super(host);
49        mController = host.getNetworkController();
50        mDetailAdapter = new CellularDetailAdapter();
51    }
52
53    @Override
54    protected SignalState newTileState() {
55        return new SignalState();
56    }
57
58    @Override
59    public DetailAdapter getDetailAdapter() {
60        return mDetailAdapter;
61    }
62
63    @Override
64    public void setListening(boolean listening) {
65        if (listening) {
66            mController.addNetworkSignalChangedCallback(mCallback);
67        } else {
68            mController.removeNetworkSignalChangedCallback(mCallback);
69        }
70    }
71
72    @Override
73    public QSTileView createTileView(Context context) {
74        return new SignalTileView(context);
75    }
76
77    @Override
78    protected void handleClick() {
79        if (mController.isMobileDataSupported()) {
80            showDetail(true);
81        } else {
82            mHost.startSettingsActivity(CELLULAR_SETTINGS);
83        }
84    }
85
86    @Override
87    protected void handleUpdateState(SignalState state, Object arg) {
88        state.visible = mController.hasMobileDataFeature();
89        if (!state.visible) return;
90        final CallbackInfo cb = (CallbackInfo) arg;
91        if (cb == null) return;
92
93        final Resources r = mContext.getResources();
94        state.iconId = cb.noSim ? R.drawable.stat_sys_no_sim
95                : !cb.enabled || cb.airplaneModeEnabled ? R.drawable.ic_qs_signal_disabled
96                : cb.mobileSignalIconId > 0 ? cb.mobileSignalIconId
97                : R.drawable.ic_qs_signal_no_signal;
98        state.overlayIconId = cb.enabled && (cb.dataTypeIconId > 0) && !cb.wifiConnected
99                ? cb.dataTypeIconId
100                : 0;
101        state.filter = state.iconId != R.drawable.stat_sys_no_sim;
102        state.activityIn = cb.enabled && cb.activityIn;
103        state.activityOut = cb.enabled && cb.activityOut;
104
105        state.label = cb.enabled
106                ? removeTrailingPeriod(cb.enabledDesc)
107                : r.getString(R.string.quick_settings_rssi_emergency_only);
108
109        final String signalContentDesc = cb.enabled && (cb.mobileSignalIconId > 0)
110                ? cb.signalContentDescription
111                : r.getString(R.string.accessibility_no_signal);
112        final String dataContentDesc = cb.enabled && (cb.dataTypeIconId > 0) && !cb.wifiEnabled
113                ? cb.dataContentDescription
114                : r.getString(R.string.accessibility_no_data);
115        state.contentDescription = r.getString(
116                R.string.accessibility_quick_settings_mobile,
117                signalContentDesc, dataContentDesc,
118                state.label);
119    }
120
121    // Remove the period from the network name
122    public static String removeTrailingPeriod(String string) {
123        if (string == null) return null;
124        final int length = string.length();
125        if (string.endsWith(".")) {
126            return string.substring(0, length - 1);
127        }
128        return string;
129    }
130
131    private static final class CallbackInfo {
132        boolean enabled;
133        boolean wifiEnabled;
134        boolean wifiConnected;
135        boolean airplaneModeEnabled;
136        int mobileSignalIconId;
137        String signalContentDescription;
138        int dataTypeIconId;
139        String dataContentDescription;
140        boolean activityIn;
141        boolean activityOut;
142        String enabledDesc;
143        boolean noSim;
144    }
145
146    private final NetworkSignalChangedCallback mCallback = new NetworkSignalChangedCallback() {
147        private boolean mWifiEnabled;
148        private boolean mWifiConnected;
149        private boolean mAirplaneModeEnabled;
150
151        @Override
152        public void onWifiSignalChanged(boolean enabled, boolean connected, int wifiSignalIconId,
153                boolean activityIn, boolean activityOut,
154                String wifiSignalContentDescriptionId, String description) {
155            mWifiEnabled = enabled;
156            mWifiConnected = connected;
157        }
158
159        @Override
160        public void onMobileDataSignalChanged(boolean enabled,
161                int mobileSignalIconId,
162                String mobileSignalContentDescriptionId, int dataTypeIconId,
163                boolean activityIn, boolean activityOut,
164                String dataTypeContentDescriptionId, String description, boolean noSim) {
165            final CallbackInfo info = new CallbackInfo();  // TODO pool?
166            info.enabled = enabled;
167            info.wifiEnabled = mWifiEnabled;
168            info.wifiConnected = mWifiConnected;
169            info.airplaneModeEnabled = mAirplaneModeEnabled;
170            info.mobileSignalIconId = mobileSignalIconId;
171            info.signalContentDescription = mobileSignalContentDescriptionId;
172            info.dataTypeIconId = dataTypeIconId;
173            info.dataContentDescription = dataTypeContentDescriptionId;
174            info.activityIn = activityIn;
175            info.activityOut = activityOut;
176            info.enabledDesc = description;
177            info.noSim = noSim;
178            refreshState(info);
179        }
180
181        @Override
182        public void onAirplaneModeChanged(boolean enabled) {
183            mAirplaneModeEnabled = enabled;
184        }
185
186        public void onMobileDataEnabled(boolean enabled) {
187            mDetailAdapter.setMobileDataEnabled(enabled);
188        }
189    };
190
191    private final class CellularDetailAdapter implements DetailAdapter {
192
193        @Override
194        public int getTitle() {
195            return R.string.quick_settings_cellular_detail_title;
196        }
197
198        @Override
199        public Boolean getToggleState() {
200            return mController.isMobileDataSupported() ? mController.isMobileDataEnabled() : null;
201        }
202
203        @Override
204        public Intent getSettingsIntent() {
205            return CELLULAR_SETTINGS;
206        }
207
208        @Override
209        public void setToggleState(boolean state) {
210            mController.setMobileDataEnabled(state);
211        }
212
213        @Override
214        public View createDetailView(Context context, View convertView, ViewGroup parent) {
215            final DataUsageDetailView v = (DataUsageDetailView) (convertView != null
216                    ? convertView
217                    : LayoutInflater.from(mContext).inflate(R.layout.data_usage, parent, false));
218            final DataUsageInfo info = mController.getDataUsageInfo();
219            if (info == null) return v;
220            v.bind(info);
221            return v;
222        }
223
224        public void setMobileDataEnabled(boolean enabled) {
225            fireToggleStateChanged(enabled);
226        }
227    }
228}
229