Merge "DO NOT MERGE Adding package caller to prepareForUnattendedReboot."
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index 1a867b6..c9d5eb0 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -276,23 +276,10 @@
         private int mState;
         // The possible tones we can play.
         public static final int TONE_NONE = 0;
-        public static final int TONE_CALL_WAITING = 1;
-        public static final int TONE_BUSY = 2;
-        public static final int TONE_CONGESTION = 3;
-        public static final int TONE_CALL_ENDED = 4;
         public static final int TONE_VOICE_PRIVACY = 5;
-        public static final int TONE_REORDER = 6;
-        public static final int TONE_INTERCEPT = 7;
-        public static final int TONE_CDMA_DROP = 8;
-        public static final int TONE_OUT_OF_SERVICE = 9;
-        public static final int TONE_REDIAL = 10;
-        public static final int TONE_OTA_CALL_END = 11;
-        public static final int TONE_UNOBTAINABLE_NUMBER = 13;
 
         // The tone volume relative to other sounds in the stream
-        static final int TONE_RELATIVE_VOLUME_EMERGENCY = 100;
         static final int TONE_RELATIVE_VOLUME_HIPRI = 80;
-        static final int TONE_RELATIVE_VOLUME_LOPRI = 50;
 
         // Buffer time (in msec) to add on to tone timeout value.
         // Needed mainly when the timeout value for a tone is the
@@ -320,70 +307,11 @@
             int phoneType = mCM.getFgPhone().getPhoneType();
 
             switch (mToneId) {
-                case TONE_CALL_WAITING:
-                    toneType = ToneGenerator.TONE_SUP_CALL_WAITING;
-                    toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
-                    // Call waiting tone is stopped by stopTone() method
-                    toneLengthMillis = Integer.MAX_VALUE - TONE_TIMEOUT_BUFFER;
-                    break;
-                case TONE_BUSY:
-                    if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-                        toneType = ToneGenerator.TONE_CDMA_NETWORK_BUSY_ONE_SHOT;
-                        toneVolume = TONE_RELATIVE_VOLUME_LOPRI;
-                        toneLengthMillis = 1000;
-                    } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM
-                            || phoneType == PhoneConstants.PHONE_TYPE_SIP
-                            || phoneType == PhoneConstants.PHONE_TYPE_IMS
-                            || phoneType == PhoneConstants.PHONE_TYPE_THIRD_PARTY) {
-                        toneType = ToneGenerator.TONE_SUP_BUSY;
-                        toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
-                        toneLengthMillis = 4000;
-                    } else {
-                        throw new IllegalStateException("Unexpected phone type: " + phoneType);
-                    }
-                    break;
-                case TONE_CONGESTION:
-                    toneType = ToneGenerator.TONE_SUP_CONGESTION;
-                    toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
-                    toneLengthMillis = 4000;
-                    break;
-
-                case TONE_CALL_ENDED:
-                    toneType = ToneGenerator.TONE_PROP_PROMPT;
-                    toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
-                    toneLengthMillis = 200;
-                    break;
                 case TONE_VOICE_PRIVACY:
                     toneType = ToneGenerator.TONE_CDMA_ALERT_NETWORK_LITE;
                     toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
                     toneLengthMillis = 5000;
                     break;
