am 4f1cce63: am 12c2136e: Merge "Additional changes to SubscriptionManager API as per API council." into lmp-mr1-dev
* commit '4f1cce63061976490e2e2cfc4085e1634d3a02de': Additional changes to SubscriptionManager API as per API council.
This commit is contained in:
@@ -373,8 +373,8 @@ LOCAL_SRC_FILES += \
|
||||
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 \
|
||||
|
||||
@@ -7272,6 +7272,7 @@ package android.content {
|
||||
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";
|
||||
@@ -16934,8 +16935,8 @@ package android.net {
|
||||
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";
|
||||
@@ -25581,7 +25582,7 @@ package android.provider {
|
||||
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";
|
||||
@@ -25614,7 +25615,7 @@ package android.provider {
|
||||
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";
|
||||
}
|
||||
@@ -25715,7 +25716,7 @@ package android.provider {
|
||||
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 {
|
||||
@@ -25801,7 +25802,7 @@ package android.provider {
|
||||
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";
|
||||
}
|
||||
@@ -28640,6 +28641,8 @@ package android.telephony {
|
||||
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();
|
||||
@@ -28654,20 +28657,22 @@ package android.telephony {
|
||||
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 {
|
||||
@@ -28705,6 +28710,7 @@ package android.telephony {
|
||||
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();
|
||||
|
||||
@@ -20,9 +20,9 @@ import android.app.usage.IUsageStatsManager;
|
||||
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.print.PrintManager;
|
||||
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 @@ class ContextImpl extends Context {
|
||||
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());
|
||||
|
||||
@@ -2245,6 +2245,8 @@ public abstract class Context {
|
||||
* @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
|
||||
@@ -2587,6 +2589,16 @@ public abstract class Context {
|
||||
*/
|
||||
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
|
||||
* {@link android.telecom.TelecomManager} to manage telecom-related features
|
||||
|
||||
@@ -387,7 +387,6 @@ public class CallLog {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -82,10 +82,10 @@ public class KeyguardSecurityModel {
|
||||
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 {
|
||||
|
||||
@@ -71,7 +71,7 @@ public class KeyguardSimPinView extends KeyguardPinBasedInputView {
|
||||
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;
|
||||
|
||||
@@ -114,7 +114,7 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView {
|
||||
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;
|
||||
|
||||
@@ -27,7 +27,6 @@ import android.content.ContentResolver;
|
||||
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_LEVEL;
|
||||
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.FingerprintManager;
|
||||
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 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
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 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
}
|
||||
};
|
||||
|
||||
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 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
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 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
}
|
||||
}
|
||||
|
||||
/** @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 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
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 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
|
||||
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 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
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 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
+ 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 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
/**
|
||||
* 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);
|
||||
|
||||
@@ -926,9 +926,10 @@ public class KeyguardViewMediator extends SystemUI {
|
||||
// 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);
|
||||
|
||||
|
||||
@@ -239,7 +239,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
||||
|
||||
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(
|
||||
|
||||
@@ -34,8 +34,6 @@ import android.os.UserHandle;
|
||||
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.ServiceState;
|
||||
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.TextUtils;
|
||||
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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
|
||||
private final IBatteryStats mBatteryStats;
|
||||
|
||||
private boolean hasNotifySubscriptionInfoChangedOccurred = false;
|
||||
|
||||
private int mNumPhones;
|
||||
|
||||
private int[] mCallState;
|
||||
@@ -168,9 +167,9 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
|
||||
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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
//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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
}
|
||||
|
||||
@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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
@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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
// 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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
}
|
||||
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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
}
|
||||
|
||||
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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
}
|
||||
|
||||
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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
}
|
||||
|
||||
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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
}
|
||||
|
||||
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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
}
|
||||
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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
}
|
||||
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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
}
|
||||
|
||||
public void notifyDataConnectionFailed(String reason, String apnType) {
|
||||
notifyDataConnectionFailedForSubscriber(SubscriptionManager.DEFAULT_SUB_ID,
|
||||
notifyDataConnectionFailedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
|
||||
reason, apnType);
|
||||
}
|
||||
|
||||
@@ -1062,7 +1066,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
}
|
||||
|
||||
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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
}
|
||||
|
||||
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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
|
||||
@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 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -73,8 +73,8 @@ import android.provider.Telephony.Carriers;
|
||||
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 @@ public class GpsLocationProvider implements LocationProviderInterface {
|
||||
}
|
||||
};
|
||||
|
||||
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 @@ public class GpsLocationProvider implements LocationProviderInterface {
|
||||
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);
|
||||
|
||||
@@ -227,7 +227,7 @@ public class PhoneStateListener {
|
||||
* @hide
|
||||
*/
|
||||
/** @hide */
|
||||
protected int mSubId = SubscriptionManager.INVALID_SUB_ID;
|
||||
protected int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
|
||||
private final Handler mHandler;
|
||||
|
||||
@@ -237,7 +237,7 @@ public class PhoneStateListener {
|
||||
* 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 @@ public class PhoneStateListener {
|
||||
* @hide
|
||||
*/
|
||||
public PhoneStateListener(Looper looper) {
|
||||
this(SubscriptionManager.DEFAULT_SUB_ID, looper);
|
||||
this(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, looper);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -101,12 +101,17 @@ public class SubscriptionInfo implements Parcelable {
|
||||
*/
|
||||
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 @@ public class SubscriptionInfo implements Parcelable {
|
||||
this.mIconBitmap = icon;
|
||||
this.mMcc = mcc;
|
||||
this.mMnc = mnc;
|
||||
this.mCountryIso = countryIso;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,7 +165,6 @@ public class SubscriptionInfo implements Parcelable {
|
||||
|
||||
/**
|
||||
* Returns the name displayed to the user that identifies Subscription provider name
|
||||
* @hide
|
||||
*/
|
||||
public CharSequence getCarrierName() {
|
||||
return this.mCarrierName;
|
||||
@@ -265,6 +270,13 @@ public class SubscriptionInfo implements Parcelable {
|
||||
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 @@ public class SubscriptionInfo implements Parcelable {
|
||||
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 @@ public class SubscriptionInfo implements Parcelable {
|
||||
dest.writeInt(mDataRoaming);
|
||||
dest.writeInt(mMcc);
|
||||
dest.writeInt(mMnc);
|
||||
dest.writeString(mCountryIso);
|
||||
mIconBitmap.writeToParcel(dest, flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -21,14 +21,17 @@ import android.annotation.SdkConstant.SdkConstantType;
|
||||
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 @@ import java.util.List;
|
||||
/**
|
||||
* 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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
/**
|
||||
* 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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
|
||||
/**
|
||||
* 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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
* @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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
* @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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
* @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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
* @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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
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 class SubscriptionManager implements BaseColumns {
|
||||
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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
}
|
||||
|
||||
private static void logd(String msg) {
|
||||
Rlog.d(LOG_TAG, "[SubManager] " + msg);
|
||||
Rlog.d(LOG_TAG, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -713,7 +826,7 @@ public class SubscriptionManager implements BaseColumns {
|
||||
* @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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
|
||||
/** @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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
}
|
||||
|
||||
/** @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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static SubscriptionInfo getDefaultVoiceSubscriptionInfo() {
|
||||
return getSubscriptionInfoForSubscriber(getDefaultVoiceSubId());
|
||||
public SubscriptionInfo getDefaultVoiceSubscriptionInfo() {
|
||||
return getActiveSubscriptionInfo(getDefaultVoiceSubId());
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@@ -769,11 +882,13 @@ public class SubscriptionManager implements BaseColumns {
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
}
|
||||
|
||||
/** @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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
}
|
||||
|
||||
/** @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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
}
|
||||
|
||||
/** @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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
}
|
||||
|
||||
/** @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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
|
||||
//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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
|
||||
/**
|
||||
* 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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
* @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 @@ public class SubscriptionManager implements BaseColumns {
|
||||
* is never null but the length maybe 0.
|
||||
* @hide
|
||||
*/
|
||||
public static int[] getActiveSubIdList() {
|
||||
public int[] getActiveSubscriptionIdList() {
|
||||
int[] subId = null;
|
||||
|
||||
try {
|
||||
@@ -976,5 +1083,25 @@ public class SubscriptionManager implements BaseColumns {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ public class TelephonyManager {
|
||||
}
|
||||
|
||||
private final Context mContext;
|
||||
private SubscriptionManager mSubscriptionManager;
|
||||
|
||||
private static String multiSimConfig =
|
||||
SystemProperties.get(TelephonyProperties.PROPERTY_MULTI_SIM_CONFIG);
|
||||
@@ -104,6 +105,7 @@ public class TelephonyManager {
|
||||
} else {
|
||||
mContext = context;
|
||||
}
|
||||
mSubscriptionManager = SubscriptionManager.from(mContext);
|
||||
|
||||
if (sRegistry == null) {
|
||||
sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
|
||||
@@ -157,6 +159,9 @@ public class TelephonyManager {
|
||||
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 @@ public class TelephonyManager {
|
||||
* @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 @@ public class TelephonyManager {
|
||||
* <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.
|
||||
*/
|
||||
@@ -2375,8 +2380,6 @@ public class TelephonyManager {
|
||||
* 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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -22,50 +22,70 @@ import com.android.internal.telephony.ISubscriptionListener;
|
||||
|
||||
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
|
||||
|
||||
@@ -27,11 +27,13 @@ import android.telephony.SignalStrength;
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user