Merge "DO NOT MERGE: Add radio state condition for high power indications"
diff --git a/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java b/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java
index 69d59af..4b4980e 100644
--- a/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java
+++ b/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java
@@ -38,6 +38,7 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
+import android.util.LocalLog;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -68,6 +69,7 @@
     @VisibleForTesting
     public SparseArray<String> mLastSimState = new SparseArray<>();
     private final PackageChangeReceiver mPackageMonitor = new CarrierServicePackageMonitor();
+    private final LocalLog mLocalLog = new LocalLog(100);
 
     // whether we have successfully bound to the service
     private boolean mServiceBound = false;
@@ -76,7 +78,7 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             final String action = intent.getAction();
-            log("Received " + action);
+            logdWithLocalLog("Received " + action);
 
             if (Intent.ACTION_USER_UNLOCKED.equals(action)) {
                 // On user unlock, new components might become available, so reevaluate all
@@ -101,20 +103,21 @@
         public void handleMessage(Message msg) {
             int phoneId;
             AppBinding binding;
-            log("mHandler: " + msg.what);
+            logdWithLocalLog("mHandler: " + msg.what);
 
             switch (msg.what) {
                 case EVENT_REBIND:
                     phoneId = (int) msg.obj;
                     binding = mBindings.get(phoneId);
                     if (binding == null) return;
-                    log("Rebinding if necessary for phoneId: " + binding.getPhoneId());
+                    logdWithLocalLog("Rebinding if necessary for phoneId: " + binding.getPhoneId());
                     binding.rebind();
                     break;
                 case EVENT_PERFORM_IMMEDIATE_UNBIND:
                     phoneId = (int) msg.obj;
                     binding = mBindings.get(phoneId);
                     if (binding == null) return;
+                    logdWithLocalLog("Unbind immediate with phoneId: " + binding.getPhoneId());
                     binding.performImmediateUnbind();
                     break;
                 case EVENT_MULTI_SIM_CONFIG_CHANGED:
@@ -125,7 +128,7 @@
     };
 
     public CarrierServiceBindHelper(Context context) {
-        mContext = context;
+        mContext = context.createContextAsUser(Process.myUserHandle(), 0);
 
         updateBindingsAndSimStates();
 
@@ -141,7 +144,7 @@
                 new IntentFilter(Intent.ACTION_USER_UNLOCKED), null /* broadcastPermission */,
                 mHandler);
         } catch (PackageManager.NameNotFoundException e) {
-            loge("Package name not found: " + e.getMessage());
+            logeWithLocalLog("Package name not found: " + e.getMessage());
         }
     }
 
@@ -166,7 +169,7 @@
     }
 
     void updateForPhoneId(int phoneId, String simState) {
-        log("update binding for phoneId: " + phoneId + " simState: " + simState);
+        logdWithLocalLog("update binding for phoneId: " + phoneId + " simState: " + simState);
         if (!SubscriptionManager.isValidPhoneId(phoneId)) {
             return;
         }
@@ -218,13 +221,13 @@
                 );
 
             if (carrierPackageNames == null || carrierPackageNames.size() <= 0) {
-                log("No carrier app for: " + phoneId);
+                logdWithLocalLog("No carrier app for: " + phoneId);
                 // Unbind after a delay in case this is a temporary blip in carrier privileges.
                 unbind(false /* immediate */);
                 return;
             }
 