-                case TONE_REORDER:
-                    toneType = ToneGenerator.TONE_CDMA_REORDER;
-                    toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
-                    toneLengthMillis = 4000;
-                    break;
-                case TONE_INTERCEPT:
-                    toneType = ToneGenerator.TONE_CDMA_ABBR_INTERCEPT;
-                    toneVolume = TONE_RELATIVE_VOLUME_LOPRI;
-                    toneLengthMillis = 500;
-                    break;
-                case TONE_CDMA_DROP:
-                case TONE_OUT_OF_SERVICE:
-                    toneType = ToneGenerator.TONE_CDMA_CALLDROP_LITE;
-                    toneVolume = TONE_RELATIVE_VOLUME_LOPRI;
-                    toneLengthMillis = 375;
-                    break;
-                case TONE_REDIAL:
-                    toneType = ToneGenerator.TONE_CDMA_ALERT_AUTOREDIAL_LITE;
-                    toneVolume = TONE_RELATIVE_VOLUME_LOPRI;
-                    toneLengthMillis = 5000;
-                    break;
-                case TONE_UNOBTAINABLE_NUMBER:
-                    toneType = ToneGenerator.TONE_SUP_ERROR;
-                    toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
-                    toneLengthMillis = 4000;
-                    break;
                 default:
                     throw new IllegalArgumentException("Bad toneId: " + mToneId);
             }
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index 577d2c0..b0a4653 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -107,10 +107,6 @@
     private CarrierServiceConnection[] mServiceConnection;
     // Service connection for binding to carrier config app for no SIM config.
     private CarrierServiceConnection[] mServiceConnectionForNoSimConfig;
-    // Whether we are bound to a service for each phone
-    private boolean[] mServiceBound;
-    // Whether we are bound to a service for no SIM config
-    private boolean[] mServiceBoundForNoSimConfig;
     // Whether we have sent config change broadcast for each phone id.
     private boolean[] mHasSentConfigChange;
     // Whether the broadcast was sent from EVENT_SYSTEM_UNLOCKED, to track rebroadcasts
@@ -311,7 +307,7 @@
                     final CarrierServiceConnection conn = (CarrierServiceConnection) msg.obj;
                     // If new service connection has been created, unbind.
                     if (mServiceConnection[phoneId] != conn || conn.service == null) {
-                        unbindIfBound(mContext, conn, phoneId);
+                        unbindIfBound(mContext, conn);
                         break;
                     }
                     final CarrierIdentifier carrierId = getCarrierIdentifierForPhoneId(phoneId);
