Update SubscriptionManager API as per API council.

bug: 17575308
Change-Id: Ib39a60e4f75981a466e9d606ec627756efad018d
diff --git a/src/java/android/telephony/SmsManager.java b/src/java/android/telephony/SmsManager.java
index b808112..249cf5f 100644
--- a/src/java/android/telephony/SmsManager.java
+++ b/src/java/android/telephony/SmsManager.java
@@ -501,7 +501,7 @@
      */
     public int getSubId() {
         if (mSubId == DEFAULT_SUB_ID) {
-            return getDefaultSmsSubId();
+            return getDefaultSmsSubscriptionId();
         }
         return mSubId;
     }
@@ -858,10 +858,17 @@
      * Get default sms subId
      *
      * @return the default SubId
-     * @hide
      */
-    public static int getDefaultSmsSubId() {
-        return SubscriptionManager.getDefaultSmsSubId();
+    public static int getDefaultSmsSubscriptionId() {
+        ISms iccISms = null;
+        try {
+            iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
+            return iccISms.getPreferredSmsSubscription();
+        } catch (RemoteException ex) {
+            return SubscriptionManager.INVALID_SUB_ID;
+        } catch (NullPointerException ex) {
+            return SubscriptionManager.INVALID_SUB_ID;
+        }
     }
 
     /**
diff --git a/src/java/com/android/internal/telephony/IccProvider.java b/src/java/com/android/internal/telephony/IccProvider.java
index edb0fb1..b73d561 100755
--- a/src/java/com/android/internal/telephony/IccProvider.java
+++ b/src/java/com/android/internal/telephony/IccProvider.java
@@ -25,7 +25,7 @@
 import android.net.Uri;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.telephony.SubInfoRecord;
+import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
@@ -117,7 +117,7 @@
 
     private Cursor loadAllSimContacts(int efType) {
         Cursor [] result;
-        List<SubInfoRecord> subInfoList = SubscriptionManager.getActiveSubInfoList();
+        List<SubscriptionInfo> subInfoList = SubscriptionManager.getActiveSubscriptionInfoList();
 
         if ((subInfoList == null) || (subInfoList.size() == 0)) {
             result = new Cursor[0];
diff --git a/src/java/com/android/internal/telephony/PhoneFactory.java b/src/java/com/android/internal/telephony/PhoneFactory.java
index c3afa46..5603e3a 100644
--- a/src/java/com/android/internal/telephony/PhoneFactory.java
+++ b/src/java/com/android/internal/telephony/PhoneFactory.java
@@ -34,7 +34,7 @@
 import com.android.internal.telephony.cdma.CDMAPhone;
 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
 import com.android.internal.telephony.gsm.GSMPhone;
-import com.android.internal.telephony.SubInfoRecordUpdater;
+import com.android.internal.telephony.SubscriptionInfoUpdater;
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.imsphone.ImsPhoneFactory;
 import com.android.internal.telephony.sip.SipPhone;
@@ -66,7 +66,7 @@
     static private UiccController mUiccController;
 
     static private CommandsInterface sCommandsInterface = null;
-    static private SubInfoRecordUpdater sSubInfoRecordUpdater = null;
+    static private SubscriptionInfoUpdater sSubInfoRecordUpdater = null;
 
     static private boolean sMadeDefaults = false;
     static private PhoneNotifier sPhoneNotifier;
@@ -201,7 +201,7 @@
                 sMadeDefaults = true;
 
                 Rlog.i(LOG_TAG, "Creating SubInfoRecordUpdater ");
-                sSubInfoRecordUpdater = new SubInfoRecordUpdater(context,
+                sSubInfoRecordUpdater = new SubscriptionInfoUpdater(context,
                         sProxyPhones, sCommandsInterfaces);
                 SubscriptionController.getInstance().updatePhonesAvailability(sProxyPhones);
             }
@@ -263,36 +263,6 @@
         }
     }
 
-    public static Phone getCdmaPhone() {
-        if (!sMadeDefaults) {
-            throw new IllegalStateException("Default phones haven't been made yet!");
-        }
-        Phone phone;
-        synchronized(PhoneProxy.lockForRadioTechnologyChange) {
-            switch (TelephonyManager.getLteOnCdmaModeStatic()) {
-                case PhoneConstants.LTE_ON_CDMA_TRUE: {
-                    phone = new CDMALTEPhone(sContext, sCommandsInterface, sPhoneNotifier);
-                    break;
-                }
-                case PhoneConstants.LTE_ON_CDMA_FALSE:
-                case PhoneConstants.LTE_ON_CDMA_UNKNOWN:
-                default: {
-                    phone = new CDMAPhone(sContext, sCommandsInterface, sPhoneNotifier);
-                    break;
-                }
-            }
-        }
-        return phone;
-    }
-
-    public static Phone getGsmPhone() {
-        int phoneId = SubscriptionController.getInstance().getPhoneId(getDefaultSubscription());
-        if (phoneId < 0 || phoneId >= TelephonyManager.getDefault().getPhoneCount()) {
-            phoneId = 0;
-        }
-        return getGsmPhone(phoneId);
-    }
-
     /**
      * Makes a {@link SipPhone} object.
      * @param sipUri the local SIP URI the phone runs on
diff --git a/src/java/com/android/internal/telephony/SubscriptionController.java b/src/java/com/android/internal/telephony/SubscriptionController.java
index 24f7ef4..4808c99 100644
--- a/src/java/com/android/internal/telephony/SubscriptionController.java
+++ b/src/java/com/android/internal/telephony/SubscriptionController.java
@@ -20,25 +20,33 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.net.Uri;
 import android.os.AsyncResult;
+import android.os.Binder;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Message;
+import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.provider.BaseColumns;
 import android.provider.Settings;
+
 import android.telephony.Rlog;
-import android.telephony.SubInfoRecord;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionListener;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.text.format.Time;
 import android.util.Log;
 
+import com.android.internal.telephony.ITelephonyRegistry;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -72,6 +80,25 @@
     static final int MAX_LOCAL_LOG_LINES = 500; // TODO: Reduce to 100 when 17678050 is fixed
     private ScLocalLog mLocalLog = new ScLocalLog(MAX_LOCAL_LOG_LINES);
 
+    private static class Record {
+        String pkgForDebug;
+        IBinder binder;
+        ISubscriptionListener callback;
+        int callerUid;
+        int events;
+
+        @Override
+        public String toString() {
+            return "{pkgForDebug=" + pkgForDebug + " callerUid=" + callerUid +
+                    " events=" + Integer.toHexString(events) + "}";
+        }
+    }
+
+    // All types of access to both mRemoveList and mRecords must
+    // be inside a synchronized(mRecords) block.
+    private final ArrayList<IBinder> mRemoveList = new ArrayList<IBinder>();
+    private final ArrayList<Record> mRecords = new ArrayList<Record>();
+
     /**
      * Copied from android.util.LocalLog with flush() adding flush and line number
      * TODO: Update LocalLog
@@ -215,37 +242,51 @@
     }
 
     /**
-     * Broadcast when subinfo settings has chanded
-     * @SubId The unique SubInfoRecord index in database
-     * @param columnName The column that is updated
-     * @param intContent The updated integer value
-     * @param stringContent The updated string value
+     * Broadcast when SubscriptionInfo has changed
+     * FIXME: Hopefully removed if the API council accepts SubscriptionInfoListener
      */
-     private void broadcastSimInfoContentChanged(int subId,
-            String columnName, int intContent, String stringContent) {
-
+     private void broadcastSimInfoContentChanged() {
         Intent intent = new Intent(TelephonyIntents.ACTION_SUBINFO_CONTENT_CHANGE);
-        intent.putExtra(BaseColumns._ID, subId);
-        intent.putExtra(TelephonyIntents.EXTRA_COLUMN_NAME, columnName);
-        intent.putExtra(TelephonyIntents.EXTRA_INT_CONTENT, intContent);
-        intent.putExtra(TelephonyIntents.EXTRA_STRING_CONTENT, stringContent);
-        if (intContent != SubscriptionManager.DEFAULT_INT_VALUE) {
-            logd("[broadcastSimInfoContentChanged] subId" + subId
-                    + " changed, " + columnName + " -> " +  intContent);
-        } else {
-            logd("[broadcastSimInfoContentChanged] subId" + subId
-                    + " changed, " + columnName + " -> " +  stringContent);
-        }
         mContext.sendBroadcast(intent);
-    }
+        intent = new Intent(TelephonyIntents.ACTION_SUBINFO_RECORD_UPDATED);
+        mContext.sendBroadcast(intent);
+     }
 
+     private boolean checkNotifyPermission(String method) {
+         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+                     == PackageManager.PERMISSION_GRANTED) {
+             return true;
+         }
+         if (DBG) {
+             logd("checkNotifyPermission Permission Denial: " + method + " from pid="
+                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
+         }
+         return false;
+     }
+
+     public void notifySubscriptionInfoChanged() {
+         if (!checkNotifyPermission("notifySubscriptionInfoChanged")) {
+             return;
+         }
+         ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
+                 "telephony.registry"));
+         try {
+             if (DBG) logd("notifySubscriptionInfoChanged:");
+             tr.notifySubscriptionInfoChanged();
+         } catch (RemoteException ex) {
+             // Should never happen because its always available.
+         }
+
+         // FIXME: Remove if listener technique accepted.
+         broadcastSimInfoContentChanged();
+     }
 
     /**
      * New SubInfoRecord instance and fill in detail info
      * @param cursor
      * @return the query result of desired SubInfoRecord
      */