-            log("Found carrier app: " + carrierPackageNames);
+            logdWithLocalLog("Found carrier app: " + carrierPackageNames);
             String candidateCarrierPackage = carrierPackageNames.get(0);
             // If we are binding to a different package, unbind immediately from the current one.
             if (!TextUtils.equals(carrierPackage, candidateCarrierPackage)) {
@@ -249,15 +252,18 @@
             // Only bind if the service wants it
             if (metadata == null ||
                 !metadata.getBoolean("android.service.carrier.LONG_LIVED_BINDING", false)) {
-                log("Carrier app does not want a long lived binding");
+                logdWithLocalLog("Carrier app does not want a long lived binding");
                 unbind(true /* immediate */);
                 return;
             }
 
             if (!TextUtils.equals(carrierServiceClass, candidateServiceClass)) {
+                logdWithLocalLog("CarrierService class changed, unbind immediately.");
                 // Unbind immediately if the carrier service component has changed.
                 unbind(true /* immediate */);
             } else if (connection != null) {
+                logdWithLocalLog(
+                        "CarrierService class unchanged with connection up, cancelScheduledUnbind");
                 // Component is unchanged and connection is up - do nothing, but cancel any
                 // scheduled unbinds.
                 cancelScheduledUnbind();
@@ -267,7 +273,7 @@
             carrierPackage = candidateCarrierPackage;
             carrierServiceClass = candidateServiceClass;
 
-            log("Binding to " + carrierPackage + " for phone " + phoneId);
+            logdWithLocalLog("Binding to " + carrierPackage + " for phone " + phoneId);
 
             // Log debug information
             bindCount++;
@@ -277,14 +283,14 @@
 
             String error;
             try {
-                if (mContext.createContextAsUser(Process.myUserHandle(), 0)
-                        .bindService(carrierService,
-                                Context.BIND_AUTO_CREATE
+                if (mContext.bindService(
+                        carrierService,
+                        Context.BIND_AUTO_CREATE
                                 | Context.BIND_FOREGROUND_SERVICE
                                 | Context.BIND_INCLUDE_CAPABILITIES,
-                                (r) -> mHandler.post(r),
-                                connection)) {
-                    log("service bound");
+                        (r) -> mHandler.post(r),
+                        connection)) {
+                    logdWithLocalLog("service bound");
                     mServiceBound = true;
                     return;
                 }
@@ -294,8 +300,8 @@
                 error = ex.getMessage();
             }
 
-            log("Unable to bind to " + carrierPackage + " for phone " + phoneId +
-                ". Error: " + error);
+            logdWithLocalLog("Unable to bind to " + carrierPackage + " for phone " + phoneId
+                    + ". Error: " + error);
             unbind(true /* immediate */);
         }
 
@@ -318,12 +324,13 @@
             // not running anyway and it may be a permanent disconnection (e.g. the app was
             // disabled).
             if (immediate || !connection.connected) {
+                logdWithLocalLog("unbind immediately or with disconnected connection");
                 cancelScheduledUnbind();
                 performImmediateUnbind();
             } else if (mUnbindScheduledUptimeMillis == -1) {
                 long currentUptimeMillis = SystemClock.uptimeMillis();
                 mUnbindScheduledUptimeMillis = currentUptimeMillis + UNBIND_DELAY_MILLIS;
-                log("Scheduling unbind in " + UNBIND_DELAY_MILLIS + " millis");
+                logdWithLocalLog("Scheduling unbind in " + UNBIND_DELAY_MILLIS + " millis");
                 mHandler.sendMessageAtTime(
                         mHandler.obtainMessage(EVENT_PERFORM_IMMEDIATE_UNBIND, phoneId),
                         mUnbindScheduledUptimeMillis);
@@ -341,22 +348,18 @@
 
             // Actually unbind
             if (mServiceBound) {
-                log("Unbinding from carrier app");
+                logdWithLocalLog("Unbinding from carrier app");
                 mServiceBound = false;
-                try {
-                    mContext.unbindService(connection);
-                } catch (IllegalArgumentException e) {
-                    //TODO(b/151328766): Figure out why we unbind without binding
-                    loge("Tried to unbind without binding e=" + e);
-                }
+                mContext.unbindService(connection);
             } else {
-                log("Not bound, skipping unbindService call");
+                logdWithLocalLog("Not bound, skipping unbindService call");
             }
             connection = null;
             mUnbindScheduledUptimeMillis = -1;
         }
 
         private void cancelScheduledUnbind() {
+            logdWithLocalLog("cancelScheduledUnbind");
             mHandler.removeMessages(EVENT_PERFORM_IMMEDIATE_UNBIND);
             mUnbindScheduledUptimeMillis = -1;
         }
@@ -378,25 +381,25 @@
 
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
-            log("Connected to carrier app: " + name.flattenToString());
+            logdWithLocalLog("Connected to carrier app: " + name.flattenToString());
             connected = true;
         }
 
         @Override
         public void onServiceDisconnected(ComponentName name) {
-            log("Disconnected from carrier app: " + name.flattenToString());
+            logdWithLocalLog("Disconnected from carrier app: " + name.flattenToString());
             connected = false;
         }
 
         @Override
         public void onBindingDied(ComponentName name) {
-            log("Binding from carrier app died: " + name.flattenToString());
+            logdWithLocalLog("Binding from carrier app died: " + name.flattenToString());
             connected = false;
         }
 
         @Override
         public void onNullBinding(ComponentName name) {
-            log("Null binding from carrier app: " + name.flattenToString());
+            logdWithLocalLog("Null binding from carrier app: " + name.flattenToString());
             connected = false;
         }
 
@@ -446,7 +449,8 @@
                 // is unset, in case this package change resulted in a new carrier package becoming
                 // available for binding.
                 if (isBindingForPackage) {
-                    log(carrierPackageName + " changed and corresponds to a phone. Rebinding.");
+                    logdWithLocalLog(
+                            carrierPackageName + " changed and corresponds to a phone. Rebinding.");
                 }
                 if (appBindingPackage == null || isBindingForPackage) {
                     if (forceUnbind) {
@@ -458,16 +462,22 @@
         }
     }
 
-    private static void log(String message) {
-        Log.d(LOG_TAG, message);
+    private void logdWithLocalLog(String msg) {
+        Log.d(LOG_TAG, msg);
+        mLocalLog.log(msg);
     }
 
-    private static void loge(String message) { Log.e(LOG_TAG, message); }
+    private void logeWithLocalLog(String msg) {
+        Log.e(LOG_TAG, msg);
+        mLocalLog.log(msg);
+    }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("CarrierServiceBindHelper:");
         for (int i = 0; i < mBindings.size(); i++) {
             mBindings.get(i).dump(fd, pw, args);
         }
+        pw.println("CarrierServiceBindHelperLogs=");
+        mLocalLog.dump(fd, pw, args);
     }
 }
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index a322447..ae8e4e6 100755
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -92,6 +92,7 @@
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 
+import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
 import com.android.internal.telephony.cdma.EriInfo;
