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