am 816e19eb: Merge "Revert "Additional changes to SubscriptionManager API as per API council."" into lmp-mr1-dev

* commit '816e19eb6d5795f98f072494c763b20fe3412c30':
  Revert "Additional changes to SubscriptionManager API as per API council."
This commit is contained in:
Wink Saville
2014-11-20 20:38:40 +00:00
committed by Android Git Automerger
15 changed files with 471 additions and 520 deletions

View File

@@ -372,8 +372,8 @@ LOCAL_SRC_FILES += \
telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \ telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
telephony/java/com/android/internal/telephony/ITelephony.aidl \ telephony/java/com/android/internal/telephony/ITelephony.aidl \
telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \ telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl \
telephony/java/com/android/internal/telephony/ISms.aidl \ telephony/java/com/android/internal/telephony/ISms.aidl \
telephony/java/com/android/internal/telephony/ISubscriptionListener.aidl \
telephony/java/com/android/internal/telephony/IWapPushManager.aidl \ telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
telephony/java/com/android/internal/telephony/ISub.aidl \ telephony/java/com/android/internal/telephony/ISub.aidl \
telephony/java/com/android/internal/telephony/IMms.aidl \ telephony/java/com/android/internal/telephony/IMms.aidl \

View File

@@ -7270,7 +7270,6 @@ package android.content {
field public static final java.lang.String STORAGE_SERVICE = "storage"; field public static final java.lang.String STORAGE_SERVICE = "storage";
field public static final java.lang.String TELECOM_SERVICE = "telecom"; field public static final java.lang.String TELECOM_SERVICE = "telecom";
field public static final java.lang.String TELEPHONY_SERVICE = "phone"; field public static final java.lang.String TELEPHONY_SERVICE = "phone";
field public static final java.lang.String TELEPHONY_SUBSCRIPTION_SERVICE = "telephony_subscription_service";
field public static final java.lang.String TEXT_SERVICES_MANAGER_SERVICE = "textservices"; field public static final java.lang.String TEXT_SERVICES_MANAGER_SERVICE = "textservices";
field public static final java.lang.String TV_INPUT_SERVICE = "tv_input"; field public static final java.lang.String TV_INPUT_SERVICE = "tv_input";
field public static final java.lang.String UI_MODE_SERVICE = "uimode"; field public static final java.lang.String UI_MODE_SERVICE = "uimode";
@@ -25577,7 +25576,7 @@ package android.provider {
field public static final java.lang.String STATUS = "st"; field public static final java.lang.String STATUS = "st";
field public static final java.lang.String SUBJECT = "sub"; field public static final java.lang.String SUBJECT = "sub";
field public static final java.lang.String SUBJECT_CHARSET = "sub_cs"; field public static final java.lang.String SUBJECT_CHARSET = "sub_cs";
field public static final java.lang.String SUBSCRIPTION_ID = "sub_id"; field public static final java.lang.String SUB_ID = "sub_id";
field public static final java.lang.String TEXT_ONLY = "text_only"; field public static final java.lang.String TEXT_ONLY = "text_only";
field public static final java.lang.String THREAD_ID = "thread_id"; field public static final java.lang.String THREAD_ID = "thread_id";
field public static final java.lang.String TRANSACTION_ID = "tr_id"; field public static final java.lang.String TRANSACTION_ID = "tr_id";
@@ -25610,7 +25609,7 @@ package android.provider {
field public static final java.lang.String PROXY = "proxy"; field public static final java.lang.String PROXY = "proxy";
field public static final java.lang.String ROAMING_PROTOCOL = "roaming_protocol"; field public static final java.lang.String ROAMING_PROTOCOL = "roaming_protocol";
field public static final java.lang.String SERVER = "server"; field public static final java.lang.String SERVER = "server";
field public static final java.lang.String SUBSCRIPTION_ID = "sub_id"; field public static final java.lang.String SUB_ID = "sub_id";
field public static final java.lang.String TYPE = "type"; field public static final java.lang.String TYPE = "type";
field public static final java.lang.String USER = "user"; field public static final java.lang.String USER = "user";
} }
@@ -25711,7 +25710,7 @@ package android.provider {
field public static final java.lang.String MSG_TYPE = "msg_type"; field public static final java.lang.String MSG_TYPE = "msg_type";
field public static final java.lang.String PROTO_TYPE = "proto_type"; field public static final java.lang.String PROTO_TYPE = "proto_type";
field public static final java.lang.String RETRY_INDEX = "retry_index"; field public static final java.lang.String RETRY_INDEX = "retry_index";
field public static final java.lang.String SUBSCRIPTION_ID = "pending_sub_id"; field public static final java.lang.String SUB_ID = "pending_sub_id";
} }
public static final class Telephony.Sms implements android.provider.BaseColumns android.provider.Telephony.TextBasedSmsColumns { public static final class Telephony.Sms implements android.provider.BaseColumns android.provider.Telephony.TextBasedSmsColumns {
@@ -25797,7 +25796,7 @@ package android.provider {
field public static final int STATUS_NONE = -1; // 0xffffffff field public static final int STATUS_NONE = -1; // 0xffffffff
field public static final int STATUS_PENDING = 32; // 0x20 field public static final int STATUS_PENDING = 32; // 0x20
field public static final java.lang.String SUBJECT = "subject"; field public static final java.lang.String SUBJECT = "subject";
field public static final java.lang.String SUBSCRIPTION_ID = "sub_id"; field public static final java.lang.String SUB_ID = "sub_id";
field public static final java.lang.String THREAD_ID = "thread_id"; field public static final java.lang.String THREAD_ID = "thread_id";
field public static final java.lang.String TYPE = "type"; field public static final java.lang.String TYPE = "type";
} }
@@ -28650,19 +28649,20 @@ package android.telephony {
field public static final android.os.Parcelable.Creator<android.telephony.SubscriptionInfo> CREATOR; field public static final android.os.Parcelable.Creator<android.telephony.SubscriptionInfo> CREATOR;
} }
public class SubscriptionManager { public class SubscriptionListener {
method public static android.telephony.SubscriptionManager from(android.content.Context); ctor public SubscriptionListener();
method public android.telephony.SubscriptionInfo getActiveSubscriptionInfo(int); ctor public SubscriptionListener(android.os.Looper);
method public android.telephony.SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int); method public void onSubscriptionInfoChanged();
method public java.util.List<android.telephony.SubscriptionInfo> getActiveSubscriptionInfoList(); field public static final int LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED = 1; // 0x1
method public void registerOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
method public void unregisterOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
field public static final int INVALID_SUBSCRIPTION_ID = -1; // 0xffffffff
} }
public static class SubscriptionManager.OnSubscriptionsChangedListener { public class SubscriptionManager implements android.provider.BaseColumns {
ctor public SubscriptionManager.OnSubscriptionsChangedListener(); method public static java.util.List<android.telephony.SubscriptionInfo> getActiveSubscriptionInfoList();
method public void onSubscriptionsChanged(); method public static android.telephony.SubscriptionInfo getSubscriptionInfoForSubscriber(int);
method public static java.util.List<android.telephony.SubscriptionInfo> getSubscriptionInfoUsingSlotId(int);
method public static void register(android.content.Context, android.telephony.SubscriptionListener, int);
method public static void unregister(android.content.Context, android.telephony.SubscriptionListener);
field public static final int INVALID_SUB_ID = -1000; // 0xfffffc18
} }
public class TelephonyManager { public class TelephonyManager {

View File

@@ -20,9 +20,9 @@ import android.app.usage.IUsageStatsManager;
import android.app.usage.UsageStatsManager; import android.app.usage.UsageStatsManager;
import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetManager;
import android.os.Build; import android.os.Build;
import android.service.persistentdata.IPersistentDataBlockService; import android.service.persistentdata.IPersistentDataBlockService;
import android.service.persistentdata.PersistentDataBlockManager; import android.service.persistentdata.PersistentDataBlockManager;
import com.android.internal.appwidget.IAppWidgetService; import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.policy.PolicyManager; import com.android.internal.policy.PolicyManager;
import com.android.internal.util.Preconditions; import com.android.internal.util.Preconditions;
@@ -125,7 +125,6 @@ import android.print.PrintManager;
import android.service.fingerprint.IFingerprintService; import android.service.fingerprint.IFingerprintService;
import android.service.fingerprint.FingerprintManager; import android.service.fingerprint.FingerprintManager;
import android.telecom.TelecomManager; import android.telecom.TelecomManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.content.ClipboardManager; import android.content.ClipboardManager;
import android.util.AndroidRuntimeException; import android.util.AndroidRuntimeException;
@@ -562,11 +561,6 @@ class ContextImpl extends Context {
return new TelephonyManager(ctx.getOuterContext()); return new TelephonyManager(ctx.getOuterContext());
}}); }});
registerService(TELEPHONY_SUBSCRIPTION_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new SubscriptionManager(ctx.getOuterContext());
}});
registerService(TELECOM_SERVICE, new ServiceFetcher() { registerService(TELECOM_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) { public Object createService(ContextImpl ctx) {
return new TelecomManager(ctx.getOuterContext()); return new TelecomManager(ctx.getOuterContext());

View File

@@ -2245,8 +2245,6 @@ public abstract class Context {
* @see android.media.MediaRouter * @see android.media.MediaRouter
* @see #TELEPHONY_SERVICE * @see #TELEPHONY_SERVICE
* @see android.telephony.TelephonyManager * @see android.telephony.TelephonyManager
* @see #TELEPHONY_SUBSCRIPTION_SERVICE
* @see android.telephony.SubscriptionManager
* @see #INPUT_METHOD_SERVICE * @see #INPUT_METHOD_SERVICE
* @see android.view.inputmethod.InputMethodManager * @see android.view.inputmethod.InputMethodManager
* @see #UI_MODE_SERVICE * @see #UI_MODE_SERVICE
@@ -2589,16 +2587,6 @@ public abstract class Context {
*/ */
public static final String TELEPHONY_SERVICE = "phone"; public static final String TELEPHONY_SERVICE = "phone";
/**
* Use with {@link #getSystemService} to retrieve a
* {@link android.telephony.SubscriptionManager} for handling management the
* telephony subscriptions of the device.
*
* @see #getSystemService
* @see android.telephony.SubscriptionManager
*/
public static final String TELEPHONY_SUBSCRIPTION_SERVICE = "telephony_subscription_service";
/** /**
* Use with {@link #getSystemService} to retrieve a * Use with {@link #getSystemService} to retrieve a
* {@link android.telecom.TelecomManager} to manage telecom-related features * {@link android.telecom.TelecomManager} to manage telecom-related features

View File

@@ -387,6 +387,7 @@ public class CallLog {
public static Uri addCall(CallerInfo ci, Context context, String number, public static Uri addCall(CallerInfo ci, Context context, String number,
int presentation, int callType, int features, PhoneAccountHandle accountHandle, int presentation, int callType, int features, PhoneAccountHandle accountHandle,
long start, int duration, Long dataUsage) { long start, int duration, Long dataUsage) {
// FIXME using -1 as subId instead of SubscriptionManager.INVALID_SUB_ID
return addCall(ci, context, number, presentation, callType, features, accountHandle, return addCall(ci, context, number, presentation, callType, features, accountHandle,
start, duration, dataUsage, false); start, duration, dataUsage, false);
} }

View File

@@ -239,7 +239,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
mDaemonHandler = new Handler(FgThread.get().getLooper()); mDaemonHandler = new Handler(FgThread.get().getLooper());
mPhoneStateListener = new PhoneStateListener(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, mPhoneStateListener = new PhoneStateListener(SubscriptionManager.DEFAULT_SUB_ID,
mDaemonHandler.getLooper()) { mDaemonHandler.getLooper()) {
@Override @Override
public void onDataConnectionRealTimeInfoChanged( public void onDataConnectionRealTimeInfoChanged(

View File

@@ -34,6 +34,8 @@ import android.os.UserHandle;
import android.telephony.CellLocation; import android.telephony.CellLocation;
import android.telephony.DataConnectionRealTimeInfo; import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.Rlog; import android.telephony.Rlog;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionListener;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager;
import android.telephony.PhoneStateListener; import android.telephony.PhoneStateListener;
@@ -41,6 +43,7 @@ import android.telephony.ServiceState;
import android.telephony.SignalStrength; import android.telephony.SignalStrength;
import android.telephony.CellInfo; import android.telephony.CellInfo;
import android.telephony.VoLteServiceState; import android.telephony.VoLteServiceState;
import android.telephony.TelephonyManager;
import android.telephony.DisconnectCause; import android.telephony.DisconnectCause;
import android.telephony.PreciseCallState; import android.telephony.PreciseCallState;
import android.telephony.PreciseDataConnectionState; import android.telephony.PreciseDataConnectionState;
@@ -49,12 +52,13 @@ import android.text.TextUtils;
import android.text.format.Time; import android.text.format.Time;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.List; import java.util.List;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.PrintWriter; import java.io.PrintWriter;
import com.android.internal.app.IBatteryStats; import com.android.internal.app.IBatteryStats;
import com.android.internal.telephony.IOnSubscriptionsChangedListener; import com.android.internal.telephony.ISubscriptionListener;
import com.android.internal.telephony.ITelephonyRegistry; import com.android.internal.telephony.ITelephonyRegistry;
import com.android.internal.telephony.IPhoneStateListener; import com.android.internal.telephony.IPhoneStateListener;
import com.android.internal.telephony.DefaultPhoneNotifier; import com.android.internal.telephony.DefaultPhoneNotifier;
@@ -89,29 +93,28 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
IBinder binder; IBinder binder;
IPhoneStateListener callback; IPhoneStateListener callback;
IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback; ISubscriptionListener subscriptionListenerCallback;
int callerUid; int callerUid;
int events; int events;
int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; int subId = SubscriptionManager.INVALID_SUB_ID;
int phoneId = SubscriptionManager.INVALID_PHONE_INDEX; int phoneId = SubscriptionManager.INVALID_PHONE_ID;
boolean matchPhoneStateListenerEvent(int events) { boolean matchPhoneStateListenerEvent(int events) {
return (callback != null) && ((events & this.events) != 0); return (callback != null) && ((events & this.events) != 0);
} }
boolean matchOnSubscriptionsChangedListener() { boolean matchSubscriptionListenerEvent(int events) {
return (onSubscriptionsChangedListenerCallback != null); return (subscriptionListenerCallback != null) && ((events & this.events) != 0);
} }
@Override @Override
public String toString() { public String toString() {
return "{pkgForDebug=" + pkgForDebug + " binder=" + binder + " callback=" + callback return "{pkgForDebug=" + pkgForDebug + " binder=" + binder + " callback=" + callback
+ " onSubscriptionsChangedListenererCallback=" + " subscriptionListenererCallback=" + subscriptionListenerCallback
+ onSubscriptionsChangedListenerCallback
+ " callerUid=" + callerUid + " subId=" + subId + " phoneId=" + phoneId + " callerUid=" + callerUid + " subId=" + subId + " phoneId=" + phoneId
+ " events=" + Integer.toHexString(events) + "}"; + " events=" + Integer.toHexString(events) + "}";
} }
@@ -125,8 +128,6 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
private final IBatteryStats mBatteryStats; private final IBatteryStats mBatteryStats;
private boolean hasNotifySubscriptionInfoChangedOccurred = false;
private int mNumPhones; private int mNumPhones;
private int[] mCallState; private int[] mCallState;
@@ -167,9 +168,9 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
private VoLteServiceState mVoLteServiceState = new VoLteServiceState(); private VoLteServiceState mVoLteServiceState = new VoLteServiceState();
private int mDefaultSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; private int mDefaultSubId = SubscriptionManager.INVALID_SUB_ID;
private int mDefaultPhoneId = SubscriptionManager.INVALID_PHONE_INDEX; private int mDefaultPhoneId = SubscriptionManager.INVALID_PHONE_ID;
private DataConnectionRealTimeInfo mDcRtInfo = new DataConnectionRealTimeInfo(); private DataConnectionRealTimeInfo mDcRtInfo = new DataConnectionRealTimeInfo();
@@ -226,7 +227,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
//possible missed notify callback //possible missed notify callback
synchronized (mRecords) { synchronized (mRecords) {
for (Record r : mRecords) { for (Record r : mRecords) {
if(r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) { if(r.subId == SubscriptionManager.DEFAULT_SUB_ID) {
checkPossibleMissNotify(r, newDefaultPhoneId); checkPossibleMissNotify(r, newDefaultPhoneId);
} }
} }
@@ -338,85 +339,90 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
} }
@Override @Override
public void registerOnSubscriptionsChangedListener(String pkgForDebug, public void registerSubscriptionListener(String pkgForDebug, ISubscriptionListener callback,
IOnSubscriptionsChangedListener callback) { int events) {
int callerUid = UserHandle.getCallingUserId(); int callerUid = UserHandle.getCallingUserId();
int myUid = UserHandle.myUserId(); int myUid = UserHandle.myUserId();
if (VDBG) { if (VDBG) {
log("listen oscl: E pkg=" + pkgForDebug + " myUid=" + myUid log("listen sl: E pkg=" + pkgForDebug + " events=0x" + Integer.toHexString(events)
+ " callerUid=" + callerUid + " callback=" + callback + " myUid=" + myUid + " callerUid=" + callerUid + " callback=" + callback
+ " callback.asBinder=" + callback.asBinder()); + " callback.asBinder=" + callback.asBinder());
} }
/* Checks permission and throws Security exception */ if (events != 0) {
checkOnSubscriptionsChangedListenerPermission(); /* Checks permission and throws Security exception */
Record r = null; checkSubscriptionListenerPermission(events);
Record r = null;
synchronized (mRecords) { synchronized (mRecords) {
// register // register
find_and_add: { find_and_add: {
IBinder b = callback.asBinder(); IBinder b = callback.asBinder();
final int N = mRecords.size(); final int N = mRecords.size();
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
r = mRecords.get(i); r = mRecords.get(i);
if (b == r.binder) { if (b == r.binder) {
break find_and_add; break find_and_add;
}
} }
r = new Record();
r.binder = b;
mRecords.add(r);
if (DBG) log("listen sl: add new record");
}
r.subscriptionListenerCallback = callback;
r.pkgForDebug = pkgForDebug;
r.callerUid = callerUid;
r.events = events;
if (DBG) {
log("listen sl: Register r=" + r);
} }
r = new Record();
r.binder = b;
mRecords.add(r);
if (DBG) log("listen oscl: add new record");
} }
r.onSubscriptionsChangedListenerCallback = callback; // Always notify when a listen is established.
r.pkgForDebug = pkgForDebug; if (r.matchSubscriptionListenerEvent(
r.callerUid = callerUid; SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED)) {
r.events = 0;
if (DBG) {
log("listen oscl: Register r=" + r);
}
// Always notify when registration occurs if there has been a notification.
if (hasNotifySubscriptionInfoChangedOccurred) {
try { try {
if (VDBG) log("listen oscl: send to r=" + r); if (VDBG) log("listen sl: send to r=" + r);
r.onSubscriptionsChangedListenerCallback.onSubscriptionsChanged(); r.subscriptionListenerCallback.onSubscriptionInfoChanged();
if (VDBG) log("listen oscl: sent to r=" + r); if (VDBG) log("listen sl: sent to r=" + r);
} catch (RemoteException e) { } catch (RemoteException e) {
if (VDBG) log("listen oscl: remote exception sending to r=" + r + " e=" + e); if (VDBG) log("listen sl: remote exception sending to r=" + r + " e=" + e);
remove(r.binder); remove(r.binder);
} }
} else {
log("listen oscl: hasNotifySubscriptionInfoChangedOccurred==false no callback");
} }
} else {
if (DBG) log("listen sl: Unregister as event is LISTEN_NONE");
unregisterSubscriptionListener(pkgForDebug, callback);
} }
} }
@Override @Override
public void unregisterOnSubscriptionsChangedListener(String pkgForDebug, public void unregisterSubscriptionListener(String pkgForDebug, ISubscriptionListener callback) {
IOnSubscriptionsChangedListener callback) { if (DBG) log("listen sl: Unregister as event is LISTEN_NONE");
if (DBG) log("listen oscl: Unregister");
remove(callback.asBinder()); remove(callback.asBinder());
} }
private void checkOnSubscriptionsChangedListenerPermission() { private void checkSubscriptionListenerPermission(int events) {
mContext.enforceCallingOrSelfPermission( if ((events & SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED) != 0) {
SubscriptionManager.OnSubscriptionsChangedListener mContext.enforceCallingOrSelfPermission(
.PERMISSION_ON_SUBSCRIPTIONS_CHANGED, null); SubscriptionListener.PERMISSION_LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED, null);
}
} }
@Override @Override
public void notifySubscriptionInfoChanged() { public void notifySubscriptionInfoChanged() {
if (VDBG) log("notifySubscriptionInfoChanged:"); if (VDBG) log("notifySubscriptionInfoChanged:");
synchronized (mRecords) { synchronized (mRecords) {
hasNotifySubscriptionInfoChangedOccurred = true;
mRemoveList.clear(); mRemoveList.clear();
for (Record r : mRecords) { for (Record r : mRecords) {
if (r.matchOnSubscriptionsChangedListener()) { if (r.matchSubscriptionListenerEvent(
SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED)) {
try { try {
if (VDBG) log("notifySubscriptionInfoChanged: call osc to r=" + r); if (VDBG) log("notifySubscriptionInfoChanged: send to r=" + r);
r.onSubscriptionsChangedListenerCallback.onSubscriptionsChanged(); r.subscriptionListenerCallback.onSubscriptionInfoChanged();
if (VDBG) log("notifySubscriptionInfoChanged: call osc to r=" + r); if (VDBG) log("notifySubscriptionInfoChanged: sent to r=" + r);
} catch (RemoteException ex) { } catch (RemoteException ex) {
if (VDBG) log("notifySubscriptionInfoChanged: RemoteException r=" + r); if (VDBG) log("notifySubscriptionInfoChanged: RemoteException r=" + r);
mRemoveList.add(r.binder); mRemoveList.add(r.binder);
@@ -430,8 +436,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
@Override @Override
public void listen(String pkgForDebug, IPhoneStateListener callback, int events, public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
boolean notifyNow) { boolean notifyNow) {
listenForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, pkgForDebug, callback, listenForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, pkgForDebug, callback, events,
events, notifyNow); notifyNow);
} }
@Override @Override
@@ -477,7 +483,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
// Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID, // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID,
// force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID // force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID
if (!SubscriptionManager.isValidSubId(subId)) { if (!SubscriptionManager.isValidSubId(subId)) {
r.subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; r.subId = SubscriptionManager.DEFAULT_SUB_ID;
} else {//APP specify subID } else {//APP specify subID
r.subId = subId; r.subId = subId;
} }
@@ -636,7 +642,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
synchronized (mRecords) { synchronized (mRecords) {
for (Record r : mRecords) { for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) && if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) &&
(r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) { (r.subId == SubscriptionManager.DEFAULT_SUB_ID)) {
try { try {
r.callback.onCallStateChanged(state, incomingNumber); r.callback.onCallStateChanged(state, incomingNumber);
} catch (RemoteException ex) { } catch (RemoteException ex) {
@@ -646,8 +652,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
} }
handleRemoveListLocked(); handleRemoveListLocked();
} }
broadcastCallStateChanged(state, incomingNumber, broadcastCallStateChanged(state, incomingNumber, SubscriptionManager.DEFAULT_SUB_ID);
SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
} }
public void notifyCallStateForSubscriber(int subId, int state, String incomingNumber) { public void notifyCallStateForSubscriber(int subId, int state, String incomingNumber) {
@@ -666,7 +671,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
for (Record r : mRecords) { for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) && if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) &&
(r.subId == subId) && (r.subId == subId) &&
(r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) { (r.subId != SubscriptionManager.DEFAULT_SUB_ID)) {
try { try {
r.callback.onCallStateChanged(state, incomingNumber); r.callback.onCallStateChanged(state, incomingNumber);
} catch (RemoteException ex) { } catch (RemoteException ex) {
@@ -723,8 +728,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
} }
public void notifySignalStrength(SignalStrength signalStrength) { public void notifySignalStrength(SignalStrength signalStrength) {
notifySignalStrengthForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, notifySignalStrengthForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, signalStrength);
signalStrength);
} }
public void notifySignalStrengthForSubscriber(int subId, SignalStrength signalStrength) { public void notifySignalStrengthForSubscriber(int subId, SignalStrength signalStrength) {
@@ -785,7 +789,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
} }
public void notifyCellInfo(List<CellInfo> cellInfo) { public void notifyCellInfo(List<CellInfo> cellInfo) {
notifyCellInfoForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellInfo); notifyCellInfoForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, cellInfo);
} }
public void notifyCellInfoForSubscriber(int subId, List<CellInfo> cellInfo) { public void notifyCellInfoForSubscriber(int subId, List<CellInfo> cellInfo) {
@@ -873,7 +877,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
} }
public void notifyCallForwardingChanged(boolean cfi) { public void notifyCallForwardingChanged(boolean cfi) {
notifyCallForwardingChangedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cfi); notifyCallForwardingChangedForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, cfi);
} }
public void notifyCallForwardingChangedForSubscriber(int subId, boolean cfi) { public void notifyCallForwardingChangedForSubscriber(int subId, boolean cfi) {
@@ -905,7 +909,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
} }
public void notifyDataActivity(int state) { public void notifyDataActivity(int state) {
notifyDataActivityForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state); notifyDataActivityForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, state);
} }
public void notifyDataActivityForSubscriber(int subId, int state) { public void notifyDataActivityForSubscriber(int subId, int state) {
@@ -914,15 +918,13 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
} }
synchronized (mRecords) { synchronized (mRecords) {
int phoneId = SubscriptionManager.getPhoneId(subId); int phoneId = SubscriptionManager.getPhoneId(subId);
if (validatePhoneId(phoneId)) { mDataActivity[phoneId] = state;
mDataActivity[phoneId] = state; for (Record r : mRecords) {
for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_DATA_ACTIVITY)) {
if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_DATA_ACTIVITY)) { try {
try { r.callback.onDataActivity(state);
r.callback.onDataActivity(state); } catch (RemoteException ex) {
} catch (RemoteException ex) { mRemoveList.add(r.binder);
mRemoveList.add(r.binder);
}
} }
} }
} }
@@ -933,7 +935,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
public void notifyDataConnection(int state, boolean isDataConnectivityPossible, public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
String reason, String apn, String apnType, LinkProperties linkProperties, String reason, String apn, String apnType, LinkProperties linkProperties,
NetworkCapabilities networkCapabilities, int networkType, boolean roaming) { NetworkCapabilities networkCapabilities, int networkType, boolean roaming) {
notifyDataConnectionForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state, notifyDataConnectionForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, state,
isDataConnectivityPossible,reason, apn, apnType, linkProperties, isDataConnectivityPossible,reason, apn, apnType, linkProperties,
networkCapabilities, networkType, roaming); networkCapabilities, networkType, roaming);
} }
@@ -954,69 +956,67 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
} }
synchronized (mRecords) { synchronized (mRecords) {
int phoneId = SubscriptionManager.getPhoneId(subId); int phoneId = SubscriptionManager.getPhoneId(subId);
if (validatePhoneId(phoneId)) { boolean modified = false;
boolean modified = false; if (state == TelephonyManager.DATA_CONNECTED) {
if (state == TelephonyManager.DATA_CONNECTED) { if (!mConnectedApns.contains(apnType)) {
if (!mConnectedApns.contains(apnType)) { mConnectedApns.add(apnType);
mConnectedApns.add(apnType); if (mDataConnectionState[phoneId] != state) {
if (mDataConnectionState[phoneId] != state) { mDataConnectionState[phoneId] = state;
mDataConnectionState[phoneId] = state; modified = true;
modified = true;
}
}
} else {
if (mConnectedApns.remove(apnType)) {
if (mConnectedApns.isEmpty()) {
mDataConnectionState[phoneId] = state;
modified = true;
} else {
// leave mDataConnectionState as is and
// send out the new status for the APN in question.
}
} }
} }
mDataConnectionPossible[phoneId] = isDataConnectivityPossible; } else {
mDataConnectionReason[phoneId] = reason; if (mConnectedApns.remove(apnType)) {
mDataConnectionLinkProperties[phoneId] = linkProperties; if (mConnectedApns.isEmpty()) {
mDataConnectionNetworkCapabilities[phoneId] = networkCapabilities; mDataConnectionState[phoneId] = state;
if (mDataConnectionNetworkType[phoneId] != networkType) { modified = true;
mDataConnectionNetworkType[phoneId] = networkType; } else {
// need to tell registered listeners about the new network type // leave mDataConnectionState as is and
modified = true; // send out the new status for the APN in question.
}
if (modified) {
if (DBG) {
log("onDataConnectionStateChanged(" + mDataConnectionState[phoneId]
+ ", " + mDataConnectionNetworkType[phoneId] + ")");
} }
for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent(
PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) &&
idMatch(r.subId, subId, phoneId)) {
try {
log("Notify data connection state changed on sub: " +
subId);
r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId],
mDataConnectionNetworkType[phoneId]);
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
}
}
handleRemoveListLocked();
} }
mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType, }
apnType, apn, reason, linkProperties, ""); mDataConnectionPossible[phoneId] = isDataConnectivityPossible;
mDataConnectionReason[phoneId] = reason;
mDataConnectionLinkProperties[phoneId] = linkProperties;
mDataConnectionNetworkCapabilities[phoneId] = networkCapabilities;
if (mDataConnectionNetworkType[phoneId] != networkType) {
mDataConnectionNetworkType[phoneId] = networkType;
// need to tell registered listeners about the new network type
modified = true;
}
if (modified) {
if (DBG) {
log("onDataConnectionStateChanged(" + mDataConnectionState[phoneId]
+ ", " + mDataConnectionNetworkType[phoneId] + ")");
}
for (Record r : mRecords) { for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent( if (r.matchPhoneStateListenerEvent(
PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) { PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) &&
idMatch(r.subId, subId, phoneId)) {
try { try {
r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState); log("Notify data connection state changed on sub: " +
subId);
r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId],
mDataConnectionNetworkType[phoneId]);
} catch (RemoteException ex) { } catch (RemoteException ex) {
mRemoveList.add(r.binder); mRemoveList.add(r.binder);
} }
} }
} }
handleRemoveListLocked();
}
mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType,
apnType, apn, reason, linkProperties, "");
for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent(
PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) {
try {
r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
}
} }
handleRemoveListLocked(); handleRemoveListLocked();
} }
@@ -1027,7 +1027,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
} }
public void notifyDataConnectionFailed(String reason, String apnType) { public void notifyDataConnectionFailed(String reason, String apnType) {
notifyDataConnectionFailedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, notifyDataConnectionFailedForSubscriber(SubscriptionManager.DEFAULT_SUB_ID,
reason, apnType); reason, apnType);
} }
@@ -1062,7 +1062,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
} }
public void notifyCellLocation(Bundle cellLocation) { public void notifyCellLocation(Bundle cellLocation) {
notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellLocation); notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, cellLocation);
} }
public void notifyCellLocationForSubscriber(int subId, Bundle cellLocation) { public void notifyCellLocationForSubscriber(int subId, Bundle cellLocation) {
@@ -1226,7 +1226,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
if ((r.matchPhoneStateListenerEvent( if ((r.matchPhoneStateListenerEvent(
PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT)) && PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT)) &&
((r.subId == subId) || ((r.subId == subId) ||
(r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID))) { (r.subId == SubscriptionManager.DEFAULT_SUB_ID))) {
try { try {
r.callback.onOemHookRawEvent(rawData); r.callback.onOemHookRawEvent(rawData);
} catch (RemoteException ex) { } catch (RemoteException ex) {
@@ -1399,17 +1399,14 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
} }
private void broadcastPreciseDataConnectionStateChanged(int state, int networkType, private void broadcastPreciseDataConnectionStateChanged(int state, int networkType,
String apnType, String apn, String reason, LinkProperties linkProperties, String apnType, String apn, String reason, LinkProperties linkProperties, String failCause) {
String failCause) {
Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED); Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED);
intent.putExtra(PhoneConstants.STATE_KEY, state); intent.putExtra(PhoneConstants.STATE_KEY, state);
intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType); intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType);
if (reason != null) intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason); if (reason != null) intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason);
if (apnType != null) intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); if (apnType != null) intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
if (apn != null) intent.putExtra(PhoneConstants.DATA_APN_KEY, apn); if (apn != null) intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
if (linkProperties != null) { if (linkProperties != null) intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY,linkProperties);
}
if (failCause != null) intent.putExtra(PhoneConstants.DATA_FAILURE_CAUSE_KEY, failCause); if (failCause != null) intent.putExtra(PhoneConstants.DATA_FAILURE_CAUSE_KEY, failCause);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL, mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
@@ -1509,8 +1506,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
@Override @Override
public String toString() { public String toString() {
return mS + " Time " + mTime.toString() + " mSubId " + mSubId + " mPhoneId " return mS + " Time " + mTime.toString() + " mSubId " + mSubId + " mPhoneId " + mPhoneId + " mState " + mState;
+ mPhoneId + " mState " + mState;
} }
} }
@@ -1554,7 +1550,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
} }
boolean idMatch(int rSubId, int subId, int phoneId) { boolean idMatch(int rSubId, int subId, int phoneId) {
if(rSubId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) { if(rSubId == SubscriptionManager.DEFAULT_SUB_ID) {
if(subId < 0) { if(subId < 0) {
// Invalid case, we need compare phoneId with default one. // Invalid case, we need compare phoneId with default one.
return (mDefaultPhoneId == phoneId); return (mDefaultPhoneId == phoneId);

View File

@@ -73,8 +73,8 @@ import android.provider.Telephony.Carriers;
import android.provider.Telephony.Sms.Intents; import android.provider.Telephony.Sms.Intents;
import android.telephony.SmsMessage; import android.telephony.SmsMessage;
import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionListener;
import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation; import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils; import android.text.TextUtils;
@@ -462,10 +462,9 @@ public class GpsLocationProvider implements LocationProviderInterface {
} }
}; };
private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener = private final SubscriptionListener mSubscriptionListener = new SubscriptionListener() {
new OnSubscriptionsChangedListener() {
@Override @Override
public void onSubscriptionsChanged() { public void onSubscriptionInfoChanged() {
subscriptionOrSimChanged(mContext); subscriptionOrSimChanged(mContext);
} }
}; };
@@ -641,14 +640,14 @@ public class GpsLocationProvider implements LocationProviderInterface {
mSuplEsEnabled); mSuplEsEnabled);
// TODO: When this object "finishes" we should unregister by invoking // TODO: When this object "finishes" we should unregister by invoking
// SubscriptionManager.getInstance(mContext).unregister(mOnSubscriptionsChangedListener); // SubscriptionManager.unregister(mContext, mSubscriptionListener);
// This is not strictly necessary because it will be unregistered if the // This is not strictly necessary because it will be unregistered if the
// notification fails but it is good form. // notification fails but it is good form.
// Register for SubscriptionInfo list changes which is guaranteed // Register for SubscriptionInfo list changes which is guaranteed
// to invoke onSubscriptionsChanged the first time. // to invoke onSubscriptionInfoChanged the first time.
SubscriptionManager.from(mContext) SubscriptionManager.register(mContext, mSubscriptionListener,
.registerOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener); SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED);
// construct handler, listen for events // construct handler, listen for events
mHandler = new ProviderHandler(looper); mHandler = new ProviderHandler(looper);

View File

@@ -227,7 +227,7 @@ public class PhoneStateListener {
* @hide * @hide
*/ */
/** @hide */ /** @hide */
protected int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; protected int mSubId = SubscriptionManager.INVALID_SUB_ID;
private final Handler mHandler; private final Handler mHandler;
@@ -237,7 +237,7 @@ public class PhoneStateListener {
* own non-null looper use PhoneStateListener(Looper looper) below. * own non-null looper use PhoneStateListener(Looper looper) below.
*/ */
public PhoneStateListener() { public PhoneStateListener() {
this(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, Looper.myLooper()); this(SubscriptionManager.DEFAULT_SUB_ID, Looper.myLooper());
} }
/** /**
@@ -246,7 +246,7 @@ public class PhoneStateListener {
* @hide * @hide
*/ */
public PhoneStateListener(Looper looper) { public PhoneStateListener(Looper looper) {
this(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, looper); this(SubscriptionManager.DEFAULT_SUB_ID, looper);
} }
/** /**

View File

@@ -0,0 +1,125 @@
/*
* Copyright (C) 2014 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 android.telephony;
import com.android.internal.telephony.ISub;
import com.android.internal.telephony.ISubscriptionListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.telephony.Rlog;
import java.util.List;
/**
* A listener class for monitoring changes to Subscription state
* changes on the device.
* <p>
* Override the onXxxx methods in this class and passing to the listen method
* bitwise-or of the corresponding LISTEN_Xxxx bit flags below.
* <p>
* Note that access to some of the information is permission-protected. Your
* application won't receive updates for protected information unless it has
* the appropriate permissions declared in its manifest file. Where permissions
* apply, they are noted in the appropriate LISTEN_ flags.
*/
public class SubscriptionListener {
private static final String LOG_TAG = "SubscriptionListener";
private static final boolean DBG = false; // STOPSHIP if true
/**
* Permission for LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED
*
* @hide
*/
public static final String PERMISSION_LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED =
android.Manifest.permission.READ_PHONE_STATE;
/**
* Listen for changes to the SubscriptionInoList when listening for this event
* it is guaranteed that on #onSubscriptionInfoChanged will be invoked. This initial
* invocation should be used to call SubscriptionManager.getActiveSubscriptionInfoList()
* to get the initial list.
*
* Permissions: android.Manifest.permission.READ_PHONE_STATE
* @see #onSubscriptionInfoChanged
*/
public static final int LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED = 0x00000001;
private final Handler mHandler;
/**
* Create a SubscriptionLitener for the device.
*
* This class requires Looper.myLooper() not return null. To supply your
* own non-null looper use PhoneStateListener(Looper looper) below.
*/
public SubscriptionListener() {
this(Looper.myLooper());
}
/**
* Create a PhoneStateListener for the Phone using the specified subscription
* and non-null Looper.
*/
public SubscriptionListener(Looper looper) {
if (DBG) log("ctor: looper=" + looper);
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
mHandler = new Handler(looper) {
@Override
public void handleMessage(Message msg) {
if (DBG) {
log("what=0x" + Integer.toHexString(msg.what) + " msg=" + msg);
}
switch (msg.what) {
case LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED:
SubscriptionListener.this.onSubscriptionInfoChanged();
break;
}
}
};
}
/**
* Callback invoked when there is any change to any SubscriptionInfo.
*/
public void onSubscriptionInfoChanged() {
// default implementation empty
}
/**
* The callback methods need to be called on the handler thread where
* this object was created. If the binder did that for us it'd be nice.
*/
ISubscriptionListener callback = new ISubscriptionListener.Stub() {
@Override
public void onSubscriptionInfoChanged() {
Message msg = Message.obtain(mHandler, LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED);
msg.sendToTarget();
}
};
private void log(String s) {
Rlog.d(LOG_TAG, s);
}
}

View File

@@ -21,14 +21,12 @@ import android.annotation.SdkConstant.SdkConstantType;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.provider.BaseColumns;
import android.telephony.Rlog; import android.telephony.Rlog;
import android.os.Handler;
import android.os.Message;
import android.os.ServiceManager; import android.os.ServiceManager;
import android.os.RemoteException; import android.os.RemoteException;
import com.android.internal.telephony.ISub; import com.android.internal.telephony.ISub;
import com.android.internal.telephony.IOnSubscriptionsChangedListener;
import com.android.internal.telephony.ITelephonyRegistry; import com.android.internal.telephony.ITelephonyRegistry;
import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.PhoneConstants;
@@ -38,79 +36,62 @@ import java.util.List;
/** /**
* SubscriptionManager is the application interface to SubscriptionController * SubscriptionManager is the application interface to SubscriptionController
* and provides information about the current Telephony Subscriptions. * and provides information about the current Telephony Subscriptions.
* * <p> *
* You do not instantiate this class directly; instead, you retrieve * The android.Manifest.permission.READ_PHONE_STATE to retrieve the information, except
* a reference to an instance through {@link #from}. * getActiveSubIdList and getActiveSubIdCount for which no permission is needed.
* <p>
* All SDK public methods require android.Manifest.permission.READ_PHONE_STATE.
*/ */
public class SubscriptionManager { public class SubscriptionManager implements BaseColumns {
private static final String LOG_TAG = "SubscriptionManager"; private static final String LOG_TAG = "SUB";
private static final boolean DBG = true; private static final boolean DBG = true;
private static final boolean VDBG = false; private static final boolean VDBG = false;
/** An invalid subscription identifier */ /** An invalid subscription identifier */
public static final int INVALID_SUBSCRIPTION_ID = -1; public static final int INVALID_SUB_ID = -1000;
/** Base value for Dummy SUBSCRIPTION_ID's. */
/** FIXME: Remove DummySubId's, but for now have them map just below INVALID_SUBSCRIPTION_ID
/** @hide */
public static final int DUMMY_SUBSCRIPTION_ID_BASE = INVALID_SUBSCRIPTION_ID - 1;
/** An invalid phone identifier */ /** An invalid phone identifier */
/** @hide */ /** @hide */
public static final int INVALID_PHONE_INDEX = -1; public static final int INVALID_PHONE_ID = -1;
/** An invalid slot identifier */ /** An invalid slot identifier */
/** @hide */ /** @hide */
public static final int INVALID_SIM_SLOT_INDEX = -1; public static final int INVALID_SLOT_ID = -1;
/** Indicates the caller wants the default sub id. */ /** Indicates the caller wants the default sub id. */
/** @hide */ /** @hide */
public static final int DEFAULT_SUBSCRIPTION_ID = Integer.MAX_VALUE; public static final int DEFAULT_SUB_ID = Integer.MAX_VALUE;
/** /** Indicates the caller wants the default phone id. */
* Indicates the caller wants the default phone id.
* Used in SubscriptionController and PhoneBase but do we really need it???
* @hide
*/
public static final int DEFAULT_PHONE_INDEX = Integer.MAX_VALUE;
/** Indicates the caller wants the default slot id. NOT used remove? */
/** @hide */ /** @hide */
public static final int DEFAULT_SIM_SLOT_INDEX = Integer.MAX_VALUE; public static final int DEFAULT_PHONE_ID = Integer.MAX_VALUE;
/** Indicates the caller wants the default slot id. */
/** @hide */
public static final int DEFAULT_SLOT_ID = Integer.MAX_VALUE;
/** Minimum possible subid that represents a subscription */ /** Minimum possible subid that represents a subscription */
/** @hide */ /** @hide */
public static final int MIN_SUBSCRIPTION_ID_VALUE = 0; public static final int MIN_SUB_ID_VALUE = 0;
/** Maximum possible subid that represents a subscription */ /** Maximum possible subid that represents a subscription */
/** @hide */ /** @hide */
public static final int MAX_SUBSCRIPTION_ID_VALUE = DEFAULT_SUBSCRIPTION_ID - 1; public static final int MAX_SUB_ID_VALUE = DEFAULT_SUB_ID - 1;
/** @hide */ /** @hide */
public static final Uri CONTENT_URI = Uri.parse("content://telephony/siminfo"); public static final Uri CONTENT_URI = Uri.parse("content://telephony/siminfo");
/** /**
* TelephonyProvider unique key column name is the subscription id. * The ICC ID of a SIM.
* <P>Type: TEXT (String)</P>
*/
/** @hide */
public static final String UNIQUE_KEY_SUBSCRIPTION_ID = "_id";
/**
* TelephonyProvider column name for SIM ICC Identifier
* <P>Type: TEXT (String)</P> * <P>Type: TEXT (String)</P>
*/ */
/** @hide */ /** @hide */
public static final String ICC_ID = "icc_id"; public static final String ICC_ID = "icc_id";
/** /**
* TelephonyProvider column name for user SIM_SlOT_INDEX
* <P>Type: INTEGER (int)</P> * <P>Type: INTEGER (int)</P>
*/ */
/** @hide */ /** @hide */
public static final String SIM_SLOT_INDEX = "sim_id"; public static final String SIM_ID = "sim_id";
/** SIM is not inserted */ /** SIM is not inserted */
/** @hide */ /** @hide */
@@ -249,107 +230,39 @@ public class SubscriptionManager {
/** /**
* Broadcast Action: The user has changed one of the default subs related to * Broadcast Action: The user has changed one of the default subs related to
* data, phone calls, or sms</p> * data, phone calls, or sms</p>
*
* TODO: Change to a listener
* @hide * @hide
*/ */
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String SUB_DEFAULT_CHANGED_ACTION = public static final String SUB_DEFAULT_CHANGED_ACTION =
"android.intent.action.SUB_DEFAULT_CHANGED"; "android.intent.action.SUB_DEFAULT_CHANGED";
private final Context mContext;
/**
* A listener class for monitoring changes to {@link SubscriptionInfo} records.
* <p>
* Override the onSubscriptionsChanged method in the object that extends this
* class and pass it to {@link #registerOnSubscriptionsChangedListener(OnSubscriptionsChangedListener)}
* to register your listener and to unregister invoke
* {@link #unregisterOnSubscriptionsChangedListener(OnSubscriptionsChangedListener)}
* <p>
* Permissions android.Manifest.permission.READ_PHONE_STATE is required
* for #onSubscriptionsChanged to be invoked.
*/
public static class OnSubscriptionsChangedListener {
/** @hide */
public static final String PERMISSION_ON_SUBSCRIPTIONS_CHANGED =
android.Manifest.permission.READ_PHONE_STATE;
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (DBG) {
log("handleMessage: invoke the overriden onSubscriptionsChanged()");
}
OnSubscriptionsChangedListener.this.onSubscriptionsChanged();
}
};
/**
* Callback invoked when there is any change to any SubscriptionInfo. Typically
* this method would invoke {@link #getActiveSubscriptionInfoList}
*/
public void onSubscriptionsChanged() {
if (DBG) log("onSubscriptionsChanged: NOT OVERRIDDEN");
}
/**
* The callback methods need to be called on the handler thread where
* this object was created. If the binder did that for us it'd be nice.
*/
IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() {
@Override
public void onSubscriptionsChanged() {
if (DBG) log("callbad: received, sendEmptyMessage(0) to handler");
mHandler.sendEmptyMessage(0);
}
};
private void log(String s) {
Rlog.d(LOG_TAG, s);
}
}
/** @hide */ /** @hide */
public SubscriptionManager(Context context) { public SubscriptionManager() {
if (DBG) logd("SubscriptionManager created"); if (DBG) logd("SubscriptionManager created");
mContext = context;
} }
/** /**
* Get an instance of the SubscriptionManager from the Context. * Register for changes to events defined by SubscriptionListener.LISTEN_Xxx. Some of
* This invokes {@link android.content.Context#getSystemService * the events will fire as registration completes, this could be before or after
* Context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)}. * this method returns.
* *
* @param context to use. * @param listener an instance of SubscriptionListner with overridden methods the
* @return SubscriptionManager instance * overridden method should match the bits defined in events.
* @param events is one or more of the SubscriptionListener.LISTEN_Xxx bits
*/ */
public static SubscriptionManager from(Context context) { public static void register(Context context, SubscriptionListener listener, int events) {
return (SubscriptionManager) context.getSystemService( String pkgForDebug = context != null ? context.getPackageName() : "<unknown>";
Context.TELEPHONY_SUBSCRIPTION_SERVICE);
}
/**
* Register for changes to the list of active {@link SubscriptionInfo} records or to the
* individual records themselves. When a change occurs the onSubscriptionsChanged method of
* the listener will be invoked immediately if there has been a notification.
*
* @param listener an instance of {@link OnSubscriptionsChangedListener} with
* onSubscriptionsChanged overridden.
*/
public void registerOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>";
if (DBG) { if (DBG) {
logd("register OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug logd("SubscriptionManager listen pkgForDebug=" + pkgForDebug
+ " listener=" + listener); + " events=0x" + Integer.toHexString(events) + " listener=" + listener);
} }
try { try {
// We use the TelephonyRegistry as it runs in the system and thus is always // We use the TelephonyRegistry as its runs in the system and thus is always
// available. Where as SubscriptionController could crash and not be available // available where as SubscriptionController could crash and not be available
ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
"telephony.registry")); "telephony.registry"));
if (tr != null) { if (tr != null) {
tr.registerOnSubscriptionsChangedListener(pkgForDebug, listener.callback); tr.registerSubscriptionListener(pkgForDebug, listener.callback, events);
} }
} catch (RemoteException ex) { } catch (RemoteException ex) {
// Should not happen // Should not happen
@@ -357,16 +270,15 @@ public class SubscriptionManager {
} }
/** /**
* Unregister the {@link OnSubscriptionsChangedListener}. This is not strictly necessary * Unregister the listener.
* as the listener will automatically be unregistered if an attempt to invoke the listener
* fails.
* *
* @param listener that is to be unregistered. * @param context
* @param listener
*/ */
public void unregisterOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) { public static void unregister(Context context, SubscriptionListener listener) {
String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>"; String pkgForDebug = context != null ? context.getPackageName() : "<unknown>";
if (DBG) { if (DBG) {
logd("unregister OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug logd("SubscriptionManager unregister pkgForDebug=" + pkgForDebug
+ " listener=" + listener); + " listener=" + listener);
} }
try { try {
@@ -375,7 +287,7 @@ public class SubscriptionManager {
ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
"telephony.registry")); "telephony.registry"));
if (tr != null) { if (tr != null) {
tr.unregisterOnSubscriptionsChangedListener(pkgForDebug, listener.callback); tr.unregisterSubscriptionListener(pkgForDebug, listener.callback);
} }
} catch (RemoteException ex) { } catch (RemoteException ex) {
// Should not happen // Should not happen
@@ -383,14 +295,13 @@ public class SubscriptionManager {
} }
/** /**
* Get the active SubscriptionInfo with the subId key * Get the SubscriptionInfo associated with the subId
* @param subId The unique SubscriptionInfo key in database * @param subId The unique SubscriptionInfo index in database
* @return SubscriptionInfo, maybe null if its not active. * @return SubscriptionInfo, maybe null
*/ */
public SubscriptionInfo getActiveSubscriptionInfo(int subId) { public static SubscriptionInfo getSubscriptionInfoForSubscriber(int subId) {
if (VDBG) logd("[getActiveSubscriptionInfo]+ subId=" + subId);
if (!isValidSubId(subId)) { if (!isValidSubId(subId)) {
logd("[getActiveSubscriptionInfo]- invalid subId"); logd("[getSubscriptionInfoForSubscriber]- invalid subId");
return null; return null;
} }
@@ -399,7 +310,7 @@ public class SubscriptionManager {
try { try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) { if (iSub != null) {
subInfo = iSub.getActiveSubscriptionInfo(subId); subInfo = iSub.getSubInfoForSubscriber(subId);
} }
} catch (RemoteException ex) { } catch (RemoteException ex) {
// ignore it // ignore it
@@ -410,64 +321,73 @@ public class SubscriptionManager {
} }
/** /**
* Get the active SubscriptionInfo associated with the iccId * Get the SubscriptionInfo according to an IccId
* @param iccId the IccId of SIM card * @param iccId the IccId of SIM card
* @return SubscriptionInfo, maybe null if its not active * @return SubscriptionInfo List, maybe empty but not null
* @hide * @hide
*/ */
public SubscriptionInfo getActiveSubscriptionInfoForIccIndex(String iccId) { public static List<SubscriptionInfo> getSubscriptionInfoUsingIccId(String iccId) {
if (VDBG) logd("[getActiveSubscriptionInfoForIccIndex]+ iccId=" + iccId); if (VDBG) logd("[getSubscriptionInfoUsingIccId]+ iccId=" + iccId);
if (iccId == null) { if (iccId == null) {
logd("[getActiveSubscriptionInfoForIccIndex]- null iccid"); logd("[getSubscriptionInfoUsingIccId]- null iccid");
return null; return null;
} }
SubscriptionInfo result = null; List<SubscriptionInfo> result = null;
try { try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) { if (iSub != null) {
result = iSub.getActiveSubscriptionInfoForIccId(iccId); result = iSub.getSubInfoUsingIccId(iccId);
} }
} catch (RemoteException ex) { } catch (RemoteException ex) {
// ignore it // ignore it
} }
if (result == null) {
result = new ArrayList<SubscriptionInfo>();
}
return result; return result;
} }
/** /**
* Get the active SubscriptionInfo associated with the slotIdx * Get the SubscriptionInfo according to slotId
* @param slotIdx the slot which the subscription is inserted * @param slotId the slot which the SIM is inserted
* @return SubscriptionInfo, maybe null if its not active * @return SubscriptionInfo list, maybe empty but not null
*/ */
public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIdx) { public static List<SubscriptionInfo> getSubscriptionInfoUsingSlotId(int slotId) {
if (VDBG) logd("[getActiveSubscriptionInfoForSimSlotIndex]+ slotIdx=" + slotIdx); // FIXME: Consider never returning null
if (!isValidSlotId(slotIdx)) { if (!isValidSlotId(slotId)) {
logd("[getActiveSubscriptionInfoForSimSlotIndex]- invalid slotIdx"); logd("[getSubscriptionInfoUsingSlotId]- invalid slotId");
return null; return null;
} }
SubscriptionInfo result = null; List<SubscriptionInfo> result = null;
try { try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) { if (iSub != null) {
result = iSub.getActiveSubscriptionInfoForSimSlotIndex(slotIdx); result = iSub.getSubInfoUsingSlotId(slotId);
} }
} catch (RemoteException ex) { } catch (RemoteException ex) {
// ignore it // ignore it
} }
if (result == null) {
result = new ArrayList<SubscriptionInfo>();
}
return result; return result;
} }
/** /**
* @return List of all SubscriptionInfo records in database, * Get all the SubscriptionInfo(s) in subInfo database
* include those that were inserted before, maybe empty but not null. * @return List of all SubscriptionInfos in database, include those that were inserted before
* maybe empty but not null.
* @hide * @hide
*/ */
public List<SubscriptionInfo> getAllSubscriptionInfoList() { public static List<SubscriptionInfo> getAllSubscriptionInfoList() {
if (VDBG) logd("[getAllSubscriptionInfoList]+"); if (VDBG) logd("[getAllSubscriptionInfoList]+");
List<SubscriptionInfo> result = null; List<SubscriptionInfo> result = null;
@@ -488,45 +408,33 @@ public class SubscriptionManager {
} }
/** /**
* Get the SubscriptionInfo(s) of the currently inserted SIM(s). The records will be sorted * Get the SubscriptionInfo(s) of the currently inserted SIM(s)
* by {@link SubscriptionInfo#getSimSlotIndex} then by {@link SubscriptionInfo#getSubscriptionId}. * @return Array list of currently inserted SubscriptionInfo(s) maybe empty but not null
*
* @return Sorted list of the currently {@link SubscriptionInfo} records available on the device.
* <ul>
* <li>
* If null is returned the current state is unknown but if a {@link OnSubscriptionsChangedListener}
* has been registered {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be
* invoked in the future.
* </li>
* <li>
* If the list is empty then there are no {@link SubscriptionInfo} records currently available.
* </li>
* <li>
* if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
* then by {@link SubscriptionInfo#getSubscriptionId}.
* </li>
* </ul>
*/ */
public List<SubscriptionInfo> getActiveSubscriptionInfoList() { public static List<SubscriptionInfo> getActiveSubscriptionInfoList() {
List<SubscriptionInfo> result = null; List<SubscriptionInfo> result = null;
try { try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) { if (iSub != null) {
result = iSub.getActiveSubscriptionInfoList(); result = iSub.getActiveSubInfoList();
} }
} catch (RemoteException ex) { } catch (RemoteException ex) {
// ignore it // ignore it
} }
if (result == null) {
result = new ArrayList<SubscriptionInfo>();
}
return result; return result;
} }
/** /**
* @return the count of all subscriptions in the database, this includes * Get the SUB count of all SUB(s) in subinfo database
* all subscriptions that have been seen. * @return all SIM count in database, include what was inserted before
* @hide * @hide
*/ */
public int getAllSubscriptionInfoCount() { public static int getAllSubscriptionInfoCount() {
if (VDBG) logd("[getAllSubscriptionInfoCount]+"); if (VDBG) logd("[getAllSubscriptionInfoCount]+");
int result = 0; int result = 0;
@@ -544,10 +452,11 @@ public class SubscriptionManager {
} }
/** /**
* @return the number of active subscriptions * Get the count of active SUB(s)
* @return active SIM count
* @hide * @hide
*/ */
public int getActiveSubscriptionInfoCount() { public static int getActiveSubscriptionInfoCount() {
int result = 0; int result = 0;
try { try {
@@ -562,25 +471,6 @@ public class SubscriptionManager {
return result; return result;
} }
/**
* @return the maximum number of subscriptions this device will support at any one time.
* @hide
*/
public int getActiveSubscriptionInfoCountMax() {
int result = 0;
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) {
result = iSub.getActiveSubInfoCountMax();
}
} catch (RemoteException ex) {
// ignore it
}
return result;
}
/** /**
* Add a new SubscriptionInfo to subinfo database if needed * Add a new SubscriptionInfo to subinfo database if needed
* @param iccId the IccId of the SIM card * @param iccId the IccId of the SIM card
@@ -588,7 +478,7 @@ public class SubscriptionManager {
* @return the URL of the newly created row or the updated row * @return the URL of the newly created row or the updated row
* @hide * @hide
*/ */
public Uri addSubscriptionInfoRecord(String iccId, int slotId) { public static Uri addSubscriptionInfoRecord(String iccId, int slotId) {
if (VDBG) logd("[addSubscriptionInfoRecord]+ iccId:" + iccId + " slotId:" + slotId); if (VDBG) logd("[addSubscriptionInfoRecord]+ iccId:" + iccId + " slotId:" + slotId);
if (iccId == null) { if (iccId == null) {
logd("[addSubscriptionInfoRecord]- null iccId"); logd("[addSubscriptionInfoRecord]- null iccId");
@@ -619,7 +509,7 @@ public class SubscriptionManager {
* @return the number of records updated * @return the number of records updated
* @hide * @hide
*/ */
public int setIconTint(int tint, int subId) { public static int setIconTint(int tint, int subId) {
if (VDBG) logd("[setIconTint]+ tint:" + tint + " subId:" + subId); if (VDBG) logd("[setIconTint]+ tint:" + tint + " subId:" + subId);
if (!isValidSubId(subId)) { if (!isValidSubId(subId)) {
logd("[setIconTint]- fail"); logd("[setIconTint]- fail");
@@ -648,7 +538,7 @@ public class SubscriptionManager {
* @return the number of records updated * @return the number of records updated
* @hide * @hide
*/ */
public int setDisplayName(String displayName, int subId) { public static int setDisplayName(String displayName, int subId) {
return setDisplayName(displayName, subId, NAME_SOURCE_UNDEFINDED); return setDisplayName(displayName, subId, NAME_SOURCE_UNDEFINDED);
} }
@@ -661,7 +551,7 @@ public class SubscriptionManager {
* @return the number of records updated or -1 if invalid subId * @return the number of records updated or -1 if invalid subId
* @hide * @hide
*/ */
public int setDisplayName(String displayName, int subId, long nameSource) { public static int setDisplayName(String displayName, int subId, long nameSource) {
if (VDBG) { if (VDBG) {
logd("[setDisplayName]+ displayName:" + displayName + " subId:" + subId logd("[setDisplayName]+ displayName:" + displayName + " subId:" + subId
+ " nameSource:" + nameSource); + " nameSource:" + nameSource);
@@ -693,7 +583,7 @@ public class SubscriptionManager {
* @return the number of records updated * @return the number of records updated
* @hide * @hide
*/ */
public int setDisplayNumber(String number, int subId) { public static int setDisplayNumber(String number, int subId) {
if (number == null || !isValidSubId(subId)) { if (number == null || !isValidSubId(subId)) {
logd("[setDisplayNumber]- fail"); logd("[setDisplayNumber]- fail");
return -1; return -1;
@@ -721,7 +611,7 @@ public class SubscriptionManager {
* @return the number of records updated * @return the number of records updated
* @hide * @hide
*/ */
public int setDataRoaming(int roaming, int subId) { public static int setDataRoaming(int roaming, int subId) {
if (VDBG) logd("[setDataRoaming]+ roaming:" + roaming + " subId:" + subId); if (VDBG) logd("[setDataRoaming]+ roaming:" + roaming + " subId:" + subId);
if (roaming < 0 || !isValidSubId(subId)) { if (roaming < 0 || !isValidSubId(subId)) {
logd("[setDataRoaming]- fail"); logd("[setDataRoaming]- fail");
@@ -753,7 +643,7 @@ public class SubscriptionManager {
logd("[getSlotId]- fail"); logd("[getSlotId]- fail");
} }
int result = INVALID_SIM_SLOT_INDEX; int result = INVALID_SLOT_ID;
try { try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -793,10 +683,10 @@ public class SubscriptionManager {
public static int getPhoneId(int subId) { public static int getPhoneId(int subId) {
if (!isValidSubId(subId)) { if (!isValidSubId(subId)) {
logd("[getPhoneId]- fail"); logd("[getPhoneId]- fail");
return INVALID_PHONE_INDEX; return INVALID_PHONE_ID;
} }
int result = INVALID_PHONE_INDEX; int result = INVALID_PHONE_ID;
try { try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -813,7 +703,7 @@ public class SubscriptionManager {
} }
private static void logd(String msg) { private static void logd(String msg) {
Rlog.d(LOG_TAG, msg); Rlog.d(LOG_TAG, "[SubManager] " + msg);
} }
/** /**
@@ -823,7 +713,7 @@ public class SubscriptionManager {
* @hide * @hide
*/ */
public static int getDefaultSubId() { public static int getDefaultSubId() {
int subId = INVALID_SUBSCRIPTION_ID; int subId = INVALID_SUB_ID;
try { try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -840,7 +730,7 @@ public class SubscriptionManager {
/** @hide */ /** @hide */
public static int getDefaultVoiceSubId() { public static int getDefaultVoiceSubId() {
int subId = INVALID_SUBSCRIPTION_ID; int subId = INVALID_SUB_ID;
try { try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -856,7 +746,7 @@ public class SubscriptionManager {
} }
/** @hide */ /** @hide */
public void setDefaultVoiceSubId(int subId) { public static void setDefaultVoiceSubId(int subId) {
if (VDBG) logd("setDefaultVoiceSubId sub id = " + subId); if (VDBG) logd("setDefaultVoiceSubId sub id = " + subId);
try { try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -869,8 +759,8 @@ public class SubscriptionManager {
} }
/** @hide */ /** @hide */
public SubscriptionInfo getDefaultVoiceSubscriptionInfo() { public static SubscriptionInfo getDefaultVoiceSubscriptionInfo() {
return getActiveSubscriptionInfo(getDefaultVoiceSubId()); return getSubscriptionInfoForSubscriber(getDefaultVoiceSubId());
} }
/** @hide */ /** @hide */
@@ -879,13 +769,11 @@ public class SubscriptionManager {
} }
/** /**
* @return subId of the DefaultSms subscription or * @return subId of the DefaultSms subscription or the value INVALID_SUB_ID if an error.
* the value INVALID_SUBSCRIPTION_ID if an error.
*
* @hide * @hide
*/ */
public static int getDefaultSmsSubId() { public static int getDefaultSmsSubId() {
int subId = INVALID_SUBSCRIPTION_ID; int subId = INVALID_SUB_ID;
try { try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -901,7 +789,7 @@ public class SubscriptionManager {
} }
/** @hide */ /** @hide */
public void setDefaultSmsSubId(int subId) { public static void setDefaultSmsSubId(int subId) {
if (VDBG) logd("setDefaultSmsSubId sub id = " + subId); if (VDBG) logd("setDefaultSmsSubId sub id = " + subId);
try { try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -914,18 +802,18 @@ public class SubscriptionManager {
} }
/** @hide */ /** @hide */
public SubscriptionInfo getDefaultSmsSubscriptionInfo() { public static SubscriptionInfo getDefaultSmsSubscriptionInfo() {
return getActiveSubscriptionInfo(getDefaultSmsSubId()); return getSubscriptionInfoForSubscriber(getDefaultSmsSubId());
} }
/** @hide */ /** @hide */
public int getDefaultSmsPhoneId() { public static int getDefaultSmsPhoneId() {
return getPhoneId(getDefaultSmsSubId()); return getPhoneId(getDefaultSmsSubId());
} }
/** @hide */ /** @hide */
public static int getDefaultDataSubId() { public static int getDefaultDataSubId() {
int subId = INVALID_SUBSCRIPTION_ID; int subId = INVALID_SUB_ID;
try { try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -941,7 +829,7 @@ public class SubscriptionManager {
} }
/** @hide */ /** @hide */
public void setDefaultDataSubId(int subId) { public static void setDefaultDataSubId(int subId) {
if (VDBG) logd("setDataSubscription sub id = " + subId); if (VDBG) logd("setDataSubscription sub id = " + subId);
try { try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -954,17 +842,17 @@ public class SubscriptionManager {
} }
/** @hide */ /** @hide */
public SubscriptionInfo getDefaultDataSubscriptionInfo() { public static SubscriptionInfo getDefaultDataSubscriptionInfo() {
return getActiveSubscriptionInfo(getDefaultDataSubId()); return getSubscriptionInfoForSubscriber(getDefaultDataSubId());
} }
/** @hide */ /** @hide */
public int getDefaultDataPhoneId() { public static int getDefaultDataPhoneId() {
return getPhoneId(getDefaultDataSubId()); return getPhoneId(getDefaultDataSubId());
} }
/** @hide */ /** @hide */
public void clearSubscriptionInfo() { public static void clearSubscriptionInfo() {
try { try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) { if (iSub != null) {
@@ -979,14 +867,14 @@ public class SubscriptionManager {
//FIXME this is vulnerable to race conditions //FIXME this is vulnerable to race conditions
/** @hide */ /** @hide */
public boolean allDefaultsSelected() { public static boolean allDefaultsSelected() {
if (getDefaultDataSubId() == INVALID_SUBSCRIPTION_ID) { if (getDefaultDataSubId() == INVALID_SUB_ID) {
return false; return false;
} }
if (getDefaultSmsSubId() == INVALID_SUBSCRIPTION_ID) { if (getDefaultSmsSubId() == INVALID_SUB_ID) {
return false; return false;
} }
if (getDefaultVoiceSubId() == INVALID_SUBSCRIPTION_ID) { if (getDefaultVoiceSubId() == INVALID_SUB_ID) {
return false; return false;
} }
return true; return true;
@@ -994,10 +882,10 @@ public class SubscriptionManager {
/** /**
* If a default is set to subscription which is not active, this will reset that default back to * If a default is set to subscription which is not active, this will reset that default back to
* INVALID_SUBSCRIPTION_ID. * INVALID_SUB_ID.
* @hide * @hide
*/ */
public void clearDefaultsForInactiveSubIds() { public static void clearDefaultsForInactiveSubIds() {
if (VDBG) logd("clearDefaultsForInactiveSubIds"); if (VDBG) logd("clearDefaultsForInactiveSubIds");
try { try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -1014,26 +902,34 @@ public class SubscriptionManager {
* @hide * @hide
*/ */
public static boolean isValidSubId(int subId) { public static boolean isValidSubId(int subId) {
return subId > INVALID_SUBSCRIPTION_ID ; return subId > INVALID_SUB_ID ;
} }
/** /**
* @return true if subId is an usable subId value else false. A * @return true if subId is an usable subId value else false. A
* usable subId means its neither a INVALID_SUBSCRIPTION_ID nor a DEFAUL_SUB_ID. * usable subId means its neither a INVALID_SUB_ID nor a DEFAUL_SUB_ID.
* @hide * @hide
*/ */
public static boolean isUsableSubIdValue(int subId) { public static boolean isUsableSubIdValue(int subId) {
return subId >= MIN_SUBSCRIPTION_ID_VALUE && subId <= MAX_SUBSCRIPTION_ID_VALUE; return subId >= MIN_SUB_ID_VALUE && subId <= MAX_SUB_ID_VALUE;
} }
/** @hide */ /** @hide */
public static boolean isValidSlotId(int slotId) { public static boolean isValidSlotId(int slotId) {
return slotId >= 0 && slotId < TelephonyManager.getDefault().getSimCount(); // We are testing INVALID_SLOT_ID and slotId >= 0 independently because we should
// not assume that INVALID_SLOT_ID will always be a negative value. Any negative
// value is invalid.
return slotId != INVALID_SLOT_ID && slotId >= 0 &&
slotId < TelephonyManager.getDefault().getSimCount();
} }
/** @hide */ /** @hide */
public static boolean isValidPhoneId(int phoneId) { public static boolean isValidPhoneId(int phoneId) {
return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getPhoneCount(); // We are testing INVALID_PHONE_ID and phoneId >= 0 independently because we should
// not assume that INVALID_PHONE_ID will always be a negative value. Any negative
// value is invalid.
return phoneId != INVALID_PHONE_ID && phoneId >= 0 &&
phoneId < TelephonyManager.getDefault().getPhoneCount();
} }
/** @hide */ /** @hide */
@@ -1061,7 +957,7 @@ public class SubscriptionManager {
* is never null but the length maybe 0. * is never null but the length maybe 0.
* @hide * @hide
*/ */
public int[] getActiveSubscriptionIdList() { public static int[] getActiveSubIdList() {
int[] subId = null; int[] subId = null;
try { try {
@@ -1078,6 +974,7 @@ public class SubscriptionManager {
} }
return subId; return subId;
} }
} }

View File

@@ -79,7 +79,6 @@ public class TelephonyManager {
} }
private final Context mContext; private final Context mContext;
private SubscriptionManager mSubscriptionManager;
private static String multiSimConfig = private static String multiSimConfig =
SystemProperties.get(TelephonyProperties.PROPERTY_MULTI_SIM_CONFIG); SystemProperties.get(TelephonyProperties.PROPERTY_MULTI_SIM_CONFIG);
@@ -105,7 +104,6 @@ public class TelephonyManager {
} else { } else {
mContext = context; mContext = context;
} }
mSubscriptionManager = SubscriptionManager.from(mContext);
if (sRegistry == null) { if (sRegistry == null) {
sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
@@ -159,9 +157,6 @@ public class TelephonyManager {
public int getPhoneCount() { public int getPhoneCount() {
int phoneCount = 1; int phoneCount = 1;
switch (getMultiSimConfiguration()) { switch (getMultiSimConfiguration()) {
case UNKNOWN:
phoneCount = 1;
break;
case DSDS: case DSDS:
case DSDA: case DSDA:
phoneCount = PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM; phoneCount = PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM;
@@ -1532,7 +1527,7 @@ public class TelephonyManager {
* @see #getSimState * @see #getSimState
*/ */
public String getSimOperator() { public String getSimOperator() {
int subId = mSubscriptionManager.getDefaultDataSubId(); int subId = SubscriptionManager.getDefaultDataSubId();
if (!SubscriptionManager.isUsableSubIdValue(subId)) { if (!SubscriptionManager.isUsableSubIdValue(subId)) {
subId = SubscriptionManager.getDefaultSmsSubId(); subId = SubscriptionManager.getDefaultSmsSubId();
if (!SubscriptionManager.isUsableSubIdValue(subId)) { if (!SubscriptionManager.isUsableSubIdValue(subId)) {
@@ -1994,7 +1989,7 @@ public class TelephonyManager {
* <p>Requires that the calling app has carrier privileges. * <p>Requires that the calling app has carrier privileges.
* @see #hasCarrierPrivileges * @see #hasCarrierPrivileges
* *
* @param subId The subscription id. * @param subId The subscriber id.
* @param alphaTag The alpha tag to display. * @param alphaTag The alpha tag to display.
* @param number The voicemail number. * @param number The voicemail number.
*/ */

View File

@@ -1,22 +0,0 @@
/*
* Copyright (C) 2014 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;
oneway interface IOnSubscriptionsChangedListener {
void onSubscriptionsChanged();
}

View File

@@ -22,70 +22,50 @@ import com.android.internal.telephony.ISubscriptionListener;
interface ISub { interface ISub {
/** /**
* @return a list of all subscriptions in the database, this includes * Get the SubscriptionInfo according to an index
* all subscriptions that have been seen. * @param subId The unique SubscriptionInfo index in database
* @return SubscriptionInfo, maybe null
*/
SubscriptionInfo getSubInfoForSubscriber(int subId);
/**
* Get the SubscriptionInfo according to an IccId
* @param iccId the IccId of SIM card
* @return SubscriptionInfo, maybe null
*/
List<SubscriptionInfo> getSubInfoUsingIccId(String iccId);
/**
* Get the SubscriptionInfo according to slotId
* @param slotId the slot which the SIM is inserted
* @return SubscriptionInfo, maybe null
*/
List<SubscriptionInfo> getSubInfoUsingSlotId(int slotId);
/**
* Get all the SubscriptionInfo(s) in subinfo database
* @return Array list of all SubInfoRecords in database, include thsoe that were inserted before
*/ */
List<SubscriptionInfo> getAllSubInfoList(); List<SubscriptionInfo> getAllSubInfoList();
/** /**
* @return the count of all subscriptions in the database, this includes * Get the SubscriptionInfo(s) of the currently inserted SIM(s)
* all subscriptions that have been seen. * @return Array list of currently inserted SubscriptionInfo(s)
*/
List<SubscriptionInfo> getActiveSubInfoList();
/**
* Get the SUB count of all SUB(s) in subinfo database
* @return all SIM count in database, include what was inserted before
*/ */
int getAllSubInfoCount(); int getAllSubInfoCount();
/** /**
* Get the active SubscriptionInfo with the subId key * Get the count of active SUB(s)
* @param subId The unique SubscriptionInfo key in database * @return active SIM count
* @return SubscriptionInfo, maybe null if its not active
*/
SubscriptionInfo getActiveSubscriptionInfo(int subId);
/**
* Get the active SubscriptionInfo associated with the iccId
* @param iccId the IccId of SIM card
* @return SubscriptionInfo, maybe null if its not active
*/
SubscriptionInfo getActiveSubscriptionInfoForIccId(String iccId);
/**
* Get the active SubscriptionInfo associated with the slotIdx
* @param slotIdx the slot which the subscription is inserted
* @return SubscriptionInfo, maybe null if its not active
*/
SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIdx);
/**
* Get the SubscriptionInfo(s) of the active subscriptions. The records will be sorted
* by {@link SubscriptionInfo#getSimSlotIndex} then by {@link SubscriptionInfo#getSubscriptionId}.
*
* @return Sorted list of the currently {@link SubscriptionInfo} records available on the device.
* <ul>
* <li>
* If null is returned the current state is unknown but if a {@link OnSubscriptionsChangedListener}
* has been registered {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be
* invoked in the future.
* </li>
* <li>
* If the list is empty then there are no {@link SubscriptionInfo} records currently available.
* </li>
* <li>
* if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
* then by {@link SubscriptionInfo#getSubscriptionId}.
* </li>
* </ul>
*/
List<SubscriptionInfo> getActiveSubscriptionInfoList();
/**
* @return the number of active subscriptions
*/ */
int getActiveSubInfoCount(); int getActiveSubInfoCount();
/**
* @return the maximum number of subscriptions this device will support at any one time.
*/
int getActiveSubInfoCountMax();
/** /**
* Add a new SubscriptionInfo to subinfo database if needed * Add a new SubscriptionInfo to subinfo database if needed
* @param iccId the IccId of the SIM card * @param iccId the IccId of the SIM card

View File

@@ -27,13 +27,11 @@ import android.telephony.SignalStrength;
import android.telephony.CellInfo; import android.telephony.CellInfo;
import android.telephony.VoLteServiceState; import android.telephony.VoLteServiceState;
import com.android.internal.telephony.IPhoneStateListener; import com.android.internal.telephony.IPhoneStateListener;
import com.android.internal.telephony.IOnSubscriptionsChangedListener; import com.android.internal.telephony.ISubscriptionListener;
interface ITelephonyRegistry { interface ITelephonyRegistry {
void registerOnSubscriptionsChangedListener(String pkg, void registerSubscriptionListener(String pkg, ISubscriptionListener callback, int events);
IOnSubscriptionsChangedListener callback); void unregisterSubscriptionListener(String pkg, ISubscriptionListener callback);
void unregisterOnSubscriptionsChangedListener(String pkg,
IOnSubscriptionsChangedListener callback);
void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow); void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow);
void listenForSubscriber(in int subId, String pkg, IPhoneStateListener callback, int events, void listenForSubscriber(in int subId, String pkg, IPhoneStateListener callback, int events,
boolean notifyNow); boolean notifyNow);