diff options
7 files changed, 323 insertions, 10 deletions
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 0834eb8f9cba..ea33906940a7 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -16,7 +16,6 @@ package com.android.server; -import android.Manifest; import android.app.ActivityManager; import android.app.AppOpsManager; import android.content.BroadcastReceiver; @@ -142,6 +141,10 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { private ServiceState[] mServiceState; + private int[] mVoiceActivationState; + + private int[] mDataActivationState; + private SignalStrength[] mSignalStrength; private boolean[] mMessageWaiting; @@ -301,6 +304,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { mDataConnectionNetworkType = new int[numPhones]; mCallIncomingNumber = new String[numPhones]; mServiceState = new ServiceState[numPhones]; + mVoiceActivationState = new int[numPhones]; + mDataActivationState = new int[numPhones]; mSignalStrength = new SignalStrength[numPhones]; mMessageWaiting = new boolean[numPhones]; mDataConnectionPossible = new boolean[numPhones]; @@ -315,6 +320,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { mCallState[i] = TelephonyManager.CALL_STATE_IDLE; mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE; mDataConnectionState[i] = TelephonyManager.DATA_UNKNOWN; + mVoiceActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; + mDataActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; mCallIncomingNumber[i] = ""; mServiceState[i] = new ServiceState(); mSignalStrength[i] = new SignalStrength(); @@ -644,6 +651,20 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { remove(r.binder); } } + if ((events & PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) !=0) { + try { + r.callback.onVoiceActivationStateChanged(mVoiceActivationState[phoneId]); + } catch (RemoteException ex) { + remove(r.binder); + } + } + if ((events & PhoneStateListener.LISTEN_DATA_ACTIVATION_STATE) !=0) { + try { + r.callback.onDataActivationStateChanged(mDataActivationState[phoneId]); + } catch (RemoteException ex) { + remove(r.binder); + } + } } } } else { @@ -795,6 +816,67 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { broadcastServiceStateChanged(state, phoneId, subId); } + public void notifySimActivationStateChangedForPhoneId(int phoneId, int subId, + int activationType, int activationState) { + if (!checkNotifyPermission("notifySimActivationState()")){ + return; + } + if (VDBG) { + log("notifySimActivationStateForPhoneId: subId=" + subId + " phoneId=" + phoneId + + "type=" + activationType + " state=" + activationState); + } + synchronized (mRecords) { + if (validatePhoneId(phoneId)) { + switch (activationType) { + case PhoneConstants.SIM_ACTIVATION_TYPE_VOICE: + mVoiceActivationState[phoneId] = activationState; + break; + case PhoneConstants.SIM_ACTIVATION_TYPE_DATA: + mDataActivationState[phoneId] = activationState; + break; + default: + return; + } + for (Record r : mRecords) { + if (VDBG) { + log("notifySimActivationStateForPhoneId: r=" + r + " subId=" + subId + + " phoneId=" + phoneId + "type=" + activationType + + " state=" + activationState); + } + try { + if ((activationType == PhoneConstants.SIM_ACTIVATION_TYPE_VOICE) && + r.matchPhoneStateListenerEvent( + PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) && + idMatch(r.subId, subId, phoneId)) { + if (DBG) { + log("notifyVoiceActivationStateForPhoneId: callback.onVASC r=" + r + + " subId=" + subId + " phoneId=" + phoneId + + " state=" + activationState); + } + r.callback.onVoiceActivationStateChanged(activationState); + } + if ((activationType == PhoneConstants.SIM_ACTIVATION_TYPE_DATA) && + r.matchPhoneStateListenerEvent( + PhoneStateListener.LISTEN_DATA_ACTIVATION_STATE) && + idMatch(r.subId, subId, phoneId)) { + if (DBG) { + log("notifyDataActivationStateForPhoneId: callback.onDASC r=" + r + + " subId=" + subId + " phoneId=" + phoneId + + " state=" + activationState); + } + r.callback.onDataActivationStateChanged(activationState); + } + } catch (RemoteException ex) { + mRemoveList.add(r.binder); + } + } + } else { + log("notifySimActivationStateForPhoneId: INVALID phoneId=" + phoneId); + } + handleRemoveListLocked(); + } + } + public void notifySignalStrengthForPhoneId(int phoneId, int subId, SignalStrength signalStrength) { if (!checkNotifyPermission("notifySignalStrength()")) { @@ -1324,6 +1406,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println(" mCallState=" + mCallState[i]); pw.println(" mCallIncomingNumber=" + mCallIncomingNumber[i]); pw.println(" mServiceState=" + mServiceState[i]); + pw.println(" mVoiceActivationState= " + mVoiceActivationState[i]); + pw.println(" mDataActivationState= " + mDataActivationState[i]); pw.println(" mSignalStrength=" + mSignalStrength[i]); pw.println(" mMessageWaiting=" + mMessageWaiting[i]); pw.println(" mCallForwarding=" + mCallForwarding[i]); diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java index 32f487bb5dbe..dd0330558672 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/telephony/java/android/telephony/PhoneStateListener.java @@ -20,17 +20,9 @@ import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.telephony.SubscriptionManager; -import android.telephony.CellLocation; -import android.telephony.CellInfo; -import android.telephony.VoLteServiceState; -import android.telephony.Rlog; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; -import android.telephony.PreciseCallState; -import android.telephony.PreciseDataConnectionState; import com.android.internal.telephony.IPhoneStateListener; + import java.util.List; import java.lang.ref.WeakReference; @@ -228,6 +220,38 @@ public class PhoneStateListener { */ public static final int LISTEN_CARRIER_NETWORK_CHANGE = 0x00010000; + /** + * Listen for changes to the sim voice activation state + * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING + * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED + * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED + * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED + * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN + * {@more} + * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates voice service has been + * fully activated + * + * @see #onVoiceActivationStateChanged + * @hide + */ + public static final int LISTEN_VOICE_ACTIVATION_STATE = 0x00020000; + + /** + * Listen for changes to the sim data activation state + * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING + * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED + * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED + * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED + * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN + * {@more} + * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates data service has been + * fully activated + * + * @see #onDataActivationStateChanged + * @hide + */ + public static final int LISTEN_DATA_ACTIVATION_STATE = 0x00040000; + /* * Subscription used to listen to the phone state changes * @hide @@ -327,6 +351,12 @@ public class PhoneStateListener { case LISTEN_VOLTE_STATE: PhoneStateListener.this.onVoLteServiceStateChanged((VoLteServiceState)msg.obj); break; + case LISTEN_VOICE_ACTIVATION_STATE: + PhoneStateListener.this.onVoiceActivationStateChanged((int)msg.obj); + break; + case LISTEN_DATA_ACTIVATION_STATE: + PhoneStateListener.this.onDataActivationStateChanged((int)msg.obj); + break; case LISTEN_OEM_HOOK_RAW_EVENT: PhoneStateListener.this.onOemHookRawEvent((byte[])msg.obj); break; @@ -506,6 +536,24 @@ public class PhoneStateListener { } /** + * Callback invoked when the SIM voice activation state has changed + * @param state is the current SIM voice activation state + * @hide + */ + public void onVoiceActivationStateChanged(int state) { + + } + + /** + * Callback invoked when the SIM data activation state has changed + * @param state is the current SIM data activation state + * @hide + */ + public void onDataActivationStateChanged(int state) { + + } + + /** * Callback invoked when OEM hook raw event is received. Requires * the READ_PRIVILEGED_PHONE_STATE permission. * @param rawData is the byte array of the OEM hook raw data. @@ -619,6 +667,14 @@ public class PhoneStateListener { send(LISTEN_VOLTE_STATE, 0, 0, lteState); } + public void onVoiceActivationStateChanged(int activationState) { + send(LISTEN_VOICE_ACTIVATION_STATE, 0, 0, activationState); + } + + public void onDataActivationStateChanged(int activationState) { + send(LISTEN_DATA_ACTIVATION_STATE, 0, 0, activationState); + } + public void onOemHookRawEvent(byte[] rawData) { send(LISTEN_OEM_HOOK_RAW_EVENT, 0, 0, rawData); } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 1b3aa8aff845..4ff4d80f88dc 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -2813,6 +2813,148 @@ public class TelephonyManager { } /** + * Initial SIM activation state, unknown. Not set by any carrier apps. + * @hide + */ + public static final int SIM_ACTIVATION_STATE_UNKNOWN = 0; + + /** + * indicate SIM is under activation procedure now. + * intermediate state followed by another state update with activation procedure result: + * @see #SIM_ACTIVATION_STATE_ACTIVATED + * @see #SIM_ACTIVATION_STATE_DEACTIVATED + * @see #SIM_ACTIVATION_STATE_RESTRICTED + * @hide + */ + public static final int SIM_ACTIVATION_STATE_ACTIVATING = 1; + + /** + * Indicate SIM has been successfully activated with full service + * @hide + */ + public static final int SIM_ACTIVATION_STATE_ACTIVATED = 2; + + /** + * Indicate SIM has been deactivated by the carrier so that service is not available + * and requires activation service to enable services. + * Carrier apps could be signalled to set activation state to deactivated if detected + * deactivated sim state and set it back to activated after successfully run activation service. + * @hide + */ + public static final int SIM_ACTIVATION_STATE_DEACTIVATED = 3; + + /** + * Restricted state indicate SIM has been activated but service are restricted. + * note this is currently available for data activation state. For example out of byte sim. + * @hide + */ + public static final int SIM_ACTIVATION_STATE_RESTRICTED = 4; + + /** + * Sets the voice activation state for the given subscriber. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param subId The subscription id. + * @param activationState The voice activation state of the given subscriber. + * @see #SIM_ACTIVATION_STATE_UNKNOWN + * @see #SIM_ACTIVATION_STATE_ACTIVATING + * @see #SIM_ACTIVATION_STATE_ACTIVATED + * @see #SIM_ACTIVATION_STATE_DEACTIVATED + * @hide + */ + public void setVoiceActivationState(int subId, int activationState) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) + telephony.setVoiceActivationState(subId, activationState); + } catch (RemoteException ex) { + } catch (NullPointerException ex) { + } + } + + /** + * Sets the data activation state for the given subscriber. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE} + * Or the calling app has carrier privileges. @see #hasCarrierPrivileges + * + * @param subId The subscription id. + * @param activationState The data activation state of the given subscriber. + * @see #SIM_ACTIVATION_STATE_UNKNOWN + * @see #SIM_ACTIVATION_STATE_ACTIVATING + * @see #SIM_ACTIVATION_STATE_ACTIVATED + * @see #SIM_ACTIVATION_STATE_DEACTIVATED + * @see #SIM_ACTIVATION_STATE_RESTRICTED + * @hide + */ + public void setDataActivationState(int subId, int activationState) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) + telephony.setDataActivationState(subId, activationState); + } catch (RemoteException ex) { + } catch (NullPointerException ex) { + } + } + + /** + * Returns the voice activation state for the given subscriber. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#READ_PHONE_STATE} + * + * @param subId The subscription id. + * + * @return voiceActivationState for the given subscriber + * @see #SIM_ACTIVATION_STATE_UNKNOWN + * @see #SIM_ACTIVATION_STATE_ACTIVATING + * @see #SIM_ACTIVATION_STATE_ACTIVATED + * @see #SIM_ACTIVATION_STATE_DEACTIVATED + * @hide + */ + public int getVoiceActivationState(int subId) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) + return telephony.getVoiceActivationState(subId, getOpPackageName()); + } catch (RemoteException ex) { + } catch (NullPointerException ex) { + } + return SIM_ACTIVATION_STATE_UNKNOWN; + } + + /** + * Returns the data activation state for the given subscriber. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#READ_PHONE_STATE} + * + * @param subId The subscription id. + * + * @return dataActivationState for the given subscriber + * @see #SIM_ACTIVATION_STATE_UNKNOWN + * @see #SIM_ACTIVATION_STATE_ACTIVATING + * @see #SIM_ACTIVATION_STATE_ACTIVATED + * @see #SIM_ACTIVATION_STATE_DEACTIVATED + * @see #SIM_ACTIVATION_STATE_RESTRICTED + * @hide + */ + public int getDataActivationState(int subId) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) + return telephony.getDataActivationState(subId, getOpPackageName()); + } catch (RemoteException ex) { + } catch (NullPointerException ex) { + } + return SIM_ACTIVATION_STATE_UNKNOWN; + } + + /** * Returns the voice mail count. Return 0 if unavailable, -1 if there are unread voice messages * but the count is unknown. * <p> diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl index cbedb95d2ea5..e9c5461ab421 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -43,6 +43,8 @@ oneway interface IPhoneStateListener { void onPreciseDataConnectionStateChanged(in PreciseDataConnectionState dataConnectionState); void onDataConnectionRealTimeInfoChanged(in DataConnectionRealTimeInfo dcRtInfo); void onVoLteServiceStateChanged(in VoLteServiceState lteState); + void onVoiceActivationStateChanged(int activationState); + void onDataActivationStateChanged(int activationState); void onOemHookRawEvent(in byte[] rawData); void onCarrierNetworkChange(in boolean active); } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index f2b8804e5e54..d90a33e1022d 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -456,6 +456,30 @@ interface ITelephony { */ boolean setVoiceMailNumber(int subId, String alphaTag, String number); + /** + * Sets the voice activation state for a particular subscriber. + */ + void setVoiceActivationState(int subId, int activationState); + + /** + * Sets the data activation state for a particular subscriber. + */ + void setDataActivationState(int subId, int activationState); + + /** + * Returns the voice activation state for a particular subscriber. + * @param subId user preferred sub + * @param callingPackage package queries voice activation state + */ + int getVoiceActivationState(int subId, String callingPackage); + + /** + * Returns the data activation state for a particular subscriber. + * @param subId user preferred sub + * @param callingPackage package queris data activation state + */ + int getDataActivationState(int subId, String callingPackage); + /** * Returns the unread count of voicemails */ diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 2c6be62ee7f5..2c2206c390f8 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -65,6 +65,8 @@ interface ITelephonyRegistry { String failCause); void notifyCellInfoForSubscriber(in int subId, in List<CellInfo> cellInfo); void notifyVoLteServiceStateChanged(in VoLteServiceState lteState); + void notifySimActivationStateChangedForPhoneId(in int phoneId, in int subId, + int activationState, int activationType); void notifyOemHookRawEventForSubscriber(in int subId, in byte[] rawData); void notifySubscriptionInfoChanged(); void notifyCarrierNetworkChange(in boolean active); diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java index fdc68b9fb7c6..f9de776f9a7b 100644 --- a/telephony/java/com/android/internal/telephony/PhoneConstants.java +++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java @@ -74,6 +74,9 @@ public class PhoneConstants { public static final int PRESENTATION_UNKNOWN = 3; // no specified or unknown by network public static final int PRESENTATION_PAYPHONE = 4; // show pay phone info + // Sim activation type + public static final int SIM_ACTIVATION_TYPE_VOICE = 0; + public static final int SIM_ACTIVATION_TYPE_DATA = 1; public static final String PHONE_NAME_KEY = "phoneName"; public static final String FAILURE_REASON_KEY = "reason"; |