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