@@ -247,12 +248,6 @@
     /** Signal strength poll rate. */
     private static final int POLL_PERIOD_MILLIS = 20 * 1000;
 
-    /**
-     * The time we wait for IMS to deregister before executing a pending radio power off request.
-     */
-    @VisibleForTesting
-    public static final int DELAY_RADIO_OFF_FOR_IMS_DEREG_TIMEOUT = 3 * 1000;
-
     /** Waiting period before recheck gprs and voice registration. */
     public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
 
@@ -865,6 +860,16 @@
         setPowerStateToDesired();
     }
 
+    /**
+     * @return the timeout value in milliseconds that the framework will delay a pending radio power
+     * off command while waiting for an IMS deregistered indication.
+     */
+    @VisibleForTesting
+    public int getRadioPowerOffDelayTimeoutForImsRegistration() {
+        return mPhone.getContext().getResources().getInteger(
+                R.integer.config_delay_for_ims_dereg_millis);
+    }
+
     public void dispose() {
         mCi.unSetOnSignalStrengthUpdate(this);
         mUiccController.unregisterForIccChanged(this);
@@ -3158,7 +3163,7 @@
         } else if ((!mDesiredPowerState || mRadioDisabledByCarrier) && mCi.getRadioState()
                 == TelephonyManager.RADIO_POWER_ON) {
             // If it's on and available and we want it off gracefully
-            if (mImsRegistrationOnOff) {
+            if (mImsRegistrationOnOff && getRadioPowerOffDelayTimeoutForImsRegistration() > 0) {
                 if (DBG) log("setPowerStateToDesired: delaying power off until IMS dereg.");
                 startDelayRadioOffWaitingForImsDeregTimeout();
                 // Return early here as we do not want to hit the cancel timeout code below.
@@ -3201,7 +3206,7 @@
         }
         if (DBG) log("startDelayRadioOffWaitingForImsDeregTimeout: starting timer");
         sendEmptyMessageDelayed(EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT,
-                DELAY_RADIO_OFF_FOR_IMS_DEREG_TIMEOUT);
+                getRadioPowerOffDelayTimeoutForImsRegistration());
     }
 
     protected void onUpdateIccAvailability() {
@@ -5605,7 +5610,7 @@
         pw.println(" mImsRegistered=" + mImsRegistered);
         pw.println(" mImsRegistrationOnOff=" + mImsRegistrationOnOff);
         pw.println(" pending radio off event="
-                + hasMessages(DELAY_RADIO_OFF_FOR_IMS_DEREG_TIMEOUT));
+                + hasMessages(EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT));
         pw.println(" mRadioDisabledByCarrier" + mRadioDisabledByCarrier);
         pw.println(" mDeviceShuttingDown=" + mDeviceShuttingDown);
         pw.println(" mSpnUpdatePending=" + mSpnUpdatePending);
