[automerger skipped] Add Signal Strength to TelephonyMetrics when Data Stall am: 1a06b993f3 -s ours am: 3289a6eab6 -s ours
am skip reason: Change-Id I5b13d62aa8e9375e1db6aff8f639d0827aca8b9a with SHA-1 6a54049391 is in history

Change-Id: Id6c700513ffc3f2a8c414f01741c7cbd82d813e3
diff --git a/src/java/com/android/internal/telephony/BaseCommands.java b/src/java/com/android/internal/telephony/BaseCommands.java
index f0a718a..6b29353 100644
--- a/src/java/com/android/internal/telephony/BaseCommands.java
+++ b/src/java/com/android/internal/telephony/BaseCommands.java
@@ -17,7 +17,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.AsyncResult;
 import android.os.Handler;
diff --git a/src/java/com/android/internal/telephony/Call.java b/src/java/com/android/internal/telephony/Call.java
index a9d1bd5..bc5f1c5 100644
--- a/src/java/com/android/internal/telephony/Call.java
+++ b/src/java/com/android/internal/telephony/Call.java
@@ -16,14 +16,14 @@
 
 package com.android.internal.telephony;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.telephony.Rlog;
 
 import com.android.ims.internal.ConferenceParticipant;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * {@hide}
  */
@@ -37,23 +37,15 @@
     /* Enums */
     @UnsupportedAppUsage(implicitMember = "values()[Lcom/android/internal/telephony/Call$State;")
     public enum State {
-        @UnsupportedAppUsage
-        IDLE,
+        @UnsupportedAppUsage IDLE,
         ACTIVE,
-        @UnsupportedAppUsage
-        HOLDING,
-        @UnsupportedAppUsage
-        DIALING,
-        @UnsupportedAppUsage
-        ALERTING,
-        @UnsupportedAppUsage
-        INCOMING,
-        @UnsupportedAppUsage
-        WAITING,
-        @UnsupportedAppUsage
-        DISCONNECTED,
-        @UnsupportedAppUsage
-        DISCONNECTING;
+        @UnsupportedAppUsage HOLDING,
+        @UnsupportedAppUsage DIALING,
+        @UnsupportedAppUsage ALERTING,
+        @UnsupportedAppUsage INCOMING,
+        @UnsupportedAppUsage WAITING,
+        @UnsupportedAppUsage DISCONNECTED,
+        @UnsupportedAppUsage DISCONNECTING;
 
         @UnsupportedAppUsage
         public boolean isAlive() {
diff --git a/src/java/com/android/internal/telephony/CallForwardInfo.java b/src/java/com/android/internal/telephony/CallForwardInfo.java
index 7d4f587..1f8b536 100644
--- a/src/java/com/android/internal/telephony/CallForwardInfo.java
+++ b/src/java/com/android/internal/telephony/CallForwardInfo.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.telephony.Rlog;
 
 /**
diff --git a/src/java/com/android/internal/telephony/CallManager.java b/src/java/com/android/internal/telephony/CallManager.java
index 5112376..35abbd1 100644
--- a/src/java/com/android/internal/telephony/CallManager.java
+++ b/src/java/com/android/internal/telephony/CallManager.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.AsyncResult;
 import android.os.Handler;
@@ -27,7 +27,6 @@
 import android.telephony.PhoneStateListener;
 import android.telephony.Rlog;
 import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
 
 import com.android.internal.telephony.sip.SipPhone;
 
diff --git a/src/java/com/android/internal/telephony/CallStateException.java b/src/java/com/android/internal/telephony/CallStateException.java
index 1356a2b..3fdc444 100644
--- a/src/java/com/android/internal/telephony/CallStateException.java
+++ b/src/java/com/android/internal/telephony/CallStateException.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 
 /**
  * {@hide}
diff --git a/src/java/com/android/internal/telephony/CallTracker.java b/src/java/com/android/internal/telephony/CallTracker.java
index f24b3c8..9e81bcc 100644
--- a/src/java/com/android/internal/telephony/CallTracker.java
+++ b/src/java/com/android/internal/telephony/CallTracker.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.AsyncResult;
 import android.os.Handler;
diff --git a/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java b/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java
index 4cdfd26..0843018 100644
--- a/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java
+++ b/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
diff --git a/src/java/com/android/internal/telephony/CellBroadcastHandler.java b/src/java/com/android/internal/telephony/CellBroadcastHandler.java
deleted file mode 100644
index 0d09e04..0000000
--- a/src/java/com/android/internal/telephony/CellBroadcastHandler.java
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import static android.content.PermissionChecker.PERMISSION_GRANTED;
-import static android.provider.Settings.Secure.CMAS_ADDITIONAL_BROADCAST_PKG;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.Activity;
-import android.app.AppOpsManager;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.PermissionChecker;
-import android.content.pm.PackageManager;
-import android.location.Location;
-import android.location.LocationListener;
-import android.location.LocationManager;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.provider.Telephony;
-import android.provider.Telephony.CellBroadcasts;
-import android.telephony.CbGeoUtils;
-import android.telephony.CbGeoUtils.Geometry;
-import android.telephony.CbGeoUtils.LatLng;
-import android.telephony.SmsCbMessage;
-import android.telephony.SubscriptionManager;
-import android.text.format.DateUtils;
-import android.util.LocalLog;
-import android.util.Log;
-
-import com.android.internal.telephony.metrics.TelephonyMetrics;
-import com.android.internal.telephony.util.TelephonyUtils;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Dispatch new Cell Broadcasts to receivers. Acquires a private wakelock until the broadcast
- * completes and our result receiver is called.
- */
-public class CellBroadcastHandler extends WakeLockStateMachine {
-    private static final String EXTRA_MESSAGE = "message";
-
-    private final LocalLog mLocalLog = new LocalLog(100);
-
-    protected static final Uri CELL_BROADCAST_URI = Uri.parse("content://cellbroadcasts");
-
-    /** Uses to request the location update. */
-    public final LocationRequester mLocationRequester;
-
-    private CellBroadcastHandler(Context context, Phone phone) {
-        this("CellBroadcastHandler", context, phone);
-    }
-
-    protected CellBroadcastHandler(String debugTag, Context context, Phone phone) {
-        super(debugTag, context, phone);
-        mLocationRequester = new LocationRequester(
-                context,
-                (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE),
-                getHandler().getLooper());
-    }
-
-    /**
-     * Create a new CellBroadcastHandler.
-     * @param context the context to use for dispatching Intents
-     * @return the new handler
-     */
-    public static CellBroadcastHandler makeCellBroadcastHandler(Context context, Phone phone) {
-        CellBroadcastHandler handler = new CellBroadcastHandler(context, phone);
-        handler.start();
-        return handler;
-    }
-
-    /**
-     * Handle Cell Broadcast messages from {@code CdmaInboundSmsHandler}.
-     * 3GPP-format Cell Broadcast messages sent from radio are handled in the subclass.
-     *
-     * @param message the message to process
-     * @return true if need to wait for geo-fencing or an ordered broadcast was sent.
-     */
-    @Override
-    protected boolean handleSmsMessage(Message message) {
-        if (message.obj instanceof SmsCbMessage) {
-            handleBroadcastSms((SmsCbMessage) message.obj);
-            return true;
-        } else {
-            loge("handleMessage got object of type: " + message.obj.getClass().getName());
-            return false;
-        }
-    }
-
-    /**
-     * Dispatch a Cell Broadcast message to listeners.
-     * @param message the Cell Broadcast to broadcast
-     */
-    protected void handleBroadcastSms(SmsCbMessage message) {
-        // Log Cellbroadcast msg received event
-        TelephonyMetrics metrics = TelephonyMetrics.getInstance();
-        metrics.writeNewCBSms(mPhone.getPhoneId(), message.getMessageFormat(),
-                message.getMessagePriority(), message.isCmasMessage(), message.isEtwsMessage(),
-                message.getServiceCategory(), message.getSerialNumber(),
-                System.currentTimeMillis());
-
-        // TODO: Database inserting can be time consuming, therefore this should be changed to
-        // asynchronous.
-        ContentValues cv = message.getContentValues();
-        Uri uri = mContext.getContentResolver().insert(CELL_BROADCAST_URI, cv);
-
-        if (message.needGeoFencingCheck()) {
-            if (DBG) {
-                log("Request location update for geo-fencing. serialNumber = "
-                        + message.getSerialNumber());
-            }
-
-            requestLocationUpdate(location -> {
-                if (location == null) {
-                    // Broadcast the message directly if the location is not available.
-                    broadcastMessage(message, uri);
-                } else {
-                    performGeoFencing(message, uri, message.getGeometries(), location);
-                }
-            }, message.getMaximumWaitingDuration());
-        } else {
-            if (DBG) {
-                log("Broadcast the message directly because no geo-fencing required, "
-                        + "serialNumber = " + message.getSerialNumber()
-                        + " needGeoFencing = " + message.needGeoFencingCheck());
-            }
-            broadcastMessage(message, uri);
-        }
-    }
-
-    /**
-     * Perform a geo-fencing check for {@code message}. Broadcast the {@code message} if the
-     * {@code location} is inside the {@code broadcastArea}.
-     * @param message the message need to geo-fencing check
-     * @param uri the message's uri
-     * @param broadcastArea the broadcast area of the message
-     * @param location current location
-     */
-    protected void performGeoFencing(SmsCbMessage message, Uri uri, List<Geometry> broadcastArea,
-            LatLng location) {
-
-        if (DBG) {
-            logd("Perform geo-fencing check for message identifier = "
-                    + message.getServiceCategory()
-                    + " serialNumber = " + message.getSerialNumber());
-        }
-
-        for (Geometry geo : broadcastArea) {
-            if (geo.contains(location)) {
-                broadcastMessage(message, uri);
-                return;
-            }
-        }
-
-        if (DBG) {
-            logd("Device location is outside the broadcast area "
-                    + CbGeoUtils.encodeGeometriesToString(broadcastArea));
-        }
-
-        sendMessage(EVENT_BROADCAST_NOT_REQUIRED);
-    }
-
-    /**
-     * Request a single location update.
-     * @param callback a callback will be called when the location is available.
-     * @param maximumWaitTimeSec the maximum wait time of this request. If location is not updated
-     * within the maximum wait time, {@code callback#onLocationUpadte(null)} will be called.
-     */
-    protected void requestLocationUpdate(LocationUpdateCallback callback, int maximumWaitTimeSec) {
-        mLocationRequester.requestLocationUpdate(callback, maximumWaitTimeSec);
-    }
-
-    /**
-     * Broadcast a list of cell broadcast messages.
-     * @param cbMessages a list of cell broadcast message.
-     * @param cbMessageUris the corresponding {@link Uri} of the cell broadcast messages.
-     */
-    protected void broadcastMessage(List<SmsCbMessage> cbMessages, List<Uri> cbMessageUris) {
-        for (int i = 0; i < cbMessages.size(); i++) {
-            broadcastMessage(cbMessages.get(i), cbMessageUris.get(i));
-        }
-    }
-
-    /**
-     * Broadcast the {@code message} to the applications.
-     * @param message a message need to broadcast
-     * @param messageUri message's uri
-     */
-    protected void broadcastMessage(@NonNull SmsCbMessage message, @Nullable Uri messageUri) {
-        String receiverPermission;
-        String appOp;
-        String msg;
-        Intent intent;
-        if (message.isEmergencyMessage()) {
-            msg = "Dispatching emergency SMS CB, SmsCbMessage is: " + message;
-            log(msg);
-            mLocalLog.log(msg);
-            intent = new Intent(Telephony.Sms.Intents.ACTION_SMS_EMERGENCY_CB_RECEIVED);
-            //Emergency alerts need to be delivered with high priority
-            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-            receiverPermission = Manifest.permission.RECEIVE_EMERGENCY_BROADCAST;
-            appOp = AppOpsManager.OPSTR_RECEIVE_EMERGENCY_BROADCAST;
-
-            intent.putExtra(EXTRA_MESSAGE, message);
-            SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId());
-
-            if (TelephonyUtils.IS_DEBUGGABLE) {
-                // Send additional broadcast intent to the specified package. This is only for sl4a
-                // automation tests.
-                final String additionalPackage = Settings.Secure.getString(
-                        mContext.getContentResolver(), CMAS_ADDITIONAL_BROADCAST_PKG);
-                if (additionalPackage != null) {
-                    Intent additionalIntent = new Intent(intent);
-                    additionalIntent.setPackage(additionalPackage);
-                    try {
-                        mContext.createPackageContextAsUser(
-                                mContext.getPackageName(), 0, UserHandle.ALL)
-                                .sendOrderedBroadcast(additionalIntent, receiverPermission, appOp,
-                                        null /* resultReceiver */, getHandler(), Activity.RESULT_OK,
-                                        null /* initialData */, null /* initialExtras */);
-                    } catch (PackageManager.NameNotFoundException ignored) {
-                    }
-                }
-            }
-
-            String[] pkgs = mContext.getResources().getStringArray(
-                    com.android.internal.R.array.config_defaultCellBroadcastReceiverPkgs);
-            mReceiverCount.addAndGet(pkgs.length);
-            for (String pkg : pkgs) {
-                // Explicitly send the intent to all the configured cell broadcast receivers.
-                intent.setPackage(pkg);
-                try {
-                    mContext.createPackageContextAsUser(
-                            mContext.getPackageName(), 0, UserHandle.ALL)
-                            .sendOrderedBroadcast(intent, receiverPermission, appOp, mReceiver,
-                                    getHandler(), Activity.RESULT_OK, null /* initialData */,
-                                    null /* initialExtras */);
-                } catch (PackageManager.NameNotFoundException ignored) {
-                }
-            }
-        } else {
-            msg = "Dispatching SMS CB, SmsCbMessage is: " + message;
-            log(msg);
-            mLocalLog.log(msg);
-            intent = new Intent(Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION);
-            // Send implicit intent since there are various 3rd party carrier apps listen to
-            // this intent.
-            intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
-            receiverPermission = Manifest.permission.RECEIVE_SMS;
-            appOp = AppOpsManager.OPSTR_RECEIVE_SMS;
-
-            intent.putExtra(EXTRA_MESSAGE, message);
-            SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId());
-
-            mReceiverCount.incrementAndGet();
-            try {
-                mContext.createPackageContextAsUser(mContext.getPackageName(), 0, UserHandle.ALL)
-                        .sendOrderedBroadcast(intent, receiverPermission, appOp, mReceiver,
-                                getHandler(), Activity.RESULT_OK, null /* initialData */,
-                                null /* initialExtras */);
-            } catch (PackageManager.NameNotFoundException ignored) {
-            }
-        }
-
-        if (messageUri != null) {
-            ContentValues cv = new ContentValues();
-            cv.put(CellBroadcasts.MESSAGE_BROADCASTED, 1);
-            mContext.getContentResolver().update(CELL_BROADCAST_URI, cv,
-                    CellBroadcasts._ID + "=?", new String[] {messageUri.getLastPathSegment()});
-        }
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("CellBroadcastHandler:");
-        mLocalLog.dump(fd, pw, args);
-        pw.flush();
-    }
-
-    /** The callback interface of a location request. */
-    public interface LocationUpdateCallback {
-        /**
-         * Call when the location update is available.
-         * @param location a location in (latitude, longitude) format, or {@code null} if the
-         * location service is not available.
-         */
-        void onLocationUpdate(@Nullable LatLng location);
-    }
-
-    private static final class LocationRequester {
-        private static final String TAG = CellBroadcastHandler.class.getSimpleName();
-
-        /**
-         * Use as the default maximum wait time if the cell broadcast doesn't specify the value.
-         * Most of the location request should be responded within 30 seconds.
-         */
-        private static final int DEFAULT_MAXIMUM_WAIT_TIME_SEC = 30;
-
-        /**
-         * Trigger this event when the {@link LocationManager} is not responded within the given
-         * time.
-         */
-        private static final int EVENT_LOCATION_REQUEST_TIMEOUT = 1;
-
-        /** Request a single location update. */
-        private static final int EVENT_REQUEST_LOCATION_UPDATE = 2;
-
-        /**
-         * Request location update from network or gps location provider. Network provider will be
-         * used if available, otherwise use the gps provider.
-         */
-        private static final List<String> LOCATION_PROVIDERS = Arrays.asList(
-                LocationManager.NETWORK_PROVIDER, LocationManager.GPS_PROVIDER);
-
-        private final LocationManager mLocationManager;
-        private final Looper mLooper;
-        private final List<LocationUpdateCallback> mCallbacks;
-        private final Context mContext;
-        private Handler mLocationHandler;
-
-        LocationRequester(Context context, LocationManager locationManager, Looper looper) {
-            mLocationManager = locationManager;
-            mLooper = looper;
-            mCallbacks = new ArrayList<>();
-            mContext = context;
-            mLocationHandler = new LocationHandler(looper);
-        }
-
-        /**
-         * Request a single location update. If the location is not available, a callback with
-         * {@code null} location will be called immediately.
-         *
-         * @param callback a callback to the the response when the location is available
-         * @param maximumWaitTimeSec the maximum wait time of this request. If location is not
-         * updated within the maximum wait time, {@code callback#onLocationUpadte(null)} will be
-         * called.
-         */
-        void requestLocationUpdate(@NonNull LocationUpdateCallback callback,
-                int maximumWaitTimeSec) {
-            mLocationHandler.obtainMessage(EVENT_REQUEST_LOCATION_UPDATE, maximumWaitTimeSec,
-                    0 /* arg2 */, callback).sendToTarget();
-        }
-
-        private void onLocationUpdate(@Nullable LatLng location) {
-            for (LocationUpdateCallback callback : mCallbacks) {
-                callback.onLocationUpdate(location);
-            }
-            mCallbacks.clear();
-
-            for (LocationListener listener : mLocationListenerList) {
-                mLocationManager.removeUpdates(listener);
-            }
-            mLocationListenerList.clear();
-        }
-
-        private void requestLocationUpdateInternal(@NonNull LocationUpdateCallback callback,
-                int maximumWaitTimeSec) {
-            if (DBG) Log.d(TAG, "requestLocationUpdate");
-            if (!isLocationServiceAvailable()) {
-                if (DBG) {
-                    Log.d(TAG, "Can't request location update because of no location permission");
-                }
-                callback.onLocationUpdate(null);
-                return;
-            }
-
-            if (!mLocationHandler.hasMessages(EVENT_LOCATION_REQUEST_TIMEOUT)) {
-                if (maximumWaitTimeSec == SmsCbMessage.MAXIMUM_WAIT_TIME_NOT_SET) {
-                    maximumWaitTimeSec = DEFAULT_MAXIMUM_WAIT_TIME_SEC;
-                }
-                mLocationHandler.sendMessageDelayed(
-                        mLocationHandler.obtainMessage(EVENT_LOCATION_REQUEST_TIMEOUT),
-                        maximumWaitTimeSec * DateUtils.SECOND_IN_MILLIS);
-            }
-
-            mCallbacks.add(callback);
-
-            for (String provider : LOCATION_PROVIDERS) {
-                if (mLocationManager.isProviderEnabled(provider)) {
-                    LocationListener listener = new LocationListener() {
-                        @Override
-                        public void onLocationChanged(Location location) {
-                            mLocationListenerList.remove(this);
-                            mLocationHandler.removeMessages(EVENT_LOCATION_REQUEST_TIMEOUT);
-                            onLocationUpdate(new LatLng(location.getLatitude(),
-                                    location.getLongitude()));
-                        }
-
-                        @Override
-                        public void onStatusChanged(String provider, int status, Bundle extras) {}
-
-                        @Override
-                        public void onProviderEnabled(String provider) {}
-
-                        @Override
-                        public void onProviderDisabled(String provider) {}
-                    };
-                    mLocationListenerList.add(listener);
-                    Log.d(TAG, "Request location single update from " + provider);
-                    mLocationManager.requestSingleUpdate(provider, listener, mLooper);
-                }
-            }
-        }
-
-        private boolean isLocationServiceAvailable() {
-            if (!hasPermission(Manifest.permission.ACCESS_FINE_LOCATION)
-                    && !hasPermission(Manifest.permission.ACCESS_COARSE_LOCATION)) return false;
-            for (String provider : LOCATION_PROVIDERS) {
-                if (mLocationManager.isProviderEnabled(provider)) return true;
-            }
-            return false;
-        }
-
-        private boolean hasPermission(String permission) {
-            return PermissionChecker.checkCallingOrSelfPermissionForDataDelivery(mContext,
-                    permission) == PERMISSION_GRANTED;
-        }
-
-        private final List<LocationListener> mLocationListenerList = new ArrayList<>();
-
-        private final class LocationHandler extends Handler {
-            LocationHandler(Looper looper) {
-                super(looper);
-            }
-
-            @Override
-            public void handleMessage(Message msg) {
-                switch (msg.what) {
-                    case EVENT_LOCATION_REQUEST_TIMEOUT:
-                        if (DBG) Log.d(TAG, "location request timeout");
-                        onLocationUpdate(null);
-                        break;
-                    case EVENT_REQUEST_LOCATION_UPDATE:
-                        requestLocationUpdateInternal((LocationUpdateCallback) msg.obj, msg.arg1);
-                        break;
-                    default:
-                        Log.e(TAG, "Unsupported message type " + msg.what);
-                }
-            }
-        }
-    }
-}
diff --git a/src/java/com/android/internal/telephony/CommandException.java b/src/java/com/android/internal/telephony/CommandException.java
index 31ffcd2..5f8789d 100644
--- a/src/java/com/android/internal/telephony/CommandException.java
+++ b/src/java/com/android/internal/telephony/CommandException.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.telephony.Rlog;
 
 /**
diff --git a/src/java/com/android/internal/telephony/CommandsInterface.java b/src/java/com/android/internal/telephony/CommandsInterface.java
index c67c675..48ddfdf 100644
--- a/src/java/com/android/internal/telephony/CommandsInterface.java
+++ b/src/java/com/android/internal/telephony/CommandsInterface.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.net.KeepalivePacketData;
 import android.net.LinkProperties;
 import android.os.Handler;
diff --git a/src/java/com/android/internal/telephony/Connection.java b/src/java/com/android/internal/telephony/Connection.java
index 8ba43a6..704327c 100755
--- a/src/java/com/android/internal/telephony/Connection.java
+++ b/src/java/com/android/internal/telephony/Connection.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.SystemClock;
diff --git a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
index f0fb735..94eed47 100644
--- a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
@@ -17,17 +17,16 @@
 package com.android.internal.telephony;
 
 import android.annotation.NonNull;
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
-import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.telephony.Annotation.DataFailureCause;
 import android.telephony.Annotation.RadioPowerState;
 import android.telephony.Annotation.SrvccState;
 import android.telephony.CallQuality;
+import android.telephony.CellIdentity;
 import android.telephony.CellInfo;
-import android.telephony.CellLocation;
 import android.telephony.PhoneCapability;
 import android.telephony.PreciseCallState;
 import android.telephony.PreciseDataConnectionState;
@@ -142,11 +141,9 @@
     }
 
     @Override
-    public void notifyCellLocation(Phone sender, CellLocation cl) {
+    public void notifyCellLocation(Phone sender, CellIdentity cellIdentity) {
         int subId = sender.getSubId();
-        Bundle data = new Bundle();
-        cl.fillInNotifierBundle(data);
-        mTelephonyRegistryMgr.notifyCellLocation(subId, data);
+        mTelephonyRegistryMgr.notifyCellLocation(subId, cellIdentity);
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/DriverCall.java b/src/java/com/android/internal/telephony/DriverCall.java
index 3a7947d..a47503f 100644
--- a/src/java/com/android/internal/telephony/DriverCall.java
+++ b/src/java/com/android/internal/telephony/DriverCall.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.Rlog;
 
diff --git a/src/java/com/android/internal/telephony/GsmCdmaCall.java b/src/java/com/android/internal/telephony/GsmCdmaCall.java
index da2b057..17e2b14 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaCall.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaCall.java
@@ -16,7 +16,8 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
+
 import java.util.List;
 
 /**
diff --git a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
index 0e87544..d10d6f1 100755
--- a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -1538,7 +1538,7 @@
                     causeCode == CallFailCause.BEARER_NOT_AVAIL ||
                     causeCode == CallFailCause.ERROR_UNSPECIFIED) {
 
-                    CellLocation loc = mPhone.getCellLocation();
+                    CellLocation loc = mPhone.getCellIdentity().asCellLocation();
                     int cid = -1;
                     if (loc != null) {
                         if (loc instanceof GsmCellLocation) {
diff --git a/src/java/com/android/internal/telephony/GsmCdmaConnection.java b/src/java/com/android/internal/telephony/GsmCdmaConnection.java
index 4f695e6..0bca896 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaConnection.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaConnection.java
@@ -15,7 +15,7 @@
  */
 
 package com.android.internal.telephony;
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.AsyncResult;
 import android.os.Handler;
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 27321fb..18d5a9c 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -30,8 +30,8 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityManager;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.ContentValues;
 import android.content.Context;
@@ -61,7 +61,7 @@
 import android.telephony.AccessNetworkConstants;
 import android.telephony.Annotation.RilRadioTechnology;
 import android.telephony.CarrierConfigManager;
-import android.telephony.CellLocation;
+import android.telephony.CellIdentity;
 import android.telephony.DataFailCause;
 import android.telephony.ImsiEncryptionInfo;
 import android.telephony.NetworkScanRequest;
@@ -522,8 +522,8 @@
     }
 
     @Override
-    public void getCellLocation(WorkSource workSource, Message rspMsg) {
-        mSST.requestCellLocation(workSource, rspMsg);
+    public void getCellIdentity(WorkSource workSource, Message rspMsg) {
+        mSST.requestCellIdentity(workSource, rspMsg);
     }
 
     @UnsupportedAppUsage
@@ -811,12 +811,12 @@
     }
 
     /**
-     * Notify that the CellLocation has changed.
+     * Notify that the cell location has changed.
      *
-     * @param cl the new CellLocation
+     * @param cellIdentity the new CellIdentity
      */
-    public void notifyLocationChanged(CellLocation cl) {
-        mNotifier.notifyCellLocation(this, cl);
+    public void notifyLocationChanged(CellIdentity cellIdentity) {
+        mNotifier.notifyCellLocation(this, cellIdentity);
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/IccCard.java b/src/java/com/android/internal/telephony/IccCard.java
index d15c44c..b082516 100644
--- a/src/java/com/android/internal/telephony/IccCard.java
+++ b/src/java/com/android/internal/telephony/IccCard.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
diff --git a/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java b/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
index e619e61..66ed9ed 100644
--- a/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.pm.PackageManager;
 import android.os.AsyncResult;
 import android.os.Handler;
diff --git a/src/java/com/android/internal/telephony/IccProvider.java b/src/java/com/android/internal/telephony/IccProvider.java
index ae5cd7b..5c33f0e 100644
--- a/src/java/com/android/internal/telephony/IccProvider.java
+++ b/src/java/com/android/internal/telephony/IccProvider.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ContentProvider;
 import android.content.ContentValues;
 import android.content.UriMatcher;
diff --git a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
index d89b864..1bd9ba9 100644
--- a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
@@ -21,9 +21,9 @@
 import static android.telephony.SmsManager.STATUS_ON_ICC_UNREAD;
 
 import android.Manifest;
-import android.annotation.UnsupportedAppUsage;
 import android.app.AppOpsManager;
 import android.app.PendingIntent;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java
index 6e54f7c..5065c5a 100644
--- a/src/java/com/android/internal/telephony/InboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java
@@ -16,10 +16,14 @@
 
 package com.android.internal.telephony;
 
+import static android.provider.Telephony.Sms.Intents.RESULT_SMS_DATABASE_ERROR;
+import static android.provider.Telephony.Sms.Intents.RESULT_SMS_DISPATCH_FAILURE;
+import static android.provider.Telephony.Sms.Intents.RESULT_SMS_INVALID_URI;
+import static android.provider.Telephony.Sms.Intents.RESULT_SMS_NULL_MESSAGE;
+import static android.provider.Telephony.Sms.Intents.RESULT_SMS_NULL_PDU;
 import static android.service.carrier.CarrierMessagingService.RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE;
 import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
 
-import android.annotation.UnsupportedAppUsage;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
@@ -27,6 +31,7 @@
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -42,9 +47,9 @@
 import android.os.AsyncResult;
 import android.os.Binder;
 import android.os.Bundle;
-import android.os.IDeviceIdleController;
 import android.os.Message;
 import android.os.PowerManager;
+import android.os.PowerWhitelistManager;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -225,19 +230,13 @@
     protected Phone mPhone;
 
     @UnsupportedAppUsage
-    protected CellBroadcastHandler mCellBroadcastHandler;
-
-    @UnsupportedAppUsage
     private UserManager mUserManager;
 
     protected TelephonyMetrics mMetrics = TelephonyMetrics.getInstance();
 
     private LocalLog mLocalLog = new LocalLog(64);
 
-    @UnsupportedAppUsage
-    IDeviceIdleController mDeviceIdleController;
-
-    protected static boolean sEnableCbModule = true;
+    PowerWhitelistManager mPowerWhitelistManager;
 
     protected CellBroadcastServiceManager mCellBroadcastServiceManager;
 
@@ -263,13 +262,12 @@
      * @param storageMonitor the SmsStorageMonitor to check for storage availability
      */
     protected InboundSmsHandler(String name, Context context, SmsStorageMonitor storageMonitor,
-            Phone phone, CellBroadcastHandler cellBroadcastHandler) {
+            Phone phone) {
         super(name);
 
         mContext = context;
         mStorageMonitor = storageMonitor;
         mPhone = phone;
-        mCellBroadcastHandler = cellBroadcastHandler;
         mResolver = context.getContentResolver();
         mWapPush = new WapPushOverSms(context);
 
@@ -282,8 +280,8 @@
         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, name);
         mWakeLock.acquire();    // wake lock released after we enter idle state
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        mDeviceIdleController = TelephonyComponentFactory.getInstance()
-                .inject(IDeviceIdleController.class.getName()).getIDeviceIdleController();
+        mPowerWhitelistManager =
+                (PowerWhitelistManager) mContext.getSystemService(Context.POWER_WHITELIST_MANAGER);
         mCellBroadcastServiceManager = new CellBroadcastServiceManager(context, phone);
 
         addState(mDefaultState);
@@ -603,7 +601,7 @@
             result = dispatchMessage(sms.mWrappedSmsMessage);
         } catch (RuntimeException ex) {
             loge("Exception dispatching message", ex);
-            result = Intents.RESULT_SMS_GENERIC_ERROR;
+            result = RESULT_SMS_DISPATCH_FAILURE;
         }
 
         // RESULT_OK means that the SMS will be acknowledged by special handling,
@@ -626,14 +624,15 @@
             callback = (SmsDispatchersController.SmsInjectionCallback) ar.userObj;
             SmsMessage sms = (SmsMessage) ar.result;
             if (sms == null) {
-                result = Intents.RESULT_SMS_GENERIC_ERROR;
+                loge("Null injected sms");
+                result = RESULT_SMS_NULL_PDU;
             } else {
                 mLastSmsWasInjected = true;
                 result = dispatchMessage(sms.mWrappedSmsMessage);
             }
         } catch (RuntimeException ex) {
             loge("Exception dispatching message", ex);
-            result = Intents.RESULT_SMS_GENERIC_ERROR;
+            result = RESULT_SMS_DISPATCH_FAILURE;
         }
 
         if (callback != null) {
@@ -653,7 +652,7 @@
         // If sms is null, there was a parsing error.
         if (smsb == null) {
             loge("dispatchSmsMessage: message is null");
-            return Intents.RESULT_SMS_GENERIC_ERROR;
+            return RESULT_SMS_NULL_MESSAGE;
         }
 
         if (mSmsReceiveDisabled) {
@@ -673,7 +672,7 @@
 //        if (onlyCore) {
 //            // Device is unable to receive SMS in encrypted state
 //            log("Received a short message in encrypted state. Rejecting.");
-//            return Intents.RESULT_SMS_GENERIC_ERROR;
+//            return Intents.RESULT_SMS_RECEIVED_WHILE_ENCRYPTED;
 //        }
 
         int result = dispatchMessageRadioSpecific(smsb);
@@ -720,6 +719,7 @@
             // broadcast SMS_REJECTED_ACTION intent
             Intent intent = new Intent(Intents.SMS_REJECTED_ACTION);
             intent.putExtra("result", result);
+            intent.putExtra("subId", mPhone.getSubId());
             // Allow registered broadcast receivers to get this intent even
             // when they are in the background.
             intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
@@ -789,21 +789,28 @@
      * Helper to add the tracker to the raw table and then send a message to broadcast it, if
      * successful. Returns the SMS intent status to return to the SMSC.
      * @param tracker the tracker to save to the raw table and then deliver
-     * @return {@link Intents#RESULT_SMS_HANDLED} or {@link Intents#RESULT_SMS_GENERIC_ERROR}
-     * or {@link Intents#RESULT_SMS_DUPLICATED}
+     * @return {@link Intents#RESULT_SMS_HANDLED} or one of these errors:<br>
+     * <code>RESULT_SMS_UNSUPPORTED</code><br>
+     * <code>RESULT_SMS_DUPLICATED</code><br>
+     * <code>RESULT_SMS_DISPATCH_FAILURE</code><br>
+     * <code>RESULT_SMS_NULL_PDU</code><br>
+     * <code>RESULT_SMS_NULL_MESSAGE</code><br>
+     * <code>RESULT_SMS_RECEIVED_WHILE_ENCRYPTED</code><br>
+     * <code>RESULT_SMS_DATABASE_ERROR</code><br>
+     * <code>RESULT_SMS_INVALID_URI</code><br>
      */
     protected int addTrackerToRawTableAndSendMessage(InboundSmsTracker tracker, boolean deDup) {
-        switch(addTrackerToRawTable(tracker, deDup)) {
-        case Intents.RESULT_SMS_HANDLED:
-            sendMessage(EVENT_BROADCAST_SMS, tracker);
-            return Intents.RESULT_SMS_HANDLED;
+        int result = addTrackerToRawTable(tracker, deDup);
+        switch(result) {
+            case Intents.RESULT_SMS_HANDLED:
+                sendMessage(EVENT_BROADCAST_SMS, tracker);
+                return Intents.RESULT_SMS_HANDLED;
 
-        case Intents.RESULT_SMS_DUPLICATED:
-            return Intents.RESULT_SMS_HANDLED;
+            case Intents.RESULT_SMS_DUPLICATED:
+                return Intents.RESULT_SMS_HANDLED;
 
-        case Intents.RESULT_SMS_GENERIC_ERROR:
-        default:
-            return Intents.RESULT_SMS_GENERIC_ERROR;
+            default:
+                return result;
         }
     }
 
@@ -1234,14 +1241,11 @@
             bopts.setBackgroundActivityStartsAllowed(true);
             bundle = bopts.toBundle();
         }
-        try {
-            long duration = mDeviceIdleController.addPowerSaveTempWhitelistAppForSms(
-                    pkgName, 0, reason);
-            if (bopts == null) bopts = BroadcastOptions.makeBasic();
-            bopts.setTemporaryAppWhitelistDuration(duration);
-            bundle = bopts.toBundle();
-        } catch (RemoteException e) {
-        }
+        long duration = mPowerWhitelistManager.whitelistAppTemporarilyForEvent(
+                pkgName, PowerWhitelistManager.EVENT_SMS, reason);
+        if (bopts == null) bopts = BroadcastOptions.makeBasic();
+        bopts.setTemporaryAppWhitelistDuration(duration);
+        bundle = bopts.toBundle();
 
         return bundle;
     }
@@ -1408,7 +1412,7 @@
                 }
             } catch (SQLException e) {
                 loge("Can't access SMS database", e);
-                return Intents.RESULT_SMS_GENERIC_ERROR;    // reject message
+                return RESULT_SMS_DATABASE_ERROR;    // reject message
             }
         } else {
             logd("Skipped message de-duping logic");
@@ -1436,7 +1440,7 @@
             return Intents.RESULT_SMS_HANDLED;
         } catch (Exception e) {
             loge("error parsing URI for new row: " + newUri, e);
-            return Intents.RESULT_SMS_GENERIC_ERROR;
+            return RESULT_SMS_INVALID_URI;
         }
     }
 
@@ -1493,15 +1497,13 @@
                 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
                 // Only the primary user will receive notification of incoming mms.
                 // That app will do the actual downloading of the mms.
-                Bundle options = null;
-                try {
-                    long duration = mDeviceIdleController.addPowerSaveTempWhitelistAppForMms(
-                            mContext.getPackageName(), 0, "mms-broadcast");
-                    BroadcastOptions bopts = BroadcastOptions.makeBasic();
-                    bopts.setTemporaryAppWhitelistDuration(duration);
-                    options = bopts.toBundle();
-                } catch (RemoteException e) {
-                }
+                long duration = mPowerWhitelistManager.whitelistAppTemporarilyForEvent(
+                        mContext.getPackageName(),
+                        PowerWhitelistManager.EVENT_MMS,
+                        "mms-broadcast");
+                BroadcastOptions bopts = BroadcastOptions.makeBasic();
+                bopts.setTemporaryAppWhitelistDuration(duration);
+                Bundle options = bopts.toBundle();
 
                 String mimeType = intent.getType();
                 dispatchIntent(intent, WapPushOverSms.getPermissionForType(mimeType),
@@ -1718,9 +1720,6 @@
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         super.dump(fd, pw, args);
-        if (mCellBroadcastHandler != null) {
-            mCellBroadcastHandler.dump(fd, pw, args);
-        }
         if (mCellBroadcastServiceManager != null) {
             mCellBroadcastServiceManager.dump(fd, pw, args);
         }
@@ -1807,15 +1806,11 @@
     protected abstract class CbTestBroadcastReceiver extends BroadcastReceiver {
 
         protected abstract void handleTestAction(Intent intent);
-        protected abstract void handleToggleEnable();
-        protected abstract void handleToggleDisable(Context context);
 
         protected final String mTestAction;
-        protected final String mToggleAction;
 
-        public CbTestBroadcastReceiver(String testAction, String toggleAction) {
+        public CbTestBroadcastReceiver(String testAction) {
             mTestAction = testAction;
-            mToggleAction = toggleAction;
         }
 
         @Override
@@ -1829,19 +1824,6 @@
                     return;
                 }
                 handleTestAction(intent);
-            } else if (intent.getAction().equals(mToggleAction)) {
-                if (intent.hasExtra("enable")) {
-                    sEnableCbModule = intent.getBooleanExtra("enable", false);
-                } else {
-                    sEnableCbModule = !sEnableCbModule;
-                }
-                if (sEnableCbModule) {
-                    log("enabling CB module");
-                    handleToggleEnable();
-                } else {
-                    log("enabling legacy platform CB handling");
-                    handleToggleDisable(context);
-                }
             }
         }
     }
diff --git a/src/java/com/android/internal/telephony/InboundSmsTracker.java b/src/java/com/android/internal/telephony/InboundSmsTracker.java
index 4d9971e..30f63b2 100644
--- a/src/java/com/android/internal/telephony/InboundSmsTracker.java
+++ b/src/java/com/android/internal/telephony/InboundSmsTracker.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ContentValues;
 import android.database.Cursor;
 import android.util.Pair;
diff --git a/src/java/com/android/internal/telephony/IntRangeManager.java b/src/java/com/android/internal/telephony/IntRangeManager.java
index b82a20e..02880e0 100644
--- a/src/java/com/android/internal/telephony/IntRangeManager.java
+++ b/src/java/com/android/internal/telephony/IntRangeManager.java
@@ -16,7 +16,8 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
+
 import java.util.ArrayList;
 import java.util.Iterator;
 
diff --git a/src/java/com/android/internal/telephony/MccTable.java b/src/java/com/android/internal/telephony/MccTable.java
index 01479f9..f153afd 100644
--- a/src/java/com/android/internal/telephony/MccTable.java
+++ b/src/java/com/android/internal/telephony/MccTable.java
@@ -18,8 +18,8 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityManager;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.icu.util.ULocale;
diff --git a/src/java/com/android/internal/telephony/MmiCode.java b/src/java/com/android/internal/telephony/MmiCode.java
index eb09621..d4b1a0a 100644
--- a/src/java/com/android/internal/telephony/MmiCode.java
+++ b/src/java/com/android/internal/telephony/MmiCode.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.ResultReceiver;
 
 import java.util.regex.Pattern;
diff --git a/src/java/com/android/internal/telephony/MultiSimSettingController.java b/src/java/com/android/internal/telephony/MultiSimSettingController.java
index 3610be8..6ed1e45 100644
--- a/src/java/com/android/internal/telephony/MultiSimSettingController.java
+++ b/src/java/com/android/internal/telephony/MultiSimSettingController.java
@@ -407,7 +407,7 @@
         if (DBG) log("onSubscriptionGroupChanged");
 
         List<SubscriptionInfo> infoList = mSubController.getSubscriptionsInGroup(
-                groupUuid, mContext.getOpPackageName());
+                groupUuid, mContext.getOpPackageName(), mContext.getFeatureId());
         if (infoList == null || infoList.isEmpty()) return;
 
         // Get a reference subscription to copy settings from.
@@ -470,7 +470,8 @@
         if (!isReadyToReevaluate()) return;
 
         List<SubscriptionInfo> activeSubInfos = mSubController
-                .getActiveSubscriptionInfoList(mContext.getOpPackageName());
+                .getActiveSubscriptionInfoList(mContext.getOpPackageName(),
+                        mContext.getFeatureId());
 
         if (ArrayUtils.isEmpty(activeSubInfos)) {
             mPrimarySubList.clear();
@@ -644,7 +645,8 @@
             if (phone != null && phone.isCdmaSubscriptionAppPresent()) {
                 cdmaPhoneCount++;
                 String simName = mSubController.getActiveSubscriptionInfo(
-                        subId, mContext.getOpPackageName()).getDisplayName().toString();
+                        subId, mContext.getOpPackageName(), mContext.getFeatureId())
+                        .getDisplayName().toString();
                 if (TextUtils.isEmpty(simName)) {
                     // Fall back to carrier name.
                     simName = phone.getCarrierName();
@@ -700,7 +702,8 @@
     private void setUserDataEnabledForGroup(int subId, boolean enable) {
         log("setUserDataEnabledForGroup subId " + subId + " enable " + enable);
         List<SubscriptionInfo> infoList = mSubController.getSubscriptionsInGroup(
-                mSubController.getGroupUuid(subId), mContext.getOpPackageName());
+                mSubController.getGroupUuid(subId), mContext.getOpPackageName(),
+                mContext.getFeatureId());
 
         if (infoList == null) return;
 
@@ -730,7 +733,8 @@
     private void setRoamingDataEnabledForGroup(int subId, boolean enable) {
         SubscriptionController subController = SubscriptionController.getInstance();
         List<SubscriptionInfo> infoList = subController.getSubscriptionsInGroup(
-                mSubController.getGroupUuid(subId), mContext.getOpPackageName());
+                mSubController.getGroupUuid(subId), mContext.getOpPackageName(),
+                mContext.getFeatureId());
 
         if (infoList == null) return;
 
@@ -778,7 +782,7 @@
         if (!SubscriptionInfoUpdater.isSubInfoInitialized()) return;
 
         List<SubscriptionInfo> opptSubList = mSubController.getOpportunisticSubscriptions(
-                mContext.getOpPackageName());
+                mContext.getOpPackageName(), mContext.getFeatureId());
 
         if (ArrayUtils.isEmpty(opptSubList)) return;
 
diff --git a/src/java/com/android/internal/telephony/NetworkRegistrationManager.java b/src/java/com/android/internal/telephony/NetworkRegistrationManager.java
index bd90be6..9f2d6e1 100644
--- a/src/java/com/android/internal/telephony/NetworkRegistrationManager.java
+++ b/src/java/com/android/internal/telephony/NetworkRegistrationManager.java
@@ -102,9 +102,9 @@
         intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
         try {
             Context contextAsUser = phone.getContext().createPackageContextAsUser(
-                    phone.getContext().getPackageName(), 0, UserHandle.ALL);
+                phone.getContext().getPackageName(), 0, UserHandle.ALL);
             contextAsUser.registerReceiver(mBroadcastReceiver, intentFilter,
-                    null /* broadcastPermission */, null);
+                null /* broadcastPermission */, null);
         } catch (PackageManager.NameNotFoundException e) {
             loge("Package name not found: " + e.getMessage());
         }
diff --git a/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java b/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java
index 895170d..a76b2a7 100644
--- a/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java
+++ b/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java
@@ -16,7 +16,6 @@
 
 package com.android.internal.telephony;
 
-import static android.os.Binder.withCleanCallingIdentity;
 import static android.telephony.AccessNetworkConstants.AccessNetworkType.EUTRAN;
 import static android.telephony.AccessNetworkConstants.AccessNetworkType.GERAN;
 import static android.telephony.AccessNetworkConstants.AccessNetworkType.UTRAN;
@@ -24,6 +23,7 @@
 import android.content.Context;
 import android.hardware.radio.V1_0.RadioError;
 import android.os.AsyncResult;
+import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
@@ -188,10 +188,16 @@
      * scan when scan results are restricted due to location privacy.
      */
     public static Set<String> getAllowedMccMncsForLocationRestrictedScan(Context context) {
-        return withCleanCallingIdentity(() -> SubscriptionController.getInstance()
-            .getAvailableSubscriptionInfoList(context.getOpPackageName()).stream()
-            .flatMap(NetworkScanRequestTracker::getAllowableMccMncsFromSubscriptionInfo)
-            .collect(Collectors.toSet()));
+        final long token = Binder.clearCallingIdentity();
+        try {
+            return SubscriptionController.getInstance()
+                    .getAvailableSubscriptionInfoList(context.getOpPackageName(),
+                            context.getFeatureId()).stream()
+                    .flatMap(NetworkScanRequestTracker::getAllowableMccMncsFromSubscriptionInfo)
+                    .collect(Collectors.toSet());
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     private static Stream<String> getAllowableMccMncsFromSubscriptionInfo(SubscriptionInfo info) {
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 5abe8f2..2ec36aa 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -18,8 +18,8 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.UnsupportedAppUsage;
 import android.app.BroadcastOptions;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -45,8 +45,8 @@
 import android.telephony.Annotation.DataFailureCause;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CarrierRestrictionRules;
+import android.telephony.CellIdentity;
 import android.telephony.CellInfo;
-import android.telephony.CellLocation;
 import android.telephony.ClientRequestStats;
 import android.telephony.ImsiEncryptionInfo;
 import android.telephony.PhoneStateListener;
@@ -434,27 +434,6 @@
     }
 
     /**
-     * Set a system property for the current phone, unless we're in unit test mode
-     */
-    // CAF_MSIM TODO this need to be replated with TelephonyManager API ?
-    public void setSystemProperty(String property, String value) {
-        if (getUnitTestMode()) {
-            return;
-        }
-        TelephonyManager.setTelephonyProperty(mPhoneId, property, value);
-    }
-
-    /**
-     * Set a system property for all phones, unless we're in unit test mode
-     */
-    public void setGlobalSystemProperty(String property, String value) {
-        if (getUnitTestMode()) {
-            return;
-        }
-        TelephonyManager.setTelephonyProperty(property, value);
-    }
-
-    /**
      * Set a system property, unless we're in unit test mode
      */
     // CAF_MSIM TODO this need to be replated with TelephonyManager API ?
@@ -1885,17 +1864,16 @@
     /**
      * @return the current cell location if known
      */
-    @UnsupportedAppUsage
-    public CellLocation getCellLocation() {
-        return getServiceStateTracker().getCellLocation();
+    public CellIdentity getCellIdentity() {
+        return getServiceStateTracker().getCellIdentity();
     }
 
     /**
      * @param workSource calling WorkSource
      * @param rspMsg the response message containing the cell location
      */
-    public void getCellLocation(WorkSource workSource, Message rspMsg) {
-        getServiceStateTracker().requestCellLocation(workSource, rspMsg);
+    public void getCellIdentity(WorkSource workSource, Message rspMsg) {
+        getServiceStateTracker().requestCellIdentity(workSource, rspMsg);
     }
 
     /**
diff --git a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
index c8480ec..4a95ada 100644
--- a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
+++ b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
@@ -26,7 +26,6 @@
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.RegistrantList;
-import android.os.storage.StorageManager;
 import android.sysprop.TelephonyProperties;
 import android.telephony.PhoneCapability;
 import android.telephony.Rlog;
@@ -100,14 +99,20 @@
         notifyCapabilityChanged();
 
         mPhones = PhoneFactory.getPhones();
-        if (!StorageManager.inCryptKeeperBounce()) {
-            for (Phone phone : mPhones) {
-                phone.mCi.registerForAvailable(mHandler, Phone.EVENT_RADIO_AVAILABLE, phone);
-            }
-        } else {
-            for (Phone phone : mPhones) {
-                phone.mCi.registerForOn(mHandler, Phone.EVENT_RADIO_ON, phone);
-            }
+
+        /*
+         * To support FDE (deprecated), additional check is needed:
+         *
+         * if (!StorageManager.inCryptKeeperBounce()) {
+         *     // for loop below
+         * } else {
+         *     for (Phone phone : mPhones) {
+         *         phone.mCi.registerForOn(mHandler, Phone.EVENT_RADIO_ON, phone);
+         *     }
+         * }
+         */
+        for (Phone phone : mPhones) {
+            phone.mCi.registerForAvailable(mHandler, Phone.EVENT_RADIO_AVAILABLE, phone);
         }
     }
 
diff --git a/src/java/com/android/internal/telephony/PhoneFactory.java b/src/java/com/android/internal/telephony/PhoneFactory.java
index 800aed4..c75cf94 100644
--- a/src/java/com/android/internal/telephony/PhoneFactory.java
+++ b/src/java/com/android/internal/telephony/PhoneFactory.java
@@ -22,7 +22,7 @@
 import static java.util.Arrays.copyOf;
 
 import android.annotation.Nullable;
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.SharedPreferences;
@@ -45,6 +45,7 @@
 import com.android.internal.telephony.euicc.EuiccController;
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.imsphone.ImsPhoneFactory;
+import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.telephony.sip.SipPhone;
 import com.android.internal.telephony.sip.SipPhoneFactory;
 import com.android.internal.telephony.uicc.UiccController;
@@ -114,6 +115,9 @@
                 // create the telephony device controller.
                 TelephonyDevController.create();
 
+                TelephonyMetrics metrics = TelephonyMetrics.getInstance();
+                metrics.setContext(context);
+
                 int retryCount = 0;
                 for(;;) {
                     boolean hasException = false;
diff --git a/src/java/com/android/internal/telephony/PhoneInternalInterface.java b/src/java/com/android/internal/telephony/PhoneInternalInterface.java
index a3ec284..b4d861b 100644
--- a/src/java/com/android/internal/telephony/PhoneInternalInterface.java
+++ b/src/java/com/android/internal/telephony/PhoneInternalInterface.java
@@ -17,7 +17,7 @@
 package com.android.internal.telephony;
 
 import android.annotation.NonNull;
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
diff --git a/src/java/com/android/internal/telephony/PhoneNotifier.java b/src/java/com/android/internal/telephony/PhoneNotifier.java
index 5049494..19dbe13 100644
--- a/src/java/com/android/internal/telephony/PhoneNotifier.java
+++ b/src/java/com/android/internal/telephony/PhoneNotifier.java
@@ -16,13 +16,13 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.telephony.Annotation.DataFailureCause;
 import android.telephony.Annotation.RadioPowerState;
 import android.telephony.Annotation.SrvccState;
 import android.telephony.CallQuality;
+import android.telephony.CellIdentity;
 import android.telephony.CellInfo;
-import android.telephony.CellLocation;
 import android.telephony.PhoneCapability;
 import android.telephony.PreciseDataConnectionState;
 import android.telephony.emergency.EmergencyNumber;
@@ -39,8 +39,12 @@
 
     void notifyServiceState(Phone sender);
 
-    /** Notify registrants of the current CellLocation */
-    void notifyCellLocation(Phone sender, CellLocation cl);
+    /**
+     * Notify registrants of the current CellLocation.
+     *
+     * <p>Use CellIdentity that is Parcellable to pass AIDL; convert to CellLocation in client code.
+     */
+    void notifyCellLocation(Phone sender, CellIdentity cellIdentity);
 
     @UnsupportedAppUsage
     void notifySignalStrength(Phone sender);
diff --git a/src/java/com/android/internal/telephony/PhoneStateIntentReceiver.java b/src/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
index 1d9f4f0..94b05ed 100644
--- a/src/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
+++ b/src/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
@@ -16,17 +16,17 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.Handler;
 import android.os.Message;
+import android.telephony.Rlog;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.TelephonyManager;
-import android.telephony.Rlog;
 
 /**
  *
diff --git a/src/java/com/android/internal/telephony/PhoneSubInfoController.java b/src/java/com/android/internal/telephony/PhoneSubInfoController.java
index 384a7c9..453b95c 100644
--- a/src/java/com/android/internal/telephony/PhoneSubInfoController.java
+++ b/src/java/com/android/internal/telephony/PhoneSubInfoController.java
@@ -21,8 +21,10 @@
 import static android.Manifest.permission.MODIFY_PHONE_STATE;
 import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
 
-import android.annotation.UnsupportedAppUsage;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.AppOpsManager;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Binder;
@@ -54,24 +56,31 @@
         mAppOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
     }
 
+    @Deprecated
     public String getDeviceId(String callingPackage) {
+        return getDeviceIdWithFeature(callingPackage, null);
+    }
+
+    public String getDeviceIdWithFeature(String callingPackage, String callingFeatureId) {
         return getDeviceIdForPhone(SubscriptionManager.getPhoneId(getDefaultSubscription()),
-                callingPackage);
+                callingPackage, callingFeatureId);
     }
 
-    public String getDeviceIdForPhone(int phoneId, String callingPackage) {
+    public String getDeviceIdForPhone(int phoneId, String callingPackage,
+            String callingFeatureId) {
         return callPhoneMethodForPhoneIdWithReadDeviceIdentifiersCheck(phoneId, callingPackage,
-                "getDeviceId", (phone)-> phone.getDeviceId());
+                callingFeatureId, "getDeviceId", (phone) -> phone.getDeviceId());
     }
 
-    public String getNaiForSubscriber(int subId, String callingPackage) {
+    public String getNaiForSubscriber(int subId, String callingPackage, String callingFeatureId) {
         return callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck(subId, callingPackage,
-                "getNai", (phone)-> phone.getNai());
+                callingFeatureId, "getNai", (phone)-> phone.getNai());
     }
 
-    public String getImeiForSubscriber(int subId, String callingPackage) {
+    public String getImeiForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         return callPhoneMethodForSubIdWithReadDeviceIdentifiersCheck(subId, callingPackage,
-                "getImei", (phone)-> phone.getImei());
+                callingFeatureId, "getImei", (phone) -> phone.getImei());
     }
 
     public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int subId, int keyType,
@@ -107,34 +116,43 @@
                 });
     }
 
-    public String getDeviceSvn(String callingPackage) {
-        return getDeviceSvnUsingSubId(getDefaultSubscription(), callingPackage);
+    public String getDeviceSvn(String callingPackage, String callingFeatureId) {
+        return getDeviceSvnUsingSubId(getDefaultSubscription(), callingPackage, callingFeatureId);
     }
 
-    public String getDeviceSvnUsingSubId(int subId, String callingPackage) {
-        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getDeviceSvn",
-                (phone)-> phone.getDeviceSvn());
+    public String getDeviceSvnUsingSubId(int subId, String callingPackage,
+            String callingFeatureId) {
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId,
+                "getDeviceSvn", (phone)-> phone.getDeviceSvn());
     }
 
+    @Deprecated
     public String getSubscriberId(String callingPackage) {
-        return getSubscriberIdForSubscriber(getDefaultSubscription(), callingPackage);
+        return getSubscriberIdWithFeature(callingPackage, null);
     }
 
-    public String getSubscriberIdForSubscriber(int subId, String callingPackage) {
+    public String getSubscriberIdWithFeature(String callingPackage, String callingFeatureId) {
+        return getSubscriberIdForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
+    }
+
+    public String getSubscriberIdForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         String message = "getSubscriberId";
         long identity = Binder.clearCallingIdentity();
         boolean isActive;
         try {
-            isActive = SubscriptionController.getInstance().isActiveSubId(subId, callingPackage);
+            isActive = SubscriptionController.getInstance().isActiveSubId(subId, callingPackage,
+                    callingFeatureId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
         if (isActive) {
             return callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck(subId, callingPackage,
-                    message, (phone) -> phone.getSubscriberId());
+                    callingFeatureId, message, (phone) -> phone.getSubscriberId());
         } else {
             if (!TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(
-                    mContext, subId, callingPackage, message)) {
+                    mContext, subId, callingPackage, callingFeatureId, message)) {
                 return null;
             }
             identity = Binder.clearCallingIdentity();
@@ -146,52 +164,66 @@
         }
     }
 
+    @Deprecated
+    public String getIccSerialNumber(String callingPackage) {
+        return getIccSerialNumberWithFeature(callingPackage, null);
+    }
+
     /**
      * Retrieves the serial number of the ICC, if applicable.
      */
-    public String getIccSerialNumber(String callingPackage) {
-        return getIccSerialNumberForSubscriber(getDefaultSubscription(), callingPackage);
+    public String getIccSerialNumberWithFeature(String callingPackage, String callingFeatureId) {
+        return getIccSerialNumberForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
-    public String getIccSerialNumberForSubscriber(int subId, String callingPackage) {
+    public String getIccSerialNumberForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         return callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck(subId, callingPackage,
-                "getIccSerialNumber", (phone) -> phone.getIccSerialNumber());
+                callingFeatureId, "getIccSerialNumber", (phone) -> phone.getIccSerialNumber());
     }
 
-    public String getLine1Number(String callingPackage) {
-        return getLine1NumberForSubscriber(getDefaultSubscription(), callingPackage);
+    public String getLine1Number(String callingPackage, String callingFeatureId) {
+        return getLine1NumberForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
-    public String getLine1NumberForSubscriber(int subId, String callingPackage) {
+    public String getLine1NumberForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         return callPhoneMethodForSubIdWithReadPhoneNumberCheck(
-                subId, callingPackage, "getLine1Number",
+                subId, callingPackage, callingFeatureId, "getLine1Number",
                 (phone)-> phone.getLine1Number());
     }
 
-    public String getLine1AlphaTag(String callingPackage) {
-        return getLine1AlphaTagForSubscriber(getDefaultSubscription(), callingPackage);
+    public String getLine1AlphaTag(String callingPackage, String callingFeatureId) {
+        return getLine1AlphaTagForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
-    public String getLine1AlphaTagForSubscriber(int subId, String callingPackage) {
-        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getLine1AlphaTag",
-                (phone)-> phone.getLine1AlphaTag());
+    public String getLine1AlphaTagForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId,
+                "getLine1AlphaTag", (phone)-> phone.getLine1AlphaTag());
     }
 
-    public String getMsisdn(String callingPackage) {
-        return getMsisdnForSubscriber(getDefaultSubscription(), callingPackage);
+    public String getMsisdn(String callingPackage, String callingFeatureId) {
+        return getMsisdnForSubscriber(getDefaultSubscription(), callingPackage, callingFeatureId);
     }
 
-    public String getMsisdnForSubscriber(int subId, String callingPackage) {
-        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getMsisdn",
-                (phone)-> phone.getMsisdn());
+    public String getMsisdnForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId,
+                "getMsisdn", (phone)-> phone.getMsisdn());
     }
 
-    public String getVoiceMailNumber(String callingPackage) {
-        return getVoiceMailNumberForSubscriber(getDefaultSubscription(), callingPackage);
+    public String getVoiceMailNumber(String callingPackage, String callingFeatureId) {
+        return getVoiceMailNumberForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
-    public String getVoiceMailNumberForSubscriber(int subId, String callingPackage) {
-        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage,
+    public String getVoiceMailNumberForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId,
                 "getVoiceMailNumber", (phone)-> {
                     String number = PhoneNumberUtils.extractNetworkPortion(
                             phone.getVoiceMailNumber());
@@ -200,12 +232,14 @@
                 });
     }
 
-    public String getVoiceMailAlphaTag(String callingPackage) {
-        return getVoiceMailAlphaTagForSubscriber(getDefaultSubscription(), callingPackage);
+    public String getVoiceMailAlphaTag(String callingPackage, String callingFeatureId) {
+        return getVoiceMailAlphaTagForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
-    public String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage) {
-        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage,
+    public String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId,
                 "getVoiceMailAlphaTag", (phone)-> phone.getVoiceMailAlphaTag());
     }
 
@@ -236,7 +270,7 @@
             return;
         }
         if (VDBG) log("No read privileged phone permission, check carrier privilege next.");
-        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, message);
+        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mContext, subId, message);
     }
 
     /**
@@ -353,16 +387,17 @@
             return uiccApp.getIccRecords().getIccSimChallengeResponse(authType, data);
         };
 
-        return callPhoneMethodWithPermissionCheck(
-                subId, null, "getIccSimChallengeResponse", toExecute,
-                (aContext, aSubId, aCallingPackage, aMessage)-> {
+        return callPhoneMethodWithPermissionCheck(subId, null, null, "getIccSimChallengeResponse",
+                toExecute,
+                (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage) -> {
                     enforcePrivilegedPermissionOrCarrierPrivilege(aSubId, aMessage);
                     return true;
                 });
     }
 
-    public String getGroupIdLevel1ForSubscriber(int subId, String callingPackage) {
-        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage,
+    public String getGroupIdLevel1ForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
+        return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId,
                 "getGroupIdLevel1", (phone)-> phone.getGroupIdLevel1());
     }
 
@@ -381,14 +416,17 @@
         // If passes, it should return true.
         // If permission is not granted, throws SecurityException.
         // If permission is revoked by AppOps, return false.
-        boolean checkPermission(Context context, int subId, String callingPackage, String message);
+        boolean checkPermission(Context context, int subId, String callingPackage,
+                @Nullable String callingFeatureId, String message);
     }
 
     // Base utility method that others use.
     private <T> T callPhoneMethodWithPermissionCheck(int subId, String callingPackage,
-            String message, CallPhoneMethodHelper<T> callMethodHelper,
+            @Nullable String callingFeatureId, String message,
+            CallPhoneMethodHelper<T> callMethodHelper,
             PermissionCheckHelper permissionCheckHelper) {
-        if (!permissionCheckHelper.checkPermission(mContext, subId, callingPackage, message)) {
+        if (!permissionCheckHelper.checkPermission(mContext, subId, callingPackage,
+                callingFeatureId, message)) {
             return null;
         }
 
@@ -407,33 +445,39 @@
     }
 
     private <T> T callPhoneMethodForSubIdWithReadCheck(int subId, String callingPackage,
-            String message, CallPhoneMethodHelper<T> callMethodHelper) {
-        return callPhoneMethodWithPermissionCheck(subId, callingPackage, message, callMethodHelper,
-                (aContext, aSubId, aCallingPackage, aMessage)->
+            @Nullable String callingFeatureId, String message,
+            CallPhoneMethodHelper<T> callMethodHelper) {
+        return callPhoneMethodWithPermissionCheck(subId, callingPackage, callingFeatureId,
+                message, callMethodHelper,
+                (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage)->
                         TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                                aContext, aSubId, aCallingPackage, aMessage));
+                                aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage));
     }
 
     private <T> T callPhoneMethodForSubIdWithReadDeviceIdentifiersCheck(int subId,
-            String callingPackage, String message, CallPhoneMethodHelper<T> callMethodHelper) {
-        return callPhoneMethodWithPermissionCheck(subId, callingPackage, message, callMethodHelper,
-                (aContext, aSubId, aCallingPackage, aMessage)->
+            String callingPackage, @Nullable String callingFeatureId, String message,
+            CallPhoneMethodHelper<T> callMethodHelper) {
+        return callPhoneMethodWithPermissionCheck(subId, callingPackage, callingFeatureId,
+                message, callMethodHelper,
+                (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage)->
                         TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(
-                                aContext, aSubId, aCallingPackage, aMessage));
+                                aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage));
     }
 
     private <T> T callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck(int subId,
-            String callingPackage, String message, CallPhoneMethodHelper<T> callMethodHelper) {
-        return callPhoneMethodWithPermissionCheck(subId, callingPackage, message, callMethodHelper,
-                (aContext, aSubId, aCallingPackage, aMessage)->
+            String callingPackage, @Nullable String callingFeatureId, String message,
+            CallPhoneMethodHelper<T> callMethodHelper) {
+        return callPhoneMethodWithPermissionCheck(subId, callingPackage, callingFeatureId,
+                message, callMethodHelper,
+                (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage)->
                         TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(
-                                aContext, aSubId, aCallingPackage, aMessage));
+                                aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage));
     }
 
     private <T> T callPhoneMethodForSubIdWithPrivilegedCheck(
             int subId, String message, CallPhoneMethodHelper<T> callMethodHelper) {
-        return callPhoneMethodWithPermissionCheck(subId, null, message, callMethodHelper,
-                (aContext, aSubId, aCallingPackage, aMessage)-> {
+        return callPhoneMethodWithPermissionCheck(subId, null, null, message, callMethodHelper,
+                (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage) -> {
                     mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, message);
                     return true;
                 });
@@ -441,23 +485,26 @@
 
     private <T> T callPhoneMethodForSubIdWithModifyCheck(int subId, String callingPackage,
             String message, CallPhoneMethodHelper<T> callMethodHelper) {
-        return callPhoneMethodWithPermissionCheck(subId, null, message, callMethodHelper,
-                (aContext, aSubId, aCallingPackage, aMessage)-> {
+        return callPhoneMethodWithPermissionCheck(subId, null, null, message, callMethodHelper,
+                (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage)-> {
                     enforceModifyPermission();
                     return true;
                 });
     }
 
     private <T> T callPhoneMethodForSubIdWithReadPhoneNumberCheck(int subId, String callingPackage,
-            String message, CallPhoneMethodHelper<T> callMethodHelper) {
-        return callPhoneMethodWithPermissionCheck(subId, callingPackage, message, callMethodHelper,
-                (aContext, aSubId, aCallingPackage, aMessage)->
+            @NonNull String callingFeatureId, String message,
+            CallPhoneMethodHelper<T> callMethodHelper) {
+        return callPhoneMethodWithPermissionCheck(subId, callingPackage, callingFeatureId,
+                message, callMethodHelper,
+                (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage) ->
                         TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
-                                aContext, aSubId, aCallingPackage, aMessage));
+                                aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage));
     }
 
     private <T> T callPhoneMethodForPhoneIdWithReadDeviceIdentifiersCheck(int phoneId,
-            String callingPackage, String message, CallPhoneMethodHelper<T> callMethodHelper) {
+            String callingPackage, @Nullable String callingFeatureId, String message,
+            CallPhoneMethodHelper<T> callMethodHelper) {
         // Getting subId before doing permission check.
         if (!SubscriptionManager.isValidPhoneId(phoneId)) {
             phoneId = 0;
@@ -467,7 +514,7 @@
             return null;
         }
         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mContext,
-                phone.getSubId(), callingPackage, message)) {
+                phone.getSubId(), callingPackage, callingFeatureId, message)) {
             return null;
         }
 
diff --git a/src/java/com/android/internal/telephony/PhoneSwitcher.java b/src/java/com/android/internal/telephony/PhoneSwitcher.java
index 3981eb6..cad0b75 100644
--- a/src/java/com/android/internal/telephony/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/PhoneSwitcher.java
@@ -27,7 +27,7 @@
 
 import static java.util.Arrays.copyOf;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
diff --git a/src/java/com/android/internal/telephony/ProxyController.java b/src/java/com/android/internal/telephony/ProxyController.java
index 69f8a0b..a617154 100644
--- a/src/java/com/android/internal/telephony/ProxyController.java
+++ b/src/java/com/android/internal/telephony/ProxyController.java
@@ -18,7 +18,7 @@
 
 import static java.util.Arrays.copyOf;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.Intent;
 import android.os.AsyncResult;
diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java
index 1a60ebc..79d96e1 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -19,7 +19,7 @@
 import static com.android.internal.telephony.RILConstants.*;
 import static com.android.internal.util.Preconditions.checkNotNull;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.hardware.radio.V1_0.Carrier;
 import android.hardware.radio.V1_0.CarrierRestrictions;
@@ -56,7 +56,6 @@
 import android.net.KeepalivePacketData;
 import android.net.LinkAddress;
 import android.net.LinkProperties;
-import android.net.NetworkUtils;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.HwBinder;
@@ -115,6 +114,8 @@
 import com.android.internal.telephony.uicc.IccUtils;
 import com.android.internal.telephony.util.TelephonyUtils;
 
+import libcore.net.InetAddressUtils;
+
 import java.io.ByteArrayInputStream;
 import java.io.DataInputStream;
 import java.io.FileDescriptor;
@@ -131,6 +132,7 @@
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.Collectors;
 
 /**
  * RIL implementation of the CommandsInterface.
@@ -1573,16 +1575,29 @@
                     android.hardware.radio.V1_5.DataProfileInfo dpi =
                             convertToHalDataProfile15(dataProfile);
 
+                    ArrayList<android.hardware.radio.V1_5.LinkAddress> addresses15 =
+                            new ArrayList<>();
+                    if (linkProperties != null) {
+                        for (LinkAddress la : linkProperties.getAllLinkAddresses()) {
+                            android.hardware.radio.V1_5.LinkAddress linkAddress =
+                                    new android.hardware.radio.V1_5.LinkAddress();
+                            linkAddress.address = la.getAddress().getHostAddress();
+                            linkAddress.properties = la.getFlags();
+                            // TODO: Add deprecated time and expired time support here.
+                            addresses15.add(linkAddress);
+                        }
+                    }
+
                     if (RILJ_LOGD) {
                         riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                                 + ",accessNetworkType="
                                 + AccessNetworkType.toString(accessNetworkType) + ",isRoaming="
                                 + isRoaming + ",allowRoaming=" + allowRoaming + "," + dataProfile
-                                + ",addresses=" + addresses + ",dnses=" + dnses);
+                                + ",addresses=" + addresses15 + ",dnses=" + dnses);
                     }
 
                     radioProxy15.setupDataCall_1_5(rr.mSerial, accessNetworkType, dpi, allowRoaming,
-                            reason, addresses, dnses);
+                            reason, addresses15, dnses);
                 } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
                     // IRadio V1.4
                     android.hardware.radio.V1_4.IRadio radioProxy14 =
@@ -6291,6 +6306,10 @@
         String[] dnses = null;
         String[] gateways = null;
         String[] pcscfs = null;
+
+        List<LinkAddress> laList = new ArrayList<>();
+        int version = 0;
+
         if (dcResult instanceof android.hardware.radio.V1_0.SetupDataCallResult) {
             final android.hardware.radio.V1_0.SetupDataCallResult result =
                     (android.hardware.radio.V1_0.SetupDataCallResult) dcResult;
@@ -6313,6 +6332,7 @@
                 pcscfs = result.pcscf.split("\\s+");
             }
             mtu = result.mtu;
+            version = 0;
         } else if (dcResult instanceof android.hardware.radio.V1_4.SetupDataCallResult) {
             final android.hardware.radio.V1_4.SetupDataCallResult result =
                     (android.hardware.radio.V1_4.SetupDataCallResult) dcResult;
@@ -6327,32 +6347,52 @@
             gateways = result.gateways.stream().toArray(String[]::new);
             pcscfs = result.pcscf.stream().toArray(String[]::new);
             mtu = result.mtu;
+            version = 4;
+        } else if (dcResult instanceof android.hardware.radio.V1_5.SetupDataCallResult) {
+            final android.hardware.radio.V1_5.SetupDataCallResult result =
+                    (android.hardware.radio.V1_5.SetupDataCallResult) dcResult;
+            cause = result.cause;
+            suggestedRetryTime = result.suggestedRetryTime;
+            cid = result.cid;
+            active = result.active;
+            protocolType = result.type;
+            ifname = result.ifname;
+            //addresses = result.addresses.stream().toArray(String[]::new);
+            laList = result.addresses.stream().map(a -> new LinkAddress(
+                    InetAddressUtils.parseNumericAddress(a.address), 0, a.properties, 0))
+                    .collect(Collectors.toList());
+            dnses = result.dnses.stream().toArray(String[]::new);
+            gateways = result.gateways.stream().toArray(String[]::new);
+            pcscfs = result.pcscf.stream().toArray(String[]::new);
+            mtu = result.mtu;
+            version = 5;
         } else {
             Rlog.e(RILJ_LOG_TAG, "Unsupported SetupDataCallResult " + dcResult);
             return null;
         }
 
-        // Process address
-        List<LinkAddress> laList = new ArrayList<>();
-        if (addresses != null) {
-            for (String address : addresses) {
-                address = address.trim();
-                if (address.isEmpty()) continue;
+        if (version < 5) {
+            // Process address
+            if (addresses != null) {
+                for (String address : addresses) {
+                    address = address.trim();
+                    if (address.isEmpty()) continue;
 
-                try {
-                    LinkAddress la;
-                    // Check if the address contains prefix length. If yes, LinkAddress
-                    // can parse that.
-                    if (address.split("/").length == 2) {
-                        la = new LinkAddress(address);
-                    } else {
-                        InetAddress ia = NetworkUtils.numericToInetAddress(address);
-                        la = new LinkAddress(ia, (ia instanceof Inet4Address) ? 32 : 128);
+                    try {
+                        LinkAddress la;
+                        // Check if the address contains prefix length. If yes, LinkAddress
+                        // can parse that.
+                        if (address.split("/").length == 2) {
+                            la = new LinkAddress(address);
+                        } else {
+                            InetAddress ia = InetAddressUtils.parseNumericAddress(address);
+                            la = new LinkAddress(ia, (ia instanceof Inet4Address) ? 32 : 128);
+                        }
+
+                        laList.add(la);
+                    } catch (IllegalArgumentException e) {
+                        Rlog.e(RILJ_LOG_TAG, "Unknown address: " + address, e);
                     }
-
-                    laList.add(la);
-                } catch (IllegalArgumentException e) {
-                    Rlog.e(RILJ_LOG_TAG, "Unknown address: " + address, e);
                 }
             }
         }
@@ -6364,7 +6404,7 @@
                 dns = dns.trim();
                 InetAddress ia;
                 try {
-                    ia = NetworkUtils.numericToInetAddress(dns);
+                    ia = InetAddressUtils.parseNumericAddress(dns);
                     dnsList.add(ia);
                 } catch (IllegalArgumentException e) {
                     Rlog.e(RILJ_LOG_TAG, "Unknown dns: " + dns, e);
@@ -6379,7 +6419,7 @@
                 gateway = gateway.trim();
                 InetAddress ia;
                 try {
-                    ia = NetworkUtils.numericToInetAddress(gateway);
+                    ia = InetAddressUtils.parseNumericAddress(gateway);
                     gatewayList.add(ia);
                 } catch (IllegalArgumentException e) {
                     Rlog.e(RILJ_LOG_TAG, "Unknown gateway: " + gateway, e);
@@ -6394,7 +6434,7 @@
                 pcscf = pcscf.trim();
                 InetAddress ia;
                 try {
-                    ia = NetworkUtils.numericToInetAddress(pcscf);
+                    ia = InetAddressUtils.parseNumericAddress(pcscf);
                     pcscfList.add(ia);
                 } catch (IllegalArgumentException e) {
                     Rlog.e(RILJ_LOG_TAG, "Unknown pcscf: " + pcscf, e);
diff --git a/src/java/com/android/internal/telephony/RILRequest.java b/src/java/com/android/internal/telephony/RILRequest.java
index 2d8f952..57e631d 100644
--- a/src/java/com/android/internal/telephony/RILRequest.java
+++ b/src/java/com/android/internal/telephony/RILRequest.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.AsyncResult;
 import android.os.Message;
 import android.os.SystemClock;
@@ -24,7 +24,7 @@
 import android.os.WorkSource.WorkChain;
 import android.telephony.Rlog;
 
-import java.util.ArrayList;
+import java.util.List;
 import java.util.Random;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -142,10 +142,10 @@
         }
 
         if (mWorkSource.size() > 0) {
-            return mWorkSource.get(0) + ":" + mWorkSource.getName(0);
+            return mWorkSource.getUid(0) + ":" + mWorkSource.getPackageName(0);
         }
 
-        final ArrayList<WorkChain> workChains = mWorkSource.getWorkChains();
+        final List<WorkChain> workChains = mWorkSource.getWorkChains();
         if (workChains != null && !workChains.isEmpty()) {
             final WorkChain workChain = workChains.get(0);
             return workChain.getAttributionUid() + ":" + workChain.getTags()[0];
diff --git a/src/java/com/android/internal/telephony/RadioCapability.java b/src/java/com/android/internal/telephony/RadioCapability.java
index 2b2615b..3475201 100644
--- a/src/java/com/android/internal/telephony/RadioCapability.java
+++ b/src/java/com/android/internal/telephony/RadioCapability.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.telephony.TelephonyManager;
 
 /**
diff --git a/src/java/com/android/internal/telephony/RetryManager.java b/src/java/com/android/internal/telephony/RetryManager.java
index ae5318f..67bc3c0 100644
--- a/src/java/com/android/internal/telephony/RetryManager.java
+++ b/src/java/com/android/internal/telephony/RetryManager.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.PersistableBundle;
 import android.os.SystemProperties;
diff --git a/src/java/com/android/internal/telephony/SMSDispatcher.java b/src/java/com/android/internal/telephony/SMSDispatcher.java
index 4b32c72..ad10f7c 100644
--- a/src/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/SMSDispatcher.java
@@ -30,12 +30,12 @@
 import static com.android.internal.telephony.IccSmsInterfaceManager.SMS_MESSAGE_PRIORITY_NOT_SPECIFIED;
 import static com.android.internal.telephony.SmsResponse.NO_ERROR_CODE;
 
-import android.annotation.UnsupportedAppUsage;
 import android.annotation.UserIdInt;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index 58afb7d..781d479 100755
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -26,11 +26,11 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.UnsupportedAppUsage;
 import android.app.AlarmManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -66,7 +66,6 @@
 import android.telephony.CellIdentityTdscdma;
 import android.telephony.CellIdentityWcdma;
 import android.telephony.CellInfo;
-import android.telephony.CellLocation;
 import android.telephony.CellSignalStrengthNr;
 import android.telephony.DataSpecificRegistrationInfo;
 import android.telephony.NetworkRegistrationInfo;
@@ -80,8 +79,6 @@
 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
 import android.telephony.TelephonyManager;
 import android.telephony.VoiceSpecificRegistrationInfo;
-import android.telephony.cdma.CdmaCellLocation;
-import android.telephony.gsm.GsmCellLocation;
 import android.text.TextUtils;
 import android.util.EventLog;
 import android.util.LocalLog;
@@ -1253,7 +1250,7 @@
                             .getCellIdentity();
                     updateOperatorNameForCellIdentity(cellIdentity);
                     mCellIdentity = cellIdentity;
-                    mPhone.notifyLocationChanged(getCellLocation());
+                    mPhone.notifyLocationChanged(getCellIdentity());
                 }
 
                 // Release any temporary cell lock, which could have been
@@ -1593,15 +1590,15 @@
             case EVENT_CELL_LOCATION_RESPONSE:
                 ar = (AsyncResult) msg.obj;
                 if (ar == null) {
-                    loge("Invalid null response to getCellLocation!");
+                    loge("Invalid null response to getCellIdentity!");
                     break;
                 }
                 // This response means that the correct CellInfo is already cached; thus we
                 // can rely on the last cell info to already contain any cell info that is
                 // available, which means that we can return the result of the existing
-                // getCellLocation() function without any additional processing here.
+                // getCellIdentity() function without any additional processing here.
                 Message rspRspMsg = (Message) ar.userObj;
-                AsyncResult.forMessage(rspRspMsg, getCellLocation(), ar.exception);
+                AsyncResult.forMessage(rspRspMsg, getCellIdentity(), ar.exception);
                 rspRspMsg.sendToTarget();
                 break;
 
@@ -2791,11 +2788,7 @@
     }
 
     /**
-     * Checks whether force to display "no service" to the user based on the current country.
-     *
-     * This method should only be used when SIM is unready.
-     *
-     * @return {@code True} if "no service" should be displayed.
+     * Returns whether out-of-service will be displayed as "no service" to the user.
      */
     public boolean shouldForceDisplayNoService() {
         String[] countriesWithNoService = mPhone.getContext().getResources().getStringArray(
@@ -3506,7 +3499,7 @@
         }
 
         if (hasLocationChanged) {
-            mPhone.notifyLocationChanged(getCellLocation());
+            mPhone.notifyLocationChanged(getCellIdentity());
         }
 
         if (mPhone.isPhoneTypeGsm()) {
@@ -3983,9 +3976,9 @@
     }
 
     /**
-     * Get CellLocation from the ServiceState if available or guess from cached CellInfo
+     * Get CellIdentity from the ServiceState if available or guess from cached
      *
-     * Get the CellLocation by first checking if ServiceState has a current CID. If so
+     * Get the CellIdentity by first checking if ServiceState has a current CID. If so
      * then return that info. Otherwise, check the latest List<CellInfo> and return the first GSM or
      * WCDMA result that appears. If no GSM or WCDMA results, then return an LTE result. The
      * behavior is kept consistent for backwards compatibility; (do not apply logic to determine
@@ -3993,18 +3986,19 @@
      *
      * @return the current cell location if known or a non-null "empty" cell location
      */
-    public CellLocation getCellLocation() {
-        if (mCellIdentity != null) return mCellIdentity.asCellLocation();
+    @NonNull
+    public CellIdentity getCellIdentity() {
+        if (mCellIdentity != null) return mCellIdentity;
 
-        CellLocation cl = getCellLocationFromCellInfo(getAllCellInfo());
-        if (cl != null) return cl;
+        CellIdentity ci = getCellIdentityFromCellInfo(getAllCellInfo());
+        if (ci != null) return ci;
 
         return mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA
-                ? new CdmaCellLocation() : new GsmCellLocation();
+                ? new CellIdentityCdma() : new CellIdentityGsm();
     }
 
     /**
-     * Get CellLocation from the ServiceState if available or guess from CellInfo
+     * Get CellIdentity from the ServiceState if available or guess from CellInfo
      *
      * Get the CellLocation by first checking if ServiceState has a current CID. If so
      * then return that info. Otherwise, query AllCellInfo and return the first GSM or
@@ -4015,9 +4009,9 @@
      * @param workSource calling WorkSource
      * @param rspMsg the response message which must be non-null
      */
-    public void requestCellLocation(WorkSource workSource, Message rspMsg) {
+    public void requestCellIdentity(WorkSource workSource, Message rspMsg) {
         if (mCellIdentity != null) {
-            AsyncResult.forMessage(rspMsg, mCellIdentity.asCellLocation(), null);
+            AsyncResult.forMessage(rspMsg, mCellIdentity, null);
             rspMsg.sendToTarget();
             return;
         }
@@ -4026,16 +4020,16 @@
         requestAllCellInfo(workSource, cellLocRsp);
     }
 
-    /* Find and return a CellLocation from CellInfo
+    /* Find and return a CellIdentity from CellInfo
      *
      * This method returns the first GSM or WCDMA result that appears in List<CellInfo>. If no GSM
      * or  WCDMA results are found, then it returns an LTE result. The behavior is kept consistent
      * for backwards compatibility; (do not apply logic to determine why the behavior is this way).
      *
-     * @return the current cell location from CellInfo or null
+     * @return the current CellIdentity from CellInfo or null
      */
-    private static CellLocation getCellLocationFromCellInfo(List<CellInfo> info) {
-        CellLocation cl = null;
+    private static CellIdentity getCellIdentityFromCellInfo(List<CellInfo> info) {
+        CellIdentity cl = null;
         if (info != null && info.size() > 0) {
             CellIdentity fallbackLteCid = null; // We prefer not to use LTE
             for (CellInfo ci : info) {
@@ -4045,12 +4039,12 @@
                     continue;
                 }
                 if (getCidFromCellIdentity(c) != -1) {
-                    cl = c.asCellLocation();
+                    cl = c;
                     break;
                 }
             }
             if (cl == null && fallbackLteCid != null) {
-                cl = fallbackLteCid.asCellLocation();
+                cl = fallbackLteCid;
             }
         }
         return cl;
@@ -4115,7 +4109,8 @@
         Context context = mPhone.getContext();
 
         SubscriptionInfo info = mSubscriptionController
-                .getActiveSubscriptionInfo(mPhone.getSubId(), context.getOpPackageName());
+                .getActiveSubscriptionInfo(mPhone.getSubId(), context.getOpPackageName(),
+                        context.getFeatureId());
 
         //if subscription is part of a group and non-primary, suppress all notifications
         if (info == null || (info.isOpportunistic() && info.getGroupUuid() != null)) {
@@ -4947,7 +4942,8 @@
         if (!isStale) return false;
 
         List<SubscriptionInfo> subInfoList = SubscriptionController.getInstance()
-                .getActiveSubscriptionInfoList(mPhone.getContext().getOpPackageName());
+                .getActiveSubscriptionInfoList(mPhone.getContext().getOpPackageName(),
+                        mPhone.getContext().getFeatureId());
         for (SubscriptionInfo info : subInfoList) {
             // If we have an active opportunistic subscription whose data is IN_SERVICE, we needs
             // to get signal strength to decide data switching threshold. In this case, we poll
diff --git a/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java b/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
index a1d8faa..6afc865 100644
--- a/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
+++ b/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
diff --git a/src/java/com/android/internal/telephony/SmsController.java b/src/java/com/android/internal/telephony/SmsController.java
index 243cffd..2ca3ded 100644
--- a/src/java/com/android/internal/telephony/SmsController.java
+++ b/src/java/com/android/internal/telephony/SmsController.java
@@ -21,10 +21,10 @@
 import static com.android.internal.telephony.util.TelephonyUtils.checkDumpPermission;
 
 import android.annotation.Nullable;
-import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.app.PendingIntent;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.net.Uri;
 import android.os.Binder;
@@ -511,10 +511,10 @@
     }
 
     @Override
-    public int checkSmsShortCodeDestination(
-            int subId, String callingPackage, String destAddress, String countryIso) {
+    public int checkSmsShortCodeDestination(int subId, String callingPackage,
+            String callingFeatureId, String destAddress, String countryIso) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(getPhone(subId).getContext(),
-                subId, callingPackage, "checkSmsShortCodeDestination")) {
+                subId, callingPackage, callingFeatureId, "checkSmsShortCodeDestination")) {
             return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE;
         }
         final long identity = Binder.clearCallingIdentity();
diff --git a/src/java/com/android/internal/telephony/SmsPermissions.java b/src/java/com/android/internal/telephony/SmsPermissions.java
index 3aa0756..5590ce6 100644
--- a/src/java/com/android/internal/telephony/SmsPermissions.java
+++ b/src/java/com/android/internal/telephony/SmsPermissions.java
@@ -17,8 +17,8 @@
 package com.android.internal.telephony;
 
 import android.Manifest;
-import android.annotation.UnsupportedAppUsage;
 import android.app.AppOpsManager;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -96,7 +96,8 @@
             }
         }
 
-        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mPhone.getSubId(), message);
+        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
+                mContext, mPhone.getSubId(), message);
     }
 
     /**
diff --git a/src/java/com/android/internal/telephony/SmsResponse.java b/src/java/com/android/internal/telephony/SmsResponse.java
index 9ce27bf..e2209be 100644
--- a/src/java/com/android/internal/telephony/SmsResponse.java
+++ b/src/java/com/android/internal/telephony/SmsResponse.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 
 /**
  * Object returned by the RIL upon successful completion of sendSMS.
diff --git a/src/java/com/android/internal/telephony/SmsStorageMonitor.java b/src/java/com/android/internal/telephony/SmsStorageMonitor.java
index 1dcbdd6..fe06f63 100755
--- a/src/java/com/android/internal/telephony/SmsStorageMonitor.java
+++ b/src/java/com/android/internal/telephony/SmsStorageMonitor.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
diff --git a/src/java/com/android/internal/telephony/SmsUsageMonitor.java b/src/java/com/android/internal/telephony/SmsUsageMonitor.java
index dadf62e..2a9d895 100644
--- a/src/java/com/android/internal/telephony/SmsUsageMonitor.java
+++ b/src/java/com/android/internal/telephony/SmsUsageMonitor.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
diff --git a/src/java/com/android/internal/telephony/SubscriptionController.java b/src/java/com/android/internal/telephony/SubscriptionController.java
index a866f9e..86a5d9b 100644
--- a/src/java/com/android/internal/telephony/SubscriptionController.java
+++ b/src/java/com/android/internal/telephony/SubscriptionController.java
@@ -22,9 +22,9 @@
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.UnsupportedAppUsage;
 import android.app.AppOpsManager;
 import android.app.PendingIntent;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
@@ -62,8 +62,8 @@
 import com.android.internal.telephony.uicc.IccUtils;
 import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccController;
-import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.internal.telephony.util.ArrayUtils;
+import com.android.internal.telephony.util.TelephonyUtils;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -459,10 +459,12 @@
     /**
      * Find unused color to be set for new SubInfoRecord
      * @param callingPackage The package making the IPC.
+     * @param callingFeatureId The feature in the package
      * @return RGB integer value of color
      */
-    private int getUnusedColor(String callingPackage) {
-        List<SubscriptionInfo> availableSubInfos = getActiveSubscriptionInfoList(callingPackage);
+    private int getUnusedColor(String callingPackage, String callingFeatureId) {
+        List<SubscriptionInfo> availableSubInfos = getActiveSubscriptionInfoList(callingPackage,
+                callingFeatureId);
         colorArr = mContext.getResources().getIntArray(com.android.internal.R.array.sim_colors);
         int colorIdx = 0;
 
@@ -483,17 +485,24 @@
         return colorArr[colorIdx];
     }
 
+    @Deprecated
+    @UnsupportedAppUsage
+    public SubscriptionInfo getActiveSubscriptionInfo(int subId, String callingPackage) {
+        return getActiveSubscriptionInfo(subId, callingPackage, null);
+    }
+
     /**
      * Get the active SubscriptionInfo with the subId key
      * @param subId The unique SubscriptionInfo key in database
      * @param callingPackage The package making the IPC.
+     * @param callingFeatureId The feature in the package
      * @return SubscriptionInfo, maybe null if its not active
      */
-    @UnsupportedAppUsage
     @Override
-    public SubscriptionInfo getActiveSubscriptionInfo(int subId, String callingPackage) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mContext, subId, callingPackage, "getActiveSubscriptionInfo")) {
+    public SubscriptionInfo getActiveSubscriptionInfo(int subId, String callingPackage,
+            String callingFeatureId) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId, callingPackage,
+                callingFeatureId, "getActiveSubscriptionInfo")) {
             return null;
         }
 
@@ -501,7 +510,7 @@
         final long identity = Binder.clearCallingIdentity();
         try {
             List<SubscriptionInfo> subList = getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName());
+                    mContext.getOpPackageName(), mContext.getFeatureId());
             if (subList != null) {
                 for (SubscriptionInfo si : subList) {
                     if (si.getSubscriptionId() == subId) {
@@ -542,10 +551,12 @@
      * Get the active SubscriptionInfo associated with the iccId
      * @param iccId the IccId of SIM card
      * @param callingPackage The package making the IPC.
+     * @param callingFeatureId The feature in the package
      * @return SubscriptionInfo, maybe null if its not active
      */
     @Override
-    public SubscriptionInfo getActiveSubscriptionInfoForIccId(String iccId, String callingPackage) {
+    public SubscriptionInfo getActiveSubscriptionInfoForIccId(String iccId, String callingPackage,
+            String callingFeatureId) {
         // Query the subscriptions unconditionally, and then check whether the caller has access to
         // the given subscription.
         final SubscriptionInfo si = getActiveSubscriptionInfoForIccIdInternal(iccId);
@@ -553,7 +564,8 @@
         final int subId = si != null
                 ? si.getSubscriptionId() : SubscriptionManager.INVALID_SUBSCRIPTION_ID;
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mContext, subId, callingPackage, "getActiveSubscriptionInfoForIccId")) {
+                mContext, subId, callingPackage, callingFeatureId,
+                "getActiveSubscriptionInfoForIccId")) {
             return null;
         }
 
@@ -572,7 +584,7 @@
         final long identity = Binder.clearCallingIdentity();
         try {
             List<SubscriptionInfo> subList = getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName());
+                    mContext.getOpPackageName(), mContext.getFeatureId());
             if (subList != null) {
                 for (SubscriptionInfo si : subList) {
                     if (iccId.equals(si.getIccId())) {
@@ -598,11 +610,12 @@
      * This API does not return details on Remote-SIM subscriptions.
      * @param slotIndex the slot which the subscription is inserted
      * @param callingPackage The package making the IPC.
+     * @param callingFeatureId The feature in the package
      * @return SubscriptionInfo, null for Remote-SIMs or non-active slotIndex.
      */
     @Override
     public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex,
-            String callingPackage) {
+            String callingPackage, String callingFeatureId) {
         Phone phone = PhoneFactory.getPhone(slotIndex);
         if (phone == null) {
             if (DBG) {
@@ -611,7 +624,7 @@
             return null;
         }
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mContext, phone.getSubId(), callingPackage,
+                mContext, phone.getSubId(), callingPackage, callingFeatureId,
                 "getActiveSubscriptionInfoForSimSlotIndex")) {
             return null;
         }
@@ -620,7 +633,7 @@
         final long identity = Binder.clearCallingIdentity();
         try {
             List<SubscriptionInfo> subList = getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName());
+                    mContext.getOpPackageName(), mContext.getFeatureId());
             if (subList != null) {
                 for (SubscriptionInfo si : subList) {
                     if (si.getSimSlotIndex() == slotIndex) {
@@ -649,19 +662,21 @@
 
     /**
      * @param callingPackage The package making the IPC.
+     * @param callingFeatureId The feature in the package
      * @return List of all SubscriptionInfo records in database,
      * include those that were inserted before, maybe empty but not null.
      * @hide
      */
     @Override
-    public List<SubscriptionInfo> getAllSubInfoList(String callingPackage) {
+    public List<SubscriptionInfo> getAllSubInfoList(String callingPackage,
+            String callingFeatureId) {
         if (VDBG) logd("[getAllSubInfoList]+");
 
         // This API isn't public, so no need to provide a valid subscription ID - we're not worried
         // about carrier-privileged callers not having access.
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                 mContext, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
-                "getAllSubInfoList")) {
+                callingFeatureId, "getAllSubInfoList")) {
             return null;
         }
 
@@ -681,16 +696,25 @@
         }
     }
 
+    @Deprecated
+    @UnsupportedAppUsage
+    public List<SubscriptionInfo> getActiveSubscriptionInfoList(String callingPackage) {
+        return getSubscriptionInfoListFromCacheHelper(callingPackage, null,
+                mCacheActiveSubInfoList);
+    }
+
     /**
      * Get the SubInfoRecord(s) of the currently active SIM(s) - which include both local
      * and remote SIMs.
      * @param callingPackage The package making the IPC.
+     * @param callingFeatureId The feature in the package
      * @return Array list of currently inserted SubInfoRecord(s)
      */
-    @UnsupportedAppUsage
     @Override
-    public List<SubscriptionInfo> getActiveSubscriptionInfoList(String callingPackage) {
-        return getSubscriptionInfoListFromCacheHelper(callingPackage, mCacheActiveSubInfoList);
+    public List<SubscriptionInfo> getActiveSubscriptionInfoList(String callingPackage,
+            String callingFeatureId) {
+        return getSubscriptionInfoListFromCacheHelper(callingPackage, callingFeatureId,
+                mCacheActiveSubInfoList);
     }
 
     /**
@@ -739,16 +763,23 @@
         }
     }
 
+    @Deprecated
+    @UnsupportedAppUsage
+    public int getActiveSubInfoCount(String callingPackage) {
+        return getActiveSubInfoCount(callingPackage, null);
+    }
+
     /**
      * Get the SUB count of active SUB(s)
      * @param callingPackage The package making the IPC.
+     * @param callingFeatureId The feature in the package.
      * @return active SIM count
      */
-    @UnsupportedAppUsage
     @Override
-    public int getActiveSubInfoCount(String callingPackage) {
+    public int getActiveSubInfoCount(String callingPackage, String callingFeatureId) {
         // Let getActiveSubscriptionInfoList perform permission checks / filtering.
-        List<SubscriptionInfo> records = getActiveSubscriptionInfoList(callingPackage);
+        List<SubscriptionInfo> records = getActiveSubscriptionInfoList(callingPackage,
+                callingFeatureId);
         if (records == null) {
             if (VDBG) logd("[getActiveSubInfoCount] records null");
             return 0;
@@ -760,17 +791,18 @@
     /**
      * Get the SUB count of all SUB(s) in SubscriptoinInfo database
      * @param callingPackage The package making the IPC.
+     * @param callingFeatureId The feature in the package
      * @return all SIM count in database, include what was inserted before
      */
     @Override
-    public int getAllSubInfoCount(String callingPackage) {
+    public int getAllSubInfoCount(String callingPackage, String callingFeatureId) {
         if (DBG) logd("[getAllSubInfoCount]+");
 
         // This API isn't public, so no need to provide a valid subscription ID - we're not worried
         // about carrier-privileged callers not having access.
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                 mContext, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
-                "getAllSubInfoCount")) {
+                callingFeatureId, "getAllSubInfoCount")) {
             return 0;
         }
 
@@ -808,12 +840,13 @@
     }
 
     @Override
-    public List<SubscriptionInfo> getAvailableSubscriptionInfoList(String callingPackage) {
+    public List<SubscriptionInfo> getAvailableSubscriptionInfoList(String callingPackage,
+            String callingFeatureId) {
         // This API isn't public, so no need to provide a valid subscription ID - we're not worried
         // about carrier-privileged callers not having access.
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                 mContext, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
-                "getAvailableSubscriptionInfoList")) {
+                callingFeatureId, "getAvailableSubscriptionInfoList")) {
             throw new SecurityException("Need READ_PHONE_STATE to call "
                     + " getAvailableSubscriptionInfoList");
         }
@@ -1325,7 +1358,7 @@
             int newDefault = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
             SubscriptionInfo info = null;
             final List<SubscriptionInfo> records = getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName());
+                    mContext.getOpPackageName(), mContext.getFeatureId());
             if (!records.isEmpty()) {
                 // yes, we have more subscriptions. pick the first one.
                 // FIXME do we need a policy to figure out which one is to be next default
@@ -1379,7 +1412,7 @@
         ContentResolver resolver = mContext.getContentResolver();
         ContentValues value = new ContentValues();
         value.put(SubscriptionManager.ICC_ID, uniqueId);
-        int color = getUnusedColor(mContext.getOpPackageName());
+        int color = getUnusedColor(mContext.getOpPackageName(), mContext.getFeatureId());
         // default SIM color differs between slots
         value.put(SubscriptionManager.COLOR, color);
         value.put(SubscriptionManager.SIM_SLOT_INDEX, slotIndex);
@@ -1779,7 +1812,7 @@
     // TODO: replace all updates with this helper method.
     private int updateDatabase(ContentValues value, int subId, boolean updateEntireGroup) {
         List<SubscriptionInfo> infoList = getSubscriptionsInGroup(getGroupUuid(subId),
-                mContext.getOpPackageName());
+                mContext.getOpPackageName(), mContext.getFeatureId());
         if (!updateEntireGroup || infoList == null || infoList.size() == 0) {
             // Only update specified subscriptions.
             return mContext.getContentResolver().update(
@@ -2413,7 +2446,8 @@
      * Whether a subscription is opportunistic or not.
      */
     public boolean isOpportunistic(int subId) {
-        SubscriptionInfo info = getActiveSubscriptionInfo(subId, mContext.getOpPackageName());
+        SubscriptionInfo info = getActiveSubscriptionInfo(subId, mContext.getOpPackageName(),
+                mContext.getFeatureId());
         return (info != null) && info.isOpportunistic();
     }
 
@@ -2532,9 +2566,9 @@
     }
 
     @Override
-    public boolean isActiveSubId(int subId, String callingPackage) {
+    public boolean isActiveSubId(int subId, String callingPackage, String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId, callingPackage,
-              "isActiveSubId")) {
+                callingFeatureId, "isActiveSubId")) {
             throw new SecurityException("Requires READ_PHONE_STATE permission.");
         }
         final long identity = Binder.clearCallingIdentity();
@@ -2665,9 +2699,10 @@
      * @return Value associated with subId and propKey column in database
      */
     @Override
-    public String getSubscriptionProperty(int subId, String propKey, String callingPackage) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mContext, subId, callingPackage, "getSubscriptionProperty")) {
+    public String getSubscriptionProperty(int subId, String propKey, String callingPackage,
+            String callingFeatureId) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId, callingPackage,
+                callingFeatureId, "getSubscriptionProperty")) {
             return null;
         }
 
@@ -2779,7 +2814,7 @@
             pw.println("++++++++++++++++++++++++++++++++");
 
             List<SubscriptionInfo> sirl = getActiveSubscriptionInfoList(
-                    mContext.getOpPackageName());
+                    mContext.getOpPackageName(), mContext.getFeatureId());
             if (sirl != null) {
                 pw.println(" ActiveSubInfoList:");
                 for (SubscriptionInfo entry : sirl) {
@@ -2791,7 +2826,7 @@
             pw.flush();
             pw.println("++++++++++++++++++++++++++++++++");
 
-            sirl = getAllSubInfoList(mContext.getOpPackageName());
+            sirl = getAllSubInfoList(mContext.getOpPackageName(), mContext.getFeatureId());
             if (sirl != null) {
                 pw.println(" AllSubInfoList:");
                 for (SubscriptionInfo entry : sirl) {
@@ -2947,9 +2982,10 @@
     }
 
     @Override
-    public List<SubscriptionInfo> getOpportunisticSubscriptions(String callingPackage) {
+    public List<SubscriptionInfo> getOpportunisticSubscriptions(String callingPackage,
+            String callingFeatureId) {
         return getSubscriptionInfoListFromCacheHelper(
-                callingPackage, mCacheOpportunisticSubInfoList);
+                callingPackage, callingFeatureId, mCacheOpportunisticSubInfoList);
     }
 
     /**
@@ -3292,12 +3328,12 @@
      */
     @Override
     public List<SubscriptionInfo> getSubscriptionsInGroup(ParcelUuid groupUuid,
-            String callingPackage) {
+            String callingPackage, String callingFeatureId) {
         long identity = Binder.clearCallingIdentity();
         List<SubscriptionInfo> subInfoList;
 
         try {
-            subInfoList = getAllSubInfoList(mContext.getOpPackageName());
+            subInfoList = getAllSubInfoList(mContext.getOpPackageName(), mContext.getFeatureId());
             if (groupUuid == null || subInfoList == null || subInfoList.isEmpty()) {
                 return new ArrayList<>();
             }
@@ -3309,7 +3345,7 @@
             if (!groupUuid.equals(info.getGroupUuid())) return false;
             int subId = info.getSubscriptionId();
             return TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId,
-                    callingPackage, "getSubscriptionsInGroup")
+                    callingPackage, callingFeatureId, "getSubscriptionsInGroup")
                     || info.canManageSubscription(mContext, callingPackage);
         }).collect(Collectors.toList());
     }
@@ -3355,7 +3391,7 @@
             if (enable == isActiveSubscriptionId(subId)) return true;
 
             SubscriptionInfo info = SubscriptionController.getInstance()
-                    .getAllSubInfoList(mContext.getOpPackageName())
+                    .getAllSubInfoList(mContext.getOpPackageName(), mContext.getFeatureId())
                     .stream()
                     .filter(subInfo -> subInfo.getSubscriptionId() == subId)
                     .findFirst()
@@ -3577,12 +3613,13 @@
     // Helper function of getOpportunisticSubscriptions and getActiveSubscriptionInfoList.
     // They are doing similar things except operating on different cache.
     private List<SubscriptionInfo> getSubscriptionInfoListFromCacheHelper(
-            String callingPackage, List<SubscriptionInfo> cacheSubList) {
+            String callingPackage, String callingFeatureId, List<SubscriptionInfo> cacheSubList) {
         boolean canReadAllPhoneState;
         try {
             canReadAllPhoneState = TelephonyPermissions.checkReadPhoneState(mContext,
                     SubscriptionManager.INVALID_SUBSCRIPTION_ID, Binder.getCallingPid(),
-                    Binder.getCallingUid(), callingPackage, "getSubscriptionInfoList");
+                    Binder.getCallingUid(), callingPackage, callingFeatureId,
+                    "getSubscriptionInfoList");
         } catch (SecurityException e) {
             canReadAllPhoneState = false;
         }
@@ -3599,7 +3636,7 @@
                         try {
                             return TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext,
                                     subscriptionInfo.getSubscriptionId(), callingPackage,
-                                    "getSubscriptionInfoList");
+                                    callingFeatureId, "getSubscriptionInfoList");
                         } catch (SecurityException e) {
                             return false;
                         }
diff --git a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
index 793f846..1fba358 100644
--- a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
+++ b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
@@ -18,24 +18,25 @@
 
 import android.Manifest;
 import android.annotation.Nullable;
-import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityManager;
-import android.app.UserSwitchObserver;
+import android.app.AppGlobals;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.SharedPreferences;
 import android.content.pm.IPackageManager;
 import android.os.AsyncResult;
 import android.os.Handler;
-import android.os.IRemoteCallback;
 import android.os.Looper;
 import android.os.Message;
 import android.os.ParcelUuid;
 import android.os.PersistableBundle;
-import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.permission.IPermissionManager;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
 import android.provider.Settings.Global;
@@ -114,6 +115,7 @@
     private EuiccManager mEuiccManager;
     @UnsupportedAppUsage
     private IPackageManager mPackageManager;
+    private IPermissionManager mPermissionManager;
     private Handler mBackgroundHandler;
 
     // The current foreground user ID.
@@ -136,14 +138,13 @@
 
     // TODO: The SubscriptionController instance should be passed in here from PhoneFactory
     // rather than invoking the static getter all over the place.
-    public SubscriptionInfoUpdater(
-            Looper looper, Context context, CommandsInterface[] ci) {
+    public SubscriptionInfoUpdater(Looper looper, Context context, CommandsInterface[] ci) {
         this(looper, context, ci, IPackageManager.Stub.asInterface(
-                ServiceManager.getService("package")));
+                ServiceManager.getService("package")), AppGlobals.getPermissionManager());
     }
 
     @VisibleForTesting public SubscriptionInfoUpdater(Looper looper, Context context,
-            CommandsInterface[] ci, IPackageManager packageMgr) {
+            CommandsInterface[] ci, IPackageManager packageMgr, IPermissionManager permissionMgr) {
         logd("Constructor invoked");
         mBackgroundHandler = new Handler(looper);
 
@@ -151,6 +152,7 @@
         mSubscriptionManager = SubscriptionManager.from(sContext);
         mEuiccManager = (EuiccManager) sContext.getSystemService(Context.EUICC_SERVICE);
         mPackageManager = packageMgr;
+        mPermissionManager = permissionMgr;
 
         mCarrierServiceBindHelper = new CarrierServiceBindHelper(sContext);
         initializeCarrierApps();
@@ -165,33 +167,24 @@
         // -Whenever new carrier privilege rules might change (new SIM is loaded)
         // -Whenever we switch to a new user
         mCurrentlyActiveUserId = 0;
-        try {
-            ActivityManager.getService().registerUserSwitchObserver(new UserSwitchObserver() {
-                @Override
-                public void onUserSwitching(int newUserId, IRemoteCallback reply)
-                        throws RemoteException {
-                    mCurrentlyActiveUserId = newUserId;
+        sContext.registerReceiverForAllUsers(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                // Remove this line after testing
+                if (Intent.ACTION_USER_FOREGROUND.equals(intent.getAction())) {
+                    // If couldn't get current user ID, guess it's 0.
+                    mCurrentlyActiveUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
                     CarrierAppUtils.disableCarrierAppsUntilPrivileged(sContext.getOpPackageName(),
-                            mPackageManager, TelephonyManager.getDefault(),
+                            mPackageManager, mPermissionManager, TelephonyManager.getDefault(),
                             sContext.getContentResolver(), mCurrentlyActiveUserId);
-
-                    if (reply != null) {
-                        try {
-                            reply.sendResult(null);
-                        } catch (RemoteException e) {
-                        }
-                    }
                 }
-            }, LOG_TAG);
-            ActivityManager am = (ActivityManager) sContext.getSystemService(
-                Context.ACTIVITY_SERVICE);
-            mCurrentlyActiveUserId = am.getCurrentUser();
-        } catch (RemoteException e) {
-            logd("Couldn't get current user ID; guessing it's 0: " + e.getMessage());
-        }
+            }
+        }, new IntentFilter(Intent.ACTION_USER_FOREGROUND), null, null);
+        ActivityManager am = (ActivityManager) sContext.getSystemService(Context.ACTIVITY_SERVICE);
+        mCurrentlyActiveUserId = am.getCurrentUser();
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(sContext.getOpPackageName(),
-                mPackageManager, TelephonyManager.getDefault(), sContext.getContentResolver(),
-                mCurrentlyActiveUserId);
+                mPackageManager, mPermissionManager, TelephonyManager.getDefault(),
+                sContext.getContentResolver(), mCurrentlyActiveUserId);
     }
 
     /**
@@ -555,7 +548,7 @@
 
         // Update set of enabled carrier apps now that the privilege rules may have changed.
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(sContext.getOpPackageName(),
-                mPackageManager, TelephonyManager.getDefault(),
+                mPackageManager, mPermissionManager, TelephonyManager.getDefault(),
                 sContext.getContentResolver(), mCurrentlyActiveUserId);
 
         /**
diff --git a/src/java/com/android/internal/telephony/TelephonyCapabilities.java b/src/java/com/android/internal/telephony/TelephonyCapabilities.java
index 70f15dc..66f805b 100644
--- a/src/java/com/android/internal/telephony/TelephonyCapabilities.java
+++ b/src/java/com/android/internal/telephony/TelephonyCapabilities.java
@@ -16,11 +16,9 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.telephony.Rlog;
 
-import com.android.internal.telephony.Phone;
-
 /**
  * Utilities that check if the phone supports specified capabilities.
  */
diff --git a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
index bd9b338..6a2f3cc 100644
--- a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
+++ b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
@@ -22,9 +22,7 @@
 import android.content.res.XmlResourceParser;
 import android.database.Cursor;
 import android.os.Handler;
-import android.os.IDeviceIdleController;
 import android.os.Looper;
-import android.os.ServiceManager;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
@@ -409,11 +407,6 @@
         return CdmaSubscriptionSourceManager.getInstance(context, ci, h, what, obj);
     }
 
-    public IDeviceIdleController getIDeviceIdleController() {
-        return IDeviceIdleController.Stub.asInterface(
-                ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
-    }
-
     public LocaleTracker makeLocaleTracker(Phone phone, NitzStateMachine nitzStateMachine,
                                            Looper looper) {
         return new LocaleTracker(phone, nitzStateMachine, looper);
diff --git a/src/java/com/android/internal/telephony/UUSInfo.java b/src/java/com/android/internal/telephony/UUSInfo.java
index 9ef1893..2b4f674 100644
--- a/src/java/com/android/internal/telephony/UUSInfo.java
+++ b/src/java/com/android/internal/telephony/UUSInfo.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 
 public class UUSInfo {
 
diff --git a/src/java/com/android/internal/telephony/UiccPhoneBookController.java b/src/java/com/android/internal/telephony/UiccPhoneBookController.java
index 6c9fdbe..482f340 100644
--- a/src/java/com/android/internal/telephony/UiccPhoneBookController.java
+++ b/src/java/com/android/internal/telephony/UiccPhoneBookController.java
@@ -18,7 +18,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.ServiceManager;
 import android.telephony.Rlog;
 
diff --git a/src/java/com/android/internal/telephony/WakeLockStateMachine.java b/src/java/com/android/internal/telephony/WakeLockStateMachine.java
index 7dd60e0..5cad743 100644
--- a/src/java/com/android/internal/telephony/WakeLockStateMachine.java
+++ b/src/java/com/android/internal/telephony/WakeLockStateMachine.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
diff --git a/src/java/com/android/internal/telephony/WapPushOverSms.java b/src/java/com/android/internal/telephony/WapPushOverSms.java
index 069178d..77002e0 100755
--- a/src/java/com/android/internal/telephony/WapPushOverSms.java
+++ b/src/java/com/android/internal/telephony/WapPushOverSms.java
@@ -20,10 +20,10 @@
 import static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND;
 import static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_READ_ORIG_IND;
 
-import android.annotation.UnsupportedAppUsage;
 import android.app.Activity;
 import android.app.AppOpsManager;
 import android.app.BroadcastOptions;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentValues;
@@ -37,7 +37,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.IBinder;
-import android.os.IDeviceIdleController;
+import android.os.PowerWhitelistManager;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -73,8 +73,7 @@
 
     @UnsupportedAppUsage
     private final Context mContext;
-    @UnsupportedAppUsage
-    private IDeviceIdleController mDeviceIdleController;
+    PowerWhitelistManager mPowerWhitelistManager;
 
     private String mWapPushManagerPackage;
 
@@ -136,8 +135,8 @@
 
     public WapPushOverSms(Context context) {
         mContext = context;
-        mDeviceIdleController = TelephonyComponentFactory.getInstance()
-                .inject(IDeviceIdleController.class.getName()).getIDeviceIdleController();
+        mPowerWhitelistManager =
+                (PowerWhitelistManager) mContext.getSystemService(Context.POWER_WHITELIST_MANAGER);
 
         UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
 
@@ -351,8 +350,8 @@
                     if (DBG) Rlog.w(TAG, "wap push manager not found!");
                 } else {
                     synchronized (this) {
-                        mDeviceIdleController.addPowerSaveTempWhitelistAppForMms(
-                                mWapPushManagerPackage, 0, "mms-mgr");
+                        mPowerWhitelistManager.whitelistAppTemporarilyForEvent(
+                                mWapPushManagerPackage, PowerWhitelistManager.EVENT_MMS, "mms-mgr");
                     }
 
                     Intent intent = new Intent();
@@ -409,14 +408,11 @@
             intent.setComponent(componentName);
             if (DBG) Rlog.v(TAG, "Delivering MMS to: " + componentName.getPackageName() +
                     " " + componentName.getClassName());
-            try {
-                long duration = mDeviceIdleController.addPowerSaveTempWhitelistAppForMms(
-                        componentName.getPackageName(), 0, "mms-app");
-                BroadcastOptions bopts = BroadcastOptions.makeBasic();
-                bopts.setTemporaryAppWhitelistDuration(duration);
-                options = bopts.toBundle();
-            } catch (RemoteException e) {
-            }
+            long duration = mPowerWhitelistManager.whitelistAppTemporarilyForEvent(
+                    componentName.getPackageName(), PowerWhitelistManager.EVENT_MMS, "mms-app");
+            BroadcastOptions bopts = BroadcastOptions.makeBasic();
+            bopts.setTemporaryAppWhitelistDuration(duration);
+            options = bopts.toBundle();
         }
 
         handler.dispatchIntent(intent, getPermissionForType(result.mimeType),
diff --git a/src/java/com/android/internal/telephony/WspTypeDecoder.java b/src/java/com/android/internal/telephony/WspTypeDecoder.java
index 041db61..372aa73 100755
--- a/src/java/com/android/internal/telephony/WspTypeDecoder.java
+++ b/src/java/com/android/internal/telephony/WspTypeDecoder.java
@@ -16,7 +16,8 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
+
 import java.util.HashMap;
 
 /**
diff --git a/src/java/com/android/internal/telephony/cat/AppInterface.java b/src/java/com/android/internal/telephony/cat/AppInterface.java
index 4f6ca86..079b3f6 100755
--- a/src/java/com/android/internal/telephony/cat/AppInterface.java
+++ b/src/java/com/android/internal/telephony/cat/AppInterface.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 
 /**
@@ -75,7 +75,7 @@
      */
     @UnsupportedAppUsage(implicitMember =
             "values()[Lcom/android/internal/telephony/cat/AppInterface$CommandType;")
-    enum CommandType {
+    public static enum CommandType {
         @UnsupportedAppUsage
         DISPLAY_TEXT(0x21),
         @UnsupportedAppUsage
diff --git a/src/java/com/android/internal/telephony/cat/CatCmdMessage.java b/src/java/com/android/internal/telephony/cat/CatCmdMessage.java
index 0033fff..936158a 100644
--- a/src/java/com/android/internal/telephony/cat/CatCmdMessage.java
+++ b/src/java/com/android/internal/telephony/cat/CatCmdMessage.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
 
diff --git a/src/java/com/android/internal/telephony/cat/CatLog.java b/src/java/com/android/internal/telephony/cat/CatLog.java
index 128d7ed..f41dc60 100644
--- a/src/java/com/android/internal/telephony/cat/CatLog.java
+++ b/src/java/com/android/internal/telephony/cat/CatLog.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.telephony.Rlog;
 
 public abstract class CatLog {
diff --git a/src/java/com/android/internal/telephony/cat/CatResponseMessage.java b/src/java/com/android/internal/telephony/cat/CatResponseMessage.java
index a3f2240..e1d4fe3 100644
--- a/src/java/com/android/internal/telephony/cat/CatResponseMessage.java
+++ b/src/java/com/android/internal/telephony/cat/CatResponseMessage.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 
 public class CatResponseMessage {
         CommandDetails mCmdDet = null;
diff --git a/src/java/com/android/internal/telephony/cat/CatService.java b/src/java/com/android/internal/telephony/cat/CatService.java
index e24a408..097caa4 100644
--- a/src/java/com/android/internal/telephony/cat/CatService.java
+++ b/src/java/com/android/internal/telephony/cat/CatService.java
@@ -20,11 +20,11 @@
 import static com.android.internal.telephony.cat.CatCmdMessage.SetupEventListConstants.LANGUAGE_SELECTION_EVENT;
 import static com.android.internal.telephony.cat.CatCmdMessage.SetupEventListConstants.USER_ACTIVITY_EVENT;
 
-import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.app.backup.BackupManager;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
diff --git a/src/java/com/android/internal/telephony/cat/CommandDetails.java b/src/java/com/android/internal/telephony/cat/CommandDetails.java
index dd1bbcf..51a6dd4 100644
--- a/src/java/com/android/internal/telephony/cat/CommandDetails.java
+++ b/src/java/com/android/internal/telephony/cat/CommandDetails.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
 
diff --git a/src/java/com/android/internal/telephony/cat/CommandParams.java b/src/java/com/android/internal/telephony/cat/CommandParams.java
index 80e5973..111f0cd 100755
--- a/src/java/com/android/internal/telephony/cat/CommandParams.java
+++ b/src/java/com/android/internal/telephony/cat/CommandParams.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.graphics.Bitmap;
 
 /**
diff --git a/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java b/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java
index bafb8bb..d7631ae 100644
--- a/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java
+++ b/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java
@@ -16,7 +16,13 @@
 
 package com.android.internal.telephony.cat;
 
-import android.annotation.UnsupportedAppUsage;
+import static com.android.internal.telephony.cat.CatCmdMessage.SetupEventListConstants.BROWSER_TERMINATION_EVENT;
+import static com.android.internal.telephony.cat.CatCmdMessage.SetupEventListConstants.BROWSING_STATUS_EVENT;
+import static com.android.internal.telephony.cat.CatCmdMessage.SetupEventListConstants.IDLE_SCREEN_AVAILABLE_EVENT;
+import static com.android.internal.telephony.cat.CatCmdMessage.SetupEventListConstants.LANGUAGE_SELECTION_EVENT;
+import static com.android.internal.telephony.cat.CatCmdMessage.SetupEventListConstants.USER_ACTIVITY_EVENT;
+
+import android.compat.annotation.UnsupportedAppUsage;
 import android.graphics.Bitmap;
 import android.os.Handler;
 import android.os.Message;
@@ -28,17 +34,6 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
-
-import static com.android.internal.telephony.cat.CatCmdMessage
-                   .SetupEventListConstants.BROWSER_TERMINATION_EVENT;
-import static com.android.internal.telephony.cat.CatCmdMessage
-                   .SetupEventListConstants.BROWSING_STATUS_EVENT;
-import static com.android.internal.telephony.cat.CatCmdMessage
-                   .SetupEventListConstants.IDLE_SCREEN_AVAILABLE_EVENT;
-import static com.android.internal.telephony.cat.CatCmdMessage
-                   .SetupEventListConstants.LANGUAGE_SELECTION_EVENT;
-import static com.android.internal.telephony.cat.CatCmdMessage
-                   .SetupEventListConstants.USER_ACTIVITY_EVENT;
 /**
  * Factory class, used for decoding raw byte arrays, received from baseband,
  * into a CommandParams object.
diff --git a/src/java/com/android/internal/telephony/cat/ComprehensionTlv.java b/src/java/com/android/internal/telephony/cat/ComprehensionTlv.java
index 16615a0..568c7c0 100644
--- a/src/java/com/android/internal/telephony/cat/ComprehensionTlv.java
+++ b/src/java/com/android/internal/telephony/cat/ComprehensionTlv.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.telephony.Rlog;
 
 import java.util.ArrayList;
diff --git a/src/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java b/src/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java
index 1ab18a7..f8ba49f 100644
--- a/src/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java
+++ b/src/java/com/android/internal/telephony/cat/ComprehensionTlvTag.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 
 /**
  * Enumeration for representing the tag value of COMPREHENSION-TLV objects. If
diff --git a/src/java/com/android/internal/telephony/cat/Duration.java b/src/java/com/android/internal/telephony/cat/Duration.java
index a979c54..412be9a 100644
--- a/src/java/com/android/internal/telephony/cat/Duration.java
+++ b/src/java/com/android/internal/telephony/cat/Duration.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
 
diff --git a/src/java/com/android/internal/telephony/cat/IconLoader.java b/src/java/com/android/internal/telephony/cat/IconLoader.java
index 4e5b555..94b5348 100644
--- a/src/java/com/android/internal/telephony/cat/IconLoader.java
+++ b/src/java/com/android/internal/telephony/cat/IconLoader.java
@@ -16,9 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
-import com.android.internal.telephony.uicc.IccFileHandler;
-
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.os.AsyncResult;
@@ -26,6 +24,9 @@
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
+
+import com.android.internal.telephony.uicc.IccFileHandler;
+
 import java.util.HashMap;
 
 /**
diff --git a/src/java/com/android/internal/telephony/cat/Menu.java b/src/java/com/android/internal/telephony/cat/Menu.java
index f1d19b5..7606007 100644
--- a/src/java/com/android/internal/telephony/cat/Menu.java
+++ b/src/java/com/android/internal/telephony/cat/Menu.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.graphics.Bitmap;
 import android.os.Parcel;
 import android.os.Parcelable;
diff --git a/src/java/com/android/internal/telephony/cat/ResponseData.java b/src/java/com/android/internal/telephony/cat/ResponseData.java
index 4d0a2d2..8c7f248 100644
--- a/src/java/com/android/internal/telephony/cat/ResponseData.java
+++ b/src/java/com/android/internal/telephony/cat/ResponseData.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.SystemProperties;
 import android.text.TextUtils;
 
diff --git a/src/java/com/android/internal/telephony/cat/ResultCode.java b/src/java/com/android/internal/telephony/cat/ResultCode.java
index adcf53e..dca2999 100644
--- a/src/java/com/android/internal/telephony/cat/ResultCode.java
+++ b/src/java/com/android/internal/telephony/cat/ResultCode.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 
 
 /**
diff --git a/src/java/com/android/internal/telephony/cat/ResultException.java b/src/java/com/android/internal/telephony/cat/ResultException.java
index 32acae8..208aa9a 100644
--- a/src/java/com/android/internal/telephony/cat/ResultException.java
+++ b/src/java/com/android/internal/telephony/cat/ResultException.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 
 
 /**
diff --git a/src/java/com/android/internal/telephony/cat/RilMessageDecoder.java b/src/java/com/android/internal/telephony/cat/RilMessageDecoder.java
index eeb9dd4..a068d05 100755
--- a/src/java/com/android/internal/telephony/cat/RilMessageDecoder.java
+++ b/src/java/com/android/internal/telephony/cat/RilMessageDecoder.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Handler;
 import android.os.Message;
 import android.telephony.SubscriptionManager;
diff --git a/src/java/com/android/internal/telephony/cat/TextMessage.java b/src/java/com/android/internal/telephony/cat/TextMessage.java
index e7c2da6..96ecd94 100644
--- a/src/java/com/android/internal/telephony/cat/TextMessage.java
+++ b/src/java/com/android/internal/telephony/cat/TextMessage.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.graphics.Bitmap;
 import android.os.Parcel;
 import android.os.Parcelable;
diff --git a/src/java/com/android/internal/telephony/cat/ValueParser.java b/src/java/com/android/internal/telephony/cat/ValueParser.java
index 03d7f67..2a19904 100644
--- a/src/java/com/android/internal/telephony/cat/ValueParser.java
+++ b/src/java/com/android/internal/telephony/cat/ValueParser.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.cat;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
 
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java b/src/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
index d1e0881..b6ca02d 100644
--- a/src/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
@@ -16,8 +16,9 @@
 
 package com.android.internal.telephony.cdma;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.telephony.Rlog;
+
 import com.android.internal.telephony.PhoneConstants;
 
 /**
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java b/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java
index 8d6f766..6925a5d 100644
--- a/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java
@@ -26,11 +26,8 @@
 import android.os.SystemProperties;
 import android.provider.Telephony.Sms.Intents;
 import android.telephony.PhoneNumberUtils;
-import android.telephony.SmsCbMessage;
-import android.telephony.TelephonyManager;
 import android.telephony.cdma.CdmaSmsCbProgramResults;
 
-import com.android.internal.telephony.CellBroadcastHandler;
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.InboundSmsHandler;
 import com.android.internal.telephony.InboundSmsTracker;
@@ -57,7 +54,6 @@
 public class CdmaInboundSmsHandler extends InboundSmsHandler {
 
     private final CdmaSMSDispatcher mSmsDispatcher;
-    private final CdmaServiceCategoryProgramHandler mServiceCategoryProgramHandler;
     private static CdmaCbTestBroadcastReceiver sTestBroadcastReceiver;
     private static CdmaScpTestBroadcastReceiver sTestScpBroadcastReceiver;
 
@@ -76,19 +72,14 @@
             + ".TEST_TRIGGER_CELL_BROADCAST";
     private static final String SCP_TEST_ACTION = "com.android.internal.telephony.cdma"
             + ".TEST_TRIGGER_SCP_MESSAGE";
-    private static final String TOGGLE_CB_MODULE = "com.android.internal.telephony.cdma"
-            + ".TOGGLE_CB_MODULE";
 
     /**
      * Create a new inbound SMS handler for CDMA.
      */
     private CdmaInboundSmsHandler(Context context, SmsStorageMonitor storageMonitor,
             Phone phone, CdmaSMSDispatcher smsDispatcher) {
-        super("CdmaInboundSmsHandler", context, storageMonitor, phone,
-                CellBroadcastHandler.makeCellBroadcastHandler(context, phone));
+        super("CdmaInboundSmsHandler", context, storageMonitor, phone);
         mSmsDispatcher = smsDispatcher;
-        mServiceCategoryProgramHandler = CdmaServiceCategoryProgramHandler.makeScpHandler(context,
-                phone.mCi, phone);
         phone.mCi.setOnNewCdmaSms(getHandler(), EVENT_NEW_SMS, null);
 
         mCellBroadcastServiceManager.enable();
@@ -150,7 +141,6 @@
                 sTestBroadcastReceiver = new CdmaCbTestBroadcastReceiver();
                 IntentFilter filter = new IntentFilter();
                 filter.addAction(TEST_ACTION);
-                filter.addAction(TOGGLE_CB_MODULE);
                 context.registerReceiver(sTestBroadcastReceiver, filter);
             }
             if (sTestScpBroadcastReceiver == null) {
@@ -168,7 +158,6 @@
     @Override
     protected void onQuitting() {
         mPhone.mCi.unSetOnNewCdmaSms(getHandler());
-        mCellBroadcastHandler.dispose();
 
         if (DBG) log("unregistered for 3GPP2 SMS");
         super.onQuitting();
@@ -209,11 +198,7 @@
         // Handle CMAS emergency broadcast messages.
         if (isBroadcastType) {
             log("Broadcast type message");
-            if (sEnableCbModule) {
-                mCellBroadcastServiceManager.sendCdmaMessageToHandler(sms);
-            } else {
-                legacyDispatchSmsCbMessage(sms);
-            }
+            mCellBroadcastServiceManager.sendCdmaMessageToHandler(sms);
             return Intents.RESULT_SMS_HANDLED;
         }
 
@@ -244,11 +229,7 @@
                 break;
 
             case SmsEnvelope.TELESERVICE_SCPT:
-                if (sEnableCbModule) {
-                    mCellBroadcastServiceManager.sendCdmaScpMessageToHandler(sms, mScpCallback);
-                } else {
-                    mServiceCategoryProgramHandler.dispatchSmsMessage(sms);
-                }
+                mCellBroadcastServiceManager.sendCdmaScpMessageToHandler(sms, mScpCallback);
                 return Intents.RESULT_SMS_HANDLED;
 
             case SmsEnvelope.TELESERVICE_FDEA_WAP:
@@ -283,20 +264,6 @@
         return dispatchNormalMessage(smsb);
     }
 
-    // dispatch an SMS message through the platform
-    private void legacyDispatchSmsCbMessage(SmsMessage sms) {
-        String plmn =
-                TelephonyManager.from(mContext).getNetworkOperatorForPhone(
-                        mPhone.getPhoneId());
-        SmsCbMessage cbMessage = sms.parseBroadcastSms(plmn, mPhone.getPhoneId(),
-                mPhone.getSubId());
-        if (cbMessage != null) {
-            mCellBroadcastHandler.dispatchSmsMessage(cbMessage);
-        } else {
-            loge("error trying to parse broadcast SMS");
-        }
-    }
-
     /**
      * Send an acknowledge message.
      *
@@ -485,16 +452,11 @@
      * 493925391C81193D48814D3D555120810D3D0D3D3925393C810D3D5539516480B481393D495120810D1539514 \
      * 9053081054925693D390481553951253080D0C4D481413481354D500 \
      * --ei phone_id 0 \
-     *
-     * adb shell am broadcast -a com.android.internal.telephony.cdma.TOGGLE_CB_MODULE
-     *
-     * adb shell am broadcast -a com.android.internal.telephony.cdma.TOGGLE_CB_MODULE \
-     * --ez enable true
      */
     private class CdmaCbTestBroadcastReceiver extends CbTestBroadcastReceiver {
 
         CdmaCbTestBroadcastReceiver() {
-            super(TEST_ACTION, TOGGLE_CB_MODULE);
+            super(TEST_ACTION);
         }
 
         @Override
@@ -522,23 +484,7 @@
             }
 
             SmsMessage sms = new SmsMessage(new CdmaSmsAddress(), envelope);
-            if (sEnableCbModule) {
                 mCellBroadcastServiceManager.sendCdmaMessageToHandler(sms);
-            } else {
-                legacyDispatchSmsCbMessage(sms);
-            }
-        }
-
-        @Override
-        protected void handleToggleEnable() {
-            // sEnableCbModule is already toggled in super class
-            mCellBroadcastServiceManager.enable();
-        }
-
-        @Override
-        protected void handleToggleDisable(Context context) {
-            // sEnableCbModule is already toggled in super class
-            mCellBroadcastServiceManager.disable();
         }
     }
 
@@ -550,13 +496,11 @@
      * --es originating_address_string 1234567890 \
      * --es bearer_data_string 00031007B0122610880080B2091C5F1D3965DB95054D1CB2E1E883A6F41334E \
      * 6CA830EEC882872DFC32F2E9E40
-     *
-     * To toggle use the CDMA CB test broadcast receiver.
      */
     private class CdmaScpTestBroadcastReceiver extends CbTestBroadcastReceiver {
 
         CdmaScpTestBroadcastReceiver() {
-            super(SCP_TEST_ACTION, null);
+            super(SCP_TEST_ACTION);
         }
 
         @Override
@@ -585,21 +529,7 @@
             }
             SmsMessage sms = new SmsMessage(origAddr, envelope);
             sms.parseSms();
-            if (sEnableCbModule) {
-                mCellBroadcastServiceManager.sendCdmaScpMessageToHandler(sms, mScpCallback);
-            } else {
-                mServiceCategoryProgramHandler.dispatchSmsMessage(sms);
-            }
-        }
-
-        @Override
-        protected void handleToggleEnable() {
-            // noop
-        }
-
-        @Override
-        protected void handleToggleDisable(Context context) {
-            // noop
+            mCellBroadcastServiceManager.sendCdmaScpMessageToHandler(sms, mScpCallback);
         }
     }
 }
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaMmiCode.java b/src/java/com/android/internal/telephony/cdma/CdmaMmiCode.java
index 7600c1a..e593115 100644
--- a/src/java/com/android/internal/telephony/cdma/CdmaMmiCode.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaMmiCode.java
@@ -16,24 +16,23 @@
 
 package com.android.internal.telephony.cdma;
 
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
-
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.GsmCdmaPhone;
-import com.android.internal.telephony.uicc.UiccCardApplication;
-import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
-import com.android.internal.telephony.MmiCode;
-import com.android.internal.telephony.Phone;
-
-import android.annotation.UnsupportedAppUsage;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
 import android.os.ResultReceiver;
 import android.telephony.Rlog;
 
-import java.util.regex.Pattern;
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.GsmCdmaPhone;
+import com.android.internal.telephony.MmiCode;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
+import com.android.internal.telephony.uicc.UiccCardApplication;
+
 import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * This class can handle Puk code Mmi
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/src/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index 61aa089..eda5f52 100755
--- a/src/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -18,23 +18,23 @@
 
 import static com.android.internal.telephony.SmsResponse.NO_ERROR_CODE;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Message;
 import android.telephony.Rlog;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.util.Pair;
 
+import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
 import com.android.internal.telephony.GsmCdmaPhone;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.SmsConstants;
 import com.android.internal.telephony.SMSDispatcher;
+import com.android.internal.telephony.SmsConstants;
 import com.android.internal.telephony.SmsDispatchersController;
 import com.android.internal.telephony.SmsHeader;
-import com.android.internal.telephony.util.SMSDispatcherUtil;
-import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
 import com.android.internal.telephony.SmsMessageBase;
+import com.android.internal.telephony.util.SMSDispatcherUtil;
 
 
 public class CdmaSMSDispatcher extends SMSDispatcher {
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaServiceCategoryProgramHandler.java b/src/java/com/android/internal/telephony/cdma/CdmaServiceCategoryProgramHandler.java
deleted file mode 100644
index 3dc728c..0000000
--- a/src/java/com/android/internal/telephony/cdma/CdmaServiceCategoryProgramHandler.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.cdma;
-
-import android.Manifest;
-import android.app.Activity;
-import android.app.AppOpsManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Message;
-import android.provider.Telephony.Sms.Intents;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.SubscriptionManager;
-import android.telephony.cdma.CdmaSmsCbProgramData;
-import android.telephony.cdma.CdmaSmsCbProgramResults;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.WakeLockStateMachine;
-import com.android.internal.telephony.cdma.sms.BearerData;
-import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
-import com.android.internal.telephony.cdma.sms.SmsEnvelope;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-
-/**
- * Handle CDMA Service Category Program Data requests and responses.
- */
-public final class CdmaServiceCategoryProgramHandler extends WakeLockStateMachine {
-
-    final CommandsInterface mCi;
-
-    /**
-     * Create a new CDMA inbound SMS handler.
-     */
-    CdmaServiceCategoryProgramHandler(Context context, CommandsInterface commandsInterface,
-            Phone phone) {
-        super("CdmaServiceCategoryProgramHandler", context, phone);
-        mContext = context;
-        mCi = commandsInterface;
-    }
-
-    /**
-     * Create a new State machine for SCPD requests.
-     * @param context the context to use
-     * @param commandsInterface the radio commands interface
-     * @return the new SCPD handler
-     */
-    static CdmaServiceCategoryProgramHandler makeScpHandler(Context context,
-            CommandsInterface commandsInterface, Phone phone) {
-        CdmaServiceCategoryProgramHandler handler = new CdmaServiceCategoryProgramHandler(
-                context, commandsInterface, phone);
-        handler.start();
-        return handler;
-    }
-
-    /**
-     * Handle Cell Broadcast messages from {@code CdmaInboundSmsHandler}.
-     * 3GPP-format Cell Broadcast messages sent from radio are handled in the subclass.
-     *
-     * @param message the message to process
-     * @return true if an ordered broadcast was sent; false on failure
-     */
-    @Override
-    protected boolean handleSmsMessage(Message message) {
-        if (message.obj instanceof SmsMessage) {
-            return handleServiceCategoryProgramData((SmsMessage) message.obj);
-        } else {
-            loge("handleMessage got object of type: " + message.obj.getClass().getName());
-            return false;
-        }
-    }
-
-
-    /**
-     * Send SCPD request to CellBroadcastReceiver as an ordered broadcast.
-     * @param sms the CDMA SmsMessage containing the SCPD request
-     * @return true if an ordered broadcast was sent; false on failure
-     */
-    private boolean handleServiceCategoryProgramData(SmsMessage sms) {
-        ArrayList<CdmaSmsCbProgramData> programDataList = sms.getSmsCbProgramData();
-        if (programDataList == null) {
-            loge("handleServiceCategoryProgramData: program data list is null!");
-            return false;
-        }
-
-        Intent intent = new Intent(Intents.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION);
-        intent.putExtra("sender", sms.getOriginatingAddress());
-        intent.putParcelableArrayListExtra("program_data", programDataList);
-        SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId());
-
-        String[] pkgs = mContext.getResources().getStringArray(
-                com.android.internal.R.array.config_defaultCellBroadcastReceiverPkgs);
-        mReceiverCount.addAndGet(pkgs.length);
-        for (String pkg : pkgs) {
-            intent.setPackage(pkg);
-            mContext.sendOrderedBroadcast(intent, Manifest.permission.RECEIVE_SMS,
-                    AppOpsManager.OP_RECEIVE_SMS, mScpResultsReceiver,
-                    getHandler(), Activity.RESULT_OK, null, null);
-        }
-        return true;
-    }
-
-    /**
-     * Broadcast receiver to handle results of ordered broadcast. Sends the SCPD results
-     * as a reply SMS, then sends a message to state machine to transition to idle.
-     */
-    private final BroadcastReceiver mScpResultsReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            sendScpResults();
-            if (DBG) log("mScpResultsReceiver finished");
-            if (mReceiverCount.decrementAndGet() == 0) {
-                sendMessage(EVENT_BROADCAST_COMPLETE);
-            }
-        }
-
-        private void sendScpResults() {
-            int resultCode = getResultCode();
-            if ((resultCode != Activity.RESULT_OK) && (resultCode != Intents.RESULT_SMS_HANDLED)) {
-                loge("SCP results error: result code = " + resultCode);
-                return;
-            }
-            Bundle extras = getResultExtras(false);
-            if (extras == null) {
-                loge("SCP results error: missing extras");
-                return;
-            }
-            String sender = extras.getString("sender");
-            if (sender == null) {
-                loge("SCP results error: missing sender extra.");
-                return;
-            }
-            ArrayList<CdmaSmsCbProgramResults> results
-                    = extras.getParcelableArrayList("results");
-            if (results == null) {
-                loge("SCP results error: missing results extra.");
-                return;
-            }
-
-            BearerData bData = new BearerData();
-            bData.messageType = BearerData.MESSAGE_TYPE_SUBMIT;
-            bData.messageId = SmsMessage.getNextMessageId();
-            bData.serviceCategoryProgramResults = results;
-            byte[] encodedBearerData = BearerData.encode(bData);
-
-            ByteArrayOutputStream baos = new ByteArrayOutputStream(100);
-            DataOutputStream dos = new DataOutputStream(baos);
-            try {
-                dos.writeInt(SmsEnvelope.TELESERVICE_SCPT);
-                dos.writeInt(0); //servicePresent
-                dos.writeInt(0); //serviceCategory
-                CdmaSmsAddress destAddr = CdmaSmsAddress.parse(
-                        PhoneNumberUtils.cdmaCheckAndProcessPlusCodeForSms(sender));
-                dos.write(destAddr.digitMode);
-                dos.write(destAddr.numberMode);
-                dos.write(destAddr.ton); // number_type
-                dos.write(destAddr.numberPlan);
-                dos.write(destAddr.numberOfDigits);
-                dos.write(destAddr.origBytes, 0, destAddr.origBytes.length); // digits
-                // Subaddress is not supported.
-                dos.write(0); //subaddressType
-                dos.write(0); //subaddr_odd
-                dos.write(0); //subaddr_nbr_of_digits
-                dos.write(encodedBearerData.length);
-                dos.write(encodedBearerData, 0, encodedBearerData.length);
-                // Ignore the RIL response. TODO: implement retry if SMS send fails.
-                mCi.sendCdmaSms(baos.toByteArray(), null);
-            } catch (IOException e) {
-                loge("exception creating SCP results PDU", e);
-            } finally {
-                try {
-                    dos.close();
-                } catch (IOException ignored) {
-                }
-            }
-        }
-    };
-}
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java b/src/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java
index bc09e77..1380c58 100644
--- a/src/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java
@@ -16,11 +16,7 @@
 
 package com.android.internal.telephony.cdma;
 
-import java.util.concurrent.atomic.AtomicInteger;
-
-import android.annotation.UnsupportedAppUsage;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.Phone;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.AsyncResult;
 import android.os.Handler;
@@ -30,6 +26,11 @@
 import android.provider.Settings;
 import android.telephony.Rlog;
 
+import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.Phone;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
 /**
  * Class that handles the CDMA subscription source changed events from RIL
  */
diff --git a/src/java/com/android/internal/telephony/cdma/EriManager.java b/src/java/com/android/internal/telephony/cdma/EriManager.java
index 4ef55eb..782c6b5 100644
--- a/src/java/com/android/internal/telephony/cdma/EriManager.java
+++ b/src/java/com/android/internal/telephony/cdma/EriManager.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.cdma;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index 982e3e2..bec4b20 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -267,6 +267,7 @@
     private static final String NULL_IP = "0.0.0.0";
     private Object mUserData;
     private int mSubscriptionOverride;
+    private boolean mUnmeteredOverride;
     private int mRilRat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
     private int mDataRegState = Integer.MAX_VALUE;
     private NetworkInfo mNetworkInfo;
@@ -321,9 +322,9 @@
     static final int EVENT_REEVALUATE_RESTRICTED_STATE = BASE + 25;
     static final int EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES = BASE + 26;
     static final int EVENT_NR_STATE_CHANGED = BASE + 27;
-
+    static final int EVENT_DATA_CONNECTION_METEREDNESS_CHANGED = BASE + 28;
     private static final int CMD_TO_STRING_COUNT =
-            EVENT_NR_STATE_CHANGED - BASE + 1;
+            EVENT_DATA_CONNECTION_METEREDNESS_CHANGED - BASE + 1;
 
     private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
     static {
@@ -361,6 +362,8 @@
                 "EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES";
         sCmdToString[EVENT_NR_STATE_CHANGED - BASE] =
                 "EVENT_NR_STATE_CHANGED";
+        sCmdToString[EVENT_DATA_CONNECTION_METEREDNESS_CHANGED - BASE] =
+                "EVENT_DATA_CONNECTION_METEREDNESS_CHANGED";
     }
     // Convert cmd to string or null if unknown
     static String cmdToString(int cmd) {
@@ -417,7 +420,8 @@
         return getCurrentState() == mDisconnectingState;
     }
 
-    boolean isActive() {
+    @VisibleForTesting
+    public boolean isActive() {
         return getCurrentState() == mActiveState;
     }
 
@@ -741,6 +745,15 @@
     }
 
     /**
+     * Update NetworkCapabilities.NET_CAPABILITY_NOT_METERED based on meteredness
+     * @param isUnmetered whether this DC should be set to unmetered or not
+     */
+    public void onMeterednessChanged(boolean isUnmetered) {
+        mUnmeteredOverride = isUnmetered;
+        sendMessage(obtainMessage(EVENT_DATA_CONNECTION_METEREDNESS_CHANGED));
+    }
+
+    /**
      * TearDown the data connection when the deactivation is complete a Message with
      * msg.what == EVENT_DEACTIVATE_DONE
      *
@@ -909,6 +922,8 @@
         mDcFailCause = DataFailCause.NONE;
         mDisabledApnTypeBitMask = 0;
         mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+        mSubscriptionOverride = 0;
+        mUnmeteredOverride = false;
     }
 
     /**
@@ -1330,6 +1345,11 @@
             result.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED);
         }
 
+        // Override set by DcTracker
+        if (mUnmeteredOverride) {
+            result.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+        }
+
         return result;
     }
 
@@ -1632,6 +1652,7 @@
                     break;
                 case EVENT_DATA_CONNECTION_ROAM_ON:
                 case EVENT_DATA_CONNECTION_ROAM_OFF:
+                case EVENT_DATA_CONNECTION_METEREDNESS_CHANGED:
                 case EVENT_DATA_CONNECTION_OVERRIDE_CHANGED:
                     updateNetworkInfo();
                     if (mNetworkAgent != null) {
@@ -2227,6 +2248,7 @@
                 }
                 case EVENT_DATA_CONNECTION_ROAM_ON:
                 case EVENT_DATA_CONNECTION_ROAM_OFF:
+                case EVENT_DATA_CONNECTION_METEREDNESS_CHANGED:
                 case EVENT_DATA_CONNECTION_OVERRIDE_CHANGED: {
                     updateNetworkInfo();
                     if (mNetworkAgent != null) {
@@ -2977,6 +2999,7 @@
         pw.println("mSubscriptionOverride=" + Integer.toHexString(mSubscriptionOverride));
         pw.println("mRestrictedNetworkOverride=" + mRestrictedNetworkOverride);
         pw.println("mUnmeteredUseOnly=" + mUnmeteredUseOnly);
+        pw.println("mUnmeteredOverride=" + mUnmeteredOverride);
         pw.println("disallowedApnTypes="
                 + ApnSetting.getApnTypesStringFromBitmask(getDisallowedApnTypes()));
         pw.println("mInstanceNumber=" + mInstanceNumber);
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java b/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
index ee3bfcc..ff6d2de 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
@@ -448,7 +448,7 @@
 
     private static boolean isStandAloneOpportunistic(int subId, Context context) {
         SubscriptionInfo info = SubscriptionController.getInstance().getActiveSubscriptionInfo(
-                subId, context.getOpPackageName());
+                subId, context.getOpPackageName(), context.getFeatureId());
         return (info != null) && info.isOpportunistic() && info.getGroupUuid() == null;
     }
 
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java b/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
index 87854bc..76bd054 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
@@ -26,7 +26,6 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.LinkProperties;
@@ -39,6 +38,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.permission.IPermissionManager;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.AnomalyReporter;
@@ -85,7 +85,7 @@
 
     private final CarrierConfigManager mCarrierConfigManager;
     private final AppOpsManager mAppOps;
-    private final IPackageManager mPackageManager;
+    private final IPermissionManager mPermissionManager;
 
     private final int mTransportType;
 
@@ -133,7 +133,7 @@
     private void grantPermissionsToService(String packageName) {
         final String[] pkgToGrant = {packageName};
         try {
-            mPackageManager.grantDefaultPermissionsToEnabledTelephonyDataServices(
+            mPermissionManager.grantDefaultPermissionsToEnabledTelephonyDataServices(
                     pkgToGrant, UserHandle.myUserId());
             mAppOps.setMode(AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS,
                 UserHandle.myUserId(), pkgToGrant[0], AppOpsManager.MODE_ALLOWED);
@@ -157,7 +157,7 @@
         try {
             String[] dataServicesArray = new String[dataServices.size()];
             dataServices.toArray(dataServicesArray);
-            mPackageManager.revokeDefaultPermissionsFromDisabledTelephonyDataServices(
+            mPermissionManager.revokeDefaultPermissionsFromDisabledTelephonyDataServices(
                     dataServicesArray, UserHandle.myUserId());
             for (String pkg : dataServices) {
                 mAppOps.setMode(AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS, UserHandle.myUserId(),
@@ -282,16 +282,20 @@
         mBound = false;
         mCarrierConfigManager = (CarrierConfigManager) phone.getContext().getSystemService(
                 Context.CARRIER_CONFIG_SERVICE);
-        mPackageManager = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
+        // NOTE: Do NOT use AppGlobals to retrieve the permission manager; AppGlobals
+        // caches the service instance, but we need to explicitly request a new service
+        // so it can be mocked out for tests
+        mPermissionManager =
+                IPermissionManager.Stub.asInterface(ServiceManager.getService("permissionmgr"));
         mAppOps = (AppOpsManager) phone.getContext().getSystemService(Context.APP_OPS_SERVICE);
 
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
         try {
             Context contextAsUser = phone.getContext().createPackageContextAsUser(
-                    phone.getContext().getPackageName(), 0, UserHandle.ALL);
+                phone.getContext().getPackageName(), 0, UserHandle.ALL);
             contextAsUser.registerReceiver(mBroadcastReceiver, intentFilter,
-                    null /* broadcastPermission */, null);
+                null /* broadcastPermission */, null);
         } catch (PackageManager.NameNotFoundException e) {
             loge("Package name not found: " + e.getMessage());
         }
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcController.java b/src/java/com/android/internal/telephony/dataconnection/DcController.java
index 7db4d26..caaed64 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcController.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcController.java
@@ -18,10 +18,8 @@
 
 import android.content.Context;
 import android.hardware.radio.V1_4.DataConnActiveStatus;
-import android.net.INetworkPolicyListener;
 import android.net.LinkAddress;
 import android.net.LinkProperties.CompareResult;
-import android.net.NetworkPolicyManager;
 import android.net.NetworkUtils;
 import android.os.AsyncResult;
 import android.os.Handler;
@@ -69,7 +67,6 @@
     private DccDefaultState mDccDefaultState = new DccDefaultState();
 
     final TelephonyManager mTelephonyManager;
-    final NetworkPolicyManager mNetworkPolicyManager;
 
     private PhoneStateListener mPhoneStateListener;
 
@@ -107,8 +104,6 @@
 
         mTelephonyManager = (TelephonyManager) phone.getContext()
                 .getSystemService(Context.TELEPHONY_SERVICE);
-        mNetworkPolicyManager = (NetworkPolicyManager) phone.getContext()
-                .getSystemService(Context.NETWORK_POLICY_SERVICE);
 
         mDcTesterDeactivateAll = (TelephonyUtils.IS_DEBUGGABLE)
                 ? new DcTesterDeactivateAll(mPhone, DcController.this, getHandler())
@@ -173,21 +168,6 @@
         return mExecutingCarrierChange;
     }
 
-    private final INetworkPolicyListener mListener = new NetworkPolicyManager.Listener() {
-        @Override
-        public void onSubscriptionOverride(int subId, int overrideMask, int overrideValue) {
-            if (mPhone == null || mPhone.getSubId() != subId) return;
-
-            final HashMap<Integer, DataConnection> dcListActiveByCid;
-            synchronized (mDcListAll) {
-                dcListActiveByCid = new HashMap<>(mDcListActiveByCid);
-            }
-            for (DataConnection dc : dcListActiveByCid.values()) {
-                dc.onSubscriptionOverride(overrideMask, overrideValue);
-            }
-        }
-    };
-
     private class DccDefaultState extends State {
         @Override
         public void enter() {
@@ -199,10 +179,6 @@
 
             mDataServiceManager.registerForDataCallListChanged(getHandler(),
                     DataConnection.EVENT_DATA_STATE_CHANGED);
-
-            if (mNetworkPolicyManager != null) {
-                mNetworkPolicyManager.registerListener(mListener);
-            }
         }
 
         @Override
@@ -216,9 +192,6 @@
             if (mDcTesterDeactivateAll != null) {
                 mDcTesterDeactivateAll.dispose();
             }
-            if (mNetworkPolicyManager != null) {
-                mNetworkPolicyManager.unregisterListener(mListener);
-            }
         }
 
         @Override
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index 02805a2..b599853 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -41,10 +41,12 @@
 import android.database.ContentObserver;
 import android.database.Cursor;
 import android.net.ConnectivityManager;
+import android.net.INetworkPolicyListener;
 import android.net.LinkProperties;
 import android.net.NetworkAgent;
 import android.net.NetworkCapabilities;
 import android.net.NetworkConfig;
+import android.net.NetworkPolicyManager;
 import android.net.NetworkRequest;
 import android.net.ProxyInfo;
 import android.net.TrafficStats;
@@ -67,6 +69,7 @@
 import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.Annotation.ApnType;
 import android.telephony.Annotation.DataFailureCause;
+import android.telephony.Annotation.NetworkType;
 import android.telephony.Annotation.RilRadioTechnology;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CellLocation;
@@ -78,6 +81,7 @@
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
+import android.telephony.SubscriptionPlan;
 import android.telephony.TelephonyManager;
 import android.telephony.cdma.CdmaCellLocation;
 import android.telephony.data.ApnSetting;
@@ -117,6 +121,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
@@ -333,6 +338,20 @@
     private final LocalLog mDataRoamingLeakageLog = new LocalLog(50);
     private final LocalLog mApnSettingsInitializationLog = new LocalLog(50);
 
+    /* Default for 5G connection reevaluation alarm durations */
+    private long mHysteresisTimeMs = 0;
+    private long mWatchdogTimeMs = 1000 * 60 * 60;
+
+    /* Used to check whether 5G timers are currently active and waiting to go off */
+    private boolean mHysteresis = false;
+    private boolean mWatchdog = false;
+
+    /* List of SubscriptionPlans, updated on SubscriptionManager.setSubscriptionPlans */
+    private List<SubscriptionPlan> mSubscriptionPlans = null;
+
+    /* Used to check whether phone was recently connected to 5G. */
+    private boolean m5GWasConnected = false;
+
     private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver () {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -361,6 +380,17 @@
                 if (mIccRecords.get() != null && mIccRecords.get().getRecordsLoaded()) {
                     setDefaultDataRoamingEnabled();
                 }
+                CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
+                        .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+                if (configManager != null) {
+                    PersistableBundle b = configManager.getConfigForSubId(mPhone.getSubId());
+                    if (b != null) {
+                        mHysteresisTimeMs = b.getLong(
+                                CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT);
+                        mWatchdogTimeMs = b.getLong(
+                                CarrierConfigManager.KEY_5G_WATCHDOG_TIME_MS_LONG);
+                    }
+                }
             } else {
                 if (DBG) log("onReceive: Unknown action=" + action);
             }
@@ -414,6 +444,27 @@
         }
     };
 
+    private NetworkPolicyManager mNetworkPolicyManager;
+    private final INetworkPolicyListener mNetworkPolicyListener =
+            new NetworkPolicyManager.Listener() {
+        @Override
+        public void onSubscriptionOverride(int subId, int overrideMask, int overrideValue) {
+            if (mPhone == null || mPhone.getSubId() != subId) return;
+
+            for (DataConnection dataConnection : mDataConnections.values()) {
+                dataConnection.onSubscriptionOverride(overrideMask, overrideValue);
+            }
+        }
+
+        @Override
+        public void onSubscriptionPlansChanged(int subId, SubscriptionPlan[] plans) {
+            if (mPhone == null || mPhone.getSubId() != subId) return;
+
+            mSubscriptionPlans = plans == null ? null : Arrays.asList(plans);
+            reevaluateUnmeteredConnections();
+        }
+    };
+
     private final SettingsObserver mSettingsObserver;
 
     private void registerSettingsObserver() {
@@ -695,6 +746,9 @@
         mSubscriptionManager = SubscriptionManager.from(mPhone.getContext());
         mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
 
+        mNetworkPolicyManager = NetworkPolicyManager.from(mPhone.getContext());
+        mNetworkPolicyManager.registerListener(mNetworkPolicyListener);
+
         HandlerThread dcHandlerThread = new HandlerThread("DcHandlerThread");
         dcHandlerThread.start();
         Handler dcHandler = new Handler(dcHandlerThread.getLooper());
@@ -749,6 +803,8 @@
                 DctConstants.EVENT_PS_RESTRICT_DISABLED, null);
         mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(mTransportType, this,
                 DctConstants.EVENT_DATA_RAT_CHANGED, null);
+        // listens for PhysicalChannelConfig changes
+        mPhone.registerForServiceStateChanged(this, DctConstants.EVENT_SERVICE_STATE_CHANGED, null);
     }
 
     public void unregisterServiceStateTrackerEvents() {
@@ -760,6 +816,7 @@
         mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
         mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(mTransportType,
                 this);
+        mPhone.unregisterForServiceStateChanged(this);
     }
 
     private void registerForAllEvents() {
@@ -805,6 +862,7 @@
 
         mSubscriptionManager
                 .removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
+        mNetworkPolicyManager.unregisterListener(mNetworkPolicyListener);
         mDcc.dispose();
         mDcTesterFailBringUpAll.dispose();
 
@@ -3754,6 +3812,17 @@
             case DctConstants.EVENT_DATA_ENABLED_OVERRIDE_RULES_CHANGED:
                 onDataEnabledOverrideRulesChanged();
                 break;
+            case DctConstants.EVENT_SERVICE_STATE_CHANGED:
+                reevaluateUnmeteredConnections();
+                break;
+            case DctConstants.EVENT_5G_TIMER_HYSTERESIS:
+                reevaluateUnmeteredConnections();
+                mHysteresis = false;
+                break;
+            case DctConstants.EVENT_5G_TIMER_WATCHDOG:
+                mWatchdog = false;
+                reevaluateUnmeteredConnections();
+                break;
             default:
                 Rlog.e("DcTracker", "Unhandled event=" + msg);
                 break;
@@ -3779,7 +3848,7 @@
 
     private int getCellLocationId() {
         int cid = -1;
-        CellLocation loc = mPhone.getCellLocation();
+        CellLocation loc = mPhone.getCellIdentity().asCellLocation();
 
         if (loc != null) {
             if (loc instanceof GsmCellLocation) {
@@ -3912,6 +3981,86 @@
         }
     }
 
+    private void reevaluateUnmeteredConnections() {
+        if (isNetworkTypeUnmetered(NETWORK_TYPE_NR)) {
+            if (mPhone.getServiceState().getNrState()
+                    == NetworkRegistrationInfo.NR_STATE_CONNECTED) {
+                if (!m5GWasConnected) { // 4G -> 5G
+                    stopHysteresisAlarm();
+                    setDataConnectionUnmetered(true);
+                }
+                if (!mWatchdog) {
+                    startWatchdogAlarm();
+                }
+                m5GWasConnected = true;
+            } else {
+                if (m5GWasConnected) { // 5G -> 4G
+                    if (!mHysteresis && !startHysteresisAlarm()) {
+                        // hysteresis is not active but carrier does not support hysteresis
+                        stopWatchdogAlarm();
+                        setDataConnectionUnmetered(isNetworkTypeUnmetered(
+                                mTelephonyManager.getNetworkType(mPhone.getSubId())));
+                    }
+                    m5GWasConnected = false;
+                } else { // 4G -> 4G
+                    if (!hasMessages(DctConstants.EVENT_5G_TIMER_HYSTERESIS)) {
+                        stopWatchdogAlarm();
+                        setDataConnectionUnmetered(isNetworkTypeUnmetered(
+                                mTelephonyManager.getNetworkType(mPhone.getSubId())));
+                    }
+                    // do nothing if waiting for hysteresis alarm to go off
+                }
+            }
+        } else {
+            stopWatchdogAlarm();
+            stopHysteresisAlarm();
+            setDataConnectionUnmetered(isNetworkTypeUnmetered(
+                    mTelephonyManager.getNetworkType(mPhone.getSubId())));
+            m5GWasConnected = false;
+        }
+    }
+
+    private void setDataConnectionUnmetered(boolean isUnmetered) {
+        for (DataConnection dataConnection : mDataConnections.values()) {
+            dataConnection.onMeterednessChanged(isUnmetered);
+        }
+    }
+
+    private boolean isNetworkTypeUnmetered(@NetworkType int networkType) {
+        if (mSubscriptionPlans == null || mSubscriptionPlans.size() == 0) {
+            // safe return false if unable to get subscription plans or plans don't exist
+            return false;
+        }
+
+        long bitmask = TelephonyManager.getBitMaskForNetworkType(networkType);
+        boolean isGeneralUnmetered = true;
+        for (SubscriptionPlan plan : mSubscriptionPlans) {
+            // check plan applies to given network type
+            if ((plan.getNetworkTypesBitMask() & bitmask) == bitmask) {
+                // check plan is general or specific
+                if (plan.getNetworkTypes() == null) {
+                    if (!isPlanUnmetered(plan)) {
+                        // metered takes precedence over unmetered for safety
+                        isGeneralUnmetered = false;
+                    }
+                } else {
+                    // ensure network type unknown returns general value
+                    if (networkType != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
+                        // there is only 1 specific plan per network type, so return value if found
+                        return isPlanUnmetered(plan);
+                    }
+                }
+            }
+        }
+        return isGeneralUnmetered;
+    }
+
+    private boolean isPlanUnmetered(SubscriptionPlan plan) {
+        return plan.getDataLimitBytes() == SubscriptionPlan.BYTES_UNLIMITED
+                && (plan.getDataLimitBehavior() == SubscriptionPlan.LIMIT_BEHAVIOR_UNKNOWN
+                || plan.getDataLimitBehavior() == SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED);
+    }
+
     private void log(String s) {
         Rlog.d(mLogTag, s);
     }
@@ -4744,6 +4893,36 @@
         }
     }
 
+    /**
+     * 5G connection reevaluation alarms
+     */
+    private boolean startHysteresisAlarm() {
+        if (mHysteresisTimeMs > 0) {
+            // only create hysteresis alarm if CarrierConfig allows it
+            sendMessageDelayed(obtainMessage(DctConstants.EVENT_5G_TIMER_HYSTERESIS),
+                    mHysteresisTimeMs);
+            mHysteresis = true;
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private void stopHysteresisAlarm() {
+        removeMessages(DctConstants.EVENT_5G_TIMER_HYSTERESIS);
+        mHysteresis = false;
+    }
+
+    private void startWatchdogAlarm() {
+        sendMessageDelayed(obtainMessage(DctConstants.EVENT_5G_TIMER_WATCHDOG), mWatchdogTimeMs);
+        mWatchdog = true;
+    }
+
+    private void stopWatchdogAlarm() {
+        removeMessages(DctConstants.EVENT_5G_TIMER_WATCHDOG);
+        mWatchdog = false;
+    }
+
     private static DataProfile createDataProfile(ApnSetting apn, boolean isPreferred) {
         return createDataProfile(apn, apn.getProfileId(), isPreferred);
     }
diff --git a/src/java/com/android/internal/telephony/gsm/GsmCellBroadcastHandler.java b/src/java/com/android/internal/telephony/gsm/GsmCellBroadcastHandler.java
deleted file mode 100644
index 8a3e73f..0000000
--- a/src/java/com/android/internal/telephony/gsm/GsmCellBroadcastHandler.java
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.gsm;
-
-import static com.android.internal.telephony.gsm.SmsCbConstants.MESSAGE_ID_CMAS_GEO_FENCING_TRIGGER;
-
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.os.SystemClock;
-import android.provider.Telephony.CellBroadcasts;
-import android.telephony.CbGeoUtils.Geometry;
-import android.telephony.CellLocation;
-import android.telephony.SmsCbLocation;
-import android.telephony.SmsCbMessage;
-import android.telephony.TelephonyManager;
-import android.telephony.gsm.GsmCellLocation;
-import android.text.format.DateUtils;
-
-import com.android.internal.telephony.CellBroadcastHandler;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.gsm.GsmSmsCbMessage.GeoFencingTriggerMessage;
-import com.android.internal.telephony.gsm.GsmSmsCbMessage.GeoFencingTriggerMessage.CellBroadcastIdentity;
-
-import java.text.DateFormat;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Handler for 3GPP format Cell Broadcasts. Parent class can also handle CDMA Cell Broadcasts.
- */
-public class GsmCellBroadcastHandler extends CellBroadcastHandler {
-    private static final boolean VDBG = false;  // log CB PDU data
-
-    /** Indicates that a message is not being broadcasted. */
-    private static final String MESSAGE_NOT_BROADCASTED = "0";
-
-    /** This map holds incomplete concatenated messages waiting for assembly. */
-    @UnsupportedAppUsage
-    private final HashMap<SmsCbConcatInfo, byte[][]> mSmsCbPageMap =
-            new HashMap<SmsCbConcatInfo, byte[][]>(4);
-
-    private long mLastAirplaneModeTime = 0;
-
-    protected GsmCellBroadcastHandler(Context context, Phone phone) {
-        super("GsmCellBroadcastHandler", context, phone);
-        phone.mCi.setOnNewGsmBroadcastSms(getHandler(), EVENT_NEW_SMS_MESSAGE, null);
-
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-        mContext.registerReceiver(
-                new BroadcastReceiver() {
-                    @Override
-                    public void onReceive(Context context, Intent intent) {
-                        switch (intent.getAction()) {
-                            case Intent.ACTION_AIRPLANE_MODE_CHANGED:
-                                boolean airplaneModeOn = intent.getBooleanExtra("state", false);
-                                if (airplaneModeOn) {
-                                    mLastAirplaneModeTime = System.currentTimeMillis();
-                                }
-                                break;
-                        }
-
-                    }
-                }, intentFilter);
-    }
-
-    @Override
-    protected void onQuitting() {
-        mPhone.mCi.unSetOnNewGsmBroadcastSms(getHandler());
-        super.onQuitting();     // release wakelock
-    }
-
-    /**
-     * Create a new CellBroadcastHandler.
-     * @param context the context to use for dispatching Intents
-     * @return the new handler
-     */
-    public static GsmCellBroadcastHandler makeGsmCellBroadcastHandler(Context context,
-            Phone phone) {
-        GsmCellBroadcastHandler handler = new GsmCellBroadcastHandler(context, phone);
-        handler.start();
-        return handler;
-    }
-
-    /**
-     * Find the cell broadcast messages specify by the geo-fencing trigger message and perform a
-     * geo-fencing check for these messages.
-     * @param geoFencingTriggerMessage the trigger message
-     *
-     * @return {@code True} if geo-fencing is need for some cell broadcast message.
-     */
-    private boolean handleGeoFencingTriggerMessage(
-            GeoFencingTriggerMessage geoFencingTriggerMessage) {
-        final List<SmsCbMessage> cbMessages = new ArrayList<>();
-        final List<Uri> cbMessageUris = new ArrayList<>();
-
-        long lastReceivedTime = System.currentTimeMillis() - DateUtils.DAY_IN_MILLIS;
-        Resources res = mContext.getResources();
-        if (res.getBoolean(com.android.internal.R.bool.reset_geo_fencing_check_after_boot_or_apm)) {
-            lastReceivedTime = Long.max(lastReceivedTime, mLastAirplaneModeTime);
-            lastReceivedTime = Long.max(lastReceivedTime,
-                    System.currentTimeMillis() - SystemClock.elapsedRealtime());
-        }
-
-        // Find the cell broadcast message identify by the message identifier and serial number
-        // and is not broadcasted.
-        String where = CellBroadcasts.SERVICE_CATEGORY + "=? AND "
-                + CellBroadcasts.SERIAL_NUMBER + "=? AND "
-                + CellBroadcasts.MESSAGE_BROADCASTED + "=? AND "
-                + CellBroadcasts.RECEIVED_TIME + ">?";
-
-        ContentResolver resolver = mContext.getContentResolver();
-        for (CellBroadcastIdentity identity : geoFencingTriggerMessage.cbIdentifiers) {
-            try (Cursor cursor = resolver.query(CELL_BROADCAST_URI,
-                    CellBroadcasts.QUERY_COLUMNS_FWK,
-                    where,
-                    new String[] { Integer.toString(identity.messageIdentifier),
-                            Integer.toString(identity.serialNumber), MESSAGE_NOT_BROADCASTED,
-                            Long.toString(lastReceivedTime) },
-                    null /* sortOrder */)) {
-                if (cursor != null) {
-                    while (cursor.moveToNext()) {
-                        cbMessages.add(SmsCbMessage.createFromCursor(cursor));
-                        cbMessageUris.add(ContentUris.withAppendedId(CELL_BROADCAST_URI,
-                                cursor.getInt(cursor.getColumnIndex(CellBroadcasts._ID))));
-                    }
-                }
-            }
-        }
-
-        log("Found " + cbMessages.size() + " messages since "
-                + DateFormat.getDateTimeInstance().format(lastReceivedTime));
-
-        List<Geometry> commonBroadcastArea = new ArrayList<>();
-        if (geoFencingTriggerMessage.shouldShareBroadcastArea()) {
-            for (SmsCbMessage msg : cbMessages) {
-                if (msg.getGeometries() != null) {
-                    commonBroadcastArea.addAll(msg.getGeometries());
-                }
-            }
-        }
-
-        // ATIS doesn't specify the geo fencing maximum wait time for the cell broadcasts specified
-        // in geo fencing trigger message. We will pick the largest maximum wait time among these
-        // cell broadcasts.
-        int maximumWaitTimeSec = 0;
-        for (SmsCbMessage msg : cbMessages) {
-            maximumWaitTimeSec = Math.max(maximumWaitTimeSec, msg.getMaximumWaitingDuration());
-        }
-
-        if (DBG) {
-            logd("Geo-fencing trigger message = " + geoFencingTriggerMessage);
-            for (SmsCbMessage msg : cbMessages) {
-                logd(msg.toString());
-            }
-        }
-
-        if (cbMessages.isEmpty()) {
-            if (DBG) logd("No CellBroadcast message need to be broadcasted");
-            return false;
-        }
-
-        requestLocationUpdate(location -> {
-            if (location == null) {
-                // If the location is not available, broadcast the messages directly.
-                broadcastMessage(cbMessages, cbMessageUris);
-            } else {
-                for (int i = 0; i < cbMessages.size(); i++) {
-                    List<Geometry> broadcastArea = !commonBroadcastArea.isEmpty()
-                            ? commonBroadcastArea : cbMessages.get(i).getGeometries();
-                    if (broadcastArea == null || broadcastArea.isEmpty()) {
-                        broadcastMessage(cbMessages.get(i), cbMessageUris.get(i));
-                    } else {
-                        performGeoFencing(cbMessages.get(i), cbMessageUris.get(i), broadcastArea,
-                                location);
-                    }
-                }
-            }
-        }, maximumWaitTimeSec);
-        return true;
-    }
-
-    /**
-     * Handle 3GPP-format Cell Broadcast messages sent from radio.
-     *
-     * @param message the message to process
-     * @return true if need to wait for geo-fencing or an ordered broadcast was sent.
-     */
-    @Override
-    protected boolean handleSmsMessage(Message message) {
-        if (message.obj instanceof AsyncResult) {
-            SmsCbHeader header = createSmsCbHeader((AsyncResult) message.obj);
-            if (header == null) return false;
-
-            AsyncResult ar = (AsyncResult) message.obj;
-            byte[] pdu = (byte[]) ar.result;
-            if (header.getServiceCategory() == MESSAGE_ID_CMAS_GEO_FENCING_TRIGGER) {
-                GeoFencingTriggerMessage triggerMessage =
-                        GsmSmsCbMessage.createGeoFencingTriggerMessage(pdu);
-                if (triggerMessage != null) {
-                    return handleGeoFencingTriggerMessage(triggerMessage);
-                }
-            } else {
-                SmsCbMessage cbMessage = handleGsmBroadcastSms(header, ar);
-                if (cbMessage != null) {
-                    handleBroadcastSms(cbMessage);
-                    return true;
-                }
-                if (VDBG) log("Not handled GSM broadcasts.");
-            }
-        }
-        return super.handleSmsMessage(message);
-    }
-
-    /**
-     * Handle 3GPP format SMS-CB message.
-     * @param header the cellbroadcast header.
-     * @param ar the AsyncResult containing the received PDUs
-     */
-    private SmsCbMessage handleGsmBroadcastSms(SmsCbHeader header, AsyncResult ar) {
-        try {
-            byte[] receivedPdu = (byte[]) ar.result;
-
-            if (VDBG) {
-                int pduLength = receivedPdu.length;
-                for (int i = 0; i < pduLength; i += 8) {
-                    StringBuilder sb = new StringBuilder("SMS CB pdu data: ");
-                    for (int j = i; j < i + 8 && j < pduLength; j++) {
-                        int b = receivedPdu[j] & 0xff;
-                        if (b < 0x10) {
-                            sb.append('0');
-                        }
-                        sb.append(Integer.toHexString(b)).append(' ');
-                    }
-                    log(sb.toString());
-                }
-            }
-
-            if (VDBG) log("header=" + header);
-            String plmn = TelephonyManager.from(mContext).getNetworkOperatorForPhone(
-                    mPhone.getPhoneId());
-            int lac = -1;
-            int cid = -1;
-            CellLocation cl = mPhone.getCellLocation();
-            // Check if cell location is GsmCellLocation.  This is required to support
-            // dual-mode devices such as CDMA/LTE devices that require support for
-            // both 3GPP and 3GPP2 format messages
-            if (cl instanceof GsmCellLocation) {
-                GsmCellLocation cellLocation = (GsmCellLocation)cl;
-                lac = cellLocation.getLac();
-                cid = cellLocation.getCid();
-            }
-
-            SmsCbLocation location;
-            switch (header.getGeographicalScope()) {
-                case SmsCbMessage.GEOGRAPHICAL_SCOPE_LOCATION_AREA_WIDE:
-                    location = new SmsCbLocation(plmn, lac, -1);
-                    break;
-
-                case SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE:
-                case SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE:
-                    location = new SmsCbLocation(plmn, lac, cid);
-                    break;
-
-                case SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE:
-                default:
-                    location = new SmsCbLocation(plmn);
-                    break;
-            }
-
-            byte[][] pdus;
-            int pageCount = header.getNumberOfPages();
-            if (pageCount > 1) {
-                // Multi-page message
-                SmsCbConcatInfo concatInfo = new SmsCbConcatInfo(header, location);
-
-                // Try to find other pages of the same message
-                pdus = mSmsCbPageMap.get(concatInfo);
-
-                if (pdus == null) {
-                    // This is the first page of this message, make room for all
-                    // pages and keep until complete
-                    pdus = new byte[pageCount][];
-
-                    mSmsCbPageMap.put(concatInfo, pdus);
-                }
-
-                if (VDBG) log("pdus size=" + pdus.length);
-                // Page parameter is one-based
-                pdus[header.getPageIndex() - 1] = receivedPdu;
-
-                for (byte[] pdu : pdus) {
-                    if (pdu == null) {
-                        // Still missing pages, exit
-                        log("still missing pdu");
-                        return null;
-                    }
-                }
-
-                // Message complete, remove and dispatch
-                mSmsCbPageMap.remove(concatInfo);
-            } else {
-                // Single page message
-                pdus = new byte[1][];
-                pdus[0] = receivedPdu;
-            }
-
-            // Remove messages that are out of scope to prevent the map from
-            // growing indefinitely, containing incomplete messages that were
-            // never assembled
-            Iterator<SmsCbConcatInfo> iter = mSmsCbPageMap.keySet().iterator();
-
-            while (iter.hasNext()) {
-                SmsCbConcatInfo info = iter.next();
-
-                if (!info.matchesLocation(plmn, lac, cid)) {
-                    iter.remove();
-                }
-            }
-
-            return GsmSmsCbMessage.createSmsCbMessage(mContext, header, location, pdus,
-                mPhone.getPhoneId());
-
-        } catch (RuntimeException e) {
-            loge("Error in decoding SMS CB pdu", e);
-            return null;
-        }
-    }
-
-    private SmsCbHeader createSmsCbHeader(AsyncResult ar) {
-        try {
-            return new SmsCbHeader((byte[]) ar.result);
-        } catch (Exception ex) {
-            loge("Can't create SmsCbHeader, ex = " + ex.toString());
-            return null;
-        }
-    }
-
-    /**
-     * Holds all info about a message page needed to assemble a complete concatenated message.
-     */
-    private static final class SmsCbConcatInfo {
-
-        private final SmsCbHeader mHeader;
-        private final SmsCbLocation mLocation;
-
-        @UnsupportedAppUsage
-        SmsCbConcatInfo(SmsCbHeader header, SmsCbLocation location) {
-            mHeader = header;
-            mLocation = location;
-        }
-
-        @Override
-        public int hashCode() {
-            return (mHeader.getSerialNumber() * 31) + mLocation.hashCode();
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof SmsCbConcatInfo) {
-                SmsCbConcatInfo other = (SmsCbConcatInfo)obj;
-
-                // Two pages match if they have the same serial number (which includes the
-                // geographical scope and update number), and both pages belong to the same
-                // location (PLMN, plus LAC and CID if these are part of the geographical scope).
-                return mHeader.getSerialNumber() == other.mHeader.getSerialNumber()
-                        && mLocation.equals(other.mLocation);
-            }
-
-            return false;
-        }
-
-        /**
-         * Compare the location code for this message to the current location code. The match is
-         * relative to the geographical scope of the message, which determines whether the LAC
-         * and Cell ID are saved in mLocation or set to -1 to match all values.
-         *
-         * @param plmn the current PLMN
-         * @param lac the current Location Area (GSM) or Service Area (UMTS)
-         * @param cid the current Cell ID
-         * @return true if this message is valid for the current location; false otherwise
-         */
-        @UnsupportedAppUsage
-        public boolean matchesLocation(String plmn, int lac, int cid) {
-            return mLocation.isInLocationArea(plmn, lac, cid);
-        }
-    }
-}
diff --git a/src/java/com/android/internal/telephony/gsm/GsmInboundSmsHandler.java b/src/java/com/android/internal/telephony/gsm/GsmInboundSmsHandler.java
index c258a81..47f75ca 100644
--- a/src/java/com/android/internal/telephony/gsm/GsmInboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/gsm/GsmInboundSmsHandler.java
@@ -17,6 +17,7 @@
 package com.android.internal.telephony.gsm;
 
 import android.app.Activity;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -36,8 +37,6 @@
 import com.android.internal.telephony.VisualVoicemailSmsFilter;
 import com.android.internal.telephony.uicc.UsimServiceTable;
 
-import dalvik.annotation.compat.UnsupportedAppUsage;
-
 /**
  * This class broadcasts incoming SMS messages to interested apps after storing them in
  * the SmsProvider "raw" table and ACKing them to the SMSC. After each message has been
@@ -52,30 +51,22 @@
     private static final boolean TEST_MODE = SystemProperties.getInt("ro.debuggable", 0) == 1;
     private static final String TEST_ACTION = "com.android.internal.telephony.gsm"
             + ".TEST_TRIGGER_CELL_BROADCAST";
-    private static final String TOGGLE_CB_MODULE = "com.android.internal.telephony.gsm"
-            + ".TOGGLE_CB_MODULE";
 
     /**
      * Create a new GSM inbound SMS handler.
      */
     private GsmInboundSmsHandler(Context context, SmsStorageMonitor storageMonitor,
             Phone phone) {
-        super("GsmInboundSmsHandler", context, storageMonitor, phone, null);
+        super("GsmInboundSmsHandler", context, storageMonitor, phone);
         phone.mCi.setOnNewGsmSms(getHandler(), EVENT_NEW_SMS, null);
         mDataDownloadHandler = new UsimDataDownloadHandler(phone.mCi, phone.getPhoneId());
-        if (sEnableCbModule) {
-            mCellBroadcastServiceManager.enable();
-        } else {
-            mCellBroadcastHandler = GsmCellBroadcastHandler.makeGsmCellBroadcastHandler(context,
-                    phone);
-        }
+        mCellBroadcastServiceManager.enable();
 
         if (TEST_MODE) {
             if (sTestBroadcastReceiver == null) {
                 sTestBroadcastReceiver = new GsmCbTestBroadcastReceiver();
                 IntentFilter filter = new IntentFilter();
                 filter.addAction(TEST_ACTION);
-                filter.addAction(TOGGLE_CB_MODULE);
                 context.registerReceiver(sTestBroadcastReceiver, filter);
             }
         }
@@ -95,16 +86,11 @@
      * --es pdu_string  0000110011010D0A5BAE57CE770C531790E85C716CBF3044573065B9306757309707767 \
      * A751F30025F37304463FA308C306B5099304830664E0B30553044FF086C178C615E81FF09000000000000000 \
      * 0000000000000 --ei phone_id 0
-     *
-     * adb shell am broadcast -a com.android.internal.telephony.gsm.TOGGLE_CB_MODULE
-     *
-     * adb shell am broadcast -a com.android.internal.telephony.gsm.TOGGLE_CB_MODULE \
-     * --ez enable true
      */
     private class GsmCbTestBroadcastReceiver extends CbTestBroadcastReceiver {
 
         GsmCbTestBroadcastReceiver() {
-            super(TEST_ACTION, TOGGLE_CB_MODULE);
+            super(TEST_ACTION);
         }
 
         @Override
@@ -127,30 +113,7 @@
             }
             Message m = Message.obtain();
             AsyncResult.forMessage(m, smsPdu, null);
-            if (sEnableCbModule) {
-                mCellBroadcastServiceManager.sendGsmMessageToHandler(m);
-            } else {
-                m.what = GsmCellBroadcastHandler.EVENT_NEW_SMS_MESSAGE;
-                mCellBroadcastHandler.sendMessage(m);
-            }
-        }
-
-        @Override
-        protected void handleToggleEnable() {
-            mPhone.mCi.unSetOnNewGsmBroadcastSms(mCellBroadcastHandler.getHandler());
-            mCellBroadcastServiceManager.enable();
-        }
-
-        @Override
-        protected void handleToggleDisable(Context context) {
-            mCellBroadcastServiceManager.disable();
-            if (mCellBroadcastHandler == null) {
-                mCellBroadcastHandler =
-                        GsmCellBroadcastHandler.makeGsmCellBroadcastHandler(context,
-                                mPhone);
-            }
-            mPhone.mCi.setOnNewGsmBroadcastSms(mCellBroadcastHandler.getHandler(),
-                    GsmCellBroadcastHandler.EVENT_NEW_SMS_MESSAGE, null);
+            mCellBroadcastServiceManager.sendGsmMessageToHandler(m);
         }
     }
 
@@ -160,7 +123,6 @@
     @Override
     protected void onQuitting() {
         mPhone.mCi.unSetOnNewGsmSms(getHandler());
-        mCellBroadcastHandler.dispose();
 
         if (DBG) log("unregistered for 3GPP SMS");
         super.onQuitting();     // release wakelock
diff --git a/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java
index b3c071b..6cc2bc3 100644
--- a/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java
+++ b/src/java/com/android/internal/telephony/gsm/GsmMmiCode.java
@@ -27,6 +27,7 @@
 import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_SMS;
 import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE;
 
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.AsyncResult;
@@ -55,8 +56,6 @@
 import com.android.internal.telephony.uicc.UiccCardApplication;
 import com.android.internal.telephony.util.ArrayUtils;
 
-import dalvik.annotation.compat.UnsupportedAppUsage;
-
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -152,7 +151,7 @@
     @UnsupportedAppUsage
     String mSia;                 // Service Info a
     @UnsupportedAppUsage
-    String  mSib;                // Service Info b
+    String mSib;                 // Service Info b
     @UnsupportedAppUsage
     String mSic;                 // Service Info c
     String mPoundString;         // Entire MMI string up to and including #
diff --git a/src/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/src/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
index 57d6de8..de7977b 100644
--- a/src/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
@@ -18,6 +18,7 @@
 
 import static com.android.internal.telephony.SmsResponse.NO_ERROR_CODE;
 
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.AsyncResult;
 import android.os.Message;
 import android.provider.Telephony.Sms.Intents;
@@ -39,8 +40,6 @@
 import com.android.internal.telephony.uicc.UiccController;
 import com.android.internal.telephony.util.SMSDispatcherUtil;
 
-import dalvik.annotation.compat.UnsupportedAppUsage;
-
 import java.util.HashMap;
 import java.util.concurrent.atomic.AtomicReference;
 
diff --git a/src/java/com/android/internal/telephony/gsm/SimTlv.java b/src/java/com/android/internal/telephony/gsm/SimTlv.java
index 7df1f96..ee0d3ff 100644
--- a/src/java/com/android/internal/telephony/gsm/SimTlv.java
+++ b/src/java/com/android/internal/telephony/gsm/SimTlv.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.gsm;
 
-import dalvik.annotation.compat.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 
 /**
  * SIM Tag-Length-Value record
diff --git a/src/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java b/src/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
index a541459..7594d3b 100755
--- a/src/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
+++ b/src/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.gsm;
 
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
@@ -29,8 +30,6 @@
 import com.android.internal.telephony.uicc.IccFileHandler;
 import com.android.internal.telephony.uicc.IccUtils;
 
-import dalvik.annotation.compat.UnsupportedAppUsage;
-
 import java.util.ArrayList;
 
 /**
diff --git a/src/java/com/android/internal/telephony/ims/ImsServiceController.java b/src/java/com/android/internal/telephony/ims/ImsServiceController.java
index 967152d..325c57d 100644
--- a/src/java/com/android/internal/telephony/ims/ImsServiceController.java
+++ b/src/java/com/android/internal/telephony/ims/ImsServiceController.java
@@ -16,18 +16,18 @@
 
 package com.android.internal.telephony.ims;
 
+import android.app.AppGlobals;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.content.pm.IPackageManager;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.IInterface;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.permission.IPermissionManager;
 import android.telephony.ims.ImsService;
 import android.telephony.ims.aidl.IImsConfig;
 import android.telephony.ims.aidl.IImsMmTelFeature;
@@ -199,7 +199,7 @@
     private static final int REBIND_MAXIMUM_DELAY_MS = 60 * 1000; // 1 minute
     private final ComponentName mComponentName;
     private final HandlerThread mHandlerThread = new HandlerThread("ImsServiceControllerHandler");
-    private final IPackageManager mPackageManager;
+    private final IPermissionManager mPermissionManager;
     private ImsServiceControllerCallbacks mCallbacks;
     private ExponentialBackoff mBackoff;
 
@@ -334,7 +334,7 @@
                 2, /* multiplier */
                 mHandlerThread.getLooper(),
                 mRestartImsServiceRunnable);
-        mPackageManager = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
+        mPermissionManager = AppGlobals.getPermissionManager();
     }
 
     @VisibleForTesting
@@ -351,7 +351,7 @@
                 2, /* multiplier */
                 handler,
                 mRestartImsServiceRunnable);
-        mPackageManager = null;
+        mPermissionManager = null;
     }
 
     /**
@@ -640,16 +640,16 @@
         mBackoff.start();
     }
 
-    // Grant runtime permissions to ImsService. PackageManager ensures that the ImsService is
+    // Grant runtime permissions to ImsService. PermissionManager ensures that the ImsService is
     // system/signed before granting permissions.
     private void grantPermissionsToService() {
         mLocalLog.log("grant permissions to " + getComponentName());
         Log.i(LOG_TAG, "Granting Runtime permissions to:" + getComponentName());
         String[] pkgToGrant = {mComponentName.getPackageName()};
         try {
-            if (mPackageManager != null) {
-                mPackageManager.grantDefaultPermissionsToEnabledImsServices(pkgToGrant,
-                        UserHandle.myUserId());
+            if (mPermissionManager != null) {
+                mPermissionManager.grantDefaultPermissionsToEnabledImsServices(pkgToGrant,
+                    UserHandle.myUserId());
             }
         } catch (RemoteException e) {
             Log.w(LOG_TAG, "Unable to grant permissions, binder died.");
diff --git a/src/java/com/android/internal/telephony/ims/RcsMessageController.java b/src/java/com/android/internal/telephony/ims/RcsMessageController.java
index 3f9714d..bb8757e 100644
--- a/src/java/com/android/internal/telephony/ims/RcsMessageController.java
+++ b/src/java/com/android/internal/telephony/ims/RcsMessageController.java
@@ -163,7 +163,12 @@
      */
     private <T> T performWriteOperation(String callingPackage, ThrowingSupplier<T> fn) {
         RcsPermissions.checkWritePermissions(mContext, callingPackage);
-        return Binder.withCleanCallingIdentity(fn);
+        final long token = Binder.clearCallingIdentity();
+        try {
+            return fn.get();
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     /**
@@ -173,7 +178,12 @@
      */
     private <T> T performReadOperation(String callingPackage, ThrowingSupplier<T> fn) {
         RcsPermissions.checkReadPermissions(mContext, callingPackage);
-        return Binder.withCleanCallingIdentity(fn);
+        final long token = Binder.clearCallingIdentity();
+        try {
+            return fn.get();
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     @VisibleForTesting
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsExternalCall.java b/src/java/com/android/internal/telephony/imsphone/ImsExternalCall.java
index 7b6162d..fe00ec0 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsExternalCall.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsExternalCall.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.imsphone;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.telephony.ims.ImsExternalCallState;
 
 import com.android.internal.telephony.Call;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsExternalConnection.java b/src/java/com/android/internal/telephony/imsphone/ImsExternalConnection.java
index cd5c83d..b29acdb 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsExternalConnection.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsExternalConnection.java
@@ -16,7 +16,13 @@
 
 package com.android.internal.telephony.imsphone;
 
-import com.android.internal.R;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
+import android.net.Uri;
+import android.telecom.PhoneAccount;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.ims.ImsExternalCallState;
+
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallStateException;
 import com.android.internal.telephony.Connection;
@@ -24,13 +30,6 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.UUSInfo;
 
-import android.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.net.Uri;
-import android.telecom.PhoneAccount;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ims.ImsExternalCallState;
-
 import java.util.Collections;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index 32c5188..99a175f 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -38,12 +38,12 @@
 import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_NONE;
 import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE;
 
-import android.annotation.UnsupportedAppUsage;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -241,18 +241,6 @@
         this.mCurrentSubscriberUris = currentSubscriberUris;
     }
 
-    @UnsupportedAppUsage
-    @Override
-    public void notifyCallForwardingIndicator() {
-        super.notifyCallForwardingIndicator();
-    }
-
-    @UnsupportedAppUsage
-    @Override
-    public void notifyPreciseCallStateChanged() {
-        super.notifyPreciseCallStateChanged();
-    }
-
     @Override
     public Uri[] getCurrentSubscriberUris() {
         return mCurrentSubscriberUris;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java
index f4fdebd..b8e4b84 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java
@@ -16,9 +16,7 @@
 
 package com.android.internal.telephony.imsphone;
 
-import android.annotation.UnsupportedAppUsage;
-import com.android.ims.internal.ConferenceParticipant;
-import android.telephony.Rlog;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.telephony.DisconnectCause;
 import android.telephony.Rlog;
 import android.telephony.ims.ImsStreamMediaProfile;
@@ -26,6 +24,7 @@
 
 import com.android.ims.ImsCall;
 import com.android.ims.ImsException;
+import com.android.ims.internal.ConferenceParticipant;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallStateException;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index e182b57..e3884a9 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -19,7 +19,7 @@
 import static com.android.internal.telephony.Phone.CS_FALLBACK;
 
 import android.annotation.NonNull;
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -399,6 +399,7 @@
     private int mClirMode = CommandsInterface.CLIR_DEFAULT;
     @UnsupportedAppUsage
     private Object mSyncHold = new Object();
+
     @UnsupportedAppUsage
     private ImsCall mUssdSession = null;
     @UnsupportedAppUsage
@@ -3783,8 +3784,8 @@
     protected void handlePollCalls(AsyncResult ar) {
     }
 
-    /* package */
     @UnsupportedAppUsage
+    /* package */
     ImsEcbm getEcbmInterface() throws ImsException {
         if (mImsManager == null) {
             throw getImsManagerIsNullException();
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
index e1216c2..cfe744f 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.imsphone;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.net.Uri;
 import android.os.AsyncResult;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
index 072d8ff..faefa51 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
@@ -27,7 +27,7 @@
 import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_SMS;
 import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.AsyncResult;
diff --git a/src/java/com/android/internal/telephony/metrics/ModemPowerMetrics.java b/src/java/com/android/internal/telephony/metrics/ModemPowerMetrics.java
index f9f90fa..ba1975f 100644
--- a/src/java/com/android/internal/telephony/metrics/ModemPowerMetrics.java
+++ b/src/java/com/android/internal/telephony/metrics/ModemPowerMetrics.java
@@ -15,13 +15,10 @@
  */
 package com.android.internal.telephony.metrics;
 
-import android.os.BatteryStats;
-import android.os.RemoteException;
-import android.os.ServiceManager;
+import android.os.BatteryStatsManager;
 import android.os.connectivity.CellularBatteryStats;
 import android.text.format.DateUtils;
 
-import com.android.internal.app.IBatteryStats;
 import com.android.internal.telephony.nano.TelephonyProto.ModemPowerStats;
 
 /**
@@ -30,12 +27,11 @@
  */
 public class ModemPowerMetrics {
 
-    /* BatteryStats API */
-    private final IBatteryStats mBatteryStats;
+    /* BatteryStatsManager API */
+    private BatteryStatsManager mBatteryStatsManager;
 
-    public ModemPowerMetrics() {
-        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
-            BatteryStats.SERVICE_NAME));
+    public ModemPowerMetrics(BatteryStatsManager batteryStatsManager) {
+        mBatteryStatsManager = batteryStatsManager;
     }
 
     /**
@@ -46,45 +42,44 @@
         ModemPowerStats m = new ModemPowerStats();
         CellularBatteryStats stats = getStats();
         if (stats != null) {
-            m.loggingDurationMs = stats.getLoggingDurationMs();
-            m.energyConsumedMah = stats.getEnergyConsumedMaMs()
+            m.loggingDurationMs = stats.getLoggingDurationMillis();
+            m.energyConsumedMah = stats.getEnergyConsumedMaMillis()
                 / ((double) DateUtils.HOUR_IN_MILLIS);
             m.numPacketsTx = stats.getNumPacketsTx();
-            m.cellularKernelActiveTimeMs = stats.getKernelActiveTimeMs();
-            if (stats.getTimeInRxSignalStrengthLevelMs() != null
-                && stats.getTimeInRxSignalStrengthLevelMs().length > 0) {
-                m.timeInVeryPoorRxSignalLevelMs = stats.getTimeInRxSignalStrengthLevelMs()[0];
+            m.cellularKernelActiveTimeMs = stats.getKernelActiveTimeMillis();
+            if (stats.getTimeInRxSignalStrengthLevelMicros() != null
+                    && stats.getTimeInRxSignalStrengthLevelMicros().length > 0) {
+                m.timeInVeryPoorRxSignalLevelMs = stats.getTimeInRxSignalStrengthLevelMicros()[0];
             }
-            m.sleepTimeMs = stats.getSleepTimeMs();
-            m.idleTimeMs = stats.getIdleTimeMs();
-            m.rxTimeMs = stats.getRxTimeMs();
-            long[] t = stats.getTxTimeMs();
+            m.sleepTimeMs = stats.getSleepTimeMillis();
+            m.idleTimeMs = stats.getIdleTimeMillis();
+            m.rxTimeMs = stats.getRxTimeMillis();
+            long[] t = stats.getTxTimeMillis();
             m.txTimeMs = new long[t.length];
             System.arraycopy(t, 0, m.txTimeMs, 0, t.length);
             m.numBytesTx = stats.getNumBytesTx();
             m.numPacketsRx = stats.getNumPacketsRx();
             m.numBytesRx = stats.getNumBytesRx();
-            long[] tr = stats.getTimeInRatMs();
+            long[] tr = stats.getTimeInRatMicros();
             m.timeInRatMs = new long[tr.length];
             System.arraycopy(tr, 0, m.timeInRatMs, 0, tr.length);
-            long[] trx = stats.getTimeInRxSignalStrengthLevelMs();
+            long[] trx = stats.getTimeInRxSignalStrengthLevelMicros();
             m.timeInRxSignalStrengthLevelMs = new long[trx.length];
             System.arraycopy(trx, 0, m.timeInRxSignalStrengthLevelMs, 0, trx.length);
-            m.monitoredRailEnergyConsumedMah = stats.getMonitoredRailChargeConsumedMaMs()
+            m.monitoredRailEnergyConsumedMah = stats.getMonitoredRailChargeConsumedMaMillis()
                 / ((double) DateUtils.HOUR_IN_MILLIS);
         }
         return m;
     }
 
     /**
-     * Get cellular stats from batterystats
+     * Get cellular stats from BatteryStatsManager
      * @return CellularBatteryStats
      */
     private CellularBatteryStats getStats() {
-        try {
-            return mBatteryStats.getCellularBatteryStats();
-        } catch (RemoteException e) {
+        if (mBatteryStatsManager == null) {
+            return null;
         }
-        return null;
+        return mBatteryStatsManager.getCellularBatteryStats();
     }
 }
diff --git a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
index 8fcd197..bcd58ef 100644
--- a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
+++ b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
@@ -37,7 +37,9 @@
 import static com.android.internal.telephony.nano.TelephonyProto.PdpType.PDP_TYPE_UNSTRUCTURED;
 import static com.android.internal.telephony.nano.TelephonyProto.PdpType.PDP_UNKNOWN;
 
+import android.content.Context;
 import android.net.NetworkCapabilities;
+import android.os.BatteryStatsManager;
 import android.os.Build;
 import android.os.SystemClock;
 import android.os.SystemProperties;
@@ -231,6 +233,8 @@
     /** Indicating if some of the telephony events are dropped in this log */
     private boolean mTelephonyEventsDropped = false;
 
+    private Context mContext;
+
     public TelephonyMetrics() {
         mStartSystemTimeMs = System.currentTimeMillis();
         mStartElapsedTimeMs = SystemClock.elapsedRealtime();
@@ -250,6 +254,16 @@
     }
 
     /**
+     * Set the context for telephony metrics.
+     *
+     * @param context Context
+     * @hide
+     */
+    public void setContext(Context context) {
+        mContext = context;
+    }
+
+    /**
      * Dump the state of various objects, add calls to other objects as desired.
      *
      * @param fd File descriptor
@@ -570,7 +584,11 @@
         pw.decreaseIndent();
         pw.println("Modem power stats:");
         pw.increaseIndent();
-        ModemPowerStats s = new ModemPowerMetrics().buildProto();
+
+        BatteryStatsManager batteryStatsManager = mContext == null ? null :
+                (BatteryStatsManager) mContext.getSystemService(Context.BATTERY_STATS_SERVICE);
+        ModemPowerStats s = new ModemPowerMetrics(batteryStatsManager).buildProto();
+
         pw.println("Power log duration (battery time) (ms): " + s.loggingDurationMs);
         pw.println("Energy consumed by modem (mAh): " + s.energyConsumedMah);
         pw.println("Number of packets sent (tx): " + s.numPacketsTx);
@@ -729,7 +747,9 @@
         }
 
         // Build modem power metrics
-        log.modemPowerStats = new ModemPowerMetrics().buildProto();
+        BatteryStatsManager batteryStatsManager = mContext == null ? null :
+                (BatteryStatsManager) mContext.getSystemService(Context.BATTERY_STATS_SERVICE);
+        log.modemPowerStats = new ModemPowerMetrics(batteryStatsManager).buildProto();
 
         // Log the hardware revision
         log.hardwareRevision = SystemProperties.get("ro.boot.revision", "");
diff --git a/src/java/com/android/internal/telephony/sip/SipPhone.java b/src/java/com/android/internal/telephony/sip/SipPhone.java
index 7fcaf96..080a057 100644
--- a/src/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/src/java/com/android/internal/telephony/sip/SipPhone.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.sip;
 
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.media.AudioManager;
 import android.net.rtp.AudioGroup;
@@ -40,8 +41,6 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneNotifier;
 
-import dalvik.annotation.compat.UnsupportedAppUsage;
-
 import java.text.ParseException;
 import java.util.List;
 import java.util.regex.Pattern;
diff --git a/src/java/com/android/internal/telephony/uicc/AdnRecord.java b/src/java/com/android/internal/telephony/uicc/AdnRecord.java
index 2e21297..bd99932 100644
--- a/src/java/com/android/internal/telephony/uicc/AdnRecord.java
+++ b/src/java/com/android/internal/telephony/uicc/AdnRecord.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.PhoneNumberUtils;
diff --git a/src/java/com/android/internal/telephony/uicc/AdnRecordCache.java b/src/java/com/android/internal/telephony/uicc/AdnRecordCache.java
index 959984b..90d7a38 100644
--- a/src/java/com/android/internal/telephony/uicc/AdnRecordCache.java
+++ b/src/java/com/android/internal/telephony/uicc/AdnRecordCache.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
diff --git a/src/java/com/android/internal/telephony/uicc/AdnRecordLoader.java b/src/java/com/android/internal/telephony/uicc/AdnRecordLoader.java
index 391b8fc..64b47b5 100644
--- a/src/java/com/android/internal/telephony/uicc/AdnRecordLoader.java
+++ b/src/java/com/android/internal/telephony/uicc/AdnRecordLoader.java
@@ -16,16 +16,14 @@
 
 package com.android.internal.telephony.uicc;
 
-import java.util.ArrayList;
-
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.telephony.Rlog;
 
-import com.android.internal.telephony.uicc.IccConstants;
+import java.util.ArrayList;
 
 public class AdnRecordLoader extends Handler {
     final static String LOG_TAG = "AdnRecordLoader";
diff --git a/src/java/com/android/internal/telephony/uicc/IccCardApplicationStatus.java b/src/java/com/android/internal/telephony/uicc/IccCardApplicationStatus.java
index 87bbc69..c476efb 100644
--- a/src/java/com/android/internal/telephony/uicc/IccCardApplicationStatus.java
+++ b/src/java/com/android/internal/telephony/uicc/IccCardApplicationStatus.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.telephony.Rlog;
 
 import com.android.internal.telephony.uicc.IccCardStatus.PinState;
@@ -28,11 +28,6 @@
  * {@hide}
  */
 public class IccCardApplicationStatus {
-
-    @UnsupportedAppUsage
-    public IccCardApplicationStatus() {
-    }
-
     // TODO: Replace with constants from PhoneConstants.APPTYPE_xxx
     @UnsupportedAppUsage(implicitMember =
             "values()[Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;")
@@ -144,6 +139,10 @@
     public PinState       pin2;
 
     @UnsupportedAppUsage
+    public IccCardApplicationStatus() {
+    }
+
+    @UnsupportedAppUsage
     public AppType AppTypeFromRILInt(int type) {
         AppType newType;
         /* RIL_AppType ril.h */
diff --git a/src/java/com/android/internal/telephony/uicc/IccCardStatus.java b/src/java/com/android/internal/telephony/uicc/IccCardStatus.java
index df21601..765d1e1 100644
--- a/src/java/com/android/internal/telephony/uicc/IccCardStatus.java
+++ b/src/java/com/android/internal/telephony/uicc/IccCardStatus.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.telephony.SubscriptionInfo;
 
 /**
diff --git a/src/java/com/android/internal/telephony/uicc/IccFileHandler.java b/src/java/com/android/internal/telephony/uicc/IccFileHandler.java
index 6d5232b..ceeed34 100644
--- a/src/java/com/android/internal/telephony/uicc/IccFileHandler.java
+++ b/src/java/com/android/internal/telephony/uicc/IccFileHandler.java
@@ -16,8 +16,10 @@
 
 package com.android.internal.telephony.uicc;
 
-import android.annotation.UnsupportedAppUsage;
-import android.os.*;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
 
 import com.android.internal.telephony.CommandsInterface;
 
diff --git a/src/java/com/android/internal/telephony/uicc/IccIoResult.java b/src/java/com/android/internal/telephony/uicc/IccIoResult.java
index a9077fa..c3fdf1f 100644
--- a/src/java/com/android/internal/telephony/uicc/IccIoResult.java
+++ b/src/java/com/android/internal/telephony/uicc/IccIoResult.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 
 import com.android.internal.telephony.util.TelephonyUtils;
 
diff --git a/src/java/com/android/internal/telephony/uicc/IccRecords.java b/src/java/com/android/internal/telephony/uicc/IccRecords.java
index b4cd900..47f2d5e 100644
--- a/src/java/com/android/internal/telephony/uicc/IccRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/IccRecords.java
@@ -18,7 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.Nullable;
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.AsyncResult;
 import android.os.Handler;
@@ -1181,12 +1181,6 @@
         return null;
     }
 
-    protected void setSystemProperty(String key, String val) {
-        TelephonyManager.getDefault().setTelephonyProperty(mParentApp.getPhoneId(), key, val);
-
-        log("[key, value]=" + key + ", " +  val);
-    }
-
     /**
      * Returns the response of the SIM application on the UICC to authentication
      * challenge/response algorithm. The data string and challenge response are
diff --git a/src/java/com/android/internal/telephony/uicc/IccRefreshResponse.java b/src/java/com/android/internal/telephony/uicc/IccRefreshResponse.java
index ccb6f98..30fd36f 100644
--- a/src/java/com/android/internal/telephony/uicc/IccRefreshResponse.java
+++ b/src/java/com/android/internal/telephony/uicc/IccRefreshResponse.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 
 /**
  * See also RIL_SimRefresh in include/telephony/ril.h
@@ -39,7 +39,6 @@
                                                   from 0xA0, 0x00 -> 0x41,
                                                   0x30, 0x30, 0x30 */
                                                /* Example: a0000000871002f310ffff89080000ff */
-
     @UnsupportedAppUsage
     public IccRefreshResponse() {
     }
diff --git a/src/java/com/android/internal/telephony/uicc/IccServiceTable.java b/src/java/com/android/internal/telephony/uicc/IccServiceTable.java
index b2e2f27..b811d5c 100644
--- a/src/java/com/android/internal/telephony/uicc/IccServiceTable.java
+++ b/src/java/com/android/internal/telephony/uicc/IccServiceTable.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.telephony.Rlog;
 
 /**
diff --git a/src/java/com/android/internal/telephony/uicc/IsimRecords.java b/src/java/com/android/internal/telephony/uicc/IsimRecords.java
index 65cfd6f..3de7b3d 100644
--- a/src/java/com/android/internal/telephony/uicc/IsimRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/IsimRecords.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 
 /**
  * {@hide}
diff --git a/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java b/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
index 9a4964f..766668c 100644
--- a/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.Intent;
 import android.os.AsyncResult;
diff --git a/src/java/com/android/internal/telephony/uicc/RuimRecords.java b/src/java/com/android/internal/telephony/uicc/RuimRecords.java
index 561e390..0951678 100644
--- a/src/java/com/android/internal/telephony/uicc/RuimRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/RuimRecords.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.AsyncResult;
diff --git a/src/java/com/android/internal/telephony/uicc/SIMRecords.java b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
index 26ab756..baa5683 100644
--- a/src/java/com/android/internal/telephony/uicc/SIMRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.AsyncResult;
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCard.java b/src/java/com/android/internal/telephony/uicc/UiccCard.java
index 985bfa8..d06cdb0 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCard.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCard.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageInfo;
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java b/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
index 0722394..5921046 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.AsyncResult;
 import android.os.Handler;
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
index 114447f..49715e9 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
@@ -17,7 +17,7 @@
 package com.android.internal.telephony.uicc;
 
 import android.annotation.Nullable;
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Intent;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
diff --git a/src/java/com/android/internal/telephony/uicc/UiccController.java b/src/java/com/android/internal/telephony/uicc/UiccController.java
index df4650b..bdaa4ba 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccController.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccController.java
@@ -21,8 +21,8 @@
 
 import static java.util.Arrays.copyOf;
 
-import android.annotation.UnsupportedAppUsage;
 import android.app.BroadcastOptions;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -32,7 +32,6 @@
 import android.os.Message;
 import android.os.Registrant;
 import android.os.RegistrantList;
-import android.os.storage.StorageManager;
 import android.preference.PreferenceManager;
 import android.telephony.CarrierConfigManager;
 import android.telephony.Rlog;
@@ -231,16 +230,17 @@
         for (int i = 0; i < mCis.length; i++) {
             mCis[i].registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, i);
 
-            // TODO remove this once modem correctly notifies the unsols
-            // If the device is unencrypted or has been decrypted or FBE is supported,
-            // i.e. not in CryptKeeper bounce, read SIM when radio state is available.
-            // Else wait for radio to be on. This is needed for the scenario when SIM is locked --
-            // to avoid overlap of CryptKeeper and SIM unlock screen.
-            if (!StorageManager.inCryptKeeperBounce()) {
-                mCis[i].registerForAvailable(this, EVENT_RADIO_AVAILABLE, i);
-            } else {
-                mCis[i].registerForOn(this, EVENT_RADIO_ON, i);
-            }
+            /*
+             * To support FDE (deprecated), additional check is needed:
+             *
+             * if (!StorageManager.inCryptKeeperBounce()) {
+             *     mCis[i].registerForAvailable(this, EVENT_RADIO_AVAILABLE, i);
+             * } else {
+             *     mCis[i].registerForOn(this, EVENT_RADIO_ON, i);
+             * }
+             */
+            mCis[i].registerForAvailable(this, EVENT_RADIO_AVAILABLE, i);
+
             mCis[i].registerForNotAvailable(this, EVENT_RADIO_UNAVAILABLE, i);
             mCis[i].registerForIccRefresh(this, EVENT_SIM_REFRESH, i);
         }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccProfile.java b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
index 376977e..e0b73a7 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccProfile.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
@@ -444,7 +444,7 @@
             int nameSource) {
         /* update display name with carrier override */
         SubscriptionInfo subInfo = subCon.getActiveSubscriptionInfo(
-                subId, mContext.getOpPackageName());
+                subId, mContext.getOpPackageName(), mContext.getFeatureId());
 
         if (subInfo == null) {
             return;
diff --git a/src/java/com/android/internal/telephony/uicc/UsimServiceTable.java b/src/java/com/android/internal/telephony/uicc/UsimServiceTable.java
index 2c103ca..281b5f2 100644
--- a/src/java/com/android/internal/telephony/uicc/UsimServiceTable.java
+++ b/src/java/com/android/internal/telephony/uicc/UsimServiceTable.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 
 
 /**
diff --git a/src/java/com/android/internal/telephony/uicc/VoiceMailConstants.java b/src/java/com/android/internal/telephony/uicc/VoiceMailConstants.java
index 0839758..792c7dc 100644
--- a/src/java/com/android/internal/telephony/uicc/VoiceMailConstants.java
+++ b/src/java/com/android/internal/telephony/uicc/VoiceMailConstants.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
-import android.annotation.UnsupportedAppUsage;
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Environment;
 import android.telephony.Rlog;
 import android.util.Xml;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java
index 7454930..6371c06 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java
@@ -55,8 +55,8 @@
 
     private class FakeContentResolver extends MockContentResolver {
         @Override
-        public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
-            super.notifyChange(uri, observer, syncToNetwork);
+        public void notifyChange(Uri uri, ContentObserver observer) {
+            super.notifyChange(uri, observer);
             logd("onChanged(uri=" + uri + ")" + observer);
             if (observer != null) {
                 observer.dispatchChange(false, uri);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java
index 59c36bb..e92298d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java
@@ -20,6 +20,7 @@
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.os.Bundle;
+import android.permission.IPermissionManager;
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.test.InstrumentationTestCase;
@@ -55,6 +56,7 @@
     private static final String CALLING_PACKAGE = "phone";
 
     @Mock private IPackageManager mPackageManager;
+    @Mock private IPermissionManager mPermissionManager;
     @Mock private TelephonyManager mTelephonyManager;
     private SettingsMockContentProvider mContentProvider;
     private MockContentResolver mContentResolver;
@@ -78,7 +80,7 @@
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_EmptyList() {
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID, new ArraySet<>(),
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID, new ArraySet<>(),
                 ASSOCIATED_APPS);
         Mockito.verifyNoMoreInteractions(mPackageManager, mTelephonyManager);
     }
@@ -93,13 +95,13 @@
         ArraySet<String> systemCarrierAppsDisabledUntilUsed = new ArraySet<>();
         systemCarrierAppsDisabledUntilUsed.add("com.example.missing.app");
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID,
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID,
                 systemCarrierAppsDisabledUntilUsed, ASSOCIATED_APPS);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppHiddenUntilInstalled(
                 Mockito.anyString(), Mockito.anyBoolean());
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
-        Mockito.verify(mPackageManager, Mockito.never())
+        Mockito.verify(mPermissionManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(Mockito.any(String[].class),
                         Mockito.anyInt());
         Mockito.verifyNoMoreInteractions(mTelephonyManager);
@@ -114,12 +116,13 @@
                         | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
                 USER_ID)).thenReturn(appInfo);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS,
+                ASSOCIATED_APPS);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppHiddenUntilInstalled(
                 Mockito.anyString(), Mockito.anyBoolean());
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
-        Mockito.verify(mPackageManager, Mockito.never())
+        Mockito.verify(mPermissionManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
         Mockito.verifyNoMoreInteractions(mTelephonyManager);
@@ -143,12 +146,13 @@
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS,
+                ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
-        Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
+        Mockito.verify(mPermissionManager).grantDefaultPermissionsToEnabledCarrierApps(
                 new String[] {appInfo.packageName}, USER_ID);
     }
 
@@ -166,12 +170,13 @@
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS,
+                ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
-        Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
+        Mockito.verify(mPermissionManager).grantDefaultPermissionsToEnabledCarrierApps(
                 new String[] {appInfo.packageName}, USER_ID);
     }
 
@@ -189,12 +194,13 @@
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS,
+                ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
-        Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
+        Mockito.verify(mPermissionManager).grantDefaultPermissionsToEnabledCarrierApps(
                 new String[] {appInfo.packageName}, USER_ID);
     }
 
@@ -213,12 +219,13 @@
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS,
+                ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
-        Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
+        Mockito.verify(mPermissionManager).grantDefaultPermissionsToEnabledCarrierApps(
                 new String[] {appInfo.packageName}, USER_ID);
     }
 
@@ -240,14 +247,15 @@
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS,
+                ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager).setSystemAppInstallState(
                 CARRIER_APP, true, USER_ID);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 ASSOCIATED_APP, true, USER_ID);
-        Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
+        Mockito.verify(mPermissionManager).grantDefaultPermissionsToEnabledCarrierApps(
                 new String[] {appInfo.packageName}, USER_ID);
     }
 
@@ -280,7 +288,8 @@
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS,
+                ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
@@ -289,7 +298,7 @@
                 CARRIER_APP, true, USER_ID);
         Mockito.verify(mPackageManager).setSystemAppInstallState(
                 ASSOCIATED_APP, true, USER_ID);
-        Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
+        Mockito.verify(mPermissionManager).grantDefaultPermissionsToEnabledCarrierApps(
                 new String[] {appInfo.packageName}, USER_ID);
     }
 
@@ -321,7 +330,8 @@
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS,
+                ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppHiddenUntilInstalled(
@@ -330,7 +340,7 @@
                 CARRIER_APP, true, USER_ID);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 ASSOCIATED_APP, true, USER_ID);
-        Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
+        Mockito.verify(mPermissionManager).grantDefaultPermissionsToEnabledCarrierApps(
                 new String[] {appInfo.packageName}, USER_ID);
     }
 
@@ -361,7 +371,8 @@
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS,
+                ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
@@ -370,7 +381,7 @@
                 CARRIER_APP, true, USER_ID);
         Mockito.verify(mPackageManager).setSystemAppInstallState(
                 ASSOCIATED_APP, true, USER_ID);
-        Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
+        Mockito.verify(mPermissionManager).grantDefaultPermissionsToEnabledCarrierApps(
                 new String[] {appInfo.packageName}, USER_ID);
     }
 
@@ -388,12 +399,13 @@
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS,
+                ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
-        Mockito.verify(mPackageManager, Mockito.never())
+        Mockito.verify(mPermissionManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
@@ -411,13 +423,13 @@
                         | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
                 USER_ID)).thenReturn(appInfo);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
-                ASSOCIATED_APPS);
+                mPermissionManager, null /* telephonyManager */, mContentResolver, USER_ID,
+                CARRIER_APPS, ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
-        Mockito.verify(mPackageManager, Mockito.never())
+        Mockito.verify(mPermissionManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
@@ -436,12 +448,13 @@
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS,
+                ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
-        Mockito.verify(mPackageManager, Mockito.never())
+        Mockito.verify(mPermissionManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
@@ -458,13 +471,13 @@
                         | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
                 USER_ID)).thenReturn(appInfo);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
-                ASSOCIATED_APPS);
+                mPermissionManager, null /* telephonyManager */, mContentResolver, USER_ID,
+                CARRIER_APPS, ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
-        Mockito.verify(mPackageManager, Mockito.never())
+        Mockito.verify(mPermissionManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
@@ -483,12 +496,13 @@
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS,
+                ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
-        Mockito.verify(mPackageManager, Mockito.never())
+        Mockito.verify(mPermissionManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
@@ -505,13 +519,13 @@
                         | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
                 USER_ID)).thenReturn(appInfo);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
-                ASSOCIATED_APPS);
+                mPermissionManager, null /* telephonyManager */, mContentResolver, USER_ID,
+                CARRIER_APPS, ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
-        Mockito.verify(mPackageManager, Mockito.never())
+        Mockito.verify(mPermissionManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
@@ -531,12 +545,13 @@
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS,
+                ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
-        Mockito.verify(mPackageManager, Mockito.never())
+        Mockito.verify(mPermissionManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
@@ -554,13 +569,13 @@
                         | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
                 USER_ID)).thenReturn(appInfo);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
-                ASSOCIATED_APPS);
+                mPermissionManager, null /* telephonyManager */, mContentResolver, USER_ID,
+                CARRIER_APPS, ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
-        Mockito.verify(mPackageManager, Mockito.never())
+        Mockito.verify(mPermissionManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
@@ -591,7 +606,8 @@
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS,
+                ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
@@ -600,7 +616,7 @@
                 CARRIER_APP, false, USER_ID);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 ASSOCIATED_APP, false, USER_ID);
-        Mockito.verify(mPackageManager, Mockito.never())
+        Mockito.verify(mPermissionManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
@@ -631,7 +647,8 @@
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS,
+                ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
@@ -640,7 +657,7 @@
                 CARRIER_APP, false, USER_ID);
         Mockito.verify(mPackageManager).setSystemAppInstallState(
                 ASSOCIATED_APP, false, USER_ID);
-        Mockito.verify(mPackageManager, Mockito.never())
+        Mockito.verify(mPermissionManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
@@ -673,7 +690,8 @@
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS,
+                ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
@@ -682,7 +700,7 @@
                 CARRIER_APP, false, USER_ID);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 Mockito.eq(ASSOCIATED_APP), Mockito.anyBoolean(), Mockito.anyInt());
-        Mockito.verify(mPackageManager, Mockito.never())
+        Mockito.verify(mPermissionManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
@@ -699,13 +717,13 @@
                         | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
                 USER_ID)).thenReturn(appInfo);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
-                ASSOCIATED_APPS);
+                mPermissionManager, null /* telephonyManager */, mContentResolver, USER_ID,
+                CARRIER_APPS, ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager).setSystemAppInstallState(
                 CARRIER_APP, false, USER_ID);
-        Mockito.verify(mPackageManager, Mockito.never())
+        Mockito.verify(mPermissionManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
@@ -727,12 +745,13 @@
         Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+                mPermissionManager, mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS,
+                ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
-        Mockito.verify(mPackageManager, Mockito.never())
+        Mockito.verify(mPermissionManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
@@ -752,13 +771,13 @@
                         | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
                 USER_ID)).thenReturn(appInfo);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
-                null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
-                ASSOCIATED_APPS);
+                mPermissionManager, null /* telephonyManager */, mContentResolver, USER_ID,
+                CARRIER_APPS, ASSOCIATED_APPS);
         Mockito.verify(mPackageManager).setSystemAppHiddenUntilInstalled(
                 CARRIER_APP, true);
         Mockito.verify(mPackageManager, Mockito.never()).setSystemAppInstallState(
                 Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
-        Mockito.verify(mPackageManager, Mockito.never())
+        Mockito.verify(mPermissionManager, Mockito.never())
                 .grantDefaultPermissionsToEnabledCarrierApps(
                         Mockito.any(String[].class), Mockito.anyInt());
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierServicesSmsFilterTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierServicesSmsFilterTest.java
index a10dc9b..afb0292 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierServicesSmsFilterTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierServicesSmsFilterTest.java
@@ -76,7 +76,6 @@
         super.setUp(getClass().getSimpleName());
         if (Looper.myLooper() == null) {
             Looper.prepare();
-            Looper.loop();
         }
         mCarrierServicesSmsFilterUT = new CarrierServicesSmsFilter(
                 mContext, mPhone, new byte[][]{SMS_PDU},
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
index 40cec03..19d1aec 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
@@ -55,10 +55,12 @@
 import android.net.Uri;
 import android.net.wifi.WifiManager;
 import android.os.BatteryManager;
+import android.os.BatteryStatsManager;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IInterface;
 import android.os.PersistableBundle;
+import android.os.PowerWhitelistManager;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.preference.PreferenceManager;
@@ -250,11 +252,15 @@
                     return mDownloadManager;
                 case Context.TELEPHONY_REGISTRY_SERVICE:
                     return mTelephonyRegistryManager;
+                case Context.BATTERY_STATS_SERVICE:
+                    return mBatteryStatsManager;
                 case Context.DISPLAY_SERVICE:
                 case Context.POWER_SERVICE:
                     // PowerManager and DisplayManager are final classes so cannot be mocked,
                     // return real services.
                     return TestApplication.getAppContext().getSystemService(name);
+                case Context.POWER_WHITELIST_MANAGER:
+                    return mPowerWhitelistManager;
                 default:
                     return null;
             }
@@ -325,6 +331,13 @@
         }
 
         @Override
+        public Intent registerReceiverForAllUsers(BroadcastReceiver receiver,
+                IntentFilter filter, String broadcastPermission, Handler scheduler) {
+            return registerReceiverAsUser(
+                    receiver, UserHandle.ALL, filter, broadcastPermission, scheduler);
+        }
+
+        @Override
         public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
                 IntentFilter filter, String broadcastPermission, Handler scheduler) {
             Intent result = null;
@@ -588,6 +601,8 @@
     private final PackageInfo mPackageInfo = mock(PackageInfo.class);
     private final TelephonyRegistryManager mTelephonyRegistryManager =
         mock(TelephonyRegistryManager.class);
+    private final BatteryStatsManager mBatteryStatsManager = mock(BatteryStatsManager.class);
+    private final PowerWhitelistManager mPowerWhitelistManager = mock(PowerWhitelistManager.class);
 
     private final ContentProvider mContentProvider = spy(new FakeContentProvider());
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java b/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java
index e6e39dd..cbc6a96 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java
@@ -22,7 +22,7 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import android.os.Bundle;
+import android.telephony.CellIdentityGsm;
 import android.telephony.CellInfo;
 import android.telephony.DataFailCause;
 import android.telephony.DisconnectCause;
@@ -30,7 +30,6 @@
 import android.telephony.PreciseDisconnectCause;
 import android.telephony.SignalStrength;
 import android.telephony.TelephonyManager;
-import android.telephony.gsm.GsmCellLocation;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.internal.telephony.PhoneInternalInterface.DataActivityState;
@@ -245,26 +244,24 @@
     @Test @SmallTest
     public void testNotifyCellLocation() throws Exception {
         // mock gsm cell location
-        GsmCellLocation mGsmCellLocation = new GsmCellLocation();
-        mGsmCellLocation.setLacAndCid(2, 3);
-        doReturn(mGsmCellLocation).when(mPhone).getCellLocation();
-        ArgumentCaptor<Bundle> cellLocationCapture =
-                ArgumentCaptor.forClass(Bundle.class);
+        CellIdentityGsm mGsmCellLocation = new CellIdentityGsm(2, 3, 0, 0, null, null, null, null);
+        doReturn(mGsmCellLocation).when(mPhone).getCellIdentity();
+        ArgumentCaptor<CellIdentityGsm> cellLocationCapture =
+                ArgumentCaptor.forClass(CellIdentityGsm.class);
 
         mDefaultPhoneNotifierUT.notifyCellLocation(mPhone, mGsmCellLocation);
         verify(mTelephonyRegistryManager).notifyCellLocation(eq(0),
                 cellLocationCapture.capture());
-        assertEquals(2, cellLocationCapture.getValue().getInt("lac"));
-        assertEquals(3, cellLocationCapture.getValue().getInt("cid"));
-        assertEquals(-1, cellLocationCapture.getValue().getInt("psc"));
+        assertEquals(2, cellLocationCapture.getValue().asCellLocation().getLac());
+        assertEquals(3, cellLocationCapture.getValue().asCellLocation().getCid());
+        assertEquals(-1, cellLocationCapture.getValue().asCellLocation().getPsc());
 
         doReturn(1).when(mPhone).getSubId();
-        mGsmCellLocation.setPsc(5);
         mDefaultPhoneNotifierUT.notifyCellLocation(mPhone, mGsmCellLocation);
         verify(mTelephonyRegistryManager).notifyCellLocation(eq(1),
                 cellLocationCapture.capture());
-        assertEquals(2, cellLocationCapture.getValue().getInt("lac"));
-        assertEquals(3, cellLocationCapture.getValue().getInt("cid"));
-        assertEquals(5, cellLocationCapture.getValue().getInt("psc"));
+        assertEquals(2, cellLocationCapture.getValue().asCellLocation().getLac());
+        assertEquals(3, cellLocationCapture.getValue().asCellLocation().getCid());
+        assertEquals(-1, cellLocationCapture.getValue().asCellLocation().getPsc());
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
index 4f40ec8..178f677 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
@@ -55,13 +55,13 @@
 import android.preference.PreferenceManager;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.CarrierConfigManager;
-import android.telephony.CellLocation;
+import android.telephony.CellIdentity;
+import android.telephony.CellIdentityCdma;
+import android.telephony.CellIdentityGsm;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
-import android.telephony.cdma.CdmaCellLocation;
-import android.telephony.gsm.GsmCellLocation;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -375,20 +375,20 @@
     @SmallTest
     public void testGetCellLocation() {
         // GSM
-        CellLocation cellLocation = new GsmCellLocation();
+        CellIdentity cellLocation = new CellIdentityGsm();
         WorkSource workSource = new WorkSource(Process.myUid(),
             mContext.getPackageName());
-        doReturn(cellLocation).when(mSST).getCellLocation();
-        assertEquals(cellLocation, mPhoneUT.getCellLocation());
+        doReturn(cellLocation).when(mSST).getCellIdentity();
+        assertEquals(cellLocation, mPhoneUT.getCellIdentity());
 
         // Switch to CDMA
         switchToCdma();
 
-        CdmaCellLocation cdmaCellLocation = new CdmaCellLocation();
-        doReturn(cdmaCellLocation).when(mSST).getCellLocation();
+        CellIdentityCdma cdmaCellLocation = new CellIdentityCdma();
+        doReturn(cdmaCellLocation).when(mSST).getCellIdentity();
 
-        CdmaCellLocation actualCellLocation =
-                (CdmaCellLocation) mPhoneUT.getCellLocation();
+        CellIdentityCdma actualCellLocation =
+                (CellIdentityCdma) mPhoneUT.getCellIdentity();
 
         assertEquals(actualCellLocation, cdmaCellLocation);
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ModelInterpreter.java b/tests/telephonytests/src/com/android/internal/telephony/ModelInterpreter.java
index 2a046d9..7499a7a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ModelInterpreter.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ModelInterpreter.java
@@ -16,12 +16,11 @@
 
 package com.android.internal.telephony.test;
 
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.telephony.Rlog;
 
-import dalvik.annotation.compat.UnsupportedAppUsage;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
index 194b377..d6db30e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
@@ -30,6 +30,7 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
@@ -121,7 +122,7 @@
         doReturn(2).when(mPhoneMock2).getSubId();
         List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1, mSubInfo2);
         doReturn(infoList).when(mSubControllerMock)
-                .getActiveSubscriptionInfoList(anyString());
+                .getActiveSubscriptionInfoList(anyString(), nullable(String.class));
         doReturn(new int[]{1, 2}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         mPhones = new Phone[] {mPhoneMock1, mPhoneMock2};
@@ -163,7 +164,8 @@
         doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(2);
         doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mPhoneMock2).getSubId();
         List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString());
+        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+                nullable(String.class));
         doReturn(new int[]{1}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         // Mark subscription ready as false. The below sub info change should be ignored.
@@ -200,7 +202,8 @@
         doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(2);
         doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mPhoneMock2).getSubId();
         List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString());
+        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+                nullable(String.class));
         doReturn(new int[]{1}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
@@ -215,7 +218,8 @@
         doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(1);
         doReturn(2).when(mPhoneMock1).getSubId();
         infoList = Arrays.asList(mSubInfo2);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString());
+        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+                nullable(String.class));
         doReturn(new int[]{2}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
@@ -238,7 +242,8 @@
         doReturn(SubscriptionManager.INVALID_PHONE_INDEX).when(mSubControllerMock).getPhoneId(2);
         doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mPhoneMock2).getSubId();
         List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString());
+        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+                nullable(String.class));
         doReturn(new int[]{1}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
@@ -258,7 +263,8 @@
         doReturn(1).when(mSubControllerMock).getPhoneId(2);
         doReturn(2).when(mPhoneMock2).getSubId();
         infoList = Arrays.asList(mSubInfo1, mSubInfo2);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString());
+        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+                nullable(String.class));
         doReturn(new int[]{1, 2}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
@@ -280,7 +286,8 @@
         doReturn(1).when(mSubControllerMock).getPhoneId(3);
         doReturn(3).when(mPhoneMock2).getSubId();
         infoList = Arrays.asList(mSubInfo1, mSubInfo3);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString());
+        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+                nullable(String.class));
         doReturn(new int[]{1, 3}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
@@ -325,7 +332,8 @@
         clearInvocations(mSubControllerMock);
         doReturn(false).when(mSubControllerMock).isActiveSubId(1);
         List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo2);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString());
+        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+                nullable(String.class));
         doReturn(new int[]{2}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
         mMultiSimSettingControllerUT.notifyCarrierConfigChanged(
@@ -361,7 +369,7 @@
         doReturn(mGroupUuid1).when(mSubControllerMock).getGroupUuid(3);
         doReturn(mGroupUuid1).when(mSubControllerMock).getGroupUuid(4);
         doReturn(Arrays.asList(mSubInfo2, mSubInfo3, mSubInfo4)).when(mSubControllerMock)
-                .getSubscriptionsInGroup(any(), anyString());
+                .getSubscriptionsInGroup(any(), anyString(), nullable(String.class));
         mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1);
         processAllMessages();
         // This should result in setting sync.
@@ -398,7 +406,8 @@
         doReturn(2).when(mSubControllerMock).getDefaultSmsSubId();
         doReturn(1).when(mSubControllerMock).getDefaultVoiceSubId();
         List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1, mSubInfo3);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString());
+        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+                nullable(String.class));
         doReturn(new int[]{1, 3}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         mMultiSimSettingControllerUT.notifySubscriptionInfoChanged();
@@ -475,7 +484,7 @@
         GlobalSettingsHelper.setBoolean(mContext, Settings.Global.MOBILE_DATA, 2, false);
         // Group sub 1 with sub 2.
         doReturn(Arrays.asList(mSubInfo1, mSubInfo2)).when(mSubControllerMock)
-                .getSubscriptionsInGroup(any(), anyString());
+                .getSubscriptionsInGroup(any(), anyString(), nullable(String.class));
         mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1);
         processAllMessages();
         // This should result in setting sync.
@@ -515,7 +524,7 @@
         // Create subscription grouping.
         replaceInstance(SubscriptionInfo.class, "mGroupUUID", mSubInfo1, mGroupUuid1);
         doReturn(Arrays.asList(mSubInfo1, mSubInfo2)).when(mSubControllerMock)
-                .getSubscriptionsInGroup(any(), anyString());
+                .getSubscriptionsInGroup(any(), anyString(), nullable(String.class));
         mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1);
         processAllMessages();
         // This should result in setting sync.
@@ -556,7 +565,8 @@
         doReturn(1).when(mSubControllerMock).getPhoneId(3);
         doReturn(3).when(mPhoneMock2).getSubId();
         List<SubscriptionInfo> infoList = Arrays.asList(mSubInfo1, mSubInfo3);
-        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString());
+        doReturn(infoList).when(mSubControllerMock).getActiveSubscriptionInfoList(anyString(),
+                nullable(String.class));
         doReturn(new int[]{1, 3}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
 
         // Nothing should happen until carrier config change is notified on sub 3.
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneSubInfoControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneSubInfoControllerTest.java
index 66d676c..b0ace19 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneSubInfoControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneSubInfoControllerTest.java
@@ -22,6 +22,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.anyString;
@@ -39,6 +40,8 @@
 import org.mockito.Mock;
 
 public class PhoneSubInfoControllerTest extends TelephonyTest {
+    private static final String FEATURE_ID = "myfeatureId";
+
     private PhoneSubInfoController mPhoneSubInfoControllerUT;
     private AppOpsManager mAppOsMgr;
 
@@ -54,8 +57,8 @@
         doReturn(1).when(mSubscriptionController).getPhoneId(eq(1));
         doReturn(2).when(mTelephonyManager).getPhoneCount();
         doReturn(2).when(mTelephonyManager).getActiveModemCount();
-        doReturn(true).when(mSubscriptionController).isActiveSubId(0, TAG);
-        doReturn(true).when(mSubscriptionController).isActiveSubId(1, TAG);
+        doReturn(true).when(mSubscriptionController).isActiveSubId(0, TAG, FEATURE_ID);
+        doReturn(true).when(mSubscriptionController).isActiveSubId(1, TAG, FEATURE_ID);
         doReturn(new int[]{0, 1}).when(mSubscriptionManager)
                 .getActiveSubscriptionIdList(anyBoolean());
 
@@ -75,7 +78,8 @@
         // ensure this appop does not interfere with any of the tests always return its default
         // value.
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOpNoThrow(
-                eq(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
     }
 
     @After
@@ -89,8 +93,10 @@
         doReturn("353626073736741").when(mPhone).getDeviceId();
         doReturn("353626073736742").when(mSecondPhone).getDeviceId();
 
-        assertEquals("353626073736741", mPhoneSubInfoControllerUT.getDeviceIdForPhone(0, TAG));
-        assertEquals("353626073736742", mPhoneSubInfoControllerUT.getDeviceIdForPhone(1, TAG));
+        assertEquals("353626073736741",
+                mPhoneSubInfoControllerUT.getDeviceIdForPhone(0, TAG, FEATURE_ID));
+        assertEquals("353626073736742",
+                mPhoneSubInfoControllerUT.getDeviceIdForPhone(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -105,7 +111,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getDeviceIdForPhone(0, TAG);
+            mPhoneSubInfoControllerUT.getDeviceIdForPhone(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -113,7 +119,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getDeviceIdForPhone(1, TAG);
+            mPhoneSubInfoControllerUT.getDeviceIdForPhone(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -123,9 +129,10 @@
         //case 2: no READ_PRIVILEGED_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
         try {
-            mPhoneSubInfoControllerUT.getDeviceIdForPhone(0, TAG);
+            mPhoneSubInfoControllerUT.getDeviceIdForPhone(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -133,7 +140,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getDeviceIdForPhone(1, TAG);
+            mPhoneSubInfoControllerUT.getDeviceIdForPhone(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -144,9 +151,10 @@
         // The READ_PRIVILEGED_PHONE_STATE permission is now required to get device identifiers.
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
         try {
-            mPhoneSubInfoControllerUT.getDeviceIdForPhone(0, TAG);
+            mPhoneSubInfoControllerUT.getDeviceIdForPhone(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -154,7 +162,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getDeviceIdForPhone(1, TAG);
+            mPhoneSubInfoControllerUT.getDeviceIdForPhone(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -166,10 +174,12 @@
     @SmallTest
     public void testGetNai() {
         doReturn("aaa@example.com").when(mPhone).getNai();
-        assertEquals("aaa@example.com", mPhoneSubInfoControllerUT.getNaiForSubscriber(0, TAG));
+        assertEquals("aaa@example.com",
+                mPhoneSubInfoControllerUT.getNaiForSubscriber(0, TAG, FEATURE_ID));
 
         doReturn("bbb@example.com").when(mSecondPhone).getNai();
-        assertEquals("bbb@example.com", mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG));
+        assertEquals("bbb@example.com",
+                mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -184,7 +194,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getNaiForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getNaiForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -192,7 +202,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -202,9 +212,10 @@
         //case 2: no READ_PRIVILEGED_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
         try {
-            mPhoneSubInfoControllerUT.getNaiForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getNaiForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -212,7 +223,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -222,9 +233,10 @@
         //case 3: no READ_PRIVILEGED_PHONE_STATE
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
         try {
-            mPhoneSubInfoControllerUT.getNaiForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getNaiForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -232,7 +244,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -244,10 +256,12 @@
     @SmallTest
     public void testGetImei() {
         doReturn("990000862471854").when(mPhone).getImei();
-        assertEquals("990000862471854", mPhoneSubInfoControllerUT.getImeiForSubscriber(0, TAG));
+        assertEquals("990000862471854",
+                mPhoneSubInfoControllerUT.getImeiForSubscriber(0, TAG, FEATURE_ID));
 
         doReturn("990000862471855").when(mSecondPhone).getImei();
-        assertEquals("990000862471855", mPhoneSubInfoControllerUT.getImeiForSubscriber(1, TAG));
+        assertEquals("990000862471855",
+                mPhoneSubInfoControllerUT.getImeiForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -262,7 +276,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getImeiForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getImeiForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -270,7 +284,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getImeiForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getImeiForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -280,9 +294,10 @@
         //case 2: no READ_PRIVILEGED_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
         try {
-            mPhoneSubInfoControllerUT.getImeiForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getImeiForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -290,7 +305,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getImeiForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getImeiForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -300,9 +315,10 @@
         //case 3: no READ_PRIVILEGED_PHONE_STATE
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
         try {
-            mPhoneSubInfoControllerUT.getImeiForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getImeiForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -310,7 +326,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getImeiForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getImeiForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -322,10 +338,10 @@
     @SmallTest
     public void testGetDeviceSvn() {
         doReturn("00").when(mPhone).getDeviceSvn();
-        assertEquals("00", mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(0, TAG));
+        assertEquals("00", mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(0, TAG, FEATURE_ID));
 
         doReturn("01").when(mSecondPhone).getDeviceSvn();
-        assertEquals("01", mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(1, TAG));
+        assertEquals("01", mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -337,7 +353,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(0, TAG);
+            mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -345,7 +361,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(1, TAG);
+            mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -355,17 +371,19 @@
         //case 2: no READ_PRIVILEGED_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
 
-        assertNull(mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(0, TAG));
-        assertNull(mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(1, TAG));
+        assertNull(mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(0, TAG, FEATURE_ID));
+        assertNull(mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(1, TAG, FEATURE_ID));
 
         //case 3: no READ_PRIVILEGED_PHONE_STATE
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
-        assertEquals("00", mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(0, TAG));
-        assertEquals("01", mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(1, TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
+        assertEquals("00", mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(0, TAG, FEATURE_ID));
+        assertEquals("01", mPhoneSubInfoControllerUT.getDeviceSvnUsingSubId(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -374,18 +392,18 @@
         //IMSI
         doReturn("310260426283121").when(mPhone).getSubscriberId();
         assertEquals("310260426283121", mPhoneSubInfoControllerUT
-                .getSubscriberIdForSubscriber(0, TAG));
+                .getSubscriberIdForSubscriber(0, TAG, FEATURE_ID));
 
         doReturn("310260426283122").when(mSecondPhone).getSubscriberId();
         assertEquals("310260426283122", mPhoneSubInfoControllerUT
-                .getSubscriberIdForSubscriber(1, TAG));
+                .getSubscriberIdForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
     @SmallTest
     public void testGetSubscriberIdWithInactiveSubId() {
         //IMSI
-        assertNull(mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(2, TAG));
+        assertNull(mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(2, TAG, FEATURE_ID));
     }
 
     @Test
@@ -400,7 +418,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -408,7 +426,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -418,9 +436,10 @@
         //case 2: no READ_PRIVILEGED_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
         try {
-            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -428,7 +447,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -439,9 +458,10 @@
         // The READ_PRIVILEGED_PHONE_STATE permission is now required to get device identifiers.
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
         try {
-            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -449,7 +469,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getSubscriberIdForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -463,11 +483,11 @@
         //IccId
         doReturn("8991101200003204510").when(mPhone).getIccSerialNumber();
         assertEquals("8991101200003204510", mPhoneSubInfoControllerUT
-                .getIccSerialNumberForSubscriber(0, TAG));
+                .getIccSerialNumberForSubscriber(0, TAG, FEATURE_ID));
 
         doReturn("8991101200003204511").when(mSecondPhone).getIccSerialNumber();
         assertEquals("8991101200003204511", mPhoneSubInfoControllerUT
-                .getIccSerialNumberForSubscriber(1, TAG));
+                .getIccSerialNumberForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -482,7 +502,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -490,7 +510,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -500,9 +520,10 @@
         //case 2: no READ_PRIVILEGED_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
         try {
-            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -510,7 +531,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -520,9 +541,10 @@
         //case 3: no READ_PRIVILEGED_PHONE_STATE
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
         try {
-            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -530,7 +552,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getIccSerialNumberForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -542,10 +564,12 @@
     @SmallTest
     public void testLine1Number() {
         doReturn("+18051234567").when(mPhone).getLine1Number();
-        assertEquals("+18051234567", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG));
+        assertEquals("+18051234567",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG, FEATURE_ID));
 
         doReturn("+18052345678").when(mSecondPhone).getLine1Number();
-        assertEquals("+18052345678", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG));
+        assertEquals("+18052345678",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -558,20 +582,23 @@
         READ_SMS and no OP_WRITE_SMS & OP_READ_SMS from appOsMgr */
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_SMS), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_SMS), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_WRITE_SMS), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_WRITE_SMS), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
         try {
-            mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
         }
 
         try {
-            mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -579,42 +606,55 @@
 
         /* case 2: only enable WRITE_SMS permission */
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_WRITE_SMS), anyInt(), eq(TAG));
-        assertEquals("+18051234567", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG));
-        assertEquals("+18052345678", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG));
+                eq(AppOpsManager.OPSTR_WRITE_SMS), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
+        assertEquals("+18051234567",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG, FEATURE_ID));
+        assertEquals("+18052345678",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG, FEATURE_ID));
 
         /* case 3: only enable READ_PRIVILEGED_PHONE_STATE */
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_WRITE_SMS), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_WRITE_SMS), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
         mContextFixture.addCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE);
-        assertEquals("+18051234567", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG));
-        assertEquals("+18052345678", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG));
+        assertEquals("+18051234567",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG, FEATURE_ID));
+        assertEquals("+18052345678",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG, FEATURE_ID));
 
         /* case 4: only enable READ_PHONE_STATE permission */
         mContextFixture.removeCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE);
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
-        assertNull(mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG));
-        assertNull(mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG));
+        assertNull(mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG, FEATURE_ID));
+        assertNull(mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG, FEATURE_ID));
 
         /* case 5: enable appOsMgr READ_PHONE_PERMISSION & READ_PHONE_STATE */
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
-        assertEquals("+18051234567", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG));
-        assertEquals("+18052345678", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
+        assertEquals("+18051234567",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG, FEATURE_ID));
+        assertEquals("+18052345678",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG, FEATURE_ID));
 
         /* case 6: only enable READ_SMS */
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
         mContextFixture.removeCallingOrSelfPermission(READ_PHONE_STATE);
         mContextFixture.addCallingOrSelfPermission(READ_SMS);
-        assertNull(mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG));
-        assertNull(mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG));
+        assertNull(mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG, FEATURE_ID));
+        assertNull(mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG, FEATURE_ID));
 
         /* case 7: enable READ_SMS and OP_READ_SMS */
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_SMS), anyInt(), eq(TAG));
-        assertEquals("+18051234567", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG));
-        assertEquals("+18052345678", mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG));
+                eq(AppOpsManager.OPSTR_READ_SMS), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
+        assertEquals("+18051234567",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(0, TAG, FEATURE_ID));
+        assertEquals("+18052345678",
+                mPhoneSubInfoControllerUT.getLine1NumberForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -622,11 +662,11 @@
     public void testLine1AlphaTag() {
         doReturn("LINE1_SIM_0").when(mPhone).getLine1AlphaTag();
         assertEquals("LINE1_SIM_0", mPhoneSubInfoControllerUT
-                .getLine1AlphaTagForSubscriber(0, TAG));
+                .getLine1AlphaTagForSubscriber(0, TAG, FEATURE_ID));
 
         doReturn("LINE1_SIM_1").when(mSecondPhone).getLine1AlphaTag();
         assertEquals("LINE1_SIM_1", mPhoneSubInfoControllerUT
-                .getLine1AlphaTagForSubscriber(1, TAG));
+                .getLine1AlphaTagForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -638,7 +678,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getLine1AlphaTagForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getLine1AlphaTagForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -646,7 +686,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getLine1AlphaTagForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getLine1AlphaTagForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -656,29 +696,33 @@
         //case 2: no READ_PRIVILEGED_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
 
-        assertNull(mPhoneSubInfoControllerUT.getLine1AlphaTagForSubscriber(0, TAG));
-        assertNull(mPhoneSubInfoControllerUT.getLine1AlphaTagForSubscriber(1, TAG));
+        assertNull(mPhoneSubInfoControllerUT.getLine1AlphaTagForSubscriber(0, TAG, FEATURE_ID));
+        assertNull(mPhoneSubInfoControllerUT.getLine1AlphaTagForSubscriber(1, TAG, FEATURE_ID));
 
         //case 3: no READ_PRIVILEGED_PHONE_STATE
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
         assertEquals("LINE1_SIM_0", mPhoneSubInfoControllerUT
-                .getLine1AlphaTagForSubscriber(0, TAG));
+                .getLine1AlphaTagForSubscriber(0, TAG, FEATURE_ID));
         assertEquals("LINE1_SIM_1", mPhoneSubInfoControllerUT
-                .getLine1AlphaTagForSubscriber(1, TAG));
+                .getLine1AlphaTagForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
     @SmallTest
     public void testMsisdn() {
         doReturn("+18051234567").when(mPhone).getMsisdn();
-        assertEquals("+18051234567", mPhoneSubInfoControllerUT.getMsisdnForSubscriber(0, TAG));
+        assertEquals("+18051234567",
+                mPhoneSubInfoControllerUT.getMsisdnForSubscriber(0, TAG, FEATURE_ID));
 
         doReturn("+18052345678").when(mSecondPhone).getMsisdn();
-        assertEquals("+18052345678", mPhoneSubInfoControllerUT.getMsisdnForSubscriber(1, TAG));
+        assertEquals("+18052345678",
+                mPhoneSubInfoControllerUT.getMsisdnForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -690,7 +734,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getMsisdnForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getMsisdnForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -698,7 +742,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getMsisdnForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getMsisdnForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -708,17 +752,21 @@
         //case 2: no READ_PRIVILEGED_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
 
-        assertNull(mPhoneSubInfoControllerUT.getMsisdnForSubscriber(0, TAG));
-        assertNull(mPhoneSubInfoControllerUT.getMsisdnForSubscriber(1, TAG));
+        assertNull(mPhoneSubInfoControllerUT.getMsisdnForSubscriber(0, TAG, FEATURE_ID));
+        assertNull(mPhoneSubInfoControllerUT.getMsisdnForSubscriber(1, TAG, FEATURE_ID));
 
         //case 3: no READ_PRIVILEGED_PHONE_STATE
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
-        assertEquals("+18051234567", mPhoneSubInfoControllerUT.getMsisdnForSubscriber(0, TAG));
-        assertEquals("+18052345678", mPhoneSubInfoControllerUT.getMsisdnForSubscriber(1, TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
+        assertEquals("+18051234567",
+                mPhoneSubInfoControllerUT.getMsisdnForSubscriber(0, TAG, FEATURE_ID));
+        assertEquals("+18052345678",
+                mPhoneSubInfoControllerUT.getMsisdnForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -726,11 +774,11 @@
     public void testGetVoiceMailNumber() {
         doReturn("+18051234567").when(mPhone).getVoiceMailNumber();
         assertEquals("+18051234567", mPhoneSubInfoControllerUT
-                .getVoiceMailNumberForSubscriber(0, TAG));
+                .getVoiceMailNumberForSubscriber(0, TAG, FEATURE_ID));
 
         doReturn("+18052345678").when(mSecondPhone).getVoiceMailNumber();
         assertEquals("+18052345678", mPhoneSubInfoControllerUT
-                .getVoiceMailNumberForSubscriber(1, TAG));
+                .getVoiceMailNumberForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -742,7 +790,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getVoiceMailNumberForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getVoiceMailNumberForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -750,7 +798,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getVoiceMailNumberForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getVoiceMailNumberForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -760,19 +808,21 @@
         //case 2: no READ_PRIVILEGED_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
 
-        assertNull(mPhoneSubInfoControllerUT.getVoiceMailNumberForSubscriber(0, TAG));
-        assertNull(mPhoneSubInfoControllerUT.getVoiceMailNumberForSubscriber(1, TAG));
+        assertNull(mPhoneSubInfoControllerUT.getVoiceMailNumberForSubscriber(0, TAG, FEATURE_ID));
+        assertNull(mPhoneSubInfoControllerUT.getVoiceMailNumberForSubscriber(1, TAG, FEATURE_ID));
 
         //case 3: no READ_PRIVILEGED_PHONE_STATE
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
         assertEquals("+18051234567", mPhoneSubInfoControllerUT
-                .getVoiceMailNumberForSubscriber(0, TAG));
+                .getVoiceMailNumberForSubscriber(0, TAG, FEATURE_ID));
         assertEquals("+18052345678", mPhoneSubInfoControllerUT
-                .getVoiceMailNumberForSubscriber(1, TAG));
+                .getVoiceMailNumberForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -780,11 +830,11 @@
     public void testGetVoiceMailAlphaTag() {
         doReturn("VM_SIM_0").when(mPhone).getVoiceMailAlphaTag();
         assertEquals("VM_SIM_0", mPhoneSubInfoControllerUT
-                .getVoiceMailAlphaTagForSubscriber(0, TAG));
+                .getVoiceMailAlphaTagForSubscriber(0, TAG, FEATURE_ID));
 
         doReturn("VM_SIM_1").when(mSecondPhone).getVoiceMailAlphaTag();
         assertEquals("VM_SIM_1", mPhoneSubInfoControllerUT
-                .getVoiceMailAlphaTagForSubscriber(1, TAG));
+                .getVoiceMailAlphaTagForSubscriber(1, TAG, FEATURE_ID));
     }
 
     @Test
@@ -796,7 +846,7 @@
         //case 1: no READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
         try {
-            mPhoneSubInfoControllerUT.getVoiceMailAlphaTagForSubscriber(0, TAG);
+            mPhoneSubInfoControllerUT.getVoiceMailAlphaTagForSubscriber(0, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -804,7 +854,7 @@
         }
 
         try {
-            mPhoneSubInfoControllerUT.getVoiceMailAlphaTagForSubscriber(1, TAG);
+            mPhoneSubInfoControllerUT.getVoiceMailAlphaTagForSubscriber(1, TAG, FEATURE_ID);
             Assert.fail("expected Security Exception Thrown");
         } catch (Exception ex) {
             assertTrue(ex instanceof SecurityException);
@@ -814,18 +864,20 @@
         //case 2: no READ_PRIVILEGED_PHONE_STATE & appOsMgr READ_PHONE_PERMISSION
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ERRORED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
 
-        assertNull(mPhoneSubInfoControllerUT.getVoiceMailAlphaTagForSubscriber(0, TAG));
-        assertNull(mPhoneSubInfoControllerUT.getVoiceMailAlphaTagForSubscriber(1, TAG));
+        assertNull(mPhoneSubInfoControllerUT.getVoiceMailAlphaTagForSubscriber(0, TAG, FEATURE_ID));
+        assertNull(mPhoneSubInfoControllerUT.getVoiceMailAlphaTagForSubscriber(1, TAG, FEATURE_ID));
 
         //case 3: no READ_PRIVILEGED_PHONE_STATE
         mContextFixture.addCallingOrSelfPermission(READ_PHONE_STATE);
         doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOsMgr).noteOp(
-                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG));
+                eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), eq(TAG), eq(FEATURE_ID),
+                nullable(String.class));
         assertEquals("VM_SIM_0", mPhoneSubInfoControllerUT
-                .getVoiceMailAlphaTagForSubscriber(0, TAG));
+                .getVoiceMailAlphaTagForSubscriber(0, TAG, FEATURE_ID));
         assertEquals("VM_SIM_1", mPhoneSubInfoControllerUT
-                .getVoiceMailAlphaTagForSubscriber(1, TAG));
+                .getVoiceMailAlphaTagForSubscriber(1, TAG, FEATURE_ID));
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
index 0408253..8068ca9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
@@ -56,7 +56,6 @@
 import android.os.Messenger;
 import android.telephony.PhoneCapability;
 import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyRegistryManager;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -368,7 +367,6 @@
         assertFalse("data allowed", mDataAllowed[1]);
 
         addInternetNetworkRequest(null, 0);
-
         // should be no change
         assertTrue("data not allowed", mDataAllowed[0]);
         assertFalse("data allowed", mDataAllowed[1]);
@@ -483,14 +481,14 @@
         doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
         initialize();
 
+        // Mark sub 2 as opportunistic.
+        doReturn(true).when(mSubscriptionController).isOpportunistic(2);
         // Phone 0 has sub 1, phone 1 has sub 2.
         // Sub 1 is default data sub.
         // Both are active subscriptions are active sub, as they are in both active slots.
         setSlotIndexToSubId(0, 1);
         setSlotIndexToSubId(1, 2);
         setDefaultDataSubId(1);
-        // Mark sub 2 as opportunistic.
-        doReturn(true).when(mSubscriptionController).isOpportunistic(2);
 
         // Phone 0 (sub 1) should be activated as it has default data sub.
         assertEquals(0, mPhoneSwitcher.getPreferredDataPhoneId());
@@ -649,6 +647,7 @@
         clearInvocations(mTelephonyRegistryManager);
 
         // override the phone ID in prep for emergency call
+
         mPhoneSwitcher.overrideDefaultDataForEmergency(1, 1, mFuturePhone);
         sendPreferredDataSuccessResult(1);
         processAllMessages();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index 36850a7..2550621 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -853,7 +853,7 @@
 
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
         WorkSource workSource = new WorkSource(Process.myUid(), mContext.getPackageName());
-        GsmCellLocation cl = (GsmCellLocation) sst.getCellLocation();
+        GsmCellLocation cl = (GsmCellLocation) sst.getCellIdentity().asCellLocation();
         assertEquals(2, cl.getLac());
         assertEquals(3, cl.getCid());
     }
@@ -877,7 +877,7 @@
 
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
         WorkSource workSource = new WorkSource(Process.myUid(), mContext.getPackageName());
-        CdmaCellLocation cl = (CdmaCellLocation) sst.getCellLocation();
+        CdmaCellLocation cl = (CdmaCellLocation) sst.getCellIdentity().asCellLocation();
         assertEquals(5, cl.getBaseStationLatitude());
         assertEquals(4, cl.getBaseStationLongitude());
     }
@@ -1509,7 +1509,7 @@
         doReturn(subId).when(mSubInfo).getSubscriptionId();
 
         doReturn(mSubInfo).when(mSubscriptionController).getActiveSubscriptionInfo(
-                anyInt(), anyString());
+                anyInt(), anyString(), nullable(String.class));
 
         final NotificationManager nm = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -1541,7 +1541,7 @@
         sst.mSubId = subId;
         doReturn(subId).when(mSubInfo).getSubscriptionId();
         doReturn(mSubInfo).when(mSubscriptionController)
-                .getActiveSubscriptionInfo(anyInt(), anyString());
+                .getActiveSubscriptionInfo(anyInt(), anyString(), nullable(String.class));
 
         final NotificationManager nm = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -1574,7 +1574,7 @@
         sst.mSubId = subId;
         doReturn(subId).when(mSubInfo).getSubscriptionId();
         doReturn(mSubInfo).when(mSubscriptionController)
-                .getActiveSubscriptionInfo(anyInt(), anyString());
+                .getActiveSubscriptionInfo(anyInt(), anyString(), nullable(String.class));
 
         final NotificationManager nm = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -1606,7 +1606,7 @@
         sst.mSubId = subId;
         doReturn(subId).when(mSubInfo).getSubscriptionId();
         doReturn(mSubInfo).when(mSubscriptionController)
-                .getActiveSubscriptionInfo(anyInt(), anyString());
+                .getActiveSubscriptionInfo(anyInt(), anyString(), nullable(String.class));
 
         final NotificationManager nm = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
index 009f71c..e6f5f63 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.test;
 
+import android.compat.annotation.UnsupportedAppUsage;
 import android.hardware.radio.V1_0.DataRegStateResult;
 import android.hardware.radio.V1_0.SetupDataCallResult;
 import android.hardware.radio.V1_0.VoiceRegStateResult;
@@ -71,8 +72,6 @@
 import com.android.internal.telephony.uicc.IccIoResult;
 import com.android.internal.telephony.uicc.IccSlotStatus;
 
-import dalvik.annotation.compat.UnsupportedAppUsage;
-
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -182,9 +181,10 @@
         mPin2Code = DEFAULT_SIM_PIN2_CODE;
     }
 
-    public void dispose() {
+    public void dispose() throws Exception {
         if (mHandlerThread != null) {
             mHandlerThread.quit();
+            mHandlerThread.join();
         }
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java
index 93077e3..7e82719 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.test;
 
+import android.compat.annotation.UnsupportedAppUsage;
 import android.net.KeepalivePacketData;
 import android.net.LinkProperties;
 import android.os.Handler;
@@ -33,8 +34,6 @@
 import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
 
-import dalvik.annotation.compat.UnsupportedAppUsage;
-
 public class SimulatedCommandsVerifier implements CommandsInterface {
     private static SimulatedCommandsVerifier sInstance;
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimulatedGsmCallState.java b/tests/telephonytests/src/com/android/internal/telephony/SimulatedGsmCallState.java
index 72e2d93..6d4f385 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SimulatedGsmCallState.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SimulatedGsmCallState.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.test;
 
+import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -25,8 +26,6 @@
 import com.android.internal.telephony.ATParseEx;
 import com.android.internal.telephony.DriverCall;
 
-import dalvik.annotation.compat.UnsupportedAppUsage;
-
 import java.util.ArrayList;
 import java.util.List;
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SmsPermissionsTest.java b/tests/telephonytests/src/com/android/internal/telephony/SmsPermissionsTest.java
index e427574..dd79f69 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SmsPermissionsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SmsPermissionsTest.java
@@ -39,7 +39,7 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-public class SmsPermissionsTest {
+public class SmsPermissionsTest extends TelephonyTest {
     private static final String PACKAGE = "com.example.package";
     private static final String MESSAGE = "msg";
 
@@ -59,6 +59,8 @@
 
     @Before
     public void setUp() throws Exception {
+        super.setUp("SmsPermissionsTest");
+
         MockitoAnnotations.initMocks(this);
         mHandlerThread = new HandlerThread("IccSmsInterfaceManagerTest");
         mHandlerThread.start();
@@ -89,6 +91,8 @@
     @After
     public void tearDown() throws Exception {
         mHandlerThread.quit();
+        mHandlerThread.join();
+        super.tearDown();
     }
 
     @Test
@@ -196,6 +200,8 @@
 
     @Test
     public void testCheckCallingOrSelfCanGetSmscAddressPermissions_noPermissions() {
+        Mockito.when(mMockContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(
+                mTelephonyManager);
         Mockito.when(mMockContext.checkCallingOrSelfPermission(
                     Manifest.permission.READ_PRIVILEGED_PHONE_STATE))
                 .thenReturn(PERMISSION_DENIED);
@@ -221,9 +227,10 @@
 
     @Test
     public void testCheckCallingOrSelfCanSetSmscAddressPermissions_noPermissions() {
+        Mockito.when(mMockContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(
+                mTelephonyManager);
         Mockito.when(mMockContext.checkCallingOrSelfPermission(
-                    Manifest.permission.MODIFY_PHONE_STATE))
-                .thenReturn(PERMISSION_DENIED);
+                Manifest.permission.MODIFY_PHONE_STATE)).thenReturn(PERMISSION_DENIED);
         assertFalse(mSmsPermissionsTest.checkCallingOrSelfCanSetSmscAddress(PACKAGE, MESSAGE));
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
index 899ffc8..018ae1d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
@@ -66,6 +66,7 @@
     private static final int SINGLE_SIM = 1;
     private static final int DUAL_SIM = 2;
     private String mCallingPackage;
+    private String mCallingFeature;
     private SubscriptionController mSubscriptionControllerUT;
     private MockContentResolver mMockContentResolver;
     private FakeTelephonyProvider mFakeTelephonyProvider;
@@ -95,6 +96,7 @@
 
         mSubscriptionControllerUT = SubscriptionController.init(mContext);
         mCallingPackage = mContext.getOpPackageName();
+        mCallingFeature = mContext.getFeatureId();
 
         doReturn(1).when(mProxyController).getMaxRafSupported();
         mContextFixture.putIntArrayResource(com.android.internal.R.array.sim_colors, new int[]{5});
@@ -129,18 +131,20 @@
     @Test @SmallTest
     public void testInsertSim() {
         //verify there is no sim inserted in the SubscriptionManager
-        assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage));
+        assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage,
+                mCallingFeature));
 
         int slotID = 0;
         //insert one Subscription Info
         mSubscriptionControllerUT.addSubInfoRecord("test", slotID);
 
         //verify there is one sim
-        assertEquals(1, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage));
+        assertEquals(1, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage,
+                mCallingFeature));
 
         //sanity for slot id and sub id
         List<SubscriptionInfo> mSubList = mSubscriptionControllerUT
-                .getActiveSubscriptionInfoList(mCallingPackage);
+                .getActiveSubscriptionInfoList(mCallingPackage, mCallingFeature);
         assertTrue(mSubList != null && mSubList.size() > 0);
         for (int i = 0; i < mSubList.size(); i++) {
             assertTrue(SubscriptionManager.isValidSubscriptionId(
@@ -165,7 +169,7 @@
 
         /* Getting, there is no direct getter function for each fields of property */
         SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(subID, mCallingPackage);
+                .getActiveSubscriptionInfo(subID, mCallingPackage, mCallingFeature);
 
         /* Setting */
         mSubscriptionControllerUT.setDisplayNameUsingSrc(disName, subID,
@@ -176,7 +180,7 @@
         mSubscriptionControllerUT.setOpportunistic(isOpportunistic, subID, mCallingPackage);
 
         subInfo = mSubscriptionControllerUT
-            .getActiveSubscriptionInfo(subID, mCallingPackage);
+            .getActiveSubscriptionInfo(subID, mCallingPackage, mCallingFeature);
 
         assertNotNull(subInfo);
         assertEquals(dataRoaming, subInfo.getDataRoaming());
@@ -206,7 +210,7 @@
         int nameSource = SubscriptionManager.NAME_SOURCE_SIM_SPN;
         mSubscriptionControllerUT.setDisplayNameUsingSrc(disName, subID, nameSource);
         SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(subID, mCallingPackage);
+                .getActiveSubscriptionInfo(subID, mCallingPackage, mCallingFeature);
         assertNotNull(subInfo);
         assertEquals(disName, subInfo.getDisplayName());
         assertEquals(nameSource, subInfo.getNameSource());
@@ -253,7 +257,7 @@
         mSubscriptionControllerUT.setMccMnc(mCcMncVERIZON, 1);
 
         SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(1, mCallingPackage);
+                .getActiveSubscriptionInfo(1, mCallingPackage, mCallingFeature);
         assertNotNull(subInfo);
         assertEquals(Integer.parseInt(mCcMncVERIZON.substring(0, 3)), subInfo.getMcc());
         assertEquals(Integer.parseInt(mCcMncVERIZON.substring(3)), subInfo.getMnc());
@@ -272,7 +276,7 @@
         mSubscriptionControllerUT.setCarrierId(carrierId, 1);
 
         SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(1, mCallingPackage);
+                .getActiveSubscriptionInfo(1, mCallingPackage, mCallingFeature);
         assertNotNull(subInfo);
         assertEquals(carrierId, subInfo.getCarrierId());
 
@@ -359,27 +363,32 @@
         assertEquals("1", mSubscriptionControllerUT.getSubscriptionProperty(
                 subID,
                 SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
-                mCallingPackage));
+                mCallingPackage,
+                mCallingFeature));
 
         assertEquals("0", mSubscriptionControllerUT.getSubscriptionProperty(
                 subID,
                 SubscriptionManager.VT_IMS_ENABLED,
-                mCallingPackage));
+                mCallingPackage,
+                mCallingFeature));
 
         assertEquals("1", mSubscriptionControllerUT.getSubscriptionProperty(
                 subID,
                 SubscriptionManager.WFC_IMS_ENABLED,
-                mCallingPackage));
+                mCallingPackage,
+                mCallingFeature));
 
         assertEquals("2", mSubscriptionControllerUT.getSubscriptionProperty(
                 subID,
                 SubscriptionManager.WFC_IMS_MODE,
-                mCallingPackage));
+                mCallingPackage,
+                mCallingFeature));
 
         assertEquals("3", mSubscriptionControllerUT.getSubscriptionProperty(
                 subID,
                 SubscriptionManager.WFC_IMS_ROAMING_MODE,
-                mCallingPackage));
+                mCallingPackage,
+                mCallingFeature));
     }
 
     @Test
@@ -448,7 +457,7 @@
         // Neither sub1 or sub2 are opportunistic. So getOpportunisticSubscriptions
         // should return empty list and no callback triggered.
         List<SubscriptionInfo> opptSubList = mSubscriptionControllerUT
-                .getOpportunisticSubscriptions(mCallingPackage);
+                .getOpportunisticSubscriptions(mCallingPackage, mCallingFeature);
 
         assertTrue(opptSubList.isEmpty());
         verify(mTelephonyRegisteryMock, times(0))
@@ -460,7 +469,7 @@
         verify(mTelephonyRegisteryMock, times(1))
                 .notifyOpportunisticSubscriptionInfoChanged();
         opptSubList = mSubscriptionControllerUT
-                .getOpportunisticSubscriptions(mCallingPackage);
+                .getOpportunisticSubscriptions(mCallingPackage, mCallingFeature);
         assertEquals(1, opptSubList.size());
         assertEquals("test2", opptSubList.get(0).getIccId());
 
@@ -481,7 +490,8 @@
         makeThisDeviceMultiSimCapable();
 
         // verify there are no sim's in the system.
-        assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage));
+        assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage,
+                mCallingFeature));
 
         addAndVerifyRemoteSimAddition(1, 0);
     }
@@ -489,14 +499,15 @@
     private void addAndVerifyRemoteSimAddition(int num, int numOfCurrentSubs) {
         // Verify the number of current subs in the system
         assertEquals(numOfCurrentSubs,
-                mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage));
+                mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage, mCallingFeature));
 
         // if there are current subs in the system, get that info
         List<SubscriptionInfo> mSubList;
         ArrayList<String> macAddresses = new ArrayList<>();
         ArrayList<String> displayNames = new ArrayList<>();
         if (numOfCurrentSubs > 0) {
-            mSubList = mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage);
+            mSubList = mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage,
+                    mCallingFeature);
             assertNotNull(mSubList);
             assertEquals(numOfCurrentSubs, mSubList.size());
             for (SubscriptionInfo info : mSubList) {
@@ -536,7 +547,8 @@
             assertEquals(expectedNumOfSubs, subIdsList.size());
 
             // validate slot index, sub id etc
-            mSubList = mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage);
+            mSubList = mSubscriptionControllerUT.getActiveSubscriptionInfoList(mCallingPackage,
+                    mCallingFeature);
             assertNotNull(mSubList);
             assertEquals(expectedNumOfSubs, mSubList.size());
 
@@ -566,7 +578,8 @@
         makeThisDeviceMultiSimCapable();
 
         // verify that there are no subscription info records
-        assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage));
+        assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage,
+                mCallingFeature));
         Map<Integer, ArrayList<Integer>> slotIndexToSubsMap =
                 mSubscriptionControllerUT.getSlotIndexToSubIdsMap();
         assertNotNull(slotIndexToSubsMap);
@@ -708,8 +721,9 @@
                 subIdList, mContext.getOpPackageName());
         assertNotEquals(null, groupId);
 
-        List<SubscriptionInfo> subInfoList = mSubscriptionControllerUT
-                .getActiveSubscriptionInfoList(mContext.getOpPackageName());
+        List<SubscriptionInfo> subInfoList =
+                mSubscriptionControllerUT.getActiveSubscriptionInfoList(mContext.getOpPackageName(),
+                        mContext.getFeatureId());
 
         // Put sub3 into slot 1 to make sub2 inactive.
         mContextFixture.addCallingOrSelfPermission(
@@ -775,7 +789,7 @@
         doReturn(true).when(mTelephonyManager).hasCarrierPrivileges(1);
         mSubscriptionControllerUT.addSubscriptionsIntoGroup(new int[] {2}, groupId, "packageName2");
         List<SubscriptionInfo> infoList = mSubscriptionControllerUT
-                .getSubscriptionsInGroup(groupId, "packageName2");
+                .getSubscriptionsInGroup(groupId, "packageName2", "feature2");
         assertEquals(2, infoList.size());
     }
 
@@ -807,7 +821,7 @@
         mSubscriptionControllerUT.addSubscriptionsIntoGroup(
                 new int[] {2}, groupId, "packageName1");
         List<SubscriptionInfo> infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupId, "packageName1");
+                groupId, "packageName1", "feature1");
         assertEquals(2, infoList.size());
         assertEquals(1, infoList.get(0).getSubscriptionId());
         assertEquals(2, infoList.get(1).getSubscriptionId());
@@ -815,7 +829,7 @@
         mSubscriptionControllerUT.removeSubscriptionsFromGroup(
                 new int[] {2}, groupId, "packageName1");
         infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupId, "packageName1");
+                groupId, "packageName1", "feature1");
         assertEquals(1, infoList.size());
         assertEquals(1, infoList.get(0).getSubscriptionId());
 
@@ -835,7 +849,7 @@
         mSubscriptionControllerUT.addSubscriptionsIntoGroup(
                 new int[] {2}, groupId, "packageName1");
         infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupId, "packageName1");
+                groupId, "packageName1", "feature1");
         assertEquals(2, infoList.size());
         assertEquals(1, infoList.get(0).getSubscriptionId());
         assertEquals(2, infoList.get(1).getSubscriptionId());
@@ -843,7 +857,7 @@
         mSubscriptionControllerUT.removeSubscriptionsFromGroup(
                 new int[] {2}, groupId, "packageName1");
         infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
-                groupId, "packageName1");
+                groupId, "packageName1", "feature1");
         assertEquals(1, infoList.size());
         assertEquals(1, infoList.get(0).getSubscriptionId());
     }
@@ -878,7 +892,7 @@
         verify(mTelephonyRegisteryMock, times(2))
                 .notifyOpportunisticSubscriptionInfoChanged();
         List<SubscriptionInfo> opptSubList = mSubscriptionControllerUT
-                .getOpportunisticSubscriptions(mCallingPackage);
+                .getOpportunisticSubscriptions(mCallingPackage, mCallingFeature);
         assertEquals(1, opptSubList.size());
         assertEquals(2, opptSubList.get(0).getSubscriptionId());
         assertEquals(false, opptSubList.get(0).isGroupDisabled());
@@ -893,7 +907,8 @@
 
         verify(mTelephonyRegisteryMock, times(3))
                 .notifyOpportunisticSubscriptionInfoChanged();
-        opptSubList = mSubscriptionControllerUT.getOpportunisticSubscriptions(mCallingPackage);
+        opptSubList = mSubscriptionControllerUT.getOpportunisticSubscriptions(mCallingPackage,
+                mCallingFeature);
         assertEquals(1, opptSubList.size());
         assertEquals(2, opptSubList.get(0).getSubscriptionId());
         assertEquals(true, opptSubList.get(0).isGroupDisabled());
@@ -914,7 +929,7 @@
         assertTrue(mSubscriptionControllerUT.isActiveSubId(1));
         assertTrue(mSubscriptionControllerUT.isActiveSubId(2));
         assertTrue(TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, 1,
-                mContext.getOpPackageName(), "getSubscriptionsInGroup"));
+                mContext.getOpPackageName(), mContext.getFeatureId(), "getSubscriptionsInGroup"));
 
         int[] subIdList = new int[] {1};
         ParcelUuid groupUuid = mSubscriptionControllerUT.createSubscriptionGroup(
@@ -922,8 +937,8 @@
         assertNotEquals(null, groupUuid);
 
         // Sub 1 and sub 2 should be in same group.
-        List<SubscriptionInfo> infoList = mSubscriptionControllerUT
-                .getSubscriptionsInGroup(groupUuid, mContext.getOpPackageName());
+        List<SubscriptionInfo> infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(
+                groupUuid, mContext.getOpPackageName(), mContext.getFeatureId());
         assertNotEquals(null, infoList);
         assertEquals(1, infoList.size());
         assertEquals(1, infoList.get(0).getSubscriptionId());
@@ -932,8 +947,8 @@
 
         mSubscriptionControllerUT.addSubscriptionsIntoGroup(
                 subIdList, groupUuid, mContext.getOpPackageName());
-        infoList = mSubscriptionControllerUT
-                .getSubscriptionsInGroup(groupUuid, mContext.getOpPackageName());
+        infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(groupUuid,
+                mContext.getOpPackageName(), mContext.getFeatureId());
         assertEquals(2, infoList.size());
         assertEquals(2, infoList.get(1).getSubscriptionId());
 
@@ -941,8 +956,8 @@
         subIdList = new int[] {1};
         mSubscriptionControllerUT.removeSubscriptionsFromGroup(
                 subIdList, groupUuid, mContext.getOpPackageName());
-        infoList = mSubscriptionControllerUT
-                .getSubscriptionsInGroup(groupUuid, mContext.getOpPackageName());
+        infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(groupUuid,
+                mContext.getOpPackageName(), mContext.getFeatureId());
         assertEquals(1, infoList.size());
         assertEquals(2, infoList.get(0).getSubscriptionId());
 
@@ -950,8 +965,8 @@
         groupUuid = new ParcelUuid(UUID.randomUUID());
         mSubscriptionControllerUT.addSubscriptionsIntoGroup(
                 subIdList, groupUuid, mContext.getOpPackageName());
-        infoList = mSubscriptionControllerUT
-                .getSubscriptionsInGroup(groupUuid, mContext.getOpPackageName());
+        infoList = mSubscriptionControllerUT.getSubscriptionsInGroup(groupUuid,
+                mContext.getOpPackageName(), mContext.getFeatureId());
         assertEquals(1, infoList.size());
         assertEquals(1, infoList.get(0).getSubscriptionId());
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
index 6c34903..b57971d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
@@ -40,6 +40,7 @@
 import android.os.Looper;
 import android.os.ParcelUuid;
 import android.os.PersistableBundle;
+import android.permission.IPermissionManager;
 import android.service.euicc.EuiccProfileInfo;
 import android.service.euicc.EuiccService;
 import android.service.euicc.GetEuiccProfileInfoListResult;
@@ -104,6 +105,8 @@
     @Mock
     private IPackageManager mPackageManager;
     @Mock
+    private IPermissionManager mPermissionManager;
+    @Mock
     private UiccSlot mUiccSlot;
 
     /*Custom ContentProvider */
@@ -157,7 +160,7 @@
         mIccRecord = mUiccProfile.getIccRecords();
 
         mUpdater = new SubscriptionInfoUpdater(Looper.myLooper(), mContext,
-            new CommandsInterface[]{mSimulatedCommands}, mPackageManager);
+            new CommandsInterface[]{mSimulatedCommands}, mPackageManager, mPermissionManager);
         processAllMessages();
 
         assertFalse(mUpdater.isSubInfoInitialized());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
index 08defe3..b98b374 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
@@ -18,11 +18,12 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.when;
@@ -63,6 +64,7 @@
     private static final int PID = Binder.getCallingPid();
     private static final int UID = Binder.getCallingUid();
     private static final String PACKAGE = "com.example";
+    private static final String FEATURE = "com.example.feature";
     private static final String MSG = "message";
 
     @Mock
@@ -81,6 +83,12 @@
     private ApplicationInfo mMockApplicationInfo;
     @Mock
     private DevicePolicyManager mMockDevicePolicyManager;
+    @Mock
+    private TelephonyManager mTelephonyManagerMock;
+    @Mock
+    private TelephonyManager mTelephonyManagerMockForSub1;
+    @Mock
+    private TelephonyManager mTelephonyManagerMockForSub2;
 
     private MockContentResolver mMockContentResolver;
     private FakeSettingsConfigProvider mFakeSettingsConfigProvider;
@@ -88,6 +96,11 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+
+        when(mMockContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(
+                mTelephonyManagerMock);
+        when(mTelephonyManagerMock.createForSubscriptionId(anyInt())).thenReturn(
+                mTelephonyManagerMock);
         when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mMockAppOps);
         when(mMockContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)).thenReturn(
                 mMockSubscriptionManager);
@@ -101,10 +114,10 @@
                 .enforcePermission(anyString(), eq(PID), eq(UID), eq(MSG));
         doThrow(new SecurityException()).when(mMockContext)
                 .enforcePermission(anyString(), eq(PID), eq(UID), eq(MSG));
-        when(mMockAppOps.noteOp(anyString(), eq(UID), eq(PACKAGE)))
-                .thenReturn(AppOpsManager.MODE_ERRORED);
-        when(mMockAppOps.noteOpNoThrow(anyString(), eq(UID), eq(PACKAGE))).thenReturn(
-                AppOpsManager.MODE_ERRORED);
+        when(mMockAppOps.noteOp(anyString(), eq(UID), eq(PACKAGE), eq(FEATURE),
+                nullable(String.class))).thenReturn(AppOpsManager.MODE_ERRORED);
+        when(mMockAppOps.noteOpNoThrow(anyString(), eq(UID), eq(PACKAGE), eq(FEATURE),
+                nullable(String.class))).thenReturn(AppOpsManager.MODE_ERRORED);
         when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID), eq(UID)))
                 .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
         when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID_2), eq(UID)))
@@ -120,7 +133,7 @@
     public void testCheckReadPhoneState_noPermissions() {
         try {
             TelephonyPermissions.checkReadPhoneState(
-                    mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG);
+                    mMockContext, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
@@ -132,17 +145,17 @@
         doNothing().when(mMockContext).enforcePermission(
                 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, PID, UID, MSG);
         assertTrue(TelephonyPermissions.checkReadPhoneState(
-                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG));
+                mMockContext, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
     public void testCheckReadPhoneState_hasPermissionAndAppOp() {
         doNothing().when(mMockContext).enforcePermission(
                 android.Manifest.permission.READ_PHONE_STATE, PID, UID, MSG);
-        when(mMockAppOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_STATE, UID, PACKAGE))
-                .thenReturn(AppOpsManager.MODE_ALLOWED);
+        when(mMockAppOps.noteOp(eq(AppOpsManager.OPSTR_READ_PHONE_STATE), eq(UID), eq(PACKAGE),
+                eq(FEATURE), nullable(String.class))).thenReturn(AppOpsManager.MODE_ALLOWED);
         assertTrue(TelephonyPermissions.checkReadPhoneState(
-                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG));
+                mMockContext, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -150,21 +163,23 @@
         doNothing().when(mMockContext).enforcePermission(
                 android.Manifest.permission.READ_PHONE_STATE, PID, UID, MSG);
         assertFalse(TelephonyPermissions.checkReadPhoneState(
-                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG));
+                mMockContext, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
     public void testCheckReadPhoneState_hasCarrierPrivileges() throws Exception {
-        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID), eq(UID)))
-                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+        when(mTelephonyManagerMock.createForSubscriptionId(eq(SUB_ID))).thenReturn(
+                mTelephonyManagerMockForSub1);
+        when(mTelephonyManagerMockForSub1.getCarrierPrivilegeStatus(anyInt())).thenReturn(
+                TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         assertTrue(TelephonyPermissions.checkReadPhoneState(
-                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG));
+                mMockContext, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
     public void testCheckReadPhoneStateOnAnyActiveSub_noPermissions() {
         assertFalse(TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub(
-                mMockContext, () -> mMockTelephony, PID, UID, PACKAGE, MSG));
+                mMockContext, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -172,17 +187,17 @@
         doNothing().when(mMockContext).enforcePermission(
                 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, PID, UID, MSG);
         assertTrue(TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub(
-                mMockContext, () -> mMockTelephony, PID, UID, PACKAGE, MSG));
+                mMockContext, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
     public void testCheckReadPhoneStateOnAnyActiveSub_hasPermissionAndAppOp() {
         doNothing().when(mMockContext).enforcePermission(
                 android.Manifest.permission.READ_PHONE_STATE, PID, UID, MSG);
-        when(mMockAppOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_STATE, UID, PACKAGE))
-                .thenReturn(AppOpsManager.MODE_ALLOWED);
+        when(mMockAppOps.noteOp(eq(AppOpsManager.OPSTR_READ_PHONE_STATE), eq(UID), eq(PACKAGE),
+                eq(FEATURE), nullable(String.class))).thenReturn(AppOpsManager.MODE_ALLOWED);
         assertTrue(TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub(
-                mMockContext, () -> mMockTelephony, PID, UID, PACKAGE, MSG));
+                mMockContext, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -190,22 +205,25 @@
         doNothing().when(mMockContext).enforcePermission(
                 android.Manifest.permission.READ_PHONE_STATE, PID, UID, MSG);
         assertFalse(TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub(
-                mMockContext, () -> mMockTelephony, PID, UID, PACKAGE, MSG));
+                mMockContext, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
     public void testCheckReadPhoneStateOnAnyActiveSub_hasCarrierPrivileges() throws Exception {
-        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID), eq(UID)))
-                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+        when(mTelephonyManagerMock.createForSubscriptionId(eq(SUB_ID))).thenReturn(
+                mTelephonyManagerMockForSub1);
+        when(mTelephonyManagerMockForSub1.getCarrierPrivilegeStatus(anyInt())).thenReturn(
+                TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+
         assertTrue(TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub(
-                mMockContext, () -> mMockTelephony, PID, UID, PACKAGE, MSG));
+                mMockContext, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
     public void testCheckReadPhoneNumber_noPermissions() {
         try {
             TelephonyPermissions.checkReadPhoneNumber(
-                    mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG);
+                    mMockContext, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
@@ -214,10 +232,10 @@
 
     @Test
     public void testCheckReadPhoneNumber_defaultSmsApp() {
-        when(mMockAppOps.noteOp(AppOpsManager.OPSTR_WRITE_SMS, UID, PACKAGE))
-                .thenReturn(AppOpsManager.MODE_ALLOWED);
+        when(mMockAppOps.noteOp(eq(AppOpsManager.OPSTR_WRITE_SMS), eq(UID), eq(PACKAGE),
+                eq(FEATURE), nullable(String.class))).thenReturn(AppOpsManager.MODE_ALLOWED);
         assertTrue(TelephonyPermissions.checkReadPhoneNumber(
-                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG));
+                mMockContext, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -225,27 +243,27 @@
         doNothing().when(mMockContext).enforcePermission(
                 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, PID, UID, MSG);
         assertTrue(TelephonyPermissions.checkReadPhoneNumber(
-                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG));
+                mMockContext, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
     public void testCheckReadPhoneNumber_hasReadSms() {
         doNothing().when(mMockContext).enforcePermission(
                 android.Manifest.permission.READ_SMS, PID, UID, MSG);
-        when(mMockAppOps.noteOp(AppOpsManager.OPSTR_READ_SMS, UID, PACKAGE))
-                .thenReturn(AppOpsManager.MODE_ALLOWED);
+        when(mMockAppOps.noteOp(eq(AppOpsManager.OPSTR_READ_SMS), eq(UID), eq(PACKAGE), eq(FEATURE),
+                nullable(String.class))).thenReturn(AppOpsManager.MODE_ALLOWED);
         assertTrue(TelephonyPermissions.checkReadPhoneNumber(
-                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG));
+                mMockContext, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
     public void testCheckReadPhoneNumber_hasReadPhoneNumbers() {
         doNothing().when(mMockContext).enforcePermission(
                 android.Manifest.permission.READ_PHONE_NUMBERS, PID, UID, MSG);
-        when(mMockAppOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_NUMBERS, UID, PACKAGE))
-                .thenReturn(AppOpsManager.MODE_ALLOWED);
+        when(mMockAppOps.noteOp(eq(AppOpsManager.OPSTR_READ_PHONE_NUMBERS), eq(UID), eq(PACKAGE),
+                eq(FEATURE), nullable(String.class))).thenReturn(AppOpsManager.MODE_ALLOWED);
         assertTrue(TelephonyPermissions.checkReadPhoneNumber(
-                mMockContext, () -> mMockTelephony, SUB_ID, PID, UID, PACKAGE, MSG));
+                mMockContext, SUB_ID, PID, UID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -253,7 +271,7 @@
         setupMocksForDeviceIdentifiersErrorPath();
         try {
             TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                    SUB_ID, PACKAGE, MSG);
+                    SUB_ID, PACKAGE, FEATURE, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
@@ -266,25 +284,28 @@
                 PID, UID)).thenReturn(PackageManager.PERMISSION_GRANTED);
         assertTrue(
                 TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                        SUB_ID, PACKAGE, MSG));
+                        SUB_ID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
     public void testCheckReadDeviceIdentifiers_hasCarrierPrivileges() throws Exception {
-        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID), eq(UID)))
-                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+        when(mTelephonyManagerMock.createForSubscriptionId(eq(SUB_ID))).thenReturn(
+                mTelephonyManagerMockForSub1);
+        when(mTelephonyManagerMockForSub1.getCarrierPrivilegeStatus(anyInt())).thenReturn(
+                TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         assertTrue(
                 TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                        SUB_ID, PACKAGE, MSG));
+                        SUB_ID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
     public void testCheckReadDeviceIdentifiers_hasAppOp() {
-        when(mMockAppOps.noteOpNoThrow(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, UID,
-                PACKAGE)).thenReturn(AppOpsManager.MODE_ALLOWED);
+        when(mMockAppOps.noteOpNoThrow(eq(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS), eq(UID),
+                eq(PACKAGE), eq(FEATURE), nullable(String.class))).thenReturn(
+                AppOpsManager.MODE_ALLOWED);
         assertTrue(
                 TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                        SUB_ID, PACKAGE, MSG));
+                        SUB_ID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -293,7 +314,7 @@
                 eq(UID))).thenReturn(true);
         assertTrue(
                 TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                        SUB_ID, PACKAGE, MSG));
+                        SUB_ID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -306,7 +327,7 @@
         setupMocksForDeviceIdentifiersErrorPath();
         try {
             TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                    SUB_ID, PACKAGE, MSG);
+                    SUB_ID, PACKAGE, FEATURE, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
@@ -324,7 +345,7 @@
         mMockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.P;
         assertFalse(
                 TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                        SUB_ID, PACKAGE, MSG));
+                        SUB_ID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -332,11 +353,13 @@
             throws Exception {
         when(mMockSubscriptionManager.getActiveSubscriptionIdList(anyBoolean())).thenReturn(
                 new int[]{SUB_ID, SUB_ID_2});
-        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID_2), eq(UID))).thenReturn(
+        when(mTelephonyManagerMock.createForSubscriptionId(eq(SUB_ID_2))).thenReturn(
+                mTelephonyManagerMockForSub2);
+        when(mTelephonyManagerMockForSub2.getCarrierPrivilegeStatus(anyInt())).thenReturn(
                 TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         assertTrue(
                 TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                        SUB_ID, PACKAGE, MSG));
+                        SUB_ID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -346,11 +369,13 @@
                 new int[]{SUB_ID});
         when(mMockSubscriptionManager.getActiveSubscriptionIdList(false)).thenReturn(
                 new int[]{SUB_ID, SUB_ID_2});
-        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID_2), eq(UID)))
-                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+        when(mTelephonyManagerMock.createForSubscriptionId(eq(SUB_ID_2))).thenReturn(
+                mTelephonyManagerMockForSub2);
+        when(mTelephonyManagerMockForSub2.getCarrierPrivilegeStatus(anyInt())).thenReturn(
+                TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         assertTrue(
                 TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                        SUB_ID, PACKAGE, MSG));
+                        SUB_ID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -360,11 +385,12 @@
         // still proceed to check if the calling package has the appop and any subsequent checks
         // without a NullPointerException.
         when(mMockSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(null);
-        when(mMockAppOps.noteOpNoThrow(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, UID,
-                PACKAGE)).thenReturn(AppOpsManager.MODE_ALLOWED);
+        when(mMockAppOps.noteOpNoThrow(eq(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS), eq(UID),
+                eq(PACKAGE), eq(FEATURE), nullable(String.class))).thenReturn(
+                AppOpsManager.MODE_ALLOWED);
         assertTrue(
                 TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                        SUB_ID, PACKAGE, MSG));
+                        SUB_ID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -375,7 +401,7 @@
         setupMocksForDeviceIdentifiersErrorPath();
         try {
             TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
-                    SUB_ID, null, MSG);
+                    SUB_ID, null, FEATURE, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
@@ -395,7 +421,7 @@
                 anyInt())).thenReturn(false);
         try {
             TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(mMockContext,
-                    SUB_ID, PACKAGE, MSG);
+                    SUB_ID, PACKAGE, FEATURE, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
@@ -409,11 +435,13 @@
         when(mMockContext.checkPermission(
                 eq(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE),
                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
-        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID), anyInt()))
-                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+        when(mTelephonyManagerMock.createForSubscriptionId(eq(SUB_ID))).thenReturn(
+                mTelephonyManagerMockForSub1);
+        when(mTelephonyManagerMockForSub1.getCarrierPrivilegeStatus(anyInt())).thenReturn(
+                TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         assertTrue(
                 TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(mMockContext,
-                        SUB_ID, PACKAGE, MSG));
+                        SUB_ID, PACKAGE, FEATURE, MSG));
     }
 
     @Test
@@ -426,12 +454,14 @@
                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
         when(mMockSubscriptionManager.getActiveSubscriptionIdList(anyBoolean())).thenReturn(
                 new int[]{SUB_ID, SUB_ID_2});
-        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID_2), anyInt())).thenReturn(
+        when(mTelephonyManagerMock.createForSubscriptionId(eq(SUB_ID_2))).thenReturn(
+                mTelephonyManagerMockForSub2);
+        when(mTelephonyManagerMockForSub2.getCarrierPrivilegeStatus(anyInt())).thenReturn(
                 TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
         // Carrier privilege on the other active sub shouldn't allow access to this sub.
         try {
             TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(mMockContext,
-                    SUB_ID, PACKAGE, MSG);
+                    SUB_ID, PACKAGE, FEATURE, MSG);
             fail("Should have thrown SecurityException");
         } catch (SecurityException e) {
             // expected
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
index 4671e51..57dfde8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
@@ -38,6 +38,7 @@
 import android.telephony.PhoneCapability;
 import android.telephony.PhoneStateListener;
 import android.telephony.PreciseDataConnectionState;
+import android.telephony.SubscriptionInfo;
 import android.telephony.TelephonyManager;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
@@ -57,7 +58,7 @@
 @TestableLooper.RunWithLooper
 public class TelephonyRegistryTest extends TelephonyTest {
     @Mock
-    private ISub.Stub mISubStub;
+    private SubscriptionInfo mMockSubInfo;
     private PhoneStateListenerWrapper mPhoneStateListener;
     private TelephonyRegistry mTelephonyRegistry;
     private PhoneCapability mPhoneCapability;
@@ -105,9 +106,6 @@
     @Before
     public void setUp() throws Exception {
         super.setUp("TelephonyRegistryTest");
-        // ServiceManager.getService("isub") will return this stub for any call to
-        // SubscriptionManager.
-        mServiceManagerMockedServices.put("isub", mISubStub);
         mTelephonyRegistry = new TelephonyRegistry(mContext);
         addTelephonyRegistryService();
         mPhoneStateListener = new PhoneStateListenerWrapper();
@@ -124,10 +122,12 @@
 
     @Test @SmallTest
     public void testPhoneCapabilityChanged() {
+        doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
+        doReturn(0/*slotIndex*/).when(mMockSubInfo).getSimSlotIndex();
         // mTelephonyRegistry.listen with notifyNow = true should trigger callback immediately.
         PhoneCapability phoneCapability = new PhoneCapability(1, 2, 3, null, false);
         mTelephonyRegistry.notifyPhoneCapabilityChanged(phoneCapability);
-        mTelephonyRegistry.listen(mContext.getOpPackageName(),
+        mTelephonyRegistry.listenWithFeature(mContext.getOpPackageName(), mContext.getFeatureId(),
                 mPhoneStateListener.callback,
                 LISTEN_PHONE_CAPABILITY_CHANGE, true);
         processAllMessages();
@@ -148,7 +148,7 @@
         when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(activeSubs);
         int activeSubId = 0;
         mTelephonyRegistry.notifyActiveDataSubIdChanged(activeSubId);
-        mTelephonyRegistry.listen(mContext.getOpPackageName(),
+        mTelephonyRegistry.listenWithFeature(mContext.getOpPackageName(), mContext.getFeatureId(),
                 mPhoneStateListener.callback,
                 LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE, true);
         processAllMessages();
@@ -169,20 +169,21 @@
     @Test
     @SmallTest
     public void testSrvccStateChanged() throws Exception {
-        // Return a phone ID of 0 for all sub ids given.
-        doReturn(0/*phoneId*/).when(mISubStub).getPhoneId(anyInt());
+        // Return a slotIndex / phoneId of 0 for all sub ids given.
+        doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
+        doReturn(0/*slotIndex*/).when(mMockSubInfo).getSimSlotIndex();
         int srvccState = TelephonyManager.SRVCC_STATE_HANDOVER_STARTED;
-        mTelephonyRegistry.notifySrvccStateChanged(0 /*subId*/, srvccState);
+        mTelephonyRegistry.notifySrvccStateChanged(1 /*subId*/, srvccState);
         // Should receive callback when listen is called that contains the latest notify result.
-        mTelephonyRegistry.listenForSubscriber(0 /*subId*/, mContext.getOpPackageName(),
-                mPhoneStateListener.callback,
+        mTelephonyRegistry.listenForSubscriber(1 /*subId*/, mContext.getOpPackageName(),
+                mContext.getFeatureId(), mPhoneStateListener.callback,
                 LISTEN_SRVCC_STATE_CHANGED, true);
         processAllMessages();
         assertEquals(srvccState, mSrvccState);
 
         // trigger callback
         srvccState = TelephonyManager.SRVCC_STATE_HANDOVER_COMPLETED;
-        mTelephonyRegistry.notifySrvccStateChanged(0 /*subId*/, srvccState);
+        mTelephonyRegistry.notifySrvccStateChanged(1 /*subId*/, srvccState);
         processAllMessages();
         assertEquals(srvccState, mSrvccState);
     }
@@ -200,7 +201,7 @@
         mTelephonyRegistry.notifySrvccStateChanged(0 /*subId*/, srvccState);
         try {
             mTelephonyRegistry.listenForSubscriber(0 /*subId*/, mContext.getOpPackageName(),
-                    mPhoneStateListener.callback,
+                    mContext.getFeatureId(), mPhoneStateListener.callback,
                     LISTEN_SRVCC_STATE_CHANGED, true);
             fail();
         } catch (SecurityException e) {
@@ -214,7 +215,7 @@
     @Test
     public void testMultiSimConfigChange() {
         mTelephonyRegistry.listenForSubscriber(1, mContext.getOpPackageName(),
-                mPhoneStateListener.callback,
+                mContext.getFeatureId(), mPhoneStateListener.callback,
                 LISTEN_RADIO_POWER_STATE_CHANGED, true);
         processAllMessages();
         assertEquals(RADIO_POWER_UNAVAILABLE, mRadioPowerState);
@@ -244,14 +245,16 @@
      */
     @Test
     public void testPreciseDataConnectionStateChanged() {
-        final int subId = 0;
+        final int subId = 1;
+        doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
+        doReturn(0/*slotIndex*/).when(mMockSubInfo).getSimSlotIndex();
         // Initialize the PSL with a PreciseDataConnection
         mTelephonyRegistry.notifyDataConnectionForSubscriber(
                 /*phoneId*/ 0, subId, "default",
                 new PreciseDataConnectionState(
                     0, 0, 0, "default", new LinkProperties(), 0, null));
         mTelephonyRegistry.listenForSubscriber(subId, mContext.getOpPackageName(),
-                mPhoneStateListener.callback,
+                mContext.getFeatureId(), mPhoneStateListener.callback,
                 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE, true);
         processAllMessages();
         // Verify that the PDCS is reported for the only APN
@@ -268,13 +271,13 @@
 
         // Unregister the listener
         mTelephonyRegistry.listenForSubscriber(subId, mContext.getOpPackageName(),
-                mPhoneStateListener.callback,
+                mContext.getFeatureId(), mPhoneStateListener.callback,
                 PhoneStateListener.LISTEN_NONE, true);
         processAllMessages();
 
         // Re-register the listener and ensure that both APN types are reported
         mTelephonyRegistry.listenForSubscriber(subId, mContext.getOpPackageName(),
-                mPhoneStateListener.callback,
+                mContext.getFeatureId(), mPhoneStateListener.callback,
                 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE, true);
         processAllMessages();
         assertEquals(mPhoneStateListener.invocationCount.get(), 4);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index 743fcaf..091f57a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -43,7 +43,6 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.IDeviceIdleController;
 import android.os.Looper;
 import android.os.Message;
 import android.os.MessageQueue;
@@ -189,8 +188,6 @@
     @Mock
     protected SimulatedCommandsVerifier mSimulatedCommandsVerifier;
     @Mock
-    protected IDeviceIdleController mIDeviceIdleController;
-    @Mock
     protected InboundSmsHandler mInboundSmsHandler;
     @Mock
     protected WspTypeDecoder mWspTypeDecoder;
@@ -436,8 +433,6 @@
                 .getCdmaSubscriptionSourceManagerInstance(nullable(Context.class),
                         nullable(CommandsInterface.class), nullable(Handler.class),
                         anyInt(), nullable(Object.class));
-        doReturn(mIDeviceIdleController).when(mTelephonyComponentFactory)
-                .getIDeviceIdleController();
         doReturn(mImsExternalCallTracker).when(mTelephonyComponentFactory)
                 .makeImsExternalCallTracker(nullable(ImsPhone.class));
         doReturn(mAppSmsManager).when(mTelephonyComponentFactory)
diff --git a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsDispatcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsDispatcherTest.java
index dcc25dd..3ecbd18 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsDispatcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsDispatcherTest.java
@@ -72,6 +72,7 @@
     public void tearDown() throws Exception {
         mCdmaSmsDispatcher = null;
         mCdmaSmsDispatcherTestHandler.quit();
+        mCdmaSmsDispatcherTestHandler.join();
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
index 018747e..be16b79 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
@@ -72,6 +72,7 @@
 import com.android.internal.util.IState;
 import com.android.internal.util.StateMachine;
 import com.android.server.pm.PackageManagerService;
+import com.android.server.pm.permission.PermissionManagerService;
 
 import org.junit.After;
 import org.junit.Before;
@@ -96,7 +97,9 @@
     @Mock
     DcFailBringUp mDcFailBringUp;
     @Mock
-    PackageManagerService mMockPackageManagerInternal;
+    PackageManagerService mMockPackageManager;
+    @Mock
+    PermissionManagerService mMockPermissionManager;
 
     private DataConnection mDc;
     private DataConnectionTestHandler mDataConnectionTestHandler;
@@ -282,7 +285,8 @@
     public void setUp() throws Exception {
         logd("+Setup!");
         super.setUp(getClass().getSimpleName());
-        mServiceManagerMockedServices.put("package", mMockPackageManagerInternal);
+        mServiceManagerMockedServices.put("package", mMockPackageManager);
+        mServiceManagerMockedServices.put("permissionmgr", mMockPermissionManager);
         doReturn("fake.action_detached").when(mPhone).getActionDetached();
         replaceInstance(ConnectionParams.class, "mApnContext", mCp, mApnContext);
         replaceInstance(ConnectionParams.class, "mRilRat", mCp,
@@ -326,6 +330,7 @@
         mDc = null;
         mDcc = null;
         mDataConnectionTestHandler.quit();
+        mDataConnectionTestHandler.join();
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
index 8dbbb5b..59981a6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
@@ -51,6 +51,7 @@
 import android.net.LinkProperties;
 import android.net.NetworkAgent;
 import android.net.NetworkCapabilities;
+import android.net.NetworkPolicyManager;
 import android.net.NetworkRequest;
 import android.net.Uri;
 import android.os.AsyncResult;
@@ -69,6 +70,7 @@
 import android.telephony.SignalStrength;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
+import android.telephony.SubscriptionPlan;
 import android.telephony.TelephonyManager;
 import android.telephony.data.ApnSetting;
 import android.telephony.data.DataProfile;
@@ -88,6 +90,7 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyTest;
 import com.android.server.pm.PackageManagerService;
+import com.android.server.pm.permission.PermissionManagerService;
 
 import org.junit.After;
 import org.junit.Before;
@@ -98,9 +101,15 @@
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.time.Period;
+import java.time.ZonedDateTime;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 public class DcTrackerTest extends TelephonyTest {
 
@@ -144,9 +153,13 @@
     @Mock
     DataConnection mDataConnection;
     @Mock
-    PackageManagerService mMockPackageManagerInternal;
+    PackageManagerService mMockPackageManager;
+    @Mock
+    PermissionManagerService mMockPermissionManager;
     @Mock
     Handler mHandler;
+    @Mock
+    NetworkPolicyManager mNetworkPolicyManager;
 
     private DcTracker mDct;
     private DcTrackerTestHandler mDcTrackerTestHandler;
@@ -505,11 +518,13 @@
                 }
         ).when(mSubscriptionManager).addOnSubscriptionsChangedListener(any());
         doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
-
+        doReturn(mNetworkPolicyManager).when(mContext)
+                .getSystemService(Context.NETWORK_POLICY_SERVICE);
         doReturn(1).when(mIsub).getDefaultDataSubId();
         doReturn(mIsub).when(mBinder).queryLocalInterface(anyString());
         mServiceManagerMockedServices.put("isub", mBinder);
-        mServiceManagerMockedServices.put("package", mMockPackageManagerInternal);
+        mServiceManagerMockedServices.put("package", mMockPackageManager);
+        mServiceManagerMockedServices.put("permissionmgr", mMockPermissionManager);
 
         mContextFixture.putStringArrayResource(
                 com.android.internal.R.array.config_cell_retries_per_error_code,
@@ -539,6 +554,7 @@
         mDct.removeCallbacksAndMessages(null);
         mDct = null;
         mDcTrackerTestHandler.quit();
+        mDcTrackerTestHandler.join();
         super.tearDown();
     }
 
@@ -1323,6 +1339,7 @@
 
     // Test update waiting apn list when on data rat change
     @FlakyTest /* flakes 0.86% of the time */
+    @Ignore
     @Test
     @SmallTest
     public void testUpdateWaitingApnListOnDataRatChange() throws Exception {
@@ -1792,4 +1809,216 @@
         assertEquals(reason, (int) result.second);
         clearInvocations(mHandler);
     }
+
+    private void setUpSubscriptionPlans(boolean is5GUnmetered) throws Exception {
+        List<SubscriptionPlan> plans = new ArrayList<>();
+        if (is5GUnmetered) {
+            plans.add(SubscriptionPlan.Builder
+                    .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"),
+                            Period.ofMonths(1))
+                    .setTitle("Some NR 5G unmetered workaround plan")
+                    .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
+                            SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
+                    .setNetworkTypes(new int[] {TelephonyManager.NETWORK_TYPE_NR})
+                    .build());
+        }
+        plans.add(SubscriptionPlan.Builder
+                .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"),
+                        Period.ofMonths(1))
+                .setTitle("Some 5GB Plan")
+                .setDataLimit(1_000_000_000, SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
+                .setDataUsage(500_000_000, System.currentTimeMillis())
+                .build());
+        replaceInstance(DcTracker.class, "mSubscriptionPlans", mDct, plans);
+    }
+
+    private boolean isNetworkTypeUnmetered(int networkType) throws Exception {
+        Method method = DcTracker.class.getDeclaredMethod(
+                "isNetworkTypeUnmetered", int.class);
+        method.setAccessible(true);
+        return (boolean) method.invoke(mDct, networkType);
+    }
+
+    private void setUpDataConnection() throws Exception {
+        Field dc = DcTracker.class.getDeclaredField("mDataConnections");
+        dc.setAccessible(true);
+        Field uig = DcTracker.class.getDeclaredField("mUniqueIdGenerator");
+        uig.setAccessible(true);
+        ((HashMap<Integer, DataConnection>) dc.get(mDct)).put(
+                ((AtomicInteger) uig.get(mDct)).getAndIncrement(), mDataConnection);
+    }
+
+    private void setUpWatchdogTimer() {
+        // Watchdog active for 10s
+        mBundle.putLong(CarrierConfigManager.KEY_5G_WATCHDOG_TIME_MS_LONG, 10000);
+        Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
+        mContext.sendBroadcast(intent);
+        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
+    }
+
+    private boolean getHysteresisStatus() throws Exception {
+        Field field = DcTracker.class.getDeclaredField(("mHysteresis"));
+        field.setAccessible(true);
+        return (boolean) field.get(mDct);
+    }
+
+    private boolean getWatchdogStatus() throws Exception {
+        Field field = DcTracker.class.getDeclaredField(("mWatchdog"));
+        field.setAccessible(true);
+        return (boolean) field.get(mDct);
+    }
+
+    @Test
+    public void testIsNetworkTypeUnmetered() throws Exception {
+        initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
+
+        // only 5G unmetered
+        setUpSubscriptionPlans(true);
+
+        assertTrue(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_NR));
+        assertFalse(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_LTE));
+        assertFalse(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_UNKNOWN));
+
+        // all network types metered
+        setUpSubscriptionPlans(false);
+
+        assertFalse(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_NR));
+        assertFalse(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_LTE));
+        assertFalse(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_UNKNOWN));
+
+        // all network types unmetered
+        List<SubscriptionPlan> plans = new ArrayList<>();
+        plans.add(SubscriptionPlan.Builder
+                .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"),
+                        Period.ofMonths(1))
+                .setTitle("Some 5GB Plan")
+                .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
+                        SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
+                .build());
+        replaceInstance(DcTracker.class, "mSubscriptionPlans", mDct, plans);
+
+        assertTrue(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_NR));
+        assertTrue(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_LTE));
+        assertTrue(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_UNKNOWN));
+    }
+
+    @Test
+    public void testReevaluateUnmeteredConnectionsOnNetworkChange() throws Exception {
+        initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
+        setUpDataConnection();
+        setUpSubscriptionPlans(true);
+        setUpWatchdogTimer();
+
+        // NetCapability should be unmetered when connected to 5G
+        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
+        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
+        verify(mDataConnection, times(1)).onMeterednessChanged(true);
+
+        // NetCapability should be metered when disconnected from 5G
+        doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
+        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
+        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
+        verify(mDataConnection, times(1)).onMeterednessChanged(false);
+    }
+
+    @Test
+    public void testReevaluateUnmeteredConnectionsOnHysteresis() throws Exception {
+        initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
+        setUpDataConnection();
+        setUpSubscriptionPlans(true);
+        setUpWatchdogTimer();
+
+        // Hysteresis active for 10s
+        mBundle.putLong(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, 10000);
+        Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
+        mContext.sendBroadcast(intent);
+        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
+
+        // Hysteresis inactive when unmetered and never connected to 5G
+        doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
+        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_5G_TIMER_HYSTERESIS));
+        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
+        assertFalse(getHysteresisStatus());
+
+        // Hysteresis inactive when unmetered and connected to 5G
+        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
+        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
+        assertFalse(getHysteresisStatus());
+
+        // Hysteresis active when unmetered and disconnected after connected to 5G
+        doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
+        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
+        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
+        assertTrue(getHysteresisStatus());
+
+        // NetCapability metered when hysteresis timer goes off
+        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_5G_TIMER_HYSTERESIS));
+        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
+        assertFalse(getHysteresisStatus());
+        verify(mDataConnection, times(1)).onMeterednessChanged(true);
+
+        // Hysteresis inactive when reconnected after timer goes off
+        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
+        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
+        assertFalse(getHysteresisStatus());
+
+        // Hysteresis disabled
+        mBundle.putLong(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, 0);
+        intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
+        mContext.sendBroadcast(intent);
+        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
+
+        // Hysteresis inactive when CarrierConfig is set to 0
+        doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
+        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
+        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
+        assertFalse(getHysteresisStatus());
+    }
+
+    @Test
+    public void testReevaluateUnmeteredConnectionsOnWatchdog() throws Exception {
+        initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
+        setUpDataConnection();
+        setUpSubscriptionPlans(true);
+        setUpWatchdogTimer();
+
+        // Watchdog inactive when unmetered and never connected to 5G
+        doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
+        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_5G_TIMER_WATCHDOG));
+        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
+        assertFalse(getWatchdogStatus());
+
+        // Hysteresis active for 10s
+        mBundle.putLong(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, 10000);
+        Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
+        mContext.sendBroadcast(intent);
+        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
+
+        // Watchdog active when unmetered and connected to 5G
+        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
+        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
+        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
+        assertTrue(getWatchdogStatus());
+        assertFalse(getHysteresisStatus());
+
+        // Watchdog active during hysteresis
+        doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
+        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
+        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
+        assertTrue(getHysteresisStatus());
+        assertTrue(getWatchdogStatus());
+
+        // Watchdog inactive when metered
+        setUpSubscriptionPlans(false);
+        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
+        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
+        assertFalse(getWatchdogStatus());
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java
index 9250942..ad6e7ec 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java
@@ -29,6 +29,7 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import android.net.NetworkCapabilities;
@@ -57,6 +58,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 
 import java.lang.reflect.Field;
 import java.util.ArrayList;
@@ -72,6 +74,9 @@
     @Mock
     private RadioConfig mMockRadioConfig;
 
+    @Mock
+    private DataConnection mDataConnection;
+
     private String mTestName = "";
 
     private final ArrayList<NetworkRequest> mNetworkRequestList = new ArrayList<>();
@@ -346,4 +351,41 @@
         h.sendMessage(h.obtainMessage(5, ar));
         processAllMessages();
     }
+
+    /**
+     * Test handover when the data connection is being connected.
+     */
+    @Test
+    @SmallTest
+    public void testHandoverActivatingData() throws Exception {
+        createMockedTelephonyComponents();
+        doReturn(0).when(mSubscriptionController).getSubIdUsingPhoneId(0);
+        mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(
+                TelephonyNetworkFactory.EVENT_SUBSCRIPTION_CHANGED);
+
+        activatePhoneInPhoneSwitcher(0, true);
+        makeDefaultInternetRequest();
+
+        makeSubSpecificMmsRequest(0);
+        processAllMessages();
+
+        Field f = TelephonyNetworkFactory.class.getDeclaredField("mInternalHandler");
+        f.setAccessible(true);
+        Handler h = (Handler) f.get(mTelephonyNetworkFactoryUT);
+
+        HandoverCallback handoverCallback = mock(HandoverCallback.class);
+        Mockito.reset(mDcTracker);
+        doReturn(mDataConnection).when(mDcTracker).getDataConnectionByApnType(anyString());
+        doReturn(false).when(mDataConnection).isActive();
+
+        HandoverParams hp = new HandoverParams(ApnSetting.TYPE_MMS,
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN, handoverCallback);
+        AsyncResult ar = new AsyncResult(null, hp, null);
+        h.sendMessage(h.obtainMessage(5, ar));
+        processAllMessages();
+
+        verify(mDcTracker, times(1)).releaseNetwork(any(), eq(1));
+        verify(mDcTracker, times(1)).requestNetwork(any(), eq(1), any());
+    }
+
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmCellBroadcastHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmCellBroadcastHandlerTest.java
deleted file mode 100644
index 18bc486..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmCellBroadcastHandlerTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.gsm;
-
-import static android.provider.Settings.Secure.CMAS_ADDITIONAL_BROADCAST_PKG;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.nullable;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyBoolean;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.Manifest;
-import android.app.Activity;
-import android.app.AppOpsManager;
-import android.content.BroadcastReceiver;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.provider.Telephony;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import com.android.internal.telephony.SmsStorageMonitor;
-import com.android.internal.telephony.TelephonyTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-
-import java.util.List;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class GsmCellBroadcastHandlerTest extends TelephonyTest {
-    @Mock
-    private SmsStorageMonitor mSmsStorageMonitor;
-    @Mock
-    private android.telephony.SmsMessage mSmsMessage;
-    @Mock
-    private SmsMessage mGsmSmsMessage;
-
-    private GsmCellBroadcastHandler mGsmCellBroadcastHandler;
-
-    @Before
-    public void setUp() throws Exception {
-
-        super.setUp(getClass().getSimpleName());
-
-        doReturn(true).when(mTelephonyManager).getSmsReceiveCapableForPhone(anyInt(), anyBoolean());
-        doReturn(true).when(mSmsStorageMonitor).isStorageAvailable();
-
-        mGsmCellBroadcastHandler = GsmCellBroadcastHandler.makeGsmCellBroadcastHandler(
-                mContext, mPhone);
-        monitorTestableLooper(
-                new TestableLooper(mGsmCellBroadcastHandler.getHandler().getLooper()));
-        processAllMessages();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mGsmCellBroadcastHandler = null;
-        super.tearDown();
-    }
-
-    @Test
-    @Ignore
-    public void testBroadcastSms() {
-        mContextFixture.putStringArrayResource(
-                com.android.internal.R.array.config_defaultCellBroadcastReceiverPkgs,
-                new String[]{"fake.cellbroadcastreceiver"});
-
-        Settings.Secure.putString(mContext.getContentResolver(),
-                CMAS_ADDITIONAL_BROADCAST_PKG, "another.fake.pkg");
-        mSimulatedCommands.notifyGsmBroadcastSms(new byte[] {
-                (byte)0xc0, //geographical scope
-                (byte)0x01, //serial number
-                (byte)0x01, //serial number
-                (byte)0x01, //message identifier
-                (byte)0x01, //message identifier
-                (byte)0x01
-        });
-        processAllMessages();
-        ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
-        verify(mContextFixture.getTestDouble(), times(2)).sendOrderedBroadcastAsUser(
-                intentArgumentCaptor.capture(), eq(UserHandle.ALL),
-                eq(Manifest.permission.RECEIVE_SMS), eq(AppOpsManager.OP_RECEIVE_SMS),
-                nullable(BroadcastReceiver.class), any(Handler.class), eq(Activity.RESULT_OK),
-                eq(null), eq(null));
-
-        List<Intent> intentList = intentArgumentCaptor.getAllValues();
-
-        assertEquals(Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION,
-                intentList.get(0).getAction());
-        assertEquals("another.fake.pkg", intentList.get(0).getPackage());
-
-        assertEquals(Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION,
-                intentList.get(1).getAction());
-        assertEquals("fake.cellbroadcastreceiver", intentList.get(1).getPackage());
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
index 2dce712..88b21f0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
@@ -809,8 +809,8 @@
         // verify that a broadcast receiver is registered for current user (user == null) based on
         // implementation in ContextFixture. registerReceiver may be called more than once (for
         // example by GsmInboundSmsHandler if TEST_MODE is true)
-        verify(mContext, atLeastOnce()).registerReceiverAsUser(any(BroadcastReceiver.class),
-                eq((UserHandle)null), any(IntentFilter.class), eq((String)null), eq((Handler)null));
+        verify(mContext, atLeastOnce()).registerReceiver(any(BroadcastReceiver.class),
+                any(IntentFilter.class), eq((String) null), eq((Handler) null));
 
         // wait for ScanRawTableThread
         waitForMs(100);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsCbTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsCbTest.java
deleted file mode 100644
index 8f61c21..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsCbTest.java
+++ /dev/null
@@ -1,791 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.gsm;
-
-import android.telephony.Rlog;
-import android.telephony.SmsCbEtwsInfo;
-import android.telephony.SmsCbLocation;
-import android.telephony.SmsCbMessage;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.internal.telephony.uicc.IccUtils;
-
-import org.junit.Test;
-
-import java.util.Random;
-
-/**
- * Test cases for basic SmsCbMessage operations
- */
-public class GsmSmsCbTest extends AndroidTestCase {
-
-    private static final String TAG = "GsmSmsCbTest";
-
-    private static final SmsCbLocation sTestLocation = new SmsCbLocation("94040", 1234, 5678);
-
-    private SmsCbMessage createFromPdu(byte[] pdu) {
-        try {
-            SmsCbHeader header = new SmsCbHeader(pdu);
-            byte[][] pdus = new byte[1][];
-            pdus[0] = pdu;
-            return GsmSmsCbMessage.createSmsCbMessage(getContext(), header, sTestLocation, pdus,
-                    /* slotIndex */ 0);
-        } catch (IllegalArgumentException e) {
-            return null;
-        }
-    }
-
-    private void doTestGeographicalScopeValue(byte[] pdu, byte b, int expectedGs) {
-        pdu[0] = b;
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected geographical scope decoded", expectedGs, msg
-                .getGeographicalScope());
-    }
-
-    @Test @SmallTest
-    public void testCreateNullPdu() {
-        SmsCbMessage msg = createFromPdu(null);
-        assertNull("createFromPdu(byte[] with null pdu should return null", msg);
-    }
-
-    @Test @SmallTest
-    public void testCreateTooShortPdu() {
-        byte[] pdu = new byte[4];
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertNull("createFromPdu(byte[] with too short pdu should return null", msg);
-    }
-
-    @Test @SmallTest
-    public void testGetGeographicalScope() {
-        byte[] pdu = {
-                (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x40, (byte)0x11, (byte)0x41,
-                (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
-                (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
-                (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
-                (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69,
-                (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75,
-                (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69,
-                (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
-        };
-
-        doTestGeographicalScopeValue(pdu, (byte)0x00,
-                SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE);
-        doTestGeographicalScopeValue(pdu, (byte)0x40, SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE);
-        doTestGeographicalScopeValue(pdu, (byte)0x80,
-                SmsCbMessage.GEOGRAPHICAL_SCOPE_LOCATION_AREA_WIDE);
-        doTestGeographicalScopeValue(pdu, (byte)0xC0, SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE);
-    }
-
-    @Test @SmallTest
-    public void testGetGeographicalScopeUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x40,
-
-                (byte)0x01,
-
-                (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91,
-                (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07,
-                (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C,
-                (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C,
-                (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A,
-                (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9,
-                (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93,
-                (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68,
-                (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
-                (byte)0x34
-        };
-
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected geographical scope decoded",
-                SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE, msg.getGeographicalScope());
-    }
-
-    @Test @SmallTest
-    public void testGetMessageBody7Bit() {
-        byte[] pdu = {
-                (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x40, (byte)0x11, (byte)0x41,
-                (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
-                (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
-                (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
-                (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69,
-                (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75,
-                (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69,
-                (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected 7-bit string decoded",
-                "A GSM default alphabet message with carriage return padding",
-                msg.getMessageBody());
-    }
-
-    @Test @SmallTest
-    public void testGetMessageBody7BitUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x40,
-
-                (byte)0x01,
-
-                (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91,
-                (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07,
-                (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C,
-                (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C,
-                (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A,
-                (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9,
-                (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93,
-                (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68,
-                (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
-                (byte)0x34
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected 7-bit string decoded",
-                "A GSM default alphabet message with carriage return padding",
-                msg.getMessageBody());
-    }
-
-    @Test @SmallTest
-    public void testGetMessageBody7BitMultipageUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x00, (byte)0x01, (byte)0xC0, (byte)0x00, (byte)0x40,
-
-                (byte)0x02,
-
-                (byte)0xC6, (byte)0xB4, (byte)0x7C, (byte)0x4E, (byte)0x07, (byte)0xC1,
-                (byte)0xC3, (byte)0xE7, (byte)0xF2, (byte)0xAA, (byte)0xD1, (byte)0x68,
-                (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A,
-                (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34,
-                (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68,
-                (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
-                (byte)0x0A,
-
-                (byte)0xD3, (byte)0xF2, (byte)0xF8, (byte)0xED, (byte)0x26, (byte)0x83,
-                (byte)0xE0, (byte)0xE1, (byte)0x73, (byte)0xB9, (byte)0xD1, (byte)0x68,
-                (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A,
-                (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34,
-                (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68,
-                (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
-                (byte)0x0A
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected multipage 7-bit string decoded",
-                "First page+Second page",
-                msg.getMessageBody());
-    }
-
-    @Test @SmallTest
-    public void testGetMessageBody7BitFull() {
-        byte[] pdu = {
-                (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x40, (byte)0x11, (byte)0x41,
-                (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
-                (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
-                (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
-                (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xC4, (byte)0xE5,
-                (byte)0xB4, (byte)0xFB, (byte)0x0C, (byte)0x2A, (byte)0xE3, (byte)0xC3, (byte)0x63,
-                (byte)0x3A, (byte)0x3B, (byte)0x0F, (byte)0xCA, (byte)0xCD, (byte)0x40, (byte)0x63,
-                (byte)0x74, (byte)0x58, (byte)0x1E, (byte)0x1E, (byte)0xD3, (byte)0xCB, (byte)0xF2,
-                (byte)0x39, (byte)0x88, (byte)0xFD, (byte)0x76, (byte)0x9F, (byte)0x59, (byte)0xA0,
-                (byte)0x76, (byte)0x39, (byte)0xEC, (byte)0x4E, (byte)0xBB, (byte)0xCF, (byte)0x20,
-                (byte)0x3A, (byte)0xBA, (byte)0x2C, (byte)0x2F, (byte)0x83, (byte)0xD2, (byte)0x73,
-                (byte)0x90, (byte)0xFB, (byte)0x0D, (byte)0x82, (byte)0x87, (byte)0xC9, (byte)0xE4,
-                (byte)0xB4, (byte)0xFB, (byte)0x1C, (byte)0x02
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals(
-                "Unexpected 7-bit string decoded",
-                "A GSM default alphabet message being exactly 93 characters long, " +
-                "meaning there is no padding!",
-                msg.getMessageBody());
-    }
-
-    @Test @SmallTest
-    public void testGetMessageBody7BitFullUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x40,
-
-                (byte)0x01,
-
-                (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91,
-                (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07,
-                (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C,
-                (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C,
-                (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xC4, (byte)0xE5, (byte)0xB4,
-                (byte)0xFB, (byte)0x0C, (byte)0x2A, (byte)0xE3, (byte)0xC3, (byte)0x63,
-                (byte)0x3A, (byte)0x3B, (byte)0x0F, (byte)0xCA, (byte)0xCD, (byte)0x40,
-                (byte)0x63, (byte)0x74, (byte)0x58, (byte)0x1E, (byte)0x1E, (byte)0xD3,
-                (byte)0xCB, (byte)0xF2, (byte)0x39, (byte)0x88, (byte)0xFD, (byte)0x76,
-                (byte)0x9F, (byte)0x59, (byte)0xA0, (byte)0x76, (byte)0x39, (byte)0xEC,
-                (byte)0x4E, (byte)0xBB, (byte)0xCF, (byte)0x20, (byte)0x3A, (byte)0xBA,
-                (byte)0x2C, (byte)0x2F, (byte)0x83, (byte)0xD2, (byte)0x73, (byte)0x90,
-                (byte)0xFB, (byte)0x0D, (byte)0x82, (byte)0x87, (byte)0xC9, (byte)0xE4,
-                (byte)0xB4, (byte)0xFB, (byte)0x1C, (byte)0x02,
-
-                (byte)0x52
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals(
-                "Unexpected 7-bit string decoded",
-                "A GSM default alphabet message being exactly 93 characters long, " +
-                "meaning there is no padding!",
-                msg.getMessageBody());
-    }
-
-    @Test @SmallTest
-    public void testGetMessageBody7BitWithLanguage() {
-        byte[] pdu = {
-                (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x04, (byte)0x11, (byte)0x41,
-                (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
-                (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
-                (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
-                (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69,
-                (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75,
-                (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69,
-                (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected 7-bit string decoded",
-                "A GSM default alphabet message with carriage return padding",
-                msg.getMessageBody());
-
-        assertEquals("Unexpected language indicator decoded", "es", msg.getLanguageCode());
-    }
-
-    @Test @SmallTest
-    public void testGetMessageBody7BitWithLanguageInBody() {
-        byte[] pdu = {
-                (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x10, (byte)0x11, (byte)0x73,
-                (byte)0x7B, (byte)0x23, (byte)0x08, (byte)0x3A, (byte)0x4E, (byte)0x9B, (byte)0x20,
-                (byte)0x72, (byte)0xD9, (byte)0x1C, (byte)0xAE, (byte)0xB3, (byte)0xE9, (byte)0xA0,
-                (byte)0x30, (byte)0x1B, (byte)0x8E, (byte)0x0E, (byte)0x8B, (byte)0xCB, (byte)0x74,
-                (byte)0x50, (byte)0xBB, (byte)0x3C, (byte)0x9F, (byte)0x87, (byte)0xCF, (byte)0x65,
-                (byte)0xD0, (byte)0x3D, (byte)0x4D, (byte)0x47, (byte)0x83, (byte)0xC6, (byte)0x61,
-                (byte)0xB9, (byte)0x3C, (byte)0x1D, (byte)0x3E, (byte)0x97, (byte)0x41, (byte)0xF2,
-                (byte)0x32, (byte)0xBD, (byte)0x2E, (byte)0x77, (byte)0x83, (byte)0xE0, (byte)0x61,
-                (byte)0x32, (byte)0x39, (byte)0xED, (byte)0x3E, (byte)0x37, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected 7-bit string decoded",
-                "A GSM default alphabet message with carriage return padding",
-                msg.getMessageBody());
-
-        assertEquals("Unexpected language indicator decoded", "sv", msg.getLanguageCode());
-    }
-
-    @Test @SmallTest
-    public void testGetMessageBody7BitWithLanguageInBodyUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x10,
-
-                (byte)0x01,
-
-                (byte)0x73, (byte)0x7B, (byte)0x23, (byte)0x08, (byte)0x3A, (byte)0x4E,
-                (byte)0x9B, (byte)0x20, (byte)0x72, (byte)0xD9, (byte)0x1C, (byte)0xAE,
-                (byte)0xB3, (byte)0xE9, (byte)0xA0, (byte)0x30, (byte)0x1B, (byte)0x8E,
-                (byte)0x0E, (byte)0x8B, (byte)0xCB, (byte)0x74, (byte)0x50, (byte)0xBB,
-                (byte)0x3C, (byte)0x9F, (byte)0x87, (byte)0xCF, (byte)0x65, (byte)0xD0,
-                (byte)0x3D, (byte)0x4D, (byte)0x47, (byte)0x83, (byte)0xC6, (byte)0x61,
-                (byte)0xB9, (byte)0x3C, (byte)0x1D, (byte)0x3E, (byte)0x97, (byte)0x41,
-                (byte)0xF2, (byte)0x32, (byte)0xBD, (byte)0x2E, (byte)0x77, (byte)0x83,
-                (byte)0xE0, (byte)0x61, (byte)0x32, (byte)0x39, (byte)0xED, (byte)0x3E,
-                (byte)0x37, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
-                (byte)0x37
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected 7-bit string decoded",
-                "A GSM default alphabet message with carriage return padding",
-                msg.getMessageBody());
-
-        assertEquals("Unexpected language indicator decoded", "sv", msg.getLanguageCode());
-    }
-
-    @Test @SmallTest
-    public void testGetMessageBody8Bit() {
-        byte[] pdu = {
-                (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x44, (byte)0x11, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x41,
-                (byte)0x42, (byte)0x43, (byte)0x44, (byte)0x45
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("8-bit message body should be empty", "", msg.getMessageBody());
-    }
-
-    @Test @SmallTest
-    public void testGetMessageBodyUcs2() {
-        byte[] pdu = {
-                (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x48, (byte)0x11, (byte)0x00,
-                (byte)0x41, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x55, (byte)0x00, (byte)0x43,
-                (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x20, (byte)0x00,
-                (byte)0x6D, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x73,
-                (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x65, (byte)0x00,
-                (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x6F, (byte)0x00, (byte)0x6E,
-                (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x69, (byte)0x00,
-                (byte)0x6E, (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x67,
-                (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x20, (byte)0x04,
-                (byte)0x34, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x68,
-                (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x61, (byte)0x00,
-                (byte)0x63, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x72,
-                (byte)0x00, (byte)0x0D, (byte)0x00, (byte)0x0D
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected 7-bit string decoded",
-                "A UCS2 message containing a \u0434 character", msg.getMessageBody());
-    }
-
-    @Test @SmallTest
-    public void testGetMessageBodyUcs2Umts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x48,
-
-                (byte)0x01,
-
-                (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x55,
-                (byte)0x00, (byte)0x43, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x32,
-                (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x6D, (byte)0x00, (byte)0x65,
-                (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x61,
-                (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x20,
-                (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x6F, (byte)0x00, (byte)0x6E,
-                (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x69,
-                (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x6E,
-                (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x61,
-                (byte)0x00, (byte)0x20, (byte)0x04, (byte)0x34, (byte)0x00, (byte)0x20,
-                (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x68, (byte)0x00, (byte)0x61,
-                (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x63,
-                (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x72,
-                (byte)0x00, (byte)0x0D, (byte)0x00, (byte)0x0D,
-
-                (byte)0x4E
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected 7-bit string decoded",
-                "A UCS2 message containing a \u0434 character", msg.getMessageBody());
-    }
-
-    @Test @SmallTest
-    public void testGetMessageBodyUcs2MultipageUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x48,
-
-                (byte)0x02,
-
-                (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x41,
-                (byte)0x00, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-
-                (byte)0x06,
-
-                (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x42,
-                (byte)0x00, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-                (byte)0x0D, (byte)0x0D, (byte)0x0D, (byte)0x0D,
-
-                (byte)0x06
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected multipage UCS2 string decoded",
-                "AAABBB", msg.getMessageBody());
-    }
-
-    @Test @SmallTest
-    public void testGetMessageBodyUcs2WithLanguageInBody() {
-        byte[] pdu = {
-                (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x32, (byte)0x11, (byte)0x11, (byte)0x78,
-                (byte)0x3C, (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x55,
-                (byte)0x00, (byte)0x43, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x32, (byte)0x00,
-                (byte)0x20, (byte)0x00, (byte)0x6D, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x73,
-                (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x67, (byte)0x00,
-                (byte)0x65, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x6F,
-                (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x61, (byte)0x00,
-                (byte)0x69, (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x6E,
-                (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x61, (byte)0x00,
-                (byte)0x20, (byte)0x04, (byte)0x34, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63,
-                (byte)0x00, (byte)0x68, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x72, (byte)0x00,
-                (byte)0x61, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x65,
-                (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x0D
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected 7-bit string decoded",
-                "A UCS2 message containing a \u0434 character", msg.getMessageBody());
-
-        assertEquals("Unexpected language indicator decoded", "xx", msg.getLanguageCode());
-    }
-
-    @Test @SmallTest
-    public void testGetMessageBodyUcs2WithLanguageInBodyUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x00, (byte)0x32, (byte)0xC0, (byte)0x00, (byte)0x11,
-
-                (byte)0x01,
-
-                (byte)0x78, (byte)0x3C, (byte)0x00, (byte)0x41, (byte)0x00, (byte)0x20,
-                (byte)0x00, (byte)0x55, (byte)0x00, (byte)0x43, (byte)0x00, (byte)0x53,
-                (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x6D,
-                (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x73,
-                (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x65,
-                (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x6F,
-                (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x61,
-                (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x69,
-                (byte)0x00, (byte)0x6E, (byte)0x00, (byte)0x67, (byte)0x00, (byte)0x20,
-                (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x20, (byte)0x04, (byte)0x34,
-                (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x68,
-                (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x61,
-                (byte)0x00, (byte)0x63, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x65,
-                (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x0D,
-
-                (byte)0x50
-        };
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected 7-bit string decoded",
-                "A UCS2 message containing a \u0434 character", msg.getMessageBody());
-
-        assertEquals("Unexpected language indicator decoded", "xx", msg.getLanguageCode());
-    }
-
-    @Test @SmallTest
-    public void testGetMessageIdentifier() {
-        byte[] pdu = {
-                (byte)0xC0, (byte)0x00, (byte)0x30, (byte)0x39, (byte)0x40, (byte)0x11, (byte)0x41,
-                (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
-                (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
-                (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
-                (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69,
-                (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75,
-                (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69,
-                (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
-        };
-
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected message identifier decoded", 12345, msg.getServiceCategory());
-    }
-
-    @Test @SmallTest
-    public void testGetMessageIdentifierUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x30, (byte)0x39, (byte)0x2A, (byte)0xA5, (byte)0x40,
-
-                (byte)0x01,
-
-                (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91,
-                (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07,
-                (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C,
-                (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C,
-                (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A,
-                (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9,
-                (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93,
-                (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68,
-                (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
-                (byte)0x34
-        };
-
-        SmsCbMessage msg = createFromPdu(pdu);
-
-        assertEquals("Unexpected message identifier decoded", 12345, msg.getServiceCategory());
-    }
-
-    @Test @SmallTest
-    public void testGetMessageCode() {
-        byte[] pdu = {
-                (byte)0x2A, (byte)0xA5, (byte)0x30, (byte)0x39, (byte)0x40, (byte)0x11, (byte)0x41,
-                (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
-                (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
-                (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
-                (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69,
-                (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75,
-                (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69,
-                (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
-        };
-
-        SmsCbMessage msg = createFromPdu(pdu);
-        int messageCode = (msg.getSerialNumber() & 0x3ff0) >> 4;
-
-        assertEquals("Unexpected message code decoded", 682, messageCode);
-    }
-
-    @Test @SmallTest
-    public void testGetMessageCodeUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x30, (byte)0x39, (byte)0x2A, (byte)0xA5, (byte)0x40,
-
-                (byte)0x01,
-
-                (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91,
-                (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07,
-                (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C,
-                (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C,
-                (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A,
-                (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9,
-                (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93,
-                (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68,
-                (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
-                (byte)0x34
-        };
-
-        SmsCbMessage msg = createFromPdu(pdu);
-        int messageCode = (msg.getSerialNumber() & 0x3ff0) >> 4;
-
-        assertEquals("Unexpected message code decoded", 682, messageCode);
-    }
-
-    @Test @SmallTest
-    public void testGetUpdateNumber() {
-        byte[] pdu = {
-                (byte)0x2A, (byte)0xA5, (byte)0x30, (byte)0x39, (byte)0x40, (byte)0x11, (byte)0x41,
-                (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91, (byte)0xCB, (byte)0xE6,
-                (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07, (byte)0x85, (byte)0xD9, (byte)0x70,
-                (byte)0x74, (byte)0x58, (byte)0x5C, (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5,
-                (byte)0xF9, (byte)0x3C, (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69,
-                (byte)0x3A, (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9, (byte)0x75,
-                (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93, (byte)0xC9, (byte)0x69,
-                (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00
-        };
-
-        SmsCbMessage msg = createFromPdu(pdu);
-        int updateNumber = msg.getSerialNumber() & 0x000f;
-
-        assertEquals("Unexpected update number decoded", 5, updateNumber);
-    }
-
-    @Test @SmallTest
-    public void testGetUpdateNumberUmts() {
-        byte[] pdu = {
-                (byte)0x01, (byte)0x30, (byte)0x39, (byte)0x2A, (byte)0xA5, (byte)0x40,
-
-                (byte)0x01,
-
-                (byte)0x41, (byte)0xD0, (byte)0x71, (byte)0xDA, (byte)0x04, (byte)0x91,
-                (byte)0xCB, (byte)0xE6, (byte)0x70, (byte)0x9D, (byte)0x4D, (byte)0x07,
-                (byte)0x85, (byte)0xD9, (byte)0x70, (byte)0x74, (byte)0x58, (byte)0x5C,
-                (byte)0xA6, (byte)0x83, (byte)0xDA, (byte)0xE5, (byte)0xF9, (byte)0x3C,
-                (byte)0x7C, (byte)0x2E, (byte)0x83, (byte)0xEE, (byte)0x69, (byte)0x3A,
-                (byte)0x1A, (byte)0x34, (byte)0x0E, (byte)0xCB, (byte)0xE5, (byte)0xE9,
-                (byte)0xF0, (byte)0xB9, (byte)0x0C, (byte)0x92, (byte)0x97, (byte)0xE9,
-                (byte)0x75, (byte)0xB9, (byte)0x1B, (byte)0x04, (byte)0x0F, (byte)0x93,
-                (byte)0xC9, (byte)0x69, (byte)0xF7, (byte)0xB9, (byte)0xD1, (byte)0x68,
-                (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3, (byte)0xD1,
-                (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46, (byte)0xA3,
-                (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D, (byte)0x46,
-                (byte)0xA3, (byte)0xD1, (byte)0x68, (byte)0x34, (byte)0x1A, (byte)0x8D,
-                (byte)0x46, (byte)0xA3, (byte)0xD1, (byte)0x00,
-
-                (byte)0x34
-        };
-
-        SmsCbMessage msg = createFromPdu(pdu);
-        int updateNumber = msg.getSerialNumber() & 0x000f;
-
-        assertEquals("Unexpected update number decoded", 5, updateNumber);
-    }
-
-    /* ETWS Test message including header */
-    private static final byte[] etwsMessageNormal = IccUtils.hexStringToBytes("000011001101" +
-            "0D0A5BAE57CE770C531790E85C716CBF3044573065B930675730" +
-            "9707767A751F30025F37304463FA308C306B5099304830664E0B30553044FF086C178C615E81FF09" +
-            "0000000000000000000000000000");
-
-    private static final byte[] etwsMessageCancel = IccUtils.hexStringToBytes("000011001101" +
-            "0D0A5148307B3069002800310030003A0035" +
-            "00320029306E7DCA602557309707901F5831309253D66D883057307E3059FF086C178C615E81FF09" +
-            "00000000000000000000000000000000000000000000");
-
-    private static final byte[] etwsMessageTest = IccUtils.hexStringToBytes("000011031101" +
-            "0D0A5BAE57CE770C531790E85C716CBF3044" +
-            "573065B9306757309707300263FA308C306B5099304830664E0B30553044FF086C178C615E81FF09" +
-            "00000000000000000000000000000000000000000000");
-
-    // FIXME: add example of ETWS primary notification PDU
-
-    @Test @SmallTest
-    public void testEtwsMessageNormal() {
-        SmsCbMessage msg = createFromPdu(etwsMessageNormal);
-        Rlog.d(TAG, msg.toString());
-        assertEquals("GS mismatch", 0, msg.getGeographicalScope());
-        assertEquals("serial number mismatch", 0, msg.getSerialNumber());
-        assertEquals("message ID mismatch", 0x1100, msg.getServiceCategory());
-        assertEquals("warning type mismatch", SmsCbEtwsInfo.ETWS_WARNING_TYPE_EARTHQUAKE,
-                msg.getEtwsWarningInfo().getWarningType());
-    }
-
-    @Test @SmallTest
-    public void testEtwsMessageCancel() {
-        SmsCbMessage msg = createFromPdu(etwsMessageCancel);
-        Rlog.d(TAG, msg.toString());
-        assertEquals("GS mismatch", 0, msg.getGeographicalScope());
-        assertEquals("serial number mismatch", 0, msg.getSerialNumber());
-        assertEquals("message ID mismatch", 0x1100, msg.getServiceCategory());
-        assertEquals("warning type mismatch", SmsCbEtwsInfo.ETWS_WARNING_TYPE_EARTHQUAKE,
-                msg.getEtwsWarningInfo().getWarningType());
-    }
-
-    @Test @SmallTest
-    public void testEtwsMessageTest() {
-        SmsCbMessage msg = createFromPdu(etwsMessageTest);
-        Rlog.d(TAG, msg.toString());
-        assertEquals("GS mismatch", 0, msg.getGeographicalScope());
-        assertEquals("serial number mismatch", 0, msg.getSerialNumber());
-        assertEquals("message ID mismatch", 0x1103, msg.getServiceCategory());
-        assertEquals("warning type mismatch", SmsCbEtwsInfo.ETWS_WARNING_TYPE_TEST_MESSAGE,
-                msg.getEtwsWarningInfo().getWarningType());
-    }
-
-    // Make sure we don't throw an exception if we feed random data to the PDU parser.
-    @Test @SmallTest
-    public void testRandomPdus() {
-        Random r = new Random(94040);
-        for (int run = 0; run < 10000; run++) {
-            int len = r.nextInt(140);
-            byte[] data = new byte[len];
-            for (int i = 0; i < len; i++) {
-                data[i] = (byte) r.nextInt(256);
-            }
-            try {
-                // this should return a SmsCbMessage object or null for invalid data
-                SmsCbMessage msg = createFromPdu(data);
-            } catch (Exception e) {
-                Rlog.d(TAG, "exception thrown", e);
-                fail("Exception in decoder at run " + run + " length " + len + ": " + e);
-            }
-        }
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java
index 81c6c9e..4021609 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java
@@ -136,6 +136,7 @@
     public void tearDown() throws Exception {
         mGsmSmsDispatcher = null;
         mGsmSmsDispatcherTestHandler.quit();
+        mGsmSmsDispatcherTestHandler.join();
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
index 38218c4..84c9cb3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.doReturn;
@@ -95,8 +96,8 @@
         doReturn(mSubscriptionController).when(mBinder).queryLocalInterface(anyString());
         mServiceManagerMockedServices.put("isub", mBinder);
         // Stick to the CarrierConfig defaults unless explicitly overwritten.
-        doReturn("-1").when(mSubscriptionController)
-                .getSubscriptionProperty(anyInt(), anyString(), anyString());
+        doReturn("-1").when(mSubscriptionController).getSubscriptionProperty(anyInt(), anyString(),
+                anyString(), nullable(String.class));
 
 
         doReturn(true).when(mMmTelFeatureConnection).isBinderAlive();
@@ -143,38 +144,44 @@
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         assertEquals(WFC_IMS_ROAMING_ENABLE_DEFAULT_VAL, imsManager.isWfcRoamingEnabledByUser());
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         assertEquals(ENHANCED_4G_MODE_DEFAULT_VAL,
                 imsManager.isEnhanced4gLteModeSettingEnabledByUser());
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.ENHANCED_4G_MODE_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         assertEquals(WFC_IMS_MODE_DEFAULT_VAL, imsManager.getWfcMode(false));
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         assertEquals(WFC_IMS_ROAMING_MODE_DEFAULT_VAL, imsManager.getWfcMode(true));
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         assertEquals(VT_IMS_ENABLE_DEFAULT_VAL, imsManager.isVtEnabledByUser());
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.VT_IMS_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
     }
 
     @Test @SmallTest
@@ -285,12 +292,14 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                         anyInt(),
                         eq(SubscriptionManager.WFC_IMS_MODE),
-                        anyString());
+                        anyString(),
+                        nullable(String.class));
         doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED))
                 .when(mSubscriptionController).getSubscriptionProperty(
                         anyInt(),
                         eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
-                        anyString());
+                        anyString(),
+                        nullable(String.class));
         ImsManager imsManager = getImsManagerAndInitProvisionedValues();
 
         // Roaming
@@ -345,7 +354,8 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         ImsManager imsManager = getImsManagerAndInitProvisionedValues();
 
@@ -380,7 +390,8 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         ImsManager imsManager = getImsManagerAndInitProvisionedValues();
 
@@ -454,7 +465,8 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         // The device is roaming
         doReturn(true).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0]));
@@ -500,7 +512,8 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         // The device is roaming
         doReturn(true).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0]));
@@ -534,13 +547,15 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
         // The user has enabled the "WFC while roaming" setting in the UI while WFC was enabled
         doReturn(String.valueOf(1 /*true*/))
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         ImsManager imsManager = getImsManagerAndInitProvisionedValues();
 
@@ -574,7 +589,8 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_ENABLED),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         ImsManager imsManager = getImsManagerAndInitProvisionedValues();
 
@@ -609,12 +625,14 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
         doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY))
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
         ImsManager imsManager = getImsManagerAndInitProvisionedValues();
 
         // Roaming
@@ -687,12 +705,14 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
         doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED))
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         ImsManager imsManager = getImsManagerAndInitProvisionedValues();
 
@@ -702,7 +722,8 @@
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         // Set WFC roaming network mode to not editable.
         mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL,
@@ -713,7 +734,8 @@
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
     }
 
     /**
@@ -730,12 +752,14 @@
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
         doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED))
                 .when(mSubscriptionController).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         // Set to use WFC home network mode in roaming network.
         mBundle.putBoolean(
@@ -749,7 +773,8 @@
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
 
         // Set WFC home network mode to not editable.
         mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL,
@@ -760,7 +785,8 @@
         verify(mSubscriptionController, times(1)).getSubscriptionProperty(
                 anyInt(),
                 eq(SubscriptionManager.WFC_IMS_MODE),
-                anyString());
+                anyString(),
+                nullable(String.class));
     }
 
     /**
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneFactoryTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneFactoryTest.java
index 19c40b1..5514853 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneFactoryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneFactoryTest.java
@@ -75,6 +75,7 @@
     @After
     public void tearDown() throws Exception {
         mImsPhoneFactoryHandler.quit();
+        mImsPhoneFactoryHandler.join();
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRttTextHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRttTextHandlerTest.java
index 13fe2b6..00230c5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRttTextHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRttTextHandlerTest.java
@@ -230,6 +230,7 @@
         mRttTextHandler.tearDown();
         waitForHandlerAction(mRttTextHandler, TEST_TIMEOUT);
         mHandlerThread.quit();
+        mHandlerThread.join();
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/TelephonyMetricsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/TelephonyMetricsTest.java
index 30e1297..40ec2be 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/TelephonyMetricsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/TelephonyMetricsTest.java
@@ -104,6 +104,7 @@
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
         mMetrics = new TelephonyMetrics();
+        mMetrics.setContext(mContext);
         mUusInfo = new UUSInfo(1, 2, new byte[]{1, 2});
         doReturn("123").when(mImsCallSession).getCallId();
         mImsReasonInfo = new ImsReasonInfo();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/IccPhoneBookInterfaceManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/IccPhoneBookInterfaceManagerTest.java
index 9510619..72ff321 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/IccPhoneBookInterfaceManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/IccPhoneBookInterfaceManagerTest.java
@@ -90,6 +90,7 @@
     @After
     public void tearDown() throws Exception {
         mIccPhoneBookInterfaceManagerHandler.quit();
+        mIccPhoneBookInterfaceManagerHandler.join();
         super.tearDown();
     }
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
index b3a296d..e6e7fb8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
@@ -100,6 +100,7 @@
     @After
     public void tearDown() throws Exception {
         mTestHandlerThread.quit();
+        mTestHandlerThread.join();
         super.tearDown();
     }