/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.telephony; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.telephony.Rlog; import android.util.LocalLog; import android.util.Log; import com.android.internal.util.IndentingPrintWriter; import java.io.FileDescriptor; import java.io.PrintWriter; import java.security.InvalidParameterException; import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_ACTIVATED; import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_DEACTIVATED; import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_RESTRICTED; import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_ACTIVATING; public class SimActivationTracker { /** * SimActivationTracker(SAT) serves as a central place to keep track of all knowledge of * voice & data activation state which is set by custom/default carrier apps. * Each phone object maintains a single activation tracker. */ private static final boolean DBG = true; private static final String LOG_TAG = "SAT"; private static final boolean VDBG = Rlog.isLoggable(LOG_TAG, Log.VERBOSE); private Phone mPhone; /** * Voice Activation State * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED */ private int mVoiceActivationState; /** * Data Activation State * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED */ private int mDataActivationState; private final LocalLog mVoiceActivationStateLog = new LocalLog(10); private final LocalLog mDataActivationStateLog = new LocalLog(10); private final BroadcastReceiver mReceiver; public SimActivationTracker(Phone phone) { mPhone = phone; mVoiceActivationState = SIM_ACTIVATION_STATE_UNKNOWN; mDataActivationState = SIM_ACTIVATION_STATE_UNKNOWN; mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (VDBG) log("action: " + action); if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)){ if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals( intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE))) { if (DBG) log("onSimAbsent, reset activation state to UNKNOWN"); setVoiceActivationState(SIM_ACTIVATION_STATE_UNKNOWN); setDataActivationState(SIM_ACTIVATION_STATE_UNKNOWN); } } } }; IntentFilter intentFilter = new IntentFilter(TelephonyIntents.ACTION_SIM_STATE_CHANGED); mPhone.getContext().registerReceiver(mReceiver, intentFilter); } public void setVoiceActivationState(int state) { if (!isValidActivationState(state) || (SIM_ACTIVATION_STATE_RESTRICTED == state)) { throw new IllegalArgumentException("invalid voice activation state: " + state); } if (DBG) log("setVoiceActivationState=" + state); mVoiceActivationState = state; mVoiceActivationStateLog.log(toString(state)); mPhone.notifyVoiceActivationStateChanged(state); } public void setDataActivationState(int state) { if (!isValidActivationState(state)) { throw new IllegalArgumentException("invalid data activation state: " + state); } if (DBG) log("setDataActivationState=" + state); mDataActivationState = state; mDataActivationStateLog.log(toString(state)); mPhone.notifyDataActivationStateChanged(state); } public int getVoiceActivationState() { return mVoiceActivationState; } public int getDataActivationState() { return mDataActivationState; } private static boolean isValidActivationState(int state) { switch (state) { case SIM_ACTIVATION_STATE_UNKNOWN: case SIM_ACTIVATION_STATE_ACTIVATING: case SIM_ACTIVATION_STATE_ACTIVATED: case SIM_ACTIVATION_STATE_DEACTIVATED: case SIM_ACTIVATION_STATE_RESTRICTED: return true; default: return false; } } private static String toString(int state) { switch (state) { case SIM_ACTIVATION_STATE_UNKNOWN: return "unknown"; case SIM_ACTIVATION_STATE_ACTIVATING: return "activating"; case SIM_ACTIVATION_STATE_ACTIVATED: return "activated"; case SIM_ACTIVATION_STATE_DEACTIVATED: return "deactivated"; case SIM_ACTIVATION_STATE_RESTRICTED: return "restricted"; default: return "invalid"; } } private void log(String s) { Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s); } private void loge(String s) { Rlog.e(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s); } public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); pw.println(" mVoiceActivationState Log:"); ipw.increaseIndent(); mVoiceActivationStateLog.dump(fd, ipw, args); ipw.decreaseIndent(); pw.println(" mDataActivationState Log:"); ipw.increaseIndent(); mDataActivationStateLog.dump(fd, ipw, args); ipw.decreaseIndent(); } public void dispose() { mPhone.getContext().unregisterReceiver(mReceiver); } }