diff --git a/src/java/com/android/internal/telephony/uicc/PinStorage.java b/src/java/com/android/internal/telephony/uicc/PinStorage.java
index 2885124..96cb8fc 100644
--- a/src/java/com/android/internal/telephony/uicc/PinStorage.java
+++ b/src/java/com/android/internal/telephony/uicc/PinStorage.java
@@ -47,6 +47,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.PersistableBundle;
+import android.os.WorkSource;
 import android.provider.Settings;
 import android.security.keystore.KeyGenParameterSpec;
 import android.telephony.CarrierConfigManager;
@@ -214,10 +215,8 @@
     }
 
     /** Store the {@code pin} for the {@code slotId}. */
-    public synchronized void storePin(String pin, int slotId) {
-        String iccid = getIccid(slotId);
-
-        if (!validatePin(pin) || !validateIccid(iccid) || !validateSlotId(slotId)) {
+    public synchronized void storePin(String pin, int slotId, String iccId) {
+        if (!validatePin(pin) || !validateIccid(iccId) || !validateSlotId(slotId)) {
             // We are unable to store the PIN. At least clear the old one, if present.
             loge("storePin[%d] - Invalid PIN, slotId or ICCID", slotId);
             clearPin(slotId);
@@ -231,7 +230,7 @@
         logd("storePin[%d]", slotId);
 
         StoredPin storedPin = new StoredPin();
-        storedPin.iccid = iccid;
+        storedPin.iccid = iccId;
         storedPin.pin = pin;
         storedPin.slotId = slotId;
         storedPin.status = PinStatus.AVAILABLE;
@@ -270,7 +269,7 @@
                 savePinInformation(slotId, null);
                 TelephonyStatsLog.write(PIN_STORAGE_EVENT,
                         PIN_STORAGE_EVENT__EVENT__PIN_VERIFICATION_SKIPPED_SIM_CARD_MISMATCH,
-                        /* number_of_pins= */ 1);
+                        /* number_of_pins= */ 1, /* package_name= */ "");
             } else if (storedPin.status == PinStatus.VERIFICATION_READY) {
                 logd("getPin[%d] - Found PIN ready for verification", slotId);
                 // Move the state to AVAILABLE, so that it cannot be retrieved again.
@@ -291,7 +290,7 @@
      * @return The result of the reboot preparation.
      */
     @TelephonyManager.PrepareUnattendedRebootResult
-    public synchronized int prepareUnattendedReboot() {
+    public synchronized int prepareUnattendedReboot(WorkSource workSource) {
         // Unattended reboot should never occur before the device is unlocked.
         if (mIsDeviceLocked) {
             loge("prepareUnattendedReboot - Device is locked");
@@ -341,14 +340,18 @@
         }
 
         // Generate metrics
+        String callingPackage = workSource == null || workSource.size() == 0
+                                    ? "" : workSource.getPackageName(0);
         if (result == TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS) {
             logd("prepareUnattendedReboot - Stored %d PINs", storedCount);
             TelephonyStatsLog.write(PIN_STORAGE_EVENT,
-                    PIN_STORAGE_EVENT__EVENT__PIN_STORED_FOR_VERIFICATION, storedCount);
+                    PIN_STORAGE_EVENT__EVENT__PIN_STORED_FOR_VERIFICATION, storedCount,
+                    callingPackage);
         } else if (result == TelephonyManager.PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED) {
             logd("prepareUnattendedReboot - Required %d PINs after reboot", notAvailableCount);
             TelephonyStatsLog.write(PIN_STORAGE_EVENT,
-                    PIN_STORAGE_EVENT__EVENT__PIN_REQUIRED_AFTER_REBOOT, notAvailableCount);
+                    PIN_STORAGE_EVENT__EVENT__PIN_REQUIRED_AFTER_REBOOT, notAvailableCount,
+                    callingPackage);
         }
 
         // Save number of PINs to generate metrics after reboot
@@ -455,7 +458,7 @@
         if (prevCachedPinCount > verificationReadyCount) {
             TelephonyStatsLog.write(PIN_STORAGE_EVENT,
                     PIN_STORAGE_EVENT__EVENT__PIN_COUNT_NOT_MATCHING_AFTER_REBOOT,
-                    prevCachedPinCount - verificationReadyCount);
+                    prevCachedPinCount - verificationReadyCount, /* package_name= */ "");
         }
     }
 
@@ -507,7 +510,8 @@
         // Write metrics about number of discarded PINs
         if (discardedPin > 0) {
             TelephonyStatsLog.write(PIN_STORAGE_EVENT,
-                    PIN_STORAGE_EVENT__EVENT__CACHED_PIN_DISCARDED, discardedPin);
+                    PIN_STORAGE_EVENT__EVENT__CACHED_PIN_DISCARDED, discardedPin,
+                    /* package_name= */ "");
         }
     }
 