@@ -320,7 +316,7 @@
                             new ResultReceiver(this) {
                                 @Override
                                 public void onReceiveResult(int resultCode, Bundle resultData) {
-                                    unbindIfBound(mContext, conn, phoneId);
+                                    unbindIfBound(mContext, conn);
                                     removeMessages(EVENT_FETCH_DEFAULT_TIMEOUT,
                                             getMessageToken(phoneId));
                                     // If new service connection has been created, this is stale.
@@ -355,7 +351,7 @@
                     } catch (RemoteException e) {
                         loge("Failed to get carrier config from default app: " +
                                 mPlatformCarrierConfigPackage + " err: " + e.toString());
-                        unbindIfBound(mContext, conn, phoneId);
+                        unbindIfBound(mContext, conn);
                         break; // So we don't set a timeout.
                     }
                     sendMessageDelayed(
@@ -375,7 +371,7 @@
                     if (mServiceConnection[phoneId] != null) {
                         // If a ResponseReceiver callback is in the queue when this happens, we will
                         // unbind twice and throw an exception.
-                        unbindIfBound(mContext, mServiceConnection[phoneId], phoneId);
+                        unbindIfBound(mContext, mServiceConnection[phoneId]);
                         broadcastConfigChangedIntent(phoneId);
                     }
                     // Put a stub bundle in place so that the rest of the logic continues smoothly.
@@ -441,7 +437,7 @@
                     final CarrierServiceConnection conn = (CarrierServiceConnection) msg.obj;
                     // If new service connection has been created, unbind.
                     if (mServiceConnection[phoneId] != conn || conn.service == null) {
-                        unbindIfBound(mContext, conn, phoneId);
+                        unbindIfBound(mContext, conn);
                         break;
                     }
                     final CarrierIdentifier carrierId = getCarrierIdentifierForPhoneId(phoneId);
@@ -450,7 +446,7 @@
                             new ResultReceiver(this) {
                                 @Override
                                 public void onReceiveResult(int resultCode, Bundle resultData) {
-                                    unbindIfBound(mContext, conn, phoneId);
+                                    unbindIfBound(mContext, conn);
                                     removeMessages(EVENT_FETCH_CARRIER_TIMEOUT,
                                             getMessageToken(phoneId));
                                     // If new service connection has been created, this is stale.
@@ -486,7 +482,7 @@
                                 + " carrierid: " + carrierId.toString());
                     } catch (RemoteException e) {
                         loge("Failed to get carrier config: " + e.toString());
-                        unbindIfBound(mContext, conn, phoneId);
+                        unbindIfBound(mContext, conn);
                         break; // So we don't set a timeout.
                     }
                     sendMessageDelayed(
@@ -507,7 +503,7 @@
                     if (mServiceConnection[phoneId] != null) {
                         // If a ResponseReceiver callback is in the queue when this happens, we will
                         // unbind twice and throw an exception.
-                        unbindIfBound(mContext, mServiceConnection[phoneId], phoneId);
+                        unbindIfBound(mContext, mServiceConnection[phoneId]);
                         broadcastConfigChangedIntent(phoneId);
                     }
                     // Put a stub bundle in place so that the rest of the logic continues smoothly.
@@ -601,8 +597,7 @@
                     if (mServiceConnectionForNoSimConfig[phoneId] != null) {
                         // If a ResponseReceiver callback is in the queue when this happens, we will
                         // unbind twice and throw an exception.
-                        unbindIfBoundForNoSimConfig(mContext,
-                                mServiceConnectionForNoSimConfig[phoneId], phoneId);
+                        unbindIfBound(mContext, mServiceConnectionForNoSimConfig[phoneId]);
                     }
                     broadcastConfigChangedIntent(phoneId, false);
                     break;
@@ -613,7 +608,7 @@
                     final CarrierServiceConnection conn = (CarrierServiceConnection) msg.obj;
                     // If new service connection has been created, unbind.
                     if (mServiceConnectionForNoSimConfig[phoneId] != conn || conn.service == null) {
-                        unbindIfBoundForNoSimConfig(mContext, conn, phoneId);
+                        unbindIfBound(mContext, conn);
                         break;
                     }
 
@@ -622,7 +617,7 @@
                             new ResultReceiver(this) {
                                 @Override
                                 public void onReceiveResult(int resultCode, Bundle resultData) {
-                                    unbindIfBoundForNoSimConfig(mContext, conn, phoneId);
+                                    unbindIfBound(mContext, conn);
                                     // If new service connection has been created, this is stale.
                                     if (mServiceConnectionForNoSimConfig[phoneId] != conn) {
                                         loge("Received response for stale request.");
@@ -654,7 +649,7 @@
                     } catch (RemoteException e) {
                         loge("Failed to get no sim carrier config from default app: " +
                                 mPlatformCarrierConfigPackage + " err: " + e.toString());
-                        unbindIfBoundForNoSimConfig(mContext, conn, phoneId);
+                        unbindIfBound(mContext, conn);
                         break; // So we don't set a timeout.
                     }
                     sendMessageDelayed(
@@ -701,11 +696,9 @@
         mOverrideConfigs = new PersistableBundle[numPhones];
         mNoSimConfig = new PersistableBundle();
         mServiceConnection = new CarrierServiceConnection[numPhones];
-        mServiceBound = new boolean[numPhones];
         mHasSentConfigChange = new boolean[numPhones];
         mFromSystemUnlocked = new boolean[numPhones];
         mServiceConnectionForNoSimConfig = new CarrierServiceConnection[numPhones];
-        mServiceBoundForNoSimConfig = new boolean[numPhones];
         logd("CarrierConfigLoader has started");
         mSubscriptionInfoUpdater = subscriptionInfoUpdater;
         mHandler.sendEmptyMessage(EVENT_CHECK_SYSTEM_UPDATE);
@@ -840,11 +833,7 @@
         try {
             if (mContext.bindService(carrierService, serviceConnection,
                     Context.BIND_AUTO_CREATE)) {
-                if (eventId == EVENT_CONNECTED_TO_DEFAULT_FOR_NO_SIM_CONFIG) {
-                    mServiceBoundForNoSimConfig[phoneId] = true;
-                } else {
-                    mServiceBound[phoneId] = true;
-                }
+                serviceConnection.isBound = true;
                 return true;
             } else {
                 return false;
@@ -1355,18 +1344,9 @@
         return mOverrideConfigs[phoneId];
     }
 
-    private void unbindIfBound(Context context, CarrierServiceConnection conn,
-            int phoneId) {
-        if (mServiceBound[phoneId]) {
-            mServiceBound[phoneId] = false;
-            context.unbindService(conn);
-        }
-    }
-
-    private void unbindIfBoundForNoSimConfig(Context context, CarrierServiceConnection conn,
-            int phoneId) {
-        if (mServiceBoundForNoSimConfig[phoneId]) {
-            mServiceBoundForNoSimConfig[phoneId] = false;
+    private void unbindIfBound(Context context, CarrierServiceConnection conn) {
+        if (conn.isBound) {
+            conn.isBound = false;
             context.unbindService(conn);
         }
     }
@@ -1591,11 +1571,15 @@
         final String pkgName;
         final int eventId;
         IBinder service;
+        // If bindService was called and return true which means unbindService
+        // must be called later to release the connection
+        boolean isBound;
 
         CarrierServiceConnection(int phoneId, String pkgName, int eventId) {
             this.phoneId = phoneId;
             this.pkgName = pkgName;
             this.eventId = eventId;
+            this.isBound = false;
         }
 
         @Override
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index a25e355..b67b77a 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -106,6 +106,7 @@
 import android.telephony.UssdResponse;
 import android.telephony.VisualVoicemailSmsFilterSettings;
 import android.telephony.data.ApnSetting;
+import android.telephony.data.SlicingConfig;
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.gba.GbaAuthRequest;
 import android.telephony.gba.UaSecurityProtocolIdentifier;
@@ -182,6 +183,7 @@
 import com.android.internal.telephony.uicc.IccIoResult;
 import com.android.internal.telephony.uicc.IccRecords;
 import com.android.internal.telephony.uicc.IccUtils;
+import com.android.internal.telephony.uicc.PinStorage;
 import com.android.internal.telephony.uicc.SIMRecords;
 import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccCardApplication;
@@ -329,6 +331,8 @@
     private static final int CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON = 107;
     private static final int EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE = 108;
     private static final int CMD_PREPARE_UNATTENDED_REBOOT = 109;
+    private static final int CMD_GET_SLICING_CONFIG = 110;
+    private static final int EVENT_GET_SLICING_CONFIG_DONE = 111;
 
     // Parameters of select command.
     private static final int SELECT_COMMAND = 0xA4;
@@ -1220,29 +1224,31 @@
                         ResultReceiver result = (ResultReceiver) request.argument;
                         Bundle bundle = new Bundle();
                         bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY,
-                                new ModemActivityInfo(0, 0, 0, new int[0], 0));
+                                new ModemActivityInfo(0, 0, 0,
+                                        new int[ModemActivityInfo.getNumTxPowerLevels()], 0));
                         result.send(0, bundle);
                     }
                     break;
 
-                case EVENT_GET_MODEM_ACTIVITY_INFO_DONE:
+                case EVENT_GET_MODEM_ACTIVITY_INFO_DONE: {
                     ar = (AsyncResult) msg.obj;
                     request = (MainThreadRequest) ar.userObj;
                     ResultReceiver result = (ResultReceiver) request.argument;
 
-                    ModemActivityInfo ret = new ModemActivityInfo(0, 0, 0, new int[0], 0);
+                    ModemActivityInfo ret = null;
+                    int error = 0;
                     if (ar.exception == null && ar.result != null) {
                         // Update the last modem activity info and the result of the request.
                         ModemActivityInfo info = (ModemActivityInfo) ar.result;
                         if (isModemActivityInfoValid(info)) {
-                            int[] mergedTxTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
+                            int[] mergedTxTimeMs = new int[ModemActivityInfo.getNumTxPowerLevels()];
                             int[] txTimeMs = info.getTransmitTimeMillis();
                             int[] lastModemTxTimeMs = mLastModemActivityInfo
                                     .getTransmitTimeMillis();
                             for (int i = 0; i < mergedTxTimeMs.length; i++) {
                                 mergedTxTimeMs[i] = txTimeMs[i] + lastModemTxTimeMs[i];
                             }
-                            mLastModemActivityInfo.setTimestamp(info.getTimestamp());
+                            mLastModemActivityInfo.setTimestamp(info.getTimestampMillis());
                             mLastModemActivityInfo.setSleepTimeMillis(info.getSleepTimeMillis()
                                     + mLastModemActivityInfo.getSleepTimeMillis());
                             mLastModemActivityInfo.setIdleTimeMillis(info.getIdleTimeMillis()
@@ -1252,7 +1258,7 @@
                                     info.getReceiveTimeMillis()
                                             + mLastModemActivityInfo.getReceiveTimeMillis());
                         }
-                        ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestamp(),
+                        ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestampMillis(),
                                 mLastModemActivityInfo.getSleepTimeMillis(),
                                 mLastModemActivityInfo.getIdleTimeMillis(),
                                 mLastModemActivityInfo.getTransmitTimeMillis(),
@@ -1260,18 +1266,29 @@
                     } else {
                         if (ar.result == null) {
                             loge("queryModemActivityInfo: Empty response");
+                            error = TelephonyManager.ModemActivityInfoException
+                                    .ERROR_INVALID_INFO_RECEIVED;
                         } else if (ar.exception instanceof CommandException) {
                             loge("queryModemActivityInfo: CommandException: " +
                                     ar.exception);
+                            error = TelephonyManager.ModemActivityInfoException
+                                    .ERROR_MODEM_RESPONSE_ERROR;
                         } else {
                             loge("queryModemActivityInfo: Unknown exception");
+                            error = TelephonyManager.ModemActivityInfoException
+                                    .ERROR_UNKNOWN;
                         }
                     }
                     Bundle bundle = new Bundle();
-                    bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
+                    if (ret != null) {
+                        bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
+                    } else {
+                        bundle.putInt(TelephonyManager.EXCEPTION_RESULT_KEY, error);
+                    }
                     result.send(0, bundle);
                     notifyRequester(request);
                     break;
+                }
 
                 case CMD_SET_ALLOWED_CARRIERS:
                     request = (MainThreadRequest) msg.obj;
@@ -1700,8 +1717,9 @@
                         // If the operation is successful, update the PIN storage
                         Pair<String, String> passwords = (Pair<String, String>) request.argument;
                         int phoneId = getPhoneFromRequest(request).getPhoneId();
-                        UiccController.getInstance().getPinStorage()
-                                .storePin(passwords.second, phoneId);
+                        PinStorage pinStorage = UiccController.getInstance().getPinStorage();
+                        pinStorage.storePin(passwords.second, phoneId,
+                                pinStorage.getIccid(phoneId));
                     } else {
                         request.result = msg.arg1;
                     }
@@ -1725,8 +1743,9 @@
                         Pair<Boolean, String> enabled = (Pair<Boolean, String>) request.argument;
                         int phoneId = getPhoneFromRequest(request).getPhoneId();
                         if (enabled.first) {
-                            UiccController.getInstance().getPinStorage()
-                                    .storePin(enabled.second, phoneId);
+                            PinStorage pinStorage = UiccController.getInstance().getPinStorage();
+                            pinStorage.storePin(enabled.second, phoneId,
+                                    pinStorage.getIccid(phoneId));
                         } else {
                             UiccController.getInstance().getPinStorage().clearPin(phoneId);
                         }
@@ -1897,6 +1916,42 @@
                     break;
                 }
 
+                case CMD_GET_SLICING_CONFIG: {
+                    request = (MainThreadRequest) msg.obj;
+                    onCompleted = obtainMessage(EVENT_GET_SLICING_CONFIG_DONE, request);
+                    request.phone.getSlicingConfig(onCompleted);
+                    break;
+                }
+                case EVENT_GET_SLICING_CONFIG_DONE: {
+                    ar = (AsyncResult) msg.obj;
+                    request = (MainThreadRequest) ar.userObj;
+                    ResultReceiver result = (ResultReceiver) request.argument;
+
+                    SlicingConfig slicingConfig = null;
+                    Bundle bundle = new Bundle();
+                    int resultCode = 0;
+                    if (ar.exception != null) {
+                        Log.e(LOG_TAG, "Exception retrieving slicing configuration="
+                                + ar.exception);
+                        resultCode = TelephonyManager.SlicingException.ERROR_MODEM_ERROR;
+                    } else if (ar.result == null) {
+                        Log.w(LOG_TAG, "Timeout Waiting for slicing configuration!");
+                        resultCode = TelephonyManager.SlicingException.ERROR_TIMEOUT;
+                    } else {
+                        // use the result as returned
+                        resultCode = TelephonyManager.SlicingException.SUCCESS;
+                        slicingConfig = (SlicingConfig) ar.result;
+                    }
+
+                    if (slicingConfig == null) {
+                        slicingConfig = new SlicingConfig();
+                    }
+                    bundle.putParcelable(TelephonyManager.KEY_SLICING_CONFIG_HANDLE, slicingConfig);
+                    result.send(resultCode, bundle);
+                    notifyRequester(request);
+                    break;
+                }
+
                 case CMD_PREPARE_UNATTENDED_REBOOT:
                     request = (MainThreadRequest) msg.obj;
                     request.result =
@@ -2393,7 +2448,8 @@
             resultArray[1] = mRetryCount;
 
             if (mResult == PhoneConstants.PIN_RESULT_SUCCESS && pin.length() > 0) {
-                UiccController.getInstance().getPinStorage().storePin(pin, mPhoneId);
+                PinStorage pinStorage = UiccController.getInstance().getPinStorage();
+                pinStorage.storePin(pin, mPhoneId, pinStorage.getIccid(mPhoneId));
             }
 
             return resultArray;
@@ -7418,7 +7474,7 @@
     }
 
     private final ModemActivityInfo mLastModemActivityInfo =
-            new ModemActivityInfo(0, 0, 0, new int[0], 0);
+            new ModemActivityInfo(0, 0, 0, new int[ModemActivityInfo.getNumTxPowerLevels()], 0);
 
     /**
      * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
@@ -7448,12 +7504,9 @@
             return false;
         }
         int activityDurationMs =
-            (int) (info.getTimestamp() - mLastModemActivityInfo.getTimestamp());
-        int totalTxTimeMs = 0;
-        int[] txTimeMs = info.getTransmitTimeMillis();
-        for (int i = 0; i < info.getTransmitPowerInfo().size(); i++) {
-            totalTxTimeMs += txTimeMs[i];
-        }
+                (int) (info.getTimestampMillis() - mLastModemActivityInfo.getTimestampMillis());
+        int totalTxTimeMs = Arrays.stream(info.getTransmitTimeMillis()).sum();
+
         return (info.isValid()
             && (info.getSleepTimeMillis() <= activityDurationMs)
             && (info.getIdleTimeMillis() <= activityDurationMs)
@@ -10368,4 +10421,23 @@
             Binder.restoreCallingIdentity(identity);
         }
     }
+
+    /**
+     * Request to get the current slicing configuration including URSP rules and
+     * NSSAIs (configured, allowed and rejected).
+     *
+     * Requires carrier privileges or READ_PRIVILEGED_PHONE_STATE permission.
+     */
+    @Override
+    public void getSlicingConfig(ResultReceiver callback) {
+        enforceReadPrivilegedPermission("getSlicingConfig");
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            Phone phone = getDefaultPhone();
+            sendRequestAsync(CMD_GET_SLICING_CONFIG, callback, phone, null);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
 }