-    private SubInfoRecord getSubInfoRecord(Cursor cursor) {
+    private SubscriptionInfo getSubInfoRecord(Cursor cursor) {
             int id = cursor.getInt(cursor.getColumnIndexOrThrow(BaseColumns._ID));
             String iccId = cursor.getString(cursor.getColumnIndexOrThrow(
                     SubscriptionManager.ICC_ID));
@@ -276,7 +317,7 @@
                     + " iconTint:" + iconTint + " number:" + number + " dataRoaming:" + dataRoaming
                     + " mcc:" + mcc + " mnc:" + mnc);
 
-            return new SubInfoRecord(id, iccId, simSlotIndex, displayName, carrierName, nameSource,
+            return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName, nameSource,
                     iconTint, number, dataRoaming, iconBitmap, mcc, mnc);
     }
 
@@ -286,24 +327,24 @@
      * @param queryKey query key content
      * @return Array list of queried result from database
      */
-     private List<SubInfoRecord> getSubInfo(String selection, Object queryKey) {
+     private List<SubscriptionInfo> getSubInfo(String selection, Object queryKey) {
         logd("selection:" + selection + " " + queryKey);
         String[] selectionArgs = null;
         if (queryKey != null) {
             selectionArgs = new String[] {queryKey.toString()};
         }
-        ArrayList<SubInfoRecord> subList = null;
+        ArrayList<SubscriptionInfo> subList = null;
         Cursor cursor = mContext.getContentResolver().query(SubscriptionManager.CONTENT_URI,
                 null, selection, selectionArgs, null);
         try {
             if (cursor != null) {
                 while (cursor.moveToNext()) {
-                    SubInfoRecord subInfo = getSubInfoRecord(cursor);
+                    SubscriptionInfo subInfo = getSubInfoRecord(cursor);
                     if (subInfo != null)
                     {
                         if (subList == null)
                         {
-                            subList = new ArrayList<SubInfoRecord>();
+                            subList = new ArrayList<SubscriptionInfo>();
                         }
                         subList.add(subInfo);
                 }
@@ -325,8 +366,10 @@
      * @return RGB integer value of color
      */
     private int getUnusedColor() {
-        List<SubInfoRecord> availableSubInfos = SubscriptionManager.getActiveSubInfoList();
+        List<SubscriptionInfo> availableSubInfos =
+                SubscriptionManager.getActiveSubscriptionInfoList();
         colorArr = mContext.getResources().getIntArray(com.android.internal.R.array.sim_colors);
+
         for (int i = 0; i < colorArr.length; i++) {
             int j;
             for (j = 0; j < availableSubInfos.size(); j++) {
@@ -347,7 +390,7 @@
      * @return SubInfoRecord, maybe null
      */
     @Override
-    public SubInfoRecord getSubInfoForSubscriber(int subId) {
+    public SubscriptionInfo getSubInfoForSubscriber(int subId) {
         logd("[getSubInfoForSubscriberx]+ subId:" + subId);
         enforceSubscriptionPermission();
 
@@ -383,7 +426,7 @@
      * @return SubInfoRecord, maybe null
      */
     @Override
-    public List<SubInfoRecord> getSubInfoUsingIccId(String iccId) {
+    public List<SubscriptionInfo> getSubInfoUsingIccId(String iccId) {
         logd("[getSubInfoUsingIccId]+ iccId:" + iccId);
         enforceSubscriptionPermission();
 
@@ -393,16 +436,16 @@
         }
         Cursor cursor = mContext.getContentResolver().query(SubscriptionManager.CONTENT_URI,
                 null, SubscriptionManager.ICC_ID + "=?", new String[] {iccId}, null);
-        ArrayList<SubInfoRecord> subList = null;
+        ArrayList<SubscriptionInfo> subList = null;
         try {
             if (cursor != null) {
                 while (cursor.moveToNext()) {
-                    SubInfoRecord subInfo = getSubInfoRecord(cursor);
+                    SubscriptionInfo subInfo = getSubInfoRecord(cursor);
                     if (subInfo != null)
                     {
                         if (subList == null)
                         {
-                            subList = new ArrayList<SubInfoRecord>();
+                            subList = new ArrayList<SubscriptionInfo>();
                         }
                         subList.add(subInfo);
                 }
@@ -425,7 +468,7 @@
      * @return SubInfoRecord, maybe null
      */
     @Override
-    public List<SubInfoRecord> getSubInfoUsingSlotId(int slotId) {
+    public List<SubscriptionInfo> getSubInfoUsingSlotId(int slotId) {
         return getSubInfoUsingSlotIdWithCheck(slotId, true);
     }
 
@@ -434,11 +477,11 @@
      * @return Array list of all SubInfoRecords in database, include thsoe that were inserted before
      */
     @Override
-    public List<SubInfoRecord> getAllSubInfoList() {
+    public List<SubscriptionInfo> getAllSubInfoList() {
         logd("[getAllSubInfoList]+");
         enforceSubscriptionPermission();
 
-        List<SubInfoRecord> subList = null;
+        List<SubscriptionInfo> subList = null;
         subList = getSubInfo(null, null);
         if (subList != null) {
             logd("[getAllSubInfoList]- " + subList.size() + " infos return");
@@ -454,11 +497,11 @@
      * @return Array list of currently inserted SubInfoRecord(s)
      */
     @Override
-    public List<SubInfoRecord> getActiveSubInfoList() {
+    public List<SubscriptionInfo> getActiveSubInfoList() {
         enforceSubscriptionPermission();
         logdl("[getActiveSubInfoList]+");
 
-        List<SubInfoRecord> subList = null;
+        List<SubscriptionInfo> subList = null;
 
         if (!isSubInfoReady()) {
             logdl("[getActiveSubInfoList] Sub Controller not ready");
@@ -483,7 +526,7 @@
     @Override
     public int getActiveSubInfoCount() {
         logd("[getActiveSubInfoCount]+");
-        List<SubInfoRecord> records = getActiveSubInfoList();
+        List<SubscriptionInfo> records = getActiveSubInfoList();
         if (records == null) {
             logd("[getActiveSubInfoCount] records null");
             return 0;
@@ -681,8 +724,7 @@
 
         int result = mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI, value,
                 BaseColumns._ID + "=" + Long.toString(subId), null);
-        broadcastSimInfoContentChanged(subId, SubscriptionManager.COLOR,
-                tint, SubscriptionManager.DEFAULT_STRING_VALUE);
+        notifySubscriptionInfoChanged();
 
         return result;
     }
@@ -729,8 +771,7 @@
 
         int result = mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI, value,
                 BaseColumns._ID + "=" + Long.toString(subId), null);
-        broadcastSimInfoContentChanged(subId, SubscriptionManager.DISPLAY_NAME,
-                SubscriptionManager.DEFAULT_INT_VALUE, nameToSet);
+        notifySubscriptionInfoChanged();
 
         return result;
     }
@@ -779,8 +820,7 @@
             result = mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI, value,
                     BaseColumns._ID + "=" + Long.toString(subId), null);
             logd("[setDisplayNumber]- update result :" + result);
-            broadcastSimInfoContentChanged(subId, SubscriptionManager.NUMBER,
-                    SubscriptionManager.DEFAULT_INT_VALUE, number);
+            notifySubscriptionInfoChanged();
         }
 
         return result;
@@ -808,8 +848,7 @@
 
         int result = mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI, value,
                 BaseColumns._ID + "=" + Long.toString(subId), null);
-        broadcastSimInfoContentChanged(subId, SubscriptionManager.DATA_ROAMING,
-                roaming, SubscriptionManager.DEFAULT_STRING_VALUE);
+        notifySubscriptionInfoChanged();
 
         return result;
     }
@@ -836,7 +875,7 @@
 
         int result = mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI, value,
                 BaseColumns._ID + "=" + Long.toString(subId), null);
-        broadcastSimInfoContentChanged(subId, SubscriptionManager.MCC, mcc, null);
+        notifySubscriptionInfoChanged();
 
         return result;
     }
@@ -1184,7 +1223,7 @@
 
     @Override
     public void clearDefaultsForInactiveSubIds() {
-        final List<SubInfoRecord> records = getActiveSubInfoList();
+        final List<SubscriptionInfo> records = getActiveSubInfoList();
         logdl("[clearDefaultsForInactiveSubIds] records: " + records);
         if (shouldDefaultBeCleared(records, getDefaultDataSubId())) {
             logd("[clearDefaultsForInactiveSubIds] clearing default data sub id");
@@ -1200,18 +1239,18 @@
         }
     }
 
-    private boolean shouldDefaultBeCleared(List<SubInfoRecord> records, int subId) {
+    private boolean shouldDefaultBeCleared(List<SubscriptionInfo> records, int subId) {
         logdl("[shouldDefaultBeCleared: subId] " + subId);
         if (records == null) {
             logdl("[shouldDefaultBeCleared] return true no records subId=" + subId);
             return true;
         }
-        if (subId == SubscriptionManager.ASK_USER_SUB_ID && records.size() > 1) {
-            // Only allow ASK_USER_SUB_ID if there is more than 1 subscription.
+        if (subId == SubscriptionManager.INVALID_SUB_ID) {
+            // If the subId parameter is INVALID_SUB_ID its already cleared so return false.
             logdl("[shouldDefaultBeCleared] return false only one subId, subId=" + subId);
             return false;
         }
-        for (SubInfoRecord record : records) {
+        for (SubscriptionInfo record : records) {
             int id = record.getSubscriptionId();
             logdl("[shouldDefaultBeCleared] Record.id: " + id);
             if (id == subId) {
@@ -1237,7 +1276,7 @@
         return getSubId(slotId);
     }
 
-    public List<SubInfoRecord> getSubInfoUsingSlotIdWithCheck(int slotId, boolean needCheck) {
+    public List<SubscriptionInfo> getSubInfoUsingSlotIdWithCheck(int slotId, boolean needCheck) {
         logd("[getSubInfoUsingSlotIdWithCheck]+ slotId:" + slotId);
         enforceSubscriptionPermission();
 
@@ -1256,16 +1295,16 @@
 
         Cursor cursor = mContext.getContentResolver().query(SubscriptionManager.CONTENT_URI,
                 null, SubscriptionManager.SIM_ID + "=?", new String[] {String.valueOf(slotId)}, null);
-        ArrayList<SubInfoRecord> subList = null;
+        ArrayList<SubscriptionInfo> subList = null;
         try {
             if (cursor != null) {
                 while (cursor.moveToNext()) {
-                    SubInfoRecord subInfo = getSubInfoRecord(cursor);
+                    SubscriptionInfo subInfo = getSubInfoRecord(cursor);
                     if (subInfo != null)
                     {
                         if (subList == null)
                         {
-                            subList = new ArrayList<SubInfoRecord>();
+                            subList = new ArrayList<SubscriptionInfo>();
                         }
                         subList.add(subInfo);
                     }
@@ -1349,10 +1388,10 @@
         pw.flush();
         pw.println("++++++++++++++++++++++++++++++++");
 
-        List<SubInfoRecord> sirl = getActiveSubInfoList();
+        List<SubscriptionInfo> sirl = getActiveSubInfoList();
         if (sirl != null) {
             pw.println(" ActiveSubInfoList:");
-            for (SubInfoRecord entry : sirl) {
+            for (SubscriptionInfo entry : sirl) {
                 pw.println("  " + entry.toString());
             }
         } else {
@@ -1364,7 +1403,7 @@
         sirl = getAllSubInfoList();
         if (sirl != null) {
             pw.println(" AllSubInfoList:");
-            for (SubInfoRecord entry : sirl) {
+            for (SubscriptionInfo entry : sirl) {
                 pw.println("  " + entry.toString());
             }
         } else {
diff --git a/src/java/com/android/internal/telephony/SubInfoRecordUpdater.java b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
similarity index 77%
rename from src/java/com/android/internal/telephony/SubInfoRecordUpdater.java
rename to src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
index 872d76d..cc7e3a1 100644
--- a/src/java/com/android/internal/telephony/SubInfoRecordUpdater.java
+++ b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
@@ -34,7 +34,7 @@
 import android.provider.Settings;
 import android.telephony.Rlog;
 import android.telephony.SubscriptionManager;
-import android.telephony.SubInfoRecord;
+import android.telephony.SubscriptionInfo;
 import android.telephony.TelephonyManager;
 import android.util.Log;
 
@@ -53,7 +53,7 @@
 /**
  *@hide
  */
-public class SubInfoRecordUpdater extends Handler {
+public class SubscriptionInfoUpdater extends Handler {
     private static final String LOG_TAG = "SUB";
     private static final int PROJECT_SIM_NUM = TelephonyManager.getDefault().getPhoneCount();
     private static final int EVENT_OFFSET = 8;
@@ -94,7 +94,7 @@
     // To prevent repeatedly update flow every time receiver SIM_STATE_CHANGE
     private static boolean sNeedUpdate = true;
 
-    public SubInfoRecordUpdater(Context context, Phone[] phoneProxy, CommandsInterface[] ci) {
+    public SubscriptionInfoUpdater(Context context, Phone[] phoneProxy, CommandsInterface[] ci) {
         logd("Constructor invoked");
 
         sContext = context;
@@ -150,8 +150,8 @@
                                     SubscriptionManager._ID + "=" + Long.toString(subId), null);
                         }
 
-                        SubInfoRecord subInfo =
-                                SubscriptionManager.getSubInfoForSubscriber(subId);
+                        SubscriptionInfo subInfo =
+                                SubscriptionManager.getSubscriptionInfoForSubscriber(subId);
 
                         if (subInfo != null
                                 && subInfo.getNameSource() !=
@@ -214,7 +214,7 @@
                     sFh[slotId] = null;
                     sIccId[slotId] = ICCID_STRING_FOR_NO_SIM;
                     if (isAllIccIdQueryDone() && sNeedUpdate) {
-                        updateSimInfoByIccId();
+                        updateSubscriptionInfoByIccId();
                     }
                 }
             }
@@ -235,7 +235,7 @@
     }
 
     public static void setDisplayNameForNewSub(String newSubName, int subId, int newNameSource) {
-        SubInfoRecord subInfo = SubscriptionManager.getSubInfoForSubscriber(subId);
+        SubscriptionInfo subInfo = SubscriptionManager.getSubscriptionInfoForSubscriber(subId);
         if (subInfo != null) {
             // overwrite SIM display name if it is not assigned by user
             int oldNameSource = subInfo.getNameSource();
@@ -287,7 +287,7 @@
                 }
                 logd("sIccId[" + slotId + "] = " + sIccId[slotId]);
                 if (isAllIccIdQueryDone() && sNeedUpdate) {
-                    updateSimInfoByIccId();
+                    updateSubscriptionInfoByIccId();
                 }
                 break;
             default:
@@ -314,11 +314,15 @@
         }
     }
 
-    synchronized public void updateSimInfoByIccId() {
-        logd("[updateSimInfoByIccId]+ Start");
+    /**
+     * TODO: Simplify more, as no one is interested in what happened
+     * only what the current list contains.
+     */
+    synchronized private void updateSubscriptionInfoByIccId() {
+        logd("updateSubscriptionInfoByIccId:+ Start");
         sNeedUpdate = false;
 
-        SubscriptionManager.clearSubInfo();
+        SubscriptionManager.clearSubscriptionInfo();
 
         for (int i = 0; i < PROJECT_SIM_NUM; i++) {
             sInsertSimState[i] = SIM_NOT_CHANGE;
@@ -352,11 +356,12 @@
         String[] oldIccId = new String[PROJECT_SIM_NUM];
         for (int i = 0; i < PROJECT_SIM_NUM; i++) {
             oldIccId[i] = null;
-            List<SubInfoRecord> oldSubInfo =
+            List<SubscriptionInfo> oldSubInfo =
                     SubscriptionController.getInstance().getSubInfoUsingSlotIdWithCheck(i, false);
             if (oldSubInfo != null) {
                 oldIccId[i] = oldSubInfo.get(0).getIccId();
-                logd("oldSubId = " + oldSubInfo.get(0).getSubscriptionId());
+                logd("updateSubscriptionInfoByIccId: oldSubId = "
+                        + oldSubInfo.get(0).getSubscriptionId());
                 if (sInsertSimState[i] == SIM_NOT_CHANGE && !sIccId[i].equals(oldIccId[i])) {
                     sInsertSimState[i] = SIM_CHANGED;
                 }
@@ -373,12 +378,13 @@
                     sInsertSimState[i] = SIM_CHANGED;
                 }
                 oldIccId[i] = ICCID_STRING_FOR_NO_SIM;
-                logd("No SIM in slot " + i + " last time");
+                logd("updateSubscriptionInfoByIccId: No SIM in slot " + i + " last time");
             }
         }
 
         for (int i = 0; i < PROJECT_SIM_NUM; i++) {
-            logd("oldIccId[" + i + "] = " + oldIccId[i] + ", sIccId[" + i + "] = " + sIccId[i]);
+            logd("updateSubscriptionInfoByIccId: oldIccId[" + i + "] = " + oldIccId[i] +
+                    ", sIccId[" + i + "] = " + sIccId[i]);
         }
 
         //check if the inserted SIM is new SIM
@@ -386,16 +392,16 @@
         int nNewSimStatus = 0;
         for (int i = 0; i < PROJECT_SIM_NUM; i++) {
             if (sInsertSimState[i] == SIM_NOT_INSERT) {
-                logd("No SIM inserted in slot " + i + " this time");
+                logd("updateSubscriptionInfoByIccId: No SIM inserted in slot " + i + " this time");
             } else {
                 if (sInsertSimState[i] > 0) {
                     //some special SIMs may have the same IccIds, add suffix to distinguish them
                     //FIXME: addSubInfoRecord can return an error.
-                    SubscriptionManager.addSubInfoRecord(sIccId[i]
+                    SubscriptionManager.addSubscriptionInfoRecord(sIccId[i]
                             + Integer.toString(sInsertSimState[i]), i);
                     logd("SUB" + (i + 1) + " has invalid IccId");
                 } else /*if (sInsertSimState[i] != SIM_NOT_INSERT)*/ {
-                    SubscriptionManager.addSubInfoRecord(sIccId[i], i);
+                    SubscriptionManager.addSubscriptionInfoRecord(sIccId[i], i);
                 }
                 if (isNewSim(sIccId[i], oldIccId)) {
                     nNewCardCount++;
@@ -423,14 +429,15 @@
             if (sInsertSimState[i] == SIM_CHANGED) {
                 sInsertSimState[i] = SIM_REPOSITION;
             }
-            logd("sInsertSimState[" + i + "] = " + sInsertSimState[i]);
+            logd("updateSubscriptionInfoByIccId: sInsertSimState[" + i + "] = "
+                    + sInsertSimState[i]);
         }
 
-        List<SubInfoRecord> subInfos = SubscriptionManager.getActiveSubInfoList();
+        List<SubscriptionInfo> subInfos = SubscriptionManager.getActiveSubscriptionInfoList();
         int nSubCount = (subInfos == null) ? 0 : subInfos.size();
-        logd("nSubCount = " + nSubCount);
+        logd("updateSubscriptionInfoByIccId: nSubCount = " + nSubCount);
         for (int i=0; i<nSubCount; i++) {
-            SubInfoRecord temp = subInfos.get(i);
+            SubscriptionInfo temp = subInfos.get(i);
 
             String msisdn = TelephonyManager.getDefault().getLine1NumberForSubscriber(
                     temp.getSubscriptionId());
@@ -444,87 +451,8 @@
             }
         }
 
-        // true if any slot has no SIM this time, but has SIM last time
-        boolean hasSimRemoved = false;
-        for (int i=0; i < PROJECT_SIM_NUM; i++) {
-            if (sIccId[i] != null && sIccId[i].equals(ICCID_STRING_FOR_NO_SIM)
-                    && !oldIccId[i].equals("")) {
-                hasSimRemoved = true;
-                break;
-            }
-        }
-
-        if (nNewCardCount == 0) {
-            int i;
-            if (hasSimRemoved) {
-                // no new SIM, at least one SIM is removed, check if any SIM is repositioned first
-                for (i=0; i < PROJECT_SIM_NUM; i++) {
-                    if (sInsertSimState[i] == SIM_REPOSITION) {
-                        logd("No new SIM detected and SIM repositioned");
-                        setUpdatedData(SubscriptionManager.EXTRA_VALUE_REPOSITION_SIM,
-                                nSubCount, nNewSimStatus);
-                        break;
-                    }
-                }
-                if (i == PROJECT_SIM_NUM) {
-                    // no new SIM, no SIM is repositioned => at least one SIM is removed
-                    logd("No new SIM detected and SIM removed");
-                    setUpdatedData(SubscriptionManager.EXTRA_VALUE_REMOVE_SIM,
-                            nSubCount, nNewSimStatus);
-                }
-            } else {
-                // no SIM is removed, no new SIM, just check if any SIM is repositioned
-                for (i=0; i< PROJECT_SIM_NUM; i++) {
-                    if (sInsertSimState[i] == SIM_REPOSITION) {
-                        logd("No new SIM detected and SIM repositioned");
-                        setUpdatedData(SubscriptionManager.EXTRA_VALUE_REPOSITION_SIM,
-                                nSubCount, nNewSimStatus);
-                        break;
-                    }
-                }
-                if (i == PROJECT_SIM_NUM) {
-                    // all status remain unchanged
-                    logd("[updateSimInfoByIccId] All SIM inserted into the same slot");
-                    setUpdatedData(SubscriptionManager.EXTRA_VALUE_NOCHANGE,
-                            nSubCount, nNewSimStatus);
-                }
-            }
-        } else {
-            logd("New SIM detected");
-            setUpdatedData(SubscriptionManager.EXTRA_VALUE_NEW_SIM, nSubCount, nNewSimStatus);
-        }
-
-        logd("[updateSimInfoByIccId]- SimInfo update complete");
-    }
-
-    private static void setUpdatedData(int detectedType, int subCount, int newSimStatus) {
-
-        Intent intent = new Intent(TelephonyIntents.ACTION_SUBINFO_RECORD_UPDATED);
-
-        logd("[setUpdatedData]+ ");
-
-        if (detectedType == SubscriptionManager.EXTRA_VALUE_NEW_SIM ) {
-            intent.putExtra(SubscriptionManager.INTENT_KEY_DETECT_STATUS,
-                    SubscriptionManager.EXTRA_VALUE_NEW_SIM);
-            intent.putExtra(SubscriptionManager.INTENT_KEY_SIM_COUNT, subCount);
-            intent.putExtra(SubscriptionManager.INTENT_KEY_NEW_SIM_SLOT, newSimStatus);
-        } else if (detectedType == SubscriptionManager.EXTRA_VALUE_REPOSITION_SIM) {
-            intent.putExtra(SubscriptionManager.INTENT_KEY_DETECT_STATUS,
-                    SubscriptionManager.EXTRA_VALUE_REPOSITION_SIM);
-            intent.putExtra(SubscriptionManager.INTENT_KEY_SIM_COUNT, subCount);
-        } else if (detectedType == SubscriptionManager.EXTRA_VALUE_REMOVE_SIM) {
-            intent.putExtra(SubscriptionManager.INTENT_KEY_DETECT_STATUS,
-                    SubscriptionManager.EXTRA_VALUE_REMOVE_SIM);
-            intent.putExtra(SubscriptionManager.INTENT_KEY_SIM_COUNT, subCount);
-        } else if (detectedType == SubscriptionManager.EXTRA_VALUE_NOCHANGE) {
-            intent.putExtra(SubscriptionManager.INTENT_KEY_DETECT_STATUS,
-                    SubscriptionManager.EXTRA_VALUE_NOCHANGE);
-        }
-
-        logd("broadcast intent ACTION_SUBINFO_RECORD_UPDATED : [" + detectedType + ", "
-                + subCount + ", " + newSimStatus+ "]");
-        ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE, UserHandle.USER_ALL);
-        logd("[setUpdatedData]- ");
+        SubscriptionController.getInstance().notifySubscriptionInfoChanged();
+        logd("updateSubscriptionInfoByIccId:- SsubscriptionInfo update complete");
     }
 
     private static boolean isNewSim(String iccId, String[] oldIccId) {
@@ -546,7 +474,7 @@
     }
 
     private static void logd(String message) {
-        Rlog.d(LOG_TAG, "[SubInfoRecordUpdater]" + message);
+        Rlog.d(LOG_TAG, "[SubscriptionInfoUpdater]" + message);
     }
 }
 
diff --git a/src/java/com/android/internal/telephony/UiccSmsController.java b/src/java/com/android/internal/telephony/UiccSmsController.java
index 6840f68..9746a78 100755
--- a/src/java/com/android/internal/telephony/UiccSmsController.java
+++ b/src/java/com/android/internal/telephony/UiccSmsController.java
@@ -320,7 +320,7 @@
     /**
        Gets User preferred SMS subscription */
     public int getPreferredSmsSubscription() {
-        return  SubscriptionManager.getDefaultSmsSubId();
+        return  SubscriptionController.getInstance().getDefaultSmsSubId();
     }
 
     /**
diff --git a/src/java/com/android/internal/telephony/WapPushOverSms.java b/src/java/com/android/internal/telephony/WapPushOverSms.java
index 7ba4d7a..a693957 100755
--- a/src/java/com/android/internal/telephony/WapPushOverSms.java
+++ b/src/java/com/android/internal/telephony/WapPushOverSms.java
@@ -203,7 +203,7 @@
                 // FIXME (tomtaylor) - when we've updated SubscriptionManager, change
                 // SubscriptionManager.DEFAULT_SUB_ID to SubscriptionManager.getDefaultSmsSubId()
                 int subId = (subIds != null) && (subIds.length > 0) ? subIds[0] :
-                    SmsManager.getDefaultSmsSubId();
+                    SmsManager.getDefaultSmsSubscriptionId();
                 writeInboxMessage(subId, intentData);
             }
 
diff --git a/src/java/com/android/internal/telephony/cdma/CDMALTEPhone.java b/src/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
index 63fda7b..a3438b9 100644
--- a/src/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
+++ b/src/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
@@ -96,11 +96,6 @@
 
     }
 
-    // Constructors
-    public CDMALTEPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) {
-        super(context, ci, notifier, false);
-    }
-
     @Override
     protected void initSstIcc() {
         mSST = new CdmaLteServiceStateTracker(this);
diff --git a/src/java/com/android/internal/telephony/cdma/CDMAPhone.java b/src/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 5b31ff5..cdbf2fe 100644
--- a/src/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/src/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -142,13 +142,6 @@
 
     static String PROPERTY_CDMA_HOME_OPERATOR_NUMERIC = "ro.cdma.home.operator.numeric";
 
-    // Constructors
-    public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) {
-        super("CDMA", notifier, context, ci, false);
-        initSstIcc();
-        init(context, notifier);
-    }
-
     public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
             int phoneId) {
         super("CDMA", notifier, context, ci, false, phoneId);
@@ -156,13 +149,6 @@
         init(context, notifier);
     }
 
-    public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
-            boolean unitTestMode) {
-        super("CDMA", notifier, context, ci, unitTestMode);
-        initSstIcc();
-        init(context, notifier);
-    }
-
     protected void initSstIcc() {
         mSST = new CdmaServiceStateTracker(this);
     }
diff --git a/src/java/com/android/internal/telephony/dataconnection/DctController.java b/src/java/com/android/internal/telephony/dataconnection/DctController.java
index 57eeda8..d41cb47 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DctController.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DctController.java
@@ -31,6 +31,8 @@
 import android.os.Messenger;
 import android.provider.Settings;
 import android.telephony.Rlog;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionListener;
 import android.telephony.SubscriptionManager;
 import android.util.SparseArray;
 
@@ -47,6 +49,7 @@
 import java.io.PrintWriter;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map.Entry;
 
 public class DctController extends Handler {
@@ -80,6 +83,14 @@
 
     private SubscriptionController mSubController = SubscriptionController.getInstance();
 
+    SubscriptionListener mSubscriptionListener = new SubscriptionListener() {
+        @Override
+        public void onSubscriptionInfoChanged() {
+            logd("SubscriptionListener.onSubscriptionInfoChanged: call onSubInfoReady");
+            onSubInfoReady();
+        }
+    };
+
     private ContentObserver mObserver = new ContentObserver(new Handler()) {
         @Override
         public void onChange(boolean selfChange) {
@@ -88,17 +99,6 @@
         }
     };
 
-    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver () {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            logd("onReceive: action=" + action);
-            if (action.equals(TelephonyIntents.ACTION_SUBINFO_RECORD_UPDATED)) {
-                onSubInfoReady();
-            }
-        }
-    };
-
     public void updatePhoneObject(PhoneProxy phone) {
         if (phone == null) {
             loge("updatePhoneObject phone = null");
@@ -238,9 +238,8 @@
 
         mContext = mPhones[0].getContext();
 
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(TelephonyIntents.ACTION_SUBINFO_RECORD_UPDATED);
-        mContext.registerReceiver(mIntentReceiver, filter);
+        SubscriptionManager.register(mContext, mSubscriptionListener,
+                SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED);
 
         //Register for settings change.
         mContext.getContentResolver().registerContentObserver(
@@ -258,6 +257,7 @@
             mNetworkFactoryMessenger[i] = null;
         }
 
+        SubscriptionManager.unregister(mContext, mSubscriptionListener);
         mContext.getContentResolver().unregisterContentObserver(mObserver);
     }
 
@@ -491,9 +491,11 @@
     }
 
     private void onSubInfoReady() {
-        logd("onSubInfoReady handle pending requset");
+        logd("onSubInfoReady mPhoneNum=" + mPhoneNum);
         for (int i = 0; i < mPhoneNum; ++i) {
-            mNetworkFilter[i].setNetworkSpecifier(String.valueOf(mPhones[i].getSubId()));
+            int subId = mPhones[i].getSubId();
+            logd("onSubInfoReady handle pending requests subId=" + subId);
+            mNetworkFilter[i].setNetworkSpecifier(String.valueOf(subId));
             ((DctController.TelephonyNetworkFactory)mNetworkFactory[i]).evalPendingRequest();
         }
     }
diff --git a/src/java/com/android/internal/telephony/gsm/GSMPhone.java b/src/java/com/android/internal/telephony/gsm/GSMPhone.java
index c6b5ab6..9a7e83c 100644
--- a/src/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/src/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -146,12 +146,7 @@
     // Constructors
 
     public
-    GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier) {
-        this(context,ci,notifier, false);
-    }
-
-    public
-    GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier, boolean unitTestMode) {
+    GSMPhone(Context context, CommandsInterface ci, PhoneNotifier notifier, boolean unitTestMode) {
         super("GSM", notifier, context, ci, unitTestMode);
 
         if (ci instanceof SimulatedRadioControl) {
@@ -179,12 +174,12 @@
     }
 
     public
-    GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier, int phoneId) {
+    GSMPhone(Context context, CommandsInterface ci, PhoneNotifier notifier, int phoneId) {
         this(context, ci, notifier, false, phoneId);
     }
 
     public
-    GSMPhone (Context context, CommandsInterface ci,
+    GSMPhone(Context context, CommandsInterface ci,
             PhoneNotifier notifier, boolean unitTestMode, int phoneId) {
         super("GSM", notifier, context, ci, unitTestMode, phoneId);