@@ -576,7 +580,7 @@
                 success
                     ? PIN_STORAGE_EVENT__EVENT__PIN_VERIFICATION_SUCCESS
                     : PIN_STORAGE_EVENT__EVENT__PIN_VERIFICATION_FAILURE,
-                /* number_of_pins= */ 1);
+                /* number_of_pins= */ 1, /* package_name= */ "");
     }
 
     @Override
@@ -931,7 +935,7 @@
     }
 
     /** Returns the ICCID of the SIM card for the given {@code slotId}. */
-    private String getIccid(int slotId) {
+    public String getIccid(int slotId) {
         Phone phone = PhoneFactory.getPhone(slotId);
         return phone != null ? phone.getFullIccSerialNumber() : "";
     }
@@ -1152,7 +1156,7 @@
         } catch (Exception e) {
             loge("Encrypt exception", e);
             TelephonyStatsLog.write(PIN_STORAGE_EVENT,
-                    PIN_STORAGE_EVENT__EVENT__PIN_ENCRYPTION_ERROR, 1);
+                    PIN_STORAGE_EVENT__EVENT__PIN_ENCRYPTION_ERROR, 1, /* package_name= */ "");
         }
         return new byte[0];
     }
@@ -1177,7 +1181,7 @@
         } catch (Exception e) {
             loge("Decrypt exception", e);
             TelephonyStatsLog.write(PIN_STORAGE_EVENT,
-                    PIN_STORAGE_EVENT__EVENT__PIN_DECRYPTION_ERROR, 1);
+                    PIN_STORAGE_EVENT__EVENT__PIN_DECRYPTION_ERROR, 1, /* package_name= */ "");
         }
         return new byte[0];
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index 9bdf662..62e0467 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -284,6 +284,10 @@
                 com.android.internal.R.array.wfcSpnFormats,
                 WIFI_CALLING_FORMATTERS);
 
+        // Start with power off delay disabled.
+        mContextFixture.putIntResource(
+                com.android.internal.R.integer.config_delay_for_ims_dereg_millis, 0);
+
         mBundle.putBoolean(
                 CarrierConfigManager.KEY_ENABLE_CARRIER_DISPLAY_NAME_RESOLVER_BOOL, true);
         mBundle.putInt(CarrierConfigManager.KEY_WFC_SPN_FORMAT_IDX_INT, 0);
