1 /*
2  * Copyright (C) 2016 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.internal.telephony;
17 
18 import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_ACTIVATED;
19 import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_ACTIVATING;
20 import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_DEACTIVATED;
21 import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_RESTRICTED;
22 import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
23 
24 import android.content.BroadcastReceiver;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.content.IntentFilter;
28 import android.util.LocalLog;
29 import android.util.Log;
30 
31 import com.android.internal.util.IndentingPrintWriter;
32 import com.android.telephony.Rlog;
33 
34 import java.io.FileDescriptor;
35 import java.io.PrintWriter;
36 
37 public class SimActivationTracker {
38     /**
39      * SimActivationTracker(SAT) serves as a central place to keep track of all knowledge of
40      * voice & data activation state which is set by custom/default carrier apps.
41      * Each phone object maintains a single activation tracker.
42      */
43     private static final boolean DBG = true;
44     private static final String LOG_TAG = "SAT";
45     private static final boolean VDBG = Rlog.isLoggable(LOG_TAG, Log.VERBOSE);
46 
47     private Phone mPhone;
48 
49     /**
50      * Voice Activation State
51      * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN
52      * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING
53      * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED
54      * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED
55      */
56     private int mVoiceActivationState;
57 
58     /**
59      * Data Activation State
60      * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN
61      * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING
62      * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED
63      * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED
64      * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED
65      */
66     private int mDataActivationState;
67     private final LocalLog mVoiceActivationStateLog = new LocalLog(10);
68     private final LocalLog mDataActivationStateLog = new LocalLog(10);
69     private final BroadcastReceiver mReceiver;
70 
SimActivationTracker(Phone phone)71     public SimActivationTracker(Phone phone) {
72         mPhone = phone;
73         mVoiceActivationState = SIM_ACTIVATION_STATE_UNKNOWN;
74         mDataActivationState = SIM_ACTIVATION_STATE_UNKNOWN;
75 
76         mReceiver = new  BroadcastReceiver() {
77             @Override
78             public void onReceive(Context context, Intent intent) {
79                 String action = intent.getAction();
80                 if (VDBG) log("action: " + action);
81                 if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)){
82                     if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(
83                             intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE))) {
84                         if (DBG) log("onSimAbsent, reset activation state to UNKNOWN");
85                         setVoiceActivationState(SIM_ACTIVATION_STATE_UNKNOWN);
86                         setDataActivationState(SIM_ACTIVATION_STATE_UNKNOWN);
87                     }
88                 }
89             }
90         };
91 
92         IntentFilter intentFilter = new IntentFilter(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
93         mPhone.getContext().registerReceiver(mReceiver, intentFilter);
94     }
95 
setVoiceActivationState(int state)96     public void setVoiceActivationState(int state) {
97         if (!isValidActivationState(state) || (SIM_ACTIVATION_STATE_RESTRICTED == state)) {
98             throw new IllegalArgumentException("invalid voice activation state: " + state);
99         }
100         if (DBG) log("setVoiceActivationState=" + state);
101         mVoiceActivationState = state;
102         mVoiceActivationStateLog.log(toString(state));
103         mPhone.notifyVoiceActivationStateChanged(state);
104     }
105 
setDataActivationState(int state)106     public void setDataActivationState(int state) {
107         if (!isValidActivationState(state)) {
108             throw new IllegalArgumentException("invalid data activation state: " + state);
109         }
110         if (DBG) log("setDataActivationState=" + state);
111         mDataActivationState = state;
112         mDataActivationStateLog.log(toString(state));
113         mPhone.notifyDataActivationStateChanged(state);
114     }
115 
getVoiceActivationState()116     public int getVoiceActivationState() {
117         return mVoiceActivationState;
118     }
119 
getDataActivationState()120     public int getDataActivationState() {
121         return mDataActivationState;
122     }
123 
isValidActivationState(int state)124     private static boolean isValidActivationState(int state) {
125         switch (state) {
126             case SIM_ACTIVATION_STATE_UNKNOWN:
127             case SIM_ACTIVATION_STATE_ACTIVATING:
128             case SIM_ACTIVATION_STATE_ACTIVATED:
129             case SIM_ACTIVATION_STATE_DEACTIVATED:
130             case SIM_ACTIVATION_STATE_RESTRICTED:
131                 return true;
132             default:
133                 return false;
134         }
135     }
136 
toString(int state)137     private static String toString(int state) {
138         switch (state) {
139             case SIM_ACTIVATION_STATE_UNKNOWN:
140                 return "unknown";
141             case SIM_ACTIVATION_STATE_ACTIVATING:
142                 return "activating";
143             case SIM_ACTIVATION_STATE_ACTIVATED:
144                 return "activated";
145             case SIM_ACTIVATION_STATE_DEACTIVATED:
146                 return "deactivated";
147             case SIM_ACTIVATION_STATE_RESTRICTED:
148                 return "restricted";
149             default:
150                 return "invalid";
151         }
152     }
153 
log(String s)154     private void log(String s) {
155         Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
156     }
157 
loge(String s)158     private void loge(String s) {
159         Rlog.e(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
160     }
161 
dump(FileDescriptor fd, PrintWriter pw, String[] args)162     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
163         IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
164         pw.println(" mVoiceActivationState Log:");
165         ipw.increaseIndent();
166         mVoiceActivationStateLog.dump(fd, ipw, args);
167         ipw.decreaseIndent();
168 
169         pw.println(" mDataActivationState Log:");
170         ipw.increaseIndent();
171         mDataActivationStateLog.dump(fd, ipw, args);
172         ipw.decreaseIndent();
173     }
174 
dispose()175     public void dispose() {
176         mPhone.getContext().unregisterReceiver(mReceiver);
177     }
178 }