• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package com.android.systemui.statusbar.policy;
17 
18 import android.os.Handler;
19 import android.os.Looper;
20 import android.os.Message;
21 import android.telephony.SubscriptionInfo;
22 
23 import com.android.internal.annotations.VisibleForTesting;
24 import com.android.systemui.dagger.qualifiers.Main;
25 import com.android.systemui.statusbar.policy.NetworkController.EmergencyListener;
26 import com.android.systemui.statusbar.policy.NetworkController.IconState;
27 import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators;
28 import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
29 import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators;
30 
31 import java.io.PrintWriter;
32 import java.text.SimpleDateFormat;
33 import java.util.ArrayList;
34 import java.util.List;
35 
36 import javax.inject.Inject;
37 
38 
39 /**
40  * Implements network listeners and forwards the calls along onto other listeners but on
41  * the current or specified Looper.
42  */
43 public class CallbackHandler extends Handler implements EmergencyListener, SignalCallback {
44     private static final String TAG = "CallbackHandler";
45     private static final int MSG_EMERGENCE_CHANGED           = 0;
46     private static final int MSG_SUBS_CHANGED                = 1;
47     private static final int MSG_NO_SIM_VISIBLE_CHANGED      = 2;
48     private static final int MSG_ETHERNET_CHANGED            = 3;
49     private static final int MSG_AIRPLANE_MODE_CHANGED       = 4;
50     private static final int MSG_MOBILE_DATA_ENABLED_CHANGED = 5;
51     private static final int MSG_ADD_REMOVE_EMERGENCY        = 6;
52     private static final int MSG_ADD_REMOVE_SIGNAL           = 7;
53     private static final int HISTORY_SIZE = 64;
54     private static final SimpleDateFormat SSDF = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
55 
56     // All the callbacks.
57     private final ArrayList<EmergencyListener> mEmergencyListeners = new ArrayList<>();
58     private final ArrayList<SignalCallback> mSignalCallbacks = new ArrayList<>();
59 
60     // Save the previous HISTORY_SIZE states for logging.
61     private final String[] mHistory = new String[HISTORY_SIZE];
62     // Where to copy the next state into.
63     private int mHistoryIndex;
64     private String mLastCallback;
65 
66     @Inject
67     @VisibleForTesting
CallbackHandler(@ain Looper looper)68     CallbackHandler(@Main Looper looper) {
69         super(looper);
70     }
71 
72     @Override
73     @SuppressWarnings("unchecked")
handleMessage(Message msg)74     public void handleMessage(Message msg) {
75         switch (msg.what) {
76             case MSG_EMERGENCE_CHANGED:
77                 for (EmergencyListener listener : mEmergencyListeners) {
78                     listener.setEmergencyCallsOnly(msg.arg1 != 0);
79                 }
80                 break;
81             case MSG_SUBS_CHANGED:
82                 for (SignalCallback signalCluster : mSignalCallbacks) {
83                     signalCluster.setSubs((List<SubscriptionInfo>) msg.obj);
84                 }
85                 break;
86             case MSG_NO_SIM_VISIBLE_CHANGED:
87                 for (SignalCallback signalCluster : mSignalCallbacks) {
88                     signalCluster.setNoSims(msg.arg1 != 0, msg.arg2 != 0);
89                 }
90                 break;
91             case MSG_ETHERNET_CHANGED:
92                 for (SignalCallback signalCluster : mSignalCallbacks) {
93                     signalCluster.setEthernetIndicators((IconState) msg.obj);
94                 }
95                 break;
96             case MSG_AIRPLANE_MODE_CHANGED:
97                 for (SignalCallback signalCluster : mSignalCallbacks) {
98                     signalCluster.setIsAirplaneMode((IconState) msg.obj);
99                 }
100                 break;
101             case MSG_MOBILE_DATA_ENABLED_CHANGED:
102                 for (SignalCallback signalCluster : mSignalCallbacks) {
103                     signalCluster.setMobileDataEnabled(msg.arg1 != 0);
104                 }
105                 break;
106             case MSG_ADD_REMOVE_EMERGENCY:
107                 if (msg.arg1 != 0) {
108                     mEmergencyListeners.add((EmergencyListener) msg.obj);
109                 } else {
110                     mEmergencyListeners.remove((EmergencyListener) msg.obj);
111                 }
112                 break;
113             case MSG_ADD_REMOVE_SIGNAL:
114                 if (msg.arg1 != 0) {
115                     mSignalCallbacks.add((SignalCallback) msg.obj);
116                 } else {
117                     mSignalCallbacks.remove((SignalCallback) msg.obj);
118                 }
119                 break;
120         }
121     }
122 
123     @Override
setWifiIndicators(final WifiIndicators indicators)124     public void setWifiIndicators(final WifiIndicators indicators) {
125         String log = new StringBuilder()
126                 .append(SSDF.format(System.currentTimeMillis())).append(",")
127                 .append(indicators)
128                 .toString();
129         recordLastCallback(log);
130         post(() -> {
131             for (SignalCallback callback : mSignalCallbacks) {
132                 callback.setWifiIndicators(indicators);
133             }
134         });
135     }
136 
137     @Override
setMobileDataIndicators(final MobileDataIndicators indicators)138     public void setMobileDataIndicators(final MobileDataIndicators indicators) {
139         String log = new StringBuilder()
140                 .append(SSDF.format(System.currentTimeMillis())).append(",")
141                 .append(indicators)
142                 .toString();
143         recordLastCallback(log);
144         post(() -> {
145             for (SignalCallback signalCluster : mSignalCallbacks) {
146                 signalCluster.setMobileDataIndicators(indicators);
147             }
148         });
149     }
150 
151     @Override
setConnectivityStatus(boolean noDefaultNetwork, boolean noValidatedNetwork, boolean noNetworksAvailable)152     public void setConnectivityStatus(boolean noDefaultNetwork, boolean noValidatedNetwork,
153                 boolean noNetworksAvailable) {
154         String currentCallback = new StringBuilder()
155                 .append("setConnectivityStatus: ")
156                 .append("noDefaultNetwork=").append(noDefaultNetwork).append(",")
157                 .append("noValidatedNetwork=").append(noValidatedNetwork).append(",")
158                 .append("noNetworksAvailable=").append(noNetworksAvailable)
159                 .toString();
160         if (!currentCallback.equals(mLastCallback)) {
161             mLastCallback = currentCallback;
162             String log = new StringBuilder()
163                     .append(SSDF.format(System.currentTimeMillis())).append(",")
164                     .append(currentCallback).append(",")
165                     .toString();
166             recordLastCallback(log);
167         }
168         post(() -> {
169             for (SignalCallback signalCluster : mSignalCallbacks) {
170                 signalCluster.setConnectivityStatus(
171                         noDefaultNetwork, noValidatedNetwork, noNetworksAvailable);
172             }
173         });
174     }
175 
176     @Override
setCallIndicator(IconState statusIcon, int subId)177     public void setCallIndicator(IconState statusIcon, int subId) {
178         String currentCallback = new StringBuilder()
179                 .append("setCallIndicator: ")
180                 .append("statusIcon=").append(statusIcon).append(",")
181                 .append("subId=").append(subId)
182                 .toString();
183         if (!currentCallback.equals(mLastCallback)) {
184             mLastCallback = currentCallback;
185             String log = new StringBuilder()
186                     .append(SSDF.format(System.currentTimeMillis())).append(",")
187                     .append(currentCallback).append(",")
188                     .toString();
189             recordLastCallback(log);
190         }
191         post(() -> {
192             for (SignalCallback signalCluster : mSignalCallbacks) {
193                 signalCluster.setCallIndicator(statusIcon, subId);
194             }
195         });
196     }
197 
198     @Override
setSubs(List<SubscriptionInfo> subs)199     public void setSubs(List<SubscriptionInfo> subs) {
200         String currentCallback = new StringBuilder()
201                 .append("setSubs: ")
202                 .append("subs=").append(subs == null ? "" : subs.toString())
203                 .toString();
204         if (!currentCallback.equals(mLastCallback)) {
205             mLastCallback = currentCallback;
206             String log = new StringBuilder()
207                     .append(SSDF.format(System.currentTimeMillis())).append(",")
208                     .append(currentCallback).append(",")
209                     .toString();
210             recordLastCallback(log);
211         }
212         obtainMessage(MSG_SUBS_CHANGED, subs).sendToTarget();
213     }
214 
215     @Override
setNoSims(boolean show, boolean simDetected)216     public void setNoSims(boolean show, boolean simDetected) {
217         obtainMessage(MSG_NO_SIM_VISIBLE_CHANGED, show ? 1 : 0, simDetected ? 1 : 0).sendToTarget();
218     }
219 
220     @Override
setMobileDataEnabled(boolean enabled)221     public void setMobileDataEnabled(boolean enabled) {
222         obtainMessage(MSG_MOBILE_DATA_ENABLED_CHANGED, enabled ? 1 : 0, 0).sendToTarget();
223     }
224 
225     @Override
setEmergencyCallsOnly(boolean emergencyOnly)226     public void setEmergencyCallsOnly(boolean emergencyOnly) {
227         obtainMessage(MSG_EMERGENCE_CHANGED, emergencyOnly ? 1 : 0, 0).sendToTarget();
228     }
229 
230     @Override
setEthernetIndicators(IconState icon)231     public void setEthernetIndicators(IconState icon) {
232         String log = new StringBuilder()
233                 .append(SSDF.format(System.currentTimeMillis())).append(",")
234                 .append("setEthernetIndicators: ")
235                 .append("icon=").append(icon)
236                 .toString();
237         recordLastCallback(log);
238         obtainMessage(MSG_ETHERNET_CHANGED, icon).sendToTarget();;
239     }
240 
241     @Override
setIsAirplaneMode(IconState icon)242     public void setIsAirplaneMode(IconState icon) {
243         String currentCallback = new StringBuilder()
244                 .append("setIsAirplaneMode: ")
245                 .append("icon=").append(icon)
246                 .toString();
247         if (!currentCallback.equals(mLastCallback)) {
248             mLastCallback = currentCallback;
249             String log = new StringBuilder()
250                     .append(SSDF.format(System.currentTimeMillis())).append(",")
251                     .append(currentCallback).append(",")
252                     .toString();
253             recordLastCallback(log);
254         }
255         obtainMessage(MSG_AIRPLANE_MODE_CHANGED, icon).sendToTarget();;
256     }
257 
setListening(EmergencyListener listener, boolean listening)258     public void setListening(EmergencyListener listener, boolean listening) {
259         obtainMessage(MSG_ADD_REMOVE_EMERGENCY, listening ? 1 : 0, 0, listener).sendToTarget();
260     }
261 
setListening(SignalCallback listener, boolean listening)262     public void setListening(SignalCallback listener, boolean listening) {
263         obtainMessage(MSG_ADD_REMOVE_SIGNAL, listening ? 1 : 0, 0, listener).sendToTarget();
264     }
265 
recordLastCallback(String callback)266     protected void recordLastCallback(String callback) {
267         mHistory[mHistoryIndex] = callback;
268         mHistoryIndex = (mHistoryIndex + 1) % HISTORY_SIZE;
269     }
270 
271     /**
272      * Dump the Callback logs
273      */
dump(PrintWriter pw)274     public void dump(PrintWriter pw) {
275         pw.println("  - CallbackHandler -----");
276         int size = 0;
277         for (int i = 0; i < HISTORY_SIZE; i++) {
278             if (mHistory[i] != null) {
279                 size++;
280             }
281         }
282         // Print out the previous states in ordered number.
283         for (int i = mHistoryIndex + HISTORY_SIZE - 1;
284                 i >= mHistoryIndex + HISTORY_SIZE - size; i--) {
285             pw.println("  Previous Callback(" + (mHistoryIndex + HISTORY_SIZE - i) + "): "
286                     + mHistory[i & (HISTORY_SIZE - 1)]);
287         }
288     }
289 
290 }
291