@@ -1943,6 +1947,8 @@
     @SmallTest
     public void testImsRegisteredDelayShutDown() throws Exception {
         doReturn(true).when(mPhone).isPhoneTypeGsm();
+        mContextFixture.putIntResource(
+                com.android.internal.R.integer.config_delay_for_ims_dereg_millis, 1000 /*ms*/);
         sst.setImsRegistrationState(true);
         mSimulatedCommands.setRadioPowerFailResponse(false);
         sst.setRadioPower(true);
@@ -1962,8 +1968,27 @@
 
     @Test
     @SmallTest
+    public void testImsRegisteredNoDelayShutDown() throws Exception {
+        doReturn(true).when(mPhone).isPhoneTypeGsm();
+        // The radio power off delay time is 0, so there should should be no delay.
+        sst.setImsRegistrationState(true);
+        mSimulatedCommands.setRadioPowerFailResponse(false);
+        sst.setRadioPower(true);
+        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+
+        // Turn off the radio and ensure radio power is off
+        assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
+        sst.setRadioPower(false);
+        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+        assertEquals(TelephonyManager.RADIO_POWER_OFF, mSimulatedCommands.getRadioState());
+    }
+
+    @Test
+    @SmallTest
     public void testImsRegisteredDelayShutDownTimeout() throws Exception {
         doReturn(true).when(mPhone).isPhoneTypeGsm();
+        mContextFixture.putIntResource(
+                com.android.internal.R.integer.config_delay_for_ims_dereg_millis, 1000 /*ms*/);
         sst.setImsRegistrationState(true);
         mSimulatedCommands.setRadioPowerFailResponse(false);
         sst.setRadioPower(true);
@@ -1979,7 +2004,7 @@
         // move to off.
         // Timeout for IMS reg + some extra time to remove race conditions
         waitForDelayedHandlerAction(mSSTTestHandler.getThreadHandler(),
-                ServiceStateTracker.DELAY_RADIO_OFF_FOR_IMS_DEREG_TIMEOUT + 100, 1000);
+                sst.getRadioPowerOffDelayTimeoutForImsRegistration() + 1000, 1000);
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
         assertEquals(TelephonyManager.RADIO_POWER_OFF, mSimulatedCommands.getRadioState());
     }
@@ -1988,6 +2013,8 @@
     @SmallTest
     public void testImsRegisteredAPMOnOffToggle() throws Exception {
         doReturn(true).when(mPhone).isPhoneTypeGsm();
+        mContextFixture.putIntResource(
+                com.android.internal.R.integer.config_delay_for_ims_dereg_millis, 1000 /*ms*/);
         sst.setImsRegistrationState(true);
         mSimulatedCommands.setRadioPowerFailResponse(false);
         sst.setRadioPower(true);
@@ -2003,7 +2030,7 @@
         // Ensure the timeout was cancelled and we still see radio power is on.
         // Timeout for IMS reg + some extra time to remove race conditions
         waitForDelayedHandlerAction(mSSTTestHandler.getThreadHandler(),
-                ServiceStateTracker.DELAY_RADIO_OFF_FOR_IMS_DEREG_TIMEOUT + 100, 1000);
+                sst.getRadioPowerOffDelayTimeoutForImsRegistration() + 1000, 1000);
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
         assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/PinStorageTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/PinStorageTest.java
index a26c0f9..9d7ad5b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/PinStorageTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/PinStorageTest.java
@@ -25,6 +25,7 @@
 
 import android.content.Intent;
 import android.os.PersistableBundle;
+import android.os.WorkSource;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
@@ -50,6 +51,9 @@
     private static final String ICCID_1 = "89010003006562472370";
     private static final String ICCID_2 = "89010003006562472399";
     private static final String ICCID_INVALID = "1234";
