Additional changes to SubscriptionManager API as per API council.
bug: 17575308
Change-Id: Idd98aa46c15a9219ccf28091c62602ac8bf16c62
diff --git a/Android.mk b/Android.mk
index ea22d0f..327a371 100644
--- a/Android.mk
+++ b/Android.mk
@@ -373,8 +373,8 @@
telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
telephony/java/com/android/internal/telephony/ITelephony.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/ISubscriptionListener.aidl \
telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
telephony/java/com/android/internal/telephony/ISub.aidl \
telephony/java/com/android/internal/telephony/IMms.aidl \
diff --git a/api/current.txt b/api/current.txt
index f6c3c17..024bccd 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -7272,6 +7272,7 @@
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 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 TV_INPUT_SERVICE = "tv_input";
field public static final java.lang.String UI_MODE_SERVICE = "uimode";
@@ -16932,8 +16933,8 @@
field public static final deprecated int DEFAULT_NETWORK_PREFERENCE = 1; // 0x1
field public static final java.lang.String EXTRA_EXTRA_INFO = "extraInfo";
field public static final java.lang.String EXTRA_IS_FAILOVER = "isFailover";
- field public static final deprecated java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
field public static final java.lang.String EXTRA_NETWORK = "android.net.extra.NETWORK";
+ field public static final deprecated java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
field public static final java.lang.String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST";
field public static final java.lang.String EXTRA_NETWORK_TYPE = "networkType";
field public static final java.lang.String EXTRA_NO_CONNECTIVITY = "noConnectivity";
@@ -25579,7 +25580,7 @@
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_CHARSET = "sub_cs";
- field public static final java.lang.String SUB_ID = "sub_id";
+ field public static final java.lang.String SUBSCRIPTION_ID = "sub_id";
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 TRANSACTION_ID = "tr_id";
@@ -25612,7 +25613,7 @@
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 SERVER = "server";
- field public static final java.lang.String SUB_ID = "sub_id";
+ field public static final java.lang.String SUBSCRIPTION_ID = "sub_id";
field public static final java.lang.String TYPE = "type";
field public static final java.lang.String USER = "user";
}
@@ -25713,7 +25714,7 @@
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 RETRY_INDEX = "retry_index";
- field public static final java.lang.String SUB_ID = "pending_sub_id";
+ field public static final java.lang.String SUBSCRIPTION_ID = "pending_sub_id";
}
public static final class Telephony.Sms implements android.provider.BaseColumns android.provider.Telephony.TextBasedSmsColumns {
@@ -25799,7 +25800,7 @@
field public static final int STATUS_NONE = -1; // 0xffffffff
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 SUB_ID = "sub_id";
+ field public static final java.lang.String SUBSCRIPTION_ID = "sub_id";
field public static final java.lang.String THREAD_ID = "thread_id";
field public static final java.lang.String TYPE = "type";
}
@@ -28638,6 +28639,8 @@
public class SubscriptionInfo implements android.os.Parcelable {
method public android.graphics.Bitmap createIconBitmap(android.content.Context);
method public int describeContents();
+ method public java.lang.CharSequence getCarrierName();
+ method public java.lang.String getCountryIso();
method public int getDataRoaming();
method public java.lang.CharSequence getDisplayName();
method public java.lang.String getIccId();
@@ -28652,20 +28655,22 @@
field public static final android.os.Parcelable.Creator<android.telephony.SubscriptionInfo> CREATOR;
}
- public class SubscriptionListener {
- ctor public SubscriptionListener();
- ctor public SubscriptionListener(android.os.Looper);
- method public void onSubscriptionInfoChanged();
- field public static final int LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED = 1; // 0x1
+ public class SubscriptionManager {
+ method public static android.telephony.SubscriptionManager from(android.content.Context);
+ method public android.telephony.SubscriptionInfo getActiveSubscriptionInfo(int);
+ method public int getActiveSubscriptionInfoCount();
+ method public int getActiveSubscriptionInfoCountMax();
+ method public android.telephony.SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int);
+ method public java.util.List<android.telephony.SubscriptionInfo> getActiveSubscriptionInfoList();
+ method public boolean isNetworkRoaming(int);
+ 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 class SubscriptionManager implements android.provider.BaseColumns {
- method public static java.util.List<android.telephony.SubscriptionInfo> getActiveSubscriptionInfoList();
- 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 static class SubscriptionManager.OnSubscriptionsChangedListener {
+ ctor public SubscriptionManager.OnSubscriptionsChangedListener();
+ method public void onSubscriptionsChanged();
}
public class TelephonyManager {
@@ -28703,6 +28708,7 @@
method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
method public boolean isNetworkRoaming();
method public boolean isSmsCapable();
+ method public boolean isVoiceCapable();
method public void listen(android.telephony.PhoneStateListener, int);
method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
method public boolean setGlobalPreferredNetworkType();
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 1de9b47..2df35df 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -20,9 +20,9 @@
import android.app.usage.UsageStatsManager;
import android.appwidget.AppWidgetManager;
import android.os.Build;
-
import android.service.persistentdata.IPersistentDataBlockService;
import android.service.persistentdata.PersistentDataBlockManager;
+
import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.policy.PolicyManager;
import com.android.internal.util.Preconditions;
@@ -125,6 +125,7 @@
import android.service.fingerprint.IFingerprintService;
import android.service.fingerprint.FingerprintManager;
import android.telecom.TelecomManager;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.content.ClipboardManager;
import android.util.AndroidRuntimeException;
@@ -561,6 +562,11 @@
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() {
public Object createService(ContextImpl ctx) {
return new TelecomManager(ctx.getOuterContext());
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index a73ba74..0daa8e2 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2245,6 +2245,8 @@
* @see android.media.MediaRouter
* @see #TELEPHONY_SERVICE
* @see android.telephony.TelephonyManager
+ * @see #TELEPHONY_SUBSCRIPTION_SERVICE
+ * @see android.telephony.SubscriptionManager
* @see #INPUT_METHOD_SERVICE
* @see android.view.inputmethod.InputMethodManager
* @see #UI_MODE_SERVICE
@@ -2589,6 +2591,16 @@
/**
* 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
* {@link android.telecom.TelecomManager} to manage telecom-related features
* of the device.
*
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 3ec45e9..f023df7 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -387,7 +387,6 @@
public static Uri addCall(CallerInfo ci, Context context, String number,
int presentation, int callType, int features, PhoneAccountHandle accountHandle,
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,
start, duration, dataUsage, false);
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
index a5d260d..5350e5a 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
@@ -82,10 +82,10 @@
KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
SecurityMode mode = SecurityMode.None;
if (monitor.getNextSubIdForState(IccCardConstants.State.PIN_REQUIRED)
- != SubscriptionManager.INVALID_SUB_ID) {
+ != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
mode = SecurityMode.SimPin;
} else if (monitor.getNextSubIdForState(IccCardConstants.State.PUK_REQUIRED)
- != SubscriptionManager.INVALID_SUB_ID
+ != SubscriptionManager.INVALID_SUBSCRIPTION_ID
&& mLockPatternUtils.isPukUnlockScreenEnable()) {
mode = SecurityMode.SimPuk;
} else {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
index d8feaf8..1f4311e 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
@@ -71,7 +71,7 @@
if (DEBUG) Log.v(TAG, "Resetting state");
KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
mSubId = monitor.getNextSubIdForState(IccCardConstants.State.PIN_REQUIRED);
- if (mSubId != SubscriptionManager.INVALID_SUB_ID) {
+ if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
int count = TelephonyManager.getDefault().getSimCount();
Resources rez = getResources();
final String msg;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
index c5d940c..e7f0635 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
@@ -114,7 +114,7 @@
state = ENTER_PUK;
KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
mSubId = monitor.getNextSubIdForState(IccCardConstants.State.PUK_REQUIRED);
- if (mSubId != SubscriptionManager.INVALID_SUB_ID) {
+ if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
int count = TelephonyManager.getDefault().getSimCount();
Resources rez = getResources();
final String msg;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 48b2eac..7f1314d 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -27,7 +27,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.graphics.Bitmap;
@@ -40,9 +39,7 @@
import static android.os.BatteryManager.EXTRA_HEALTH;
import android.media.AudioManager;
-import android.media.IRemoteControlDisplay;
import android.os.BatteryManager;
-import android.os.Bundle;
import android.os.Handler;
import android.os.IRemoteCallback;
import android.os.Message;
@@ -60,8 +57,8 @@
import android.service.fingerprint.FingerprintManagerReceiver;
import android.service.fingerprint.FingerprintUtils;
import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionListener;
import android.telephony.SubscriptionManager;
+import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.util.SparseBooleanArray;
@@ -158,7 +155,8 @@
private boolean mSwitchingUser;
private boolean mScreenOn;
- protected List<SubscriptionInfo> mSubscriptionInfo;
+ private SubscriptionManager mSubscriptionManager;
+ private List<SubscriptionInfo> mSubscriptionInfo;
private final Handler mHandler = new Handler() {
@Override
@@ -237,9 +235,10 @@
}
};
- private SubscriptionListener mSubscriptionListener = new SubscriptionListener() {
+ private OnSubscriptionsChangedListener mSubscriptionListener =
+ new OnSubscriptionsChangedListener() {
@Override
- public void onSubscriptionInfoChanged() {
+ public void onSubscriptionsChanged() {
mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
}
};
@@ -267,8 +266,13 @@
protected void handleSimSubscriptionInfoChanged() {
if (DEBUG_SIM_STATES) {
Log.v(TAG, "onSubscriptionInfoChanged()");
- for (SubscriptionInfo subInfo : SubscriptionManager.getActiveSubscriptionInfoList()) {
- Log.v(TAG, "SubInfo:" + subInfo);
+ List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
+ if (sil != null) {
+ for (SubscriptionInfo subInfo : sil) {
+ Log.v(TAG, "SubInfo:" + subInfo);
+ }
+ } else {
+ Log.v(TAG, "onSubscriptionInfoChanged: list is null");
}
}
List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
@@ -291,9 +295,17 @@
}
}
+ /** @return List of SubscriptionInfo records, maybe empty but never null */
List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
- if (mSubscriptionInfo == null || forceReload) {
- mSubscriptionInfo = SubscriptionManager.getActiveSubscriptionInfoList();
+ List<SubscriptionInfo> sil = mSubscriptionInfo;
+ if (sil == null || forceReload) {
+ sil = mSubscriptionManager.getActiveSubscriptionInfoList();
+ }
+ if (sil == null) {
+ // getActiveSubscriptionInfoList was null callers expect an empty list.
+ mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
+ } else {
+ mSubscriptionInfo = sil;
}
return mSubscriptionInfo;
}
@@ -524,7 +536,7 @@
String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 0);
int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
- SubscriptionManager.INVALID_SUB_ID);
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID);
if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
final String absentReason = intent
.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
@@ -660,6 +672,7 @@
private KeyguardUpdateMonitor(Context context) {
mContext = context;
+ mSubscriptionManager = SubscriptionManager.from(context);
mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
// Since device can't be un-provisioned, we only need to register a content observer
// to update mDeviceProvisioned when we are...
@@ -698,8 +711,7 @@
context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
null, null);
- SubscriptionManager.register(mContext, mSubscriptionListener,
- SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED);
+ mSubscriptionManager.registerOnSubscriptionsChangedListener(mSubscriptionListener);
try {
ActivityManagerNative.getDefault().registerUserSwitchObserver(
new IUserSwitchObserver.Stub() {
@@ -952,7 +964,7 @@
+ slotId + ", state=" + state +")");
}
- if (subId == SubscriptionManager.INVALID_SUB_ID) {
+ if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
Log.w(TAG, "invalid subId in handleSimStateChange()");
return;
}
@@ -1338,11 +1350,11 @@
/**
* Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
* @param state
- * @return subid or {@link SubscriptionManager#INVALID_SUB_ID} if none found
+ * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
*/
public int getNextSubIdForState(State state) {
List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
- int resultId = SubscriptionManager.INVALID_SUB_ID;
+ int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
for (int i = 0; i < list.size(); i++) {
final SubscriptionInfo info = list.get(i);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 8213127..d8f8727 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -926,9 +926,10 @@
// if the setup wizard hasn't run yet, don't show
final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", false);
final boolean absent = mUpdateMonitor.getNextSubIdForState(
- IccCardConstants.State.ABSENT) != SubscriptionManager.INVALID_SUB_ID;
+ IccCardConstants.State.ABSENT) != SubscriptionManager.INVALID_SUBSCRIPTION_ID;
final boolean disabled = mUpdateMonitor.getNextSubIdForState(
- IccCardConstants.State.PERM_DISABLED) != SubscriptionManager.INVALID_SUB_ID;
+ IccCardConstants.State.PERM_DISABLED)
+ != SubscriptionManager.INVALID_SUBSCRIPTION_ID;
final boolean lockedOrMissing = mUpdateMonitor.isSimPinSecure()
|| ((absent || disabled) && requireSim);
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 0f033d71..5fe0d1c 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -239,7 +239,7 @@
mDaemonHandler = new Handler(FgThread.get().getLooper());
- mPhoneStateListener = new PhoneStateListener(SubscriptionManager.DEFAULT_SUB_ID,
+ mPhoneStateListener = new PhoneStateListener(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
mDaemonHandler.getLooper()) {
@Override
public void onDataConnectionRealTimeInfoChanged(
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 2ed021a..34da901 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -34,8 +34,6 @@
import android.telephony.CellLocation;
import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.Rlog;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionListener;
import android.telephony.TelephonyManager;
import android.telephony.SubscriptionManager;
import android.telephony.PhoneStateListener;
@@ -43,7 +41,6 @@
import android.telephony.SignalStrength;
import android.telephony.CellInfo;
import android.telephony.VoLteServiceState;
-import android.telephony.TelephonyManager;
import android.telephony.DisconnectCause;
import android.telephony.PreciseCallState;
import android.telephony.PreciseDataConnectionState;
@@ -52,13 +49,12 @@
import android.text.format.Time;
import java.util.ArrayList;
-import java.util.Calendar;
import java.util.List;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import com.android.internal.app.IBatteryStats;
-import com.android.internal.telephony.ISubscriptionListener;
+import com.android.internal.telephony.IOnSubscriptionsChangedListener;
import com.android.internal.telephony.ITelephonyRegistry;
import com.android.internal.telephony.IPhoneStateListener;
import com.android.internal.telephony.DefaultPhoneNotifier;
@@ -93,28 +89,29 @@
IBinder binder;
IPhoneStateListener callback;
- ISubscriptionListener subscriptionListenerCallback;
+ IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback;
int callerUid;
int events;
- int subId = SubscriptionManager.INVALID_SUB_ID;
+ int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
- int phoneId = SubscriptionManager.INVALID_PHONE_ID;
+ int phoneId = SubscriptionManager.INVALID_PHONE_INDEX;
boolean matchPhoneStateListenerEvent(int events) {
return (callback != null) && ((events & this.events) != 0);
}
- boolean matchSubscriptionListenerEvent(int events) {
- return (subscriptionListenerCallback != null) && ((events & this.events) != 0);
+ boolean matchOnSubscriptionsChangedListener() {
+ return (onSubscriptionsChangedListenerCallback != null);
}
@Override
public String toString() {
return "{pkgForDebug=" + pkgForDebug + " binder=" + binder + " callback=" + callback
- + " subscriptionListenererCallback=" + subscriptionListenerCallback
+ + " onSubscriptionsChangedListenererCallback="
+ + onSubscriptionsChangedListenerCallback
+ " callerUid=" + callerUid + " subId=" + subId + " phoneId=" + phoneId
+ " events=" + Integer.toHexString(events) + "}";
}
@@ -128,6 +125,8 @@
private final IBatteryStats mBatteryStats;
+ private boolean hasNotifySubscriptionInfoChangedOccurred = false;
+
private int mNumPhones;
private int[] mCallState;
@@ -168,9 +167,9 @@
private VoLteServiceState mVoLteServiceState = new VoLteServiceState();
- private int mDefaultSubId = SubscriptionManager.INVALID_SUB_ID;
+ private int mDefaultSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
- private int mDefaultPhoneId = SubscriptionManager.INVALID_PHONE_ID;
+ private int mDefaultPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
private DataConnectionRealTimeInfo mDcRtInfo = new DataConnectionRealTimeInfo();
@@ -227,7 +226,7 @@
//possible missed notify callback
synchronized (mRecords) {
for (Record r : mRecords) {
- if(r.subId == SubscriptionManager.DEFAULT_SUB_ID) {
+ if(r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
checkPossibleMissNotify(r, newDefaultPhoneId);
}
}
@@ -339,90 +338,89 @@
}
@Override
- public void registerSubscriptionListener(String pkgForDebug, ISubscriptionListener callback,
- int events) {
+ public void registerOnSubscriptionsChangedListener(String pkgForDebug,
+ IOnSubscriptionsChangedListener callback) {
int callerUid = UserHandle.getCallingUserId();
int myUid = UserHandle.myUserId();
if (VDBG) {
- log("listen sl: E pkg=" + pkgForDebug + " events=0x" + Integer.toHexString(events)
- + " myUid=" + myUid + " callerUid=" + callerUid + " callback=" + callback
+ log("listen oscl: E pkg=" + pkgForDebug + " myUid=" + myUid
+ + " callerUid=" + callerUid + " callback=" + callback
+ " callback.asBinder=" + callback.asBinder());
}
- if (events != 0) {
- /* Checks permission and throws Security exception */
- checkSubscriptionListenerPermission(events);
- Record r = null;
+ /* Checks permission and throws Security exception */
+ checkOnSubscriptionsChangedListenerPermission();
+ Record r = null;
- synchronized (mRecords) {
- // register
- find_and_add: {
- IBinder b = callback.asBinder();
- final int N = mRecords.size();
- for (int i = 0; i < N; i++) {
- r = mRecords.get(i);
- if (b == r.binder) {
- break find_and_add;
- }
+ synchronized (mRecords) {
+ // register
+ find_and_add: {
+ IBinder b = callback.asBinder();
+ final int N = mRecords.size();
+ for (int i = 0; i < N; i++) {
+ r = mRecords.get(i);
+ if (b == r.binder) {
+ 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");
}
- // Always notify when a listen is established.
- if (r.matchSubscriptionListenerEvent(
- SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED)) {
+ r.onSubscriptionsChangedListenerCallback = callback;
+ r.pkgForDebug = pkgForDebug;
+ r.callerUid = callerUid;
+ 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 {
- if (VDBG) log("listen sl: send to r=" + r);
- r.subscriptionListenerCallback.onSubscriptionInfoChanged();
- if (VDBG) log("listen sl: sent to r=" + r);
+ if (VDBG) log("listen oscl: send to r=" + r);
+ r.onSubscriptionsChangedListenerCallback.onSubscriptionsChanged();
+ if (VDBG) log("listen oscl: sent to r=" + r);
} catch (RemoteException e) {
- if (VDBG) log("listen sl: remote exception sending to r=" + r + " e=" + e);
+ if (VDBG) log("listen oscl: remote exception sending to r=" + r + " e=" + e);
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
- public void unregisterSubscriptionListener(String pkgForDebug, ISubscriptionListener callback) {
- if (DBG) log("listen sl: Unregister as event is LISTEN_NONE");
+ public void unregisterOnSubscriptionsChangedListener(String pkgForDebug,
+ IOnSubscriptionsChangedListener callback) {
+ if (DBG) log("listen oscl: Unregister");
remove(callback.asBinder());
}
- private void checkSubscriptionListenerPermission(int events) {
- if ((events & SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED) != 0) {
- mContext.enforceCallingOrSelfPermission(
- SubscriptionListener.PERMISSION_LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED, null);
- }
+ private void checkOnSubscriptionsChangedListenerPermission() {
+ mContext.enforceCallingOrSelfPermission(
+ SubscriptionManager.OnSubscriptionsChangedListener
+ .PERMISSION_ON_SUBSCRIPTIONS_CHANGED, null);
}
@Override
public void notifySubscriptionInfoChanged() {
if (VDBG) log("notifySubscriptionInfoChanged:");
synchronized (mRecords) {
+ if (!hasNotifySubscriptionInfoChangedOccurred) {
+ log("notifySubscriptionInfoChanged: first invocation mRecords.size="
+ + mRecords.size());
+ }
+ hasNotifySubscriptionInfoChangedOccurred = true;
mRemoveList.clear();
for (Record r : mRecords) {
- if (r.matchSubscriptionListenerEvent(
- SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED)) {
+ if (r.matchOnSubscriptionsChangedListener()) {
try {
- if (VDBG) log("notifySubscriptionInfoChanged: send to r=" + r);
- r.subscriptionListenerCallback.onSubscriptionInfoChanged();
- if (VDBG) log("notifySubscriptionInfoChanged: sent to r=" + r);
+ if (VDBG) log("notifySubscriptionInfoChanged: call osc to r=" + r);
+ r.onSubscriptionsChangedListenerCallback.onSubscriptionsChanged();
+ if (VDBG) log("notifySubscriptionInfoChanged: done osc to r=" + r);
} catch (RemoteException ex) {
if (VDBG) log("notifySubscriptionInfoChanged: RemoteException r=" + r);
mRemoveList.add(r.binder);
@@ -436,8 +434,8 @@
@Override
public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
boolean notifyNow) {
- listenForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, pkgForDebug, callback, events,
- notifyNow);
+ listenForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, pkgForDebug, callback,
+ events, notifyNow);
}
@Override
@@ -483,7 +481,7 @@
// Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID,
// force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID
if (!SubscriptionManager.isValidSubId(subId)) {
- r.subId = SubscriptionManager.DEFAULT_SUB_ID;
+ r.subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
} else {//APP specify subID
r.subId = subId;
}
@@ -642,7 +640,7 @@
synchronized (mRecords) {
for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) &&
- (r.subId == SubscriptionManager.DEFAULT_SUB_ID)) {
+ (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
try {
r.callback.onCallStateChanged(state, incomingNumber);
} catch (RemoteException ex) {
@@ -652,7 +650,8 @@
}
handleRemoveListLocked();
}
- broadcastCallStateChanged(state, incomingNumber, SubscriptionManager.DEFAULT_SUB_ID);
+ broadcastCallStateChanged(state, incomingNumber,
+ SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
}
public void notifyCallStateForSubscriber(int subId, int state, String incomingNumber) {
@@ -671,7 +670,7 @@
for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) &&
(r.subId == subId) &&
- (r.subId != SubscriptionManager.DEFAULT_SUB_ID)) {
+ (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
try {
r.callback.onCallStateChanged(state, incomingNumber);
} catch (RemoteException ex) {
@@ -728,7 +727,8 @@
}
public void notifySignalStrength(SignalStrength signalStrength) {
- notifySignalStrengthForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, signalStrength);
+ notifySignalStrengthForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+ signalStrength);
}
public void notifySignalStrengthForSubscriber(int subId, SignalStrength signalStrength) {
@@ -789,7 +789,7 @@
}
public void notifyCellInfo(List<CellInfo> cellInfo) {
- notifyCellInfoForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, cellInfo);
+ notifyCellInfoForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellInfo);
}
public void notifyCellInfoForSubscriber(int subId, List<CellInfo> cellInfo) {
@@ -877,7 +877,7 @@
}
public void notifyCallForwardingChanged(boolean cfi) {
- notifyCallForwardingChangedForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, cfi);
+ notifyCallForwardingChangedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cfi);
}
public void notifyCallForwardingChangedForSubscriber(int subId, boolean cfi) {
@@ -909,7 +909,7 @@
}
public void notifyDataActivity(int state) {
- notifyDataActivityForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, state);
+ notifyDataActivityForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state);
}
public void notifyDataActivityForSubscriber(int subId, int state) {
@@ -918,13 +918,15 @@
}
synchronized (mRecords) {
int phoneId = SubscriptionManager.getPhoneId(subId);
- mDataActivity[phoneId] = state;
- for (Record r : mRecords) {
- if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_DATA_ACTIVITY)) {
- try {
- r.callback.onDataActivity(state);
- } catch (RemoteException ex) {
- mRemoveList.add(r.binder);
+ if (validatePhoneId(phoneId)) {
+ mDataActivity[phoneId] = state;
+ for (Record r : mRecords) {
+ if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_DATA_ACTIVITY)) {
+ try {
+ r.callback.onDataActivity(state);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
}
}
}
@@ -935,7 +937,7 @@
public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
String reason, String apn, String apnType, LinkProperties linkProperties,
NetworkCapabilities networkCapabilities, int networkType, boolean roaming) {
- notifyDataConnectionForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, state,
+ notifyDataConnectionForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state,
isDataConnectivityPossible,reason, apn, apnType, linkProperties,
networkCapabilities, networkType, roaming);
}
@@ -956,65 +958,67 @@
}
synchronized (mRecords) {
int phoneId = SubscriptionManager.getPhoneId(subId);
- boolean modified = false;
- if (state == TelephonyManager.DATA_CONNECTED) {
- if (!mConnectedApns.contains(apnType)) {
- mConnectedApns.add(apnType);
- if (mDataConnectionState[phoneId] != state) {
- mDataConnectionState[phoneId] = state;
- modified = true;
+ if (validatePhoneId(phoneId)) {
+ boolean modified = false;
+ if (state == TelephonyManager.DATA_CONNECTED) {
+ if (!mConnectedApns.contains(apnType)) {
+ mConnectedApns.add(apnType);
+ if (mDataConnectionState[phoneId] != state) {
+ mDataConnectionState[phoneId] = state;
+ 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;
- 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) {
- 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);
+ } 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.
}
}
}
- 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);
+ 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) {
+ 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, "");
+ 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);
+ }
}
}
}
@@ -1027,7 +1031,7 @@
}
public void notifyDataConnectionFailed(String reason, String apnType) {
- notifyDataConnectionFailedForSubscriber(SubscriptionManager.DEFAULT_SUB_ID,
+ notifyDataConnectionFailedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
reason, apnType);
}
@@ -1062,7 +1066,7 @@
}
public void notifyCellLocation(Bundle cellLocation) {
- notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, cellLocation);
+ notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellLocation);
}
public void notifyCellLocationForSubscriber(int subId, Bundle cellLocation) {
@@ -1226,7 +1230,7 @@
if ((r.matchPhoneStateListenerEvent(
PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT)) &&
((r.subId == subId) ||
- (r.subId == SubscriptionManager.DEFAULT_SUB_ID))) {
+ (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID))) {
try {
r.callback.onOemHookRawEvent(rawData);
} catch (RemoteException ex) {
@@ -1399,14 +1403,17 @@
}
private void broadcastPreciseDataConnectionStateChanged(int state, int networkType,
- String apnType, String apn, String reason, LinkProperties linkProperties, String failCause) {
+ String apnType, String apn, String reason, LinkProperties linkProperties,
+ String failCause) {
Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED);
intent.putExtra(PhoneConstants.STATE_KEY, state);
intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType);
if (reason != null) intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason);
if (apnType != null) intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
if (apn != null) intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
- if (linkProperties != null) intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
+ if (linkProperties != null) {
+ intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY,linkProperties);
+ }
if (failCause != null) intent.putExtra(PhoneConstants.DATA_FAILURE_CAUSE_KEY, failCause);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
@@ -1506,7 +1513,8 @@
@Override
public String toString() {
- return mS + " Time " + mTime.toString() + " mSubId " + mSubId + " mPhoneId " + mPhoneId + " mState " + mState;
+ return mS + " Time " + mTime.toString() + " mSubId " + mSubId + " mPhoneId "
+ + mPhoneId + " mState " + mState;
}
}
@@ -1550,7 +1558,7 @@
}
boolean idMatch(int rSubId, int subId, int phoneId) {
- if(rSubId == SubscriptionManager.DEFAULT_SUB_ID) {
+ if(rSubId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
if(subId < 0) {
// Invalid case, we need compare phoneId with default one.
return (mDefaultPhoneId == phoneId);
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index 8c3c102..c960c07 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -73,8 +73,8 @@
import android.provider.Telephony.Sms.Intents;
import android.telephony.SmsMessage;
import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionListener;
import android.telephony.SubscriptionManager;
+import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
@@ -462,9 +462,10 @@
}
};
- private final SubscriptionListener mSubscriptionListener = new SubscriptionListener() {
+ private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
+ new OnSubscriptionsChangedListener() {
@Override
- public void onSubscriptionInfoChanged() {
+ public void onSubscriptionsChanged() {
subscriptionOrSimChanged(mContext);
}
};
@@ -640,14 +641,14 @@
mSuplEsEnabled);
// TODO: When this object "finishes" we should unregister by invoking
- // SubscriptionManager.unregister(mContext, mSubscriptionListener);
+ // SubscriptionManager.getInstance(mContext).unregister(mOnSubscriptionsChangedListener);
// This is not strictly necessary because it will be unregistered if the
// notification fails but it is good form.
// Register for SubscriptionInfo list changes which is guaranteed
- // to invoke onSubscriptionInfoChanged the first time.
- SubscriptionManager.register(mContext, mSubscriptionListener,
- SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED);
+ // to invoke onSubscriptionsChanged the first time.
+ SubscriptionManager.from(mContext)
+ .registerOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
// construct handler, listen for events
mHandler = new ProviderHandler(looper);
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 2f1a8da..8f4a92b 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -227,7 +227,7 @@
* @hide
*/
/** @hide */
- protected int mSubId = SubscriptionManager.INVALID_SUB_ID;
+ protected int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private final Handler mHandler;
@@ -237,7 +237,7 @@
* own non-null looper use PhoneStateListener(Looper looper) below.
*/
public PhoneStateListener() {
- this(SubscriptionManager.DEFAULT_SUB_ID, Looper.myLooper());
+ this(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, Looper.myLooper());
}
/**
@@ -246,7 +246,7 @@
* @hide
*/
public PhoneStateListener(Looper looper) {
- this(SubscriptionManager.DEFAULT_SUB_ID, looper);
+ this(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, looper);
}
/**
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index a3ace36..c8b782f 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -102,11 +102,16 @@
private int mMnc;
/**
+ * ISO Country code for the subscription's provider
+ */
+ private String mCountryIso;
+
+ /**
* @hide
*/
public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
- Bitmap icon, int mcc, int mnc) {
+ Bitmap icon, int mcc, int mnc, String countryIso) {
this.mId = id;
this.mIccId = iccId;
this.mSimSlotIndex = simSlotIndex;
@@ -119,6 +124,7 @@
this.mIconBitmap = icon;
this.mMcc = mcc;
this.mMnc = mnc;
+ this.mCountryIso = countryIso;
}
/**
@@ -159,7 +165,6 @@
/**
* Returns the name displayed to the user that identifies Subscription provider name
- * @hide
*/
public CharSequence getCarrierName() {
return this.mCarrierName;
@@ -265,6 +270,13 @@
return this.mMnc;
}
+ /**
+ * Returns the ISO country code
+ */
+ public String getCountryIso() {
+ return this.mCountryIso;
+ }
+
public static final Parcelable.Creator<SubscriptionInfo> CREATOR = new Parcelable.Creator<SubscriptionInfo>() {
@Override
public SubscriptionInfo createFromParcel(Parcel source) {
@@ -279,10 +291,11 @@
int dataRoaming = source.readInt();
int mcc = source.readInt();
int mnc = source.readInt();
+ String countryIso = source.readString();
Bitmap iconBitmap = Bitmap.CREATOR.createFromParcel(source);
- return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName, nameSource,
- iconTint, number, dataRoaming, iconBitmap, mcc, mnc);
+ return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName,
+ nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso);
}
@Override
@@ -304,6 +317,7 @@
dest.writeInt(mDataRoaming);
dest.writeInt(mMcc);
dest.writeInt(mMnc);
+ dest.writeString(mCountryIso);
mIconBitmap.writeToParcel(dest, flags);
}
diff --git a/telephony/java/android/telephony/SubscriptionListener.java b/telephony/java/android/telephony/SubscriptionListener.java
deleted file mode 100644
index 5c65333..0000000
--- a/telephony/java/android/telephony/SubscriptionListener.java
+++ /dev/null
@@ -1,125 +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 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);
- }
-}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 78ab6870..40d2e77 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -21,14 +21,17 @@
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
-import android.provider.BaseColumns;
import android.telephony.Rlog;
+import android.os.Handler;
+import android.os.Message;
import android.os.ServiceManager;
import android.os.RemoteException;
import com.android.internal.telephony.ISub;
+import com.android.internal.telephony.IOnSubscriptionsChangedListener;
import com.android.internal.telephony.ITelephonyRegistry;
import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.TelephonyProperties;
import java.util.ArrayList;
import java.util.List;
@@ -36,62 +39,79 @@
/**
* SubscriptionManager is the application interface to SubscriptionController
* and provides information about the current Telephony Subscriptions.
- *
- * The android.Manifest.permission.READ_PHONE_STATE to retrieve the information, except
- * getActiveSubIdList and getActiveSubIdCount for which no permission is needed.
+ * * <p>
+ * You do not instantiate this class directly; instead, you retrieve
+ * a reference to an instance through {@link #from}.
+ * <p>
+ * All SDK public methods require android.Manifest.permission.READ_PHONE_STATE.
*/
-public class SubscriptionManager implements BaseColumns {
- private static final String LOG_TAG = "SUB";
- private static final boolean DBG = true;
+public class SubscriptionManager {
+ private static final String LOG_TAG = "SubscriptionManager";
+ private static final boolean DBG = false;
private static final boolean VDBG = false;
/** An invalid subscription identifier */
- public static final int INVALID_SUB_ID = -1000;
+ public static final int INVALID_SUBSCRIPTION_ID = -1;
+
+ /** 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 */
/** @hide */
- public static final int INVALID_PHONE_ID = -1;
+ public static final int INVALID_PHONE_INDEX = -1;
/** An invalid slot identifier */
/** @hide */
- public static final int INVALID_SLOT_ID = -1;
+ public static final int INVALID_SIM_SLOT_INDEX = -1;
/** Indicates the caller wants the default sub id. */
/** @hide */
- public static final int DEFAULT_SUB_ID = Integer.MAX_VALUE;
+ public static final int DEFAULT_SUBSCRIPTION_ID = Integer.MAX_VALUE;
- /** Indicates the caller wants the default phone id. */
- /** @hide */
- public static final int DEFAULT_PHONE_ID = Integer.MAX_VALUE;
+ /**
+ * 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. */
+ /** Indicates the caller wants the default slot id. NOT used remove? */
/** @hide */
- public static final int DEFAULT_SLOT_ID = Integer.MAX_VALUE;
+ public static final int DEFAULT_SIM_SLOT_INDEX = Integer.MAX_VALUE;
/** Minimum possible subid that represents a subscription */
/** @hide */
- public static final int MIN_SUB_ID_VALUE = 0;
+ public static final int MIN_SUBSCRIPTION_ID_VALUE = 0;
/** Maximum possible subid that represents a subscription */
/** @hide */
- public static final int MAX_SUB_ID_VALUE = DEFAULT_SUB_ID - 1;
-
+ public static final int MAX_SUBSCRIPTION_ID_VALUE = DEFAULT_SUBSCRIPTION_ID - 1;
/** @hide */
public static final Uri CONTENT_URI = Uri.parse("content://telephony/siminfo");
/**
- * The ICC ID of a SIM.
+ * TelephonyProvider unique key column name is the subscription id.
+ * <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>
*/
/** @hide */
public static final String ICC_ID = "icc_id";
/**
+ * TelephonyProvider column name for user SIM_SlOT_INDEX
* <P>Type: INTEGER (int)</P>
*/
/** @hide */
- public static final String SIM_ID = "sim_id";
+ public static final String SIM_SLOT_INDEX = "sim_id";
/** SIM is not inserted */
/** @hide */
@@ -230,39 +250,107 @@
/**
* Broadcast Action: The user has changed one of the default subs related to
* data, phone calls, or sms</p>
+ *
+ * TODO: Change to a listener
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String SUB_DEFAULT_CHANGED_ACTION =
"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("callback: received, sendEmptyMessage(0) to handler");
+ mHandler.sendEmptyMessage(0);
+ }
+ };
+
+ private void log(String s) {
+ Rlog.d(LOG_TAG, s);
+ }
+ }
+
/** @hide */
- public SubscriptionManager() {
+ public SubscriptionManager(Context context) {
if (DBG) logd("SubscriptionManager created");
+ mContext = context;
}
/**
- * Register for changes to events defined by SubscriptionListener.LISTEN_Xxx. Some of
- * the events will fire as registration completes, this could be before or after
- * this method returns.
+ * Get an instance of the SubscriptionManager from the Context.
+ * This invokes {@link android.content.Context#getSystemService
+ * Context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)}.
*
- * @param listener an instance of SubscriptionListner with overridden methods the
- * overridden method should match the bits defined in events.
- * @param events is one or more of the SubscriptionListener.LISTEN_Xxx bits
+ * @param context to use.
+ * @return SubscriptionManager instance
*/
- public static void register(Context context, SubscriptionListener listener, int events) {
- String pkgForDebug = context != null ? context.getPackageName() : "<unknown>";
+ public static SubscriptionManager from(Context context) {
+ return (SubscriptionManager) context.getSystemService(
+ 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) {
- logd("SubscriptionManager listen pkgForDebug=" + pkgForDebug
- + " events=0x" + Integer.toHexString(events) + " listener=" + listener);
+ logd("register OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug
+ + " listener=" + listener);
}
try {
- // We use the TelephonyRegistry as its runs in the system and thus is always
- // available where as SubscriptionController could crash and not be available
+ // We use the TelephonyRegistry as it runs in the system and thus is always
+ // available. Where as SubscriptionController could crash and not be available
ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
"telephony.registry"));
if (tr != null) {
- tr.registerSubscriptionListener(pkgForDebug, listener.callback, events);
+ tr.registerOnSubscriptionsChangedListener(pkgForDebug, listener.callback);
}
} catch (RemoteException ex) {
// Should not happen
@@ -270,15 +358,16 @@
}
/**
- * Unregister the listener.
+ * Unregister the {@link OnSubscriptionsChangedListener}. This is not strictly necessary
+ * as the listener will automatically be unregistered if an attempt to invoke the listener
+ * fails.
*
- * @param context
- * @param listener
+ * @param listener that is to be unregistered.
*/
- public static void unregister(Context context, SubscriptionListener listener) {
- String pkgForDebug = context != null ? context.getPackageName() : "<unknown>";
+ public void unregisterOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
+ String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>";
if (DBG) {
- logd("SubscriptionManager unregister pkgForDebug=" + pkgForDebug
+ logd("unregister OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug
+ " listener=" + listener);
}
try {
@@ -287,7 +376,7 @@
ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
"telephony.registry"));
if (tr != null) {
- tr.unregisterSubscriptionListener(pkgForDebug, listener.callback);
+ tr.unregisterOnSubscriptionsChangedListener(pkgForDebug, listener.callback);
}
} catch (RemoteException ex) {
// Should not happen
@@ -295,13 +384,14 @@
}
/**
- * Get the SubscriptionInfo associated with the subId
- * @param subId The unique SubscriptionInfo index in database
- * @return SubscriptionInfo, maybe null
+ * Get the active SubscriptionInfo with the subId key
+ * @param subId The unique SubscriptionInfo key in database
+ * @return SubscriptionInfo, maybe null if its not active.
*/
- public static SubscriptionInfo getSubscriptionInfoForSubscriber(int subId) {
+ public SubscriptionInfo getActiveSubscriptionInfo(int subId) {
+ if (VDBG) logd("[getActiveSubscriptionInfo]+ subId=" + subId);
if (!isValidSubId(subId)) {
- logd("[getSubscriptionInfoForSubscriber]- invalid subId");
+ logd("[getActiveSubscriptionInfo]- invalid subId");
return null;
}
@@ -310,7 +400,7 @@
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) {
- subInfo = iSub.getSubInfoForSubscriber(subId);
+ subInfo = iSub.getActiveSubscriptionInfo(subId);
}
} catch (RemoteException ex) {
// ignore it
@@ -321,73 +411,64 @@
}
/**
- * Get the SubscriptionInfo according to an IccId
+ * Get the active SubscriptionInfo associated with the iccId
* @param iccId the IccId of SIM card
- * @return SubscriptionInfo List, maybe empty but not null
+ * @return SubscriptionInfo, maybe null if its not active
* @hide
*/
- public static List<SubscriptionInfo> getSubscriptionInfoUsingIccId(String iccId) {
- if (VDBG) logd("[getSubscriptionInfoUsingIccId]+ iccId=" + iccId);
+ public SubscriptionInfo getActiveSubscriptionInfoForIccIndex(String iccId) {
+ if (VDBG) logd("[getActiveSubscriptionInfoForIccIndex]+ iccId=" + iccId);
if (iccId == null) {
- logd("[getSubscriptionInfoUsingIccId]- null iccid");
+ logd("[getActiveSubscriptionInfoForIccIndex]- null iccid");
return null;
}
- List<SubscriptionInfo> result = null;
+ SubscriptionInfo result = null;
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) {
- result = iSub.getSubInfoUsingIccId(iccId);
+ result = iSub.getActiveSubscriptionInfoForIccId(iccId);
}
} catch (RemoteException ex) {
// ignore it
}
-
- if (result == null) {
- result = new ArrayList<SubscriptionInfo>();
- }
return result;
}
/**
- * Get the SubscriptionInfo according to slotId
- * @param slotId the slot which the SIM is inserted
- * @return SubscriptionInfo list, maybe empty but not null
+ * 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
*/
- public static List<SubscriptionInfo> getSubscriptionInfoUsingSlotId(int slotId) {
- // FIXME: Consider never returning null
- if (!isValidSlotId(slotId)) {
- logd("[getSubscriptionInfoUsingSlotId]- invalid slotId");
+ public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIdx) {
+ if (VDBG) logd("[getActiveSubscriptionInfoForSimSlotIndex]+ slotIdx=" + slotIdx);
+ if (!isValidSlotId(slotIdx)) {
+ logd("[getActiveSubscriptionInfoForSimSlotIndex]- invalid slotIdx");
return null;
}
- List<SubscriptionInfo> result = null;
+ SubscriptionInfo result = null;
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) {
- result = iSub.getSubInfoUsingSlotId(slotId);
+ result = iSub.getActiveSubscriptionInfoForSimSlotIndex(slotIdx);
}
} catch (RemoteException ex) {
// ignore it
}
-
- if (result == null) {
- result = new ArrayList<SubscriptionInfo>();
- }
return result;
}
/**
- * Get all the SubscriptionInfo(s) in subInfo database
- * @return List of all SubscriptionInfos in database, include those that were inserted before
- * maybe empty but not null.
+ * @return List of all SubscriptionInfo records in database,
+ * include those that were inserted before, maybe empty but not null.
* @hide
*/
- public static List<SubscriptionInfo> getAllSubscriptionInfoList() {
+ public List<SubscriptionInfo> getAllSubscriptionInfoList() {
if (VDBG) logd("[getAllSubscriptionInfoList]+");
List<SubscriptionInfo> result = null;
@@ -408,33 +489,45 @@
}
/**
- * Get the SubscriptionInfo(s) of the currently inserted SIM(s)
- * @return Array list of currently inserted SubscriptionInfo(s) maybe empty but not null
+ * Get the SubscriptionInfo(s) of the currently inserted SIM(s). 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>
*/
- public static List<SubscriptionInfo> getActiveSubscriptionInfoList() {
+ public List<SubscriptionInfo> getActiveSubscriptionInfoList() {
List<SubscriptionInfo> result = null;
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) {
- result = iSub.getActiveSubInfoList();
+ result = iSub.getActiveSubscriptionInfoList();
}
} catch (RemoteException ex) {
// ignore it
}
-
- if (result == null) {
- result = new ArrayList<SubscriptionInfo>();
- }
return result;
}
/**
- * Get the SUB count of all SUB(s) in subinfo database
- * @return all SIM count in database, include what was inserted before
+ * @return the count of all subscriptions in the database, this includes
+ * all subscriptions that have been seen.
* @hide
*/
- public static int getAllSubscriptionInfoCount() {
+ public int getAllSubscriptionInfoCount() {
if (VDBG) logd("[getAllSubscriptionInfoCount]+");
int result = 0;
@@ -452,11 +545,11 @@
}
/**
- * Get the count of active SUB(s)
- * @return active SIM count
- * @hide
+ * @return the current number of active subscriptions. There is no guarantee the value
+ * returned by this method will be the same as the length of the list returned by
+ * {@link #getActiveSubscriptionInfoList}.
*/
- public static int getActiveSubscriptionInfoCount() {
+ public int getActiveSubscriptionInfoCount() {
int result = 0;
try {
@@ -472,13 +565,33 @@
}
/**
- * Add a new SubscriptionInfo to subinfo database if needed
+ * @return the maximum number of active subscriptions that will be returned by
+ * {@link #getActiveSubscriptionInfoList} and the value returned by
+ * {@link #getActiveSubscriptionInfoCount}.
+ */
+ 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 SubscriptionInfo database if needed
* @param iccId the IccId of the SIM card
* @param slotId the slot which the SIM is inserted
* @return the URL of the newly created row or the updated row
* @hide
*/
- public static Uri addSubscriptionInfoRecord(String iccId, int slotId) {
+ public Uri addSubscriptionInfoRecord(String iccId, int slotId) {
if (VDBG) logd("[addSubscriptionInfoRecord]+ iccId:" + iccId + " slotId:" + slotId);
if (iccId == null) {
logd("[addSubscriptionInfoRecord]- null iccId");
@@ -504,12 +617,12 @@
/**
* Set SIM icon tint color by simInfo index
- * @param tint the rgb value of icon tint color of the SIM
+ * @param tint the RGB value of icon tint color of the SIM
* @param subId the unique SubInfoRecord index in database
* @return the number of records updated
* @hide
*/
- public static int setIconTint(int tint, int subId) {
+ public int setIconTint(int tint, int subId) {
if (VDBG) logd("[setIconTint]+ tint:" + tint + " subId:" + subId);
if (!isValidSubId(subId)) {
logd("[setIconTint]- fail");
@@ -538,7 +651,7 @@
* @return the number of records updated
* @hide
*/
- public static int setDisplayName(String displayName, int subId) {
+ public int setDisplayName(String displayName, int subId) {
return setDisplayName(displayName, subId, NAME_SOURCE_UNDEFINDED);
}
@@ -551,7 +664,7 @@
* @return the number of records updated or -1 if invalid subId
* @hide
*/
- public static int setDisplayName(String displayName, int subId, long nameSource) {
+ public int setDisplayName(String displayName, int subId, long nameSource) {
if (VDBG) {
logd("[setDisplayName]+ displayName:" + displayName + " subId:" + subId
+ " nameSource:" + nameSource);
@@ -583,7 +696,7 @@
* @return the number of records updated
* @hide
*/
- public static int setDisplayNumber(String number, int subId) {
+ public int setDisplayNumber(String number, int subId) {
if (number == null || !isValidSubId(subId)) {
logd("[setDisplayNumber]- fail");
return -1;
@@ -611,7 +724,7 @@
* @return the number of records updated
* @hide
*/
- public static int setDataRoaming(int roaming, int subId) {
+ public int setDataRoaming(int roaming, int subId) {
if (VDBG) logd("[setDataRoaming]+ roaming:" + roaming + " subId:" + subId);
if (roaming < 0 || !isValidSubId(subId)) {
logd("[setDataRoaming]- fail");
@@ -643,7 +756,7 @@
logd("[getSlotId]- fail");
}
- int result = INVALID_SLOT_ID;
+ int result = INVALID_SIM_SLOT_INDEX;
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -683,10 +796,10 @@
public static int getPhoneId(int subId) {
if (!isValidSubId(subId)) {
logd("[getPhoneId]- fail");
- return INVALID_PHONE_ID;
+ return INVALID_PHONE_INDEX;
}
- int result = INVALID_PHONE_ID;
+ int result = INVALID_PHONE_INDEX;
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -703,7 +816,7 @@
}
private static void logd(String msg) {
- Rlog.d(LOG_TAG, "[SubManager] " + msg);
+ Rlog.d(LOG_TAG, msg);
}
/**
@@ -713,7 +826,7 @@
* @hide
*/
public static int getDefaultSubId() {
- int subId = INVALID_SUB_ID;
+ int subId = INVALID_SUBSCRIPTION_ID;
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -730,7 +843,7 @@
/** @hide */
public static int getDefaultVoiceSubId() {
- int subId = INVALID_SUB_ID;
+ int subId = INVALID_SUBSCRIPTION_ID;
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -746,7 +859,7 @@
}
/** @hide */
- public static void setDefaultVoiceSubId(int subId) {
+ public void setDefaultVoiceSubId(int subId) {
if (VDBG) logd("setDefaultVoiceSubId sub id = " + subId);
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -759,8 +872,8 @@
}
/** @hide */
- public static SubscriptionInfo getDefaultVoiceSubscriptionInfo() {
- return getSubscriptionInfoForSubscriber(getDefaultVoiceSubId());
+ public SubscriptionInfo getDefaultVoiceSubscriptionInfo() {
+ return getActiveSubscriptionInfo(getDefaultVoiceSubId());
}
/** @hide */
@@ -769,11 +882,13 @@
}
/**
- * @return subId of the DefaultSms subscription or the value INVALID_SUB_ID if an error.
+ * @return subId of the DefaultSms subscription or
+ * the value INVALID_SUBSCRIPTION_ID if an error.
+ *
* @hide
*/
public static int getDefaultSmsSubId() {
- int subId = INVALID_SUB_ID;
+ int subId = INVALID_SUBSCRIPTION_ID;
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -789,7 +904,7 @@
}
/** @hide */
- public static void setDefaultSmsSubId(int subId) {
+ public void setDefaultSmsSubId(int subId) {
if (VDBG) logd("setDefaultSmsSubId sub id = " + subId);
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -802,18 +917,18 @@
}
/** @hide */
- public static SubscriptionInfo getDefaultSmsSubscriptionInfo() {
- return getSubscriptionInfoForSubscriber(getDefaultSmsSubId());
+ public SubscriptionInfo getDefaultSmsSubscriptionInfo() {
+ return getActiveSubscriptionInfo(getDefaultSmsSubId());
}
/** @hide */
- public static int getDefaultSmsPhoneId() {
+ public int getDefaultSmsPhoneId() {
return getPhoneId(getDefaultSmsSubId());
}
/** @hide */
public static int getDefaultDataSubId() {
- int subId = INVALID_SUB_ID;
+ int subId = INVALID_SUBSCRIPTION_ID;
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -829,7 +944,7 @@
}
/** @hide */
- public static void setDefaultDataSubId(int subId) {
+ public void setDefaultDataSubId(int subId) {
if (VDBG) logd("setDataSubscription sub id = " + subId);
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -842,17 +957,17 @@
}
/** @hide */
- public static SubscriptionInfo getDefaultDataSubscriptionInfo() {
- return getSubscriptionInfoForSubscriber(getDefaultDataSubId());
+ public SubscriptionInfo getDefaultDataSubscriptionInfo() {
+ return getActiveSubscriptionInfo(getDefaultDataSubId());
}
/** @hide */
- public static int getDefaultDataPhoneId() {
+ public int getDefaultDataPhoneId() {
return getPhoneId(getDefaultDataSubId());
}
/** @hide */
- public static void clearSubscriptionInfo() {
+ public void clearSubscriptionInfo() {
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) {
@@ -867,14 +982,14 @@
//FIXME this is vulnerable to race conditions
/** @hide */
- public static boolean allDefaultsSelected() {
- if (getDefaultDataSubId() == INVALID_SUB_ID) {
+ public boolean allDefaultsSelected() {
+ if (getDefaultDataSubId() == INVALID_SUBSCRIPTION_ID) {
return false;
}
- if (getDefaultSmsSubId() == INVALID_SUB_ID) {
+ if (getDefaultSmsSubId() == INVALID_SUBSCRIPTION_ID) {
return false;
}
- if (getDefaultVoiceSubId() == INVALID_SUB_ID) {
+ if (getDefaultVoiceSubId() == INVALID_SUBSCRIPTION_ID) {
return false;
}
return true;
@@ -882,10 +997,10 @@
/**
* If a default is set to subscription which is not active, this will reset that default back to
- * INVALID_SUB_ID.
+ * INVALID_SUBSCRIPTION_ID.
* @hide
*/
- public static void clearDefaultsForInactiveSubIds() {
+ public void clearDefaultsForInactiveSubIds() {
if (VDBG) logd("clearDefaultsForInactiveSubIds");
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -902,34 +1017,26 @@
* @hide
*/
public static boolean isValidSubId(int subId) {
- return subId > INVALID_SUB_ID ;
+ return subId > INVALID_SUBSCRIPTION_ID ;
}
/**
* @return true if subId is an usable subId value else false. A
- * usable subId means its neither a INVALID_SUB_ID nor a DEFAUL_SUB_ID.
+ * usable subId means its neither a INVALID_SUBSCRIPTION_ID nor a DEFAUL_SUB_ID.
* @hide
*/
public static boolean isUsableSubIdValue(int subId) {
- return subId >= MIN_SUB_ID_VALUE && subId <= MAX_SUB_ID_VALUE;
+ return subId >= MIN_SUBSCRIPTION_ID_VALUE && subId <= MAX_SUBSCRIPTION_ID_VALUE;
}
/** @hide */
public static boolean isValidSlotId(int slotId) {
- // 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();
+ return slotId >= 0 && slotId < TelephonyManager.getDefault().getSimCount();
}
/** @hide */
public static boolean isValidPhoneId(int phoneId) {
- // 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();
+ return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getPhoneCount();
}
/** @hide */
@@ -957,7 +1064,7 @@
* is never null but the length maybe 0.
* @hide
*/
- public static int[] getActiveSubIdList() {
+ public int[] getActiveSubscriptionIdList() {
int[] subId = null;
try {
@@ -976,5 +1083,25 @@
return subId;
}
+
+ /**
+ * Returns true if the device is considered roaming on the current
+ * network for a subscription.
+ * <p>
+ * Availability: Only when user registered to a network.
+ *
+ * @param subId The subscription ID
+ * @return true if the network for the subscription is roaming, false otherwise
+ */
+ public boolean isNetworkRoaming(int subId) {
+ final int phoneId = getPhoneId(subId);
+ if (phoneId < 0) {
+ // What else can we do?
+ return false;
+ }
+ // FIXME: use better way to get roaming status instead of reading from system property
+ return Boolean.parseBoolean(TelephonyManager.getTelephonyProperty(phoneId,
+ TelephonyProperties.PROPERTY_OPERATOR_ISROAMING, null));
+ }
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 7c03d42..40a8ed4 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -79,6 +79,7 @@
}
private final Context mContext;
+ private SubscriptionManager mSubscriptionManager;
private static String multiSimConfig =
SystemProperties.get(TelephonyProperties.PROPERTY_MULTI_SIM_CONFIG);
@@ -104,6 +105,7 @@
} else {
mContext = context;
}
+ mSubscriptionManager = SubscriptionManager.from(mContext);
if (sRegistry == null) {
sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
@@ -157,6 +159,9 @@
public int getPhoneCount() {
int phoneCount = 1;
switch (getMultiSimConfiguration()) {
+ case UNKNOWN:
+ phoneCount = 1;
+ break;
case DSDS:
case DSDA:
phoneCount = PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM;
@@ -1527,7 +1532,7 @@
* @see #getSimState
*/
public String getSimOperator() {
- int subId = SubscriptionManager.getDefaultDataSubId();
+ int subId = mSubscriptionManager.getDefaultDataSubId();
if (!SubscriptionManager.isUsableSubIdValue(subId)) {
subId = SubscriptionManager.getDefaultSmsSubId();
if (!SubscriptionManager.isUsableSubIdValue(subId)) {
@@ -1989,7 +1994,7 @@
* <p>Requires that the calling app has carrier privileges.
* @see #hasCarrierPrivileges
*
- * @param subId The subscriber id.
+ * @param subId The subscription id.
* @param alphaTag The alpha tag to display.
* @param number The voicemail number.
*/
@@ -2379,8 +2384,6 @@
* PackageManager.FEATURE_TELEPHONY system feature, which is available
* on any device with a telephony radio, even if the device is
* data-only.
- *
- * @hide pending API review
*/
public boolean isVoiceCapable() {
if (mContext == null) return true;
diff --git a/telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl b/telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl
new file mode 100644
index 0000000..493b1ff
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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();
+}
+
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index d82c492..ca82083 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -22,51 +22,71 @@
interface ISub {
/**
- * Get the SubscriptionInfo according to an index
- * @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
+ * @return a list of all subscriptions in the database, this includes
+ * all subscriptions that have been seen.
*/
List<SubscriptionInfo> getAllSubInfoList();
/**
- * Get the SubscriptionInfo(s) of the currently inserted SIM(s)
- * @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
+ * @return the count of all subscriptions in the database, this includes
+ * all subscriptions that have been seen.
*/
int getAllSubInfoCount();
/**
- * Get the count of active SUB(s)
- * @return active SIM count
+ * Get the active SubscriptionInfo with the subId key
+ * @param subId The unique SubscriptionInfo key in database
+ * @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();
/**
+ * @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
* @param iccId the IccId of the SIM card
* @param slotId the slot which the SIM is inserted
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 1a1f8fe..ba62f5f 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -27,11 +27,13 @@
import android.telephony.CellInfo;
import android.telephony.VoLteServiceState;
import com.android.internal.telephony.IPhoneStateListener;
-import com.android.internal.telephony.ISubscriptionListener;
+import com.android.internal.telephony.IOnSubscriptionsChangedListener;
interface ITelephonyRegistry {
- void registerSubscriptionListener(String pkg, ISubscriptionListener callback, int events);
- void unregisterSubscriptionListener(String pkg, ISubscriptionListener callback);
+ void registerOnSubscriptionsChangedListener(String pkg,
+ IOnSubscriptionsChangedListener callback);
+ void unregisterOnSubscriptionsChangedListener(String pkg,
+ IOnSubscriptionsChangedListener callback);
void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow);
void listenForSubscriber(in int subId, String pkg, IPhoneStateListener callback, int events,
boolean notifyNow);