+    private static final String PACKAGE_NAME = "com.package.name";
+    private static final int UID = -1;
+    private static final WorkSource sWorkSource = new WorkSource(UID, PACKAGE_NAME);
 
     private int mBootCount;
     private int mSimulatedRebootsCount;
@@ -106,7 +110,7 @@
     @Test
     @SmallTest
     public void storePin_withoutReboot_pinCannotBeRetrieved() {
-        mPinStorage.storePin("1234", 0);
+        mPinStorage.storePin("1234", 0, mPinStorage.getIccid(0));
 
         assertThat(mPinStorage.getPin(0, ICCID_1)).isEqualTo("");
     }
@@ -114,7 +118,7 @@
     @Test
     @SmallTest
     public void storePin_normalReboot_pinCannotBeRetrieved() {
-        mPinStorage.storePin("1234", 0);
+        mPinStorage.storePin("1234", 0, mPinStorage.getIccid(0));
 
         simulateReboot();
 
@@ -124,7 +128,7 @@
     @Test
     @SmallTest
     public void storePin_crash_pinCannotBeRetrieved() {
-        mPinStorage.storePin("1234", 0);
+        mPinStorage.storePin("1234", 0, mPinStorage.getIccid(0));
 
         // Simulate crash
         mPinStorage = new PinStorage(mContext);
@@ -136,9 +140,9 @@
     @Test
     @SmallTest
     public void storePin_unattendedReboot_pinCanBeRetrievedOnce() {
-        mPinStorage.storePin("1234", 0);
+        mPinStorage.storePin("1234", 0, mPinStorage.getIccid(0));
 
-        int result = mPinStorage.prepareUnattendedReboot();
+        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -156,9 +160,9 @@
         when(mKeyguardManager.isDeviceLocked()).thenReturn(true);
         simulateReboot();
 
-        mPinStorage.storePin("1234", 0);
+        mPinStorage.storePin("1234", 0, mPinStorage.getIccid(0));
 
-        int result = mPinStorage.prepareUnattendedReboot();
+        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR);
 
         simulateReboot();
@@ -170,9 +174,9 @@
     @Test
     @SmallTest
     public void storePin_unattendedReboot_pinIsRemovedAfterDelay() {
-        mPinStorage.storePin("1234", 0);
+        mPinStorage.storePin("1234", 0, mPinStorage.getIccid(0));
 
-        int result = mPinStorage.prepareUnattendedReboot();
+        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -184,7 +188,7 @@
         assertThat(mPinStorage.getPin(0, ICCID_1)).isEqualTo("");
 
         // Simulate a second unattended reboot to make sure that PIN was deleted.
-        result = mPinStorage.prepareUnattendedReboot();
+        result = mPinStorage.prepareUnattendedReboot(sWorkSource);
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -195,9 +199,9 @@
     @Test
     @SmallTest
     public void storePin_unattendedRebootNotDone_pinCannotBeRetrieved() {
-        mPinStorage.storePin("1234", 0);
+        mPinStorage.storePin("1234", 0, mPinStorage.getIccid(0));
 
-        int result = mPinStorage.prepareUnattendedReboot();
+        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         // Move time forward by 60 seconds before simulating reboot
@@ -211,9 +215,9 @@
     @Test
     @SmallTest
     public void storePin_unattendedReboot_iccidChange() {
-        mPinStorage.storePin("1234", 0);
+        mPinStorage.storePin("1234", 0, mPinStorage.getIccid(0));
 
-        int result = mPinStorage.prepareUnattendedReboot();
+        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -232,10 +236,10 @@
     @Test
     @SmallTest
     public void clearPin_pinCannotBeRetrieved() {
-        mPinStorage.storePin("1234", 0);
+        mPinStorage.storePin("1234", 0, mPinStorage.getIccid(0));
         mPinStorage.clearPin(0);
 
-        int result = mPinStorage.prepareUnattendedReboot();
+        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -246,10 +250,10 @@
     @Test
     @SmallTest
     public void storePin_pinChanged_pinIsUpdated() {
-        mPinStorage.storePin("1234", 0);
-        mPinStorage.storePin("5678", 0);
+        mPinStorage.storePin("1234", 0, mPinStorage.getIccid(0));
+        mPinStorage.storePin("5678", 0, mPinStorage.getIccid(0));
 
-        int result = mPinStorage.prepareUnattendedReboot();
+        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -260,9 +264,9 @@
     @Test
     @SmallTest
     public void storePin_pinTooShort_pinIsNotStored() {
-        mPinStorage.storePin("12", 0);
+        mPinStorage.storePin("12", 0, mPinStorage.getIccid(0));
 
-        int result = mPinStorage.prepareUnattendedReboot();
+        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -273,9 +277,9 @@
     @Test
     @SmallTest
     public void storePin_pinTooLong_pinIsNotStored() {
-        mPinStorage.storePin("123456789", 0);
+        mPinStorage.storePin("123456789", 0, mPinStorage.getIccid(0));
 
-        int result = mPinStorage.prepareUnattendedReboot();
+        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -288,8 +292,8 @@
     public void storePin_invalidIccid_pinIsNotStored() {
         doReturn(ICCID_INVALID).when(mPhone).getFullIccSerialNumber();
 
-        mPinStorage.storePin("1234", 0);
-        int result = mPinStorage.prepareUnattendedReboot();
+        mPinStorage.storePin("1234", 0, mPinStorage.getIccid(0));
+        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
 
         simulateReboot();
 
@@ -302,9 +306,9 @@
         mContextFixture.putBooleanResource(
                 R.bool.config_allow_pin_storage_for_unattended_reboot, false);
 
-        mPinStorage.storePin("1234", 0);
+        mPinStorage.storePin("1234", 0, mPinStorage.getIccid(0));
 
-        int result = mPinStorage.prepareUnattendedReboot();
+        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -321,9 +325,9 @@
         when(mUiccController.getUiccProfileForPhone(anyInt())).thenReturn(mUiccProfile);
         when(mUiccCardApplication3gpp.getPin1State()).thenReturn(PINSTATE_ENABLED_VERIFIED);
 
-        mPinStorage.storePin("1234", 0);
+        mPinStorage.storePin("1234", 0, mPinStorage.getIccid(0));
 
-        int result = mPinStorage.prepareUnattendedReboot();
+        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED);
 
         simulateReboot();
@@ -339,9 +343,9 @@
                 CarrierConfigManager.KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL, false);
         when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(carrierConfigs);
 
-        mPinStorage.storePin("1234", 0);
+        mPinStorage.storePin("1234", 0, mPinStorage.getIccid(0));
 
-        int result = mPinStorage.prepareUnattendedReboot();
+        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -352,7 +356,7 @@
     @Test
     @SmallTest
     public void storePin_changeToDisabledInCarrierConfig_pinIsRemoved() {
-        mPinStorage.storePin("1234", 0);
+        mPinStorage.storePin("1234", 0, mPinStorage.getIccid(0));
 
         // Simulate change in the carrier configuration
         PersistableBundle carrierConfigs = new PersistableBundle();
@@ -364,7 +368,7 @@
         mContext.sendBroadcast(intent);
         processAllMessages();
 
-        int result = mPinStorage.prepareUnattendedReboot();
+        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -375,7 +379,7 @@
     @Test
     @SmallTest
     public void storePin_simIsRemoved_pinIsRemoved() {
-        mPinStorage.storePin("1234", 0);
+        mPinStorage.storePin("1234", 0, mPinStorage.getIccid(0));
 
         // SIM is removed
         final Intent intent = new Intent(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED);
@@ -384,7 +388,7 @@
         mContext.sendBroadcast(intent);
         processAllMessages();
 
-        int result = mPinStorage.prepareUnattendedReboot();
+        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -395,9 +399,9 @@
     @Test
     @SmallTest
     public void storePin_simReadyAfterUnattendedReboot_pinIsRemoved() {
-        mPinStorage.storePin("1234", 0);
+        mPinStorage.storePin("1234", 0, mPinStorage.getIccid(0));
 
-        int result = mPinStorage.prepareUnattendedReboot();
+        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();