Merge "Remove metrics for emergency dialer."
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..455634f
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,78 @@
+// Copyright 2019 Google Inc. All rights reserved.
+//
+// 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.
+
+// Build the Phone app which includes the emergency dialer. See Contacts
+// for the 'other' dialer.
+
+android_app {
+    name: "TeleService",
+
+    libs: [
+        "telephony-common",
+        "voip-common",
+        "ims-common",
+        "org.apache.http.legacy",
+        "libprotobuf-java-lite",
+    ],
+
+    static_libs: [
+        "androidx.appcompat_appcompat",
+        "androidx.preference_preference",
+        "androidx.recyclerview_recyclerview",
+        "androidx.legacy_legacy-preference-v14",
+        "guava",
+        "volley",
+        "android-support-annotations",
+        "com.android.phone.common-lib",
+    ],
+
+    srcs: [
+        "src/**/*.java",
+        "sip/src/**/*.java",
+        "ecc/proto/**/*.proto",
+        "src/com/android/phone/EventLogTags.logtags",
+    ],
+
+    resource_dirs: [
+        "res",
+        "sip/res",
+    ],
+
+    asset_dirs: [
+        "assets",
+        "ecc/output",
+    ],
+
+    aaptflags: [
+        "--extra-packages com.android.services.telephony.sip",
+    ],
+
+    platform_apis: true,
+
+    certificate: "platform",
+    privileged: true,
+
+    optimize: {
+        proguard_flags_files: [
+            "proguard.flags",
+            "sip/proguard.flags",
+        ],
+    },
+
+    defaults: ["SettingsLibDefaults"],
+
+    proto: {
+        type: "lite",
+    },
+}
\ No newline at end of file
diff --git a/Android.mk b/Android.mk
deleted file mode 100644
index 04c37e6..0000000
--- a/Android.mk
+++ /dev/null
@@ -1,57 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-# Build the Phone app which includes the emergency dialer. See Contacts
-# for the 'other' dialer.
-include $(CLEAR_VARS)
-
-phone_common_dir := ../../apps/PhoneCommon
-
-src_dirs := src $(phone_common_dir)/src sip/src
-res_dirs := res $(phone_common_dir)/res sip/res
-asset_dirs := assets ecc/output
-
-LOCAL_JAVA_LIBRARIES := \
-        telephony-common \
-        voip-common \
-        ims-common \
-        org.apache.http.legacy \
-        libprotobuf-java-lite
-
-LOCAL_STATIC_ANDROID_LIBRARIES := \
-        androidx.appcompat_appcompat \
-        androidx.preference_preference \
-        androidx.recyclerview_recyclerview \
-        androidx.legacy_legacy-preference-v14
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-        guava \
-        volley \
-        android-support-annotations
-
-LOCAL_SRC_FILES := $(call all-java-files-under, $(src_dirs))
-LOCAL_SRC_FILES += $(call all-proto-files-under, ecc/proto)
-LOCAL_SRC_FILES += \
-        src/com/android/phone/EventLogTags.logtags
-LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, $(res_dirs))
-LOCAL_ASSET_DIR := $(addprefix $(LOCAL_PATH)/, $(asset_dirs))
-LOCAL_USE_AAPT2 := true
-
-LOCAL_AAPT_FLAGS := \
-    --extra-packages com.android.phone.common \
-    --extra-packages com.android.services.telephony.sip
-
-LOCAL_PACKAGE_NAME := TeleService
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_CERTIFICATE := platform
-LOCAL_PRIVILEGED_MODULE := true
-
-LOCAL_PROGUARD_FLAG_FILES := proguard.flags sip/proguard.flags
-
-include frameworks/base/packages/SettingsLib/common.mk
-
-include $(BUILD_PACKAGE)
-
-# Build the test package
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index 320fc24..29df8b8 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -202,7 +202,8 @@
         if (DBG) log("onCreate: Intent is " + getIntent());
 
         // Make sure we are running as an admin user.
-        if (!UserManager.get(this).isAdminUser()) {
+        UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
+        if (!userManager.isAdminUser()) {
             Toast.makeText(this, R.string.call_settings_admin_user_only,
                     Toast.LENGTH_SHORT).show();
             finish();
diff --git a/src/com/android/phone/EmergencyInfoGroup.java b/src/com/android/phone/EmergencyInfoGroup.java
index 9e7121d..186de03 100644
--- a/src/com/android/phone/EmergencyInfoGroup.java
+++ b/src/com/android/phone/EmergencyInfoGroup.java
@@ -153,7 +153,7 @@
     private Drawable getCircularUserIcon() {
         final UserManager userManager = (UserManager) getContext().getSystemService(
                 Context.USER_SERVICE);
-        Bitmap bitmapUserIcon = userManager.getUserIcon(UserHandle.getCallingUserId());
+        Bitmap bitmapUserIcon = userManager.getUserIcon();
 
         if (bitmapUserIcon == null) {
             // get default user icon.
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index bb1e293..475cc1f 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -379,7 +379,7 @@
             for (int i = 0; i < users.size(); i++) {
                 final UserInfo user = users.get(i);
                 final UserHandle userHandle = user.getUserHandle();
-                if (!mUserManager.hasUserRestriction(
+                if (!hasUserRestriction(
                         UserManager.DISALLOW_OUTGOING_CALLS, userHandle)
                         && !user.isManagedProfile()) {
                     if (!maybeSendVoicemailNotificationUsingDefaultDialer(phone, vmCount, vmNumber,
@@ -397,7 +397,7 @@
             for (int i = 0; i < users.size(); i++) {
                 final UserInfo user = users.get(i);
                 final UserHandle userHandle = user.getUserHandle();
-                if (!mUserManager.hasUserRestriction(
+                if (!hasUserRestriction(
                         UserManager.DISALLOW_OUTGOING_CALLS, userHandle)
                         && !user.isManagedProfile()) {
                     if (!maybeSendVoicemailNotificationUsingDefaultDialer(phone, 0, null, null,
@@ -412,6 +412,12 @@
         }
     }
 
+    private boolean hasUserRestriction(String restrictionKey, UserHandle userHandle) {
+        final List<UserManager.EnforcingUser> sources = mUserManager
+                .getUserRestrictionSources(restrictionKey, userHandle);
+        return (sources != null && !sources.isEmpty());
+    }
+
     /**
      * Sends a broadcast with the voicemail notification information to the default dialer. This
      * method is also used to indicate to the default dialer when to clear the
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index c3c3eb8..de71373 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -274,7 +274,8 @@
                     // not want this running if the device is still in the FBE encrypted state.
                     // This is the same procedure that is triggered in the SipIncomingCallReceiver
                     // upon BOOT_COMPLETED.
-                    UserManager userManager = UserManager.get(sMe);
+                    UserManager userManager =
+                            (UserManager) sMe.getSystemService(Context.USER_SERVICE);
                     if (userManager != null && userManager.isUserUnlocked()) {
                         SipUtil.startSipService();
                     }
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 337d998..571be34 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -99,6 +99,7 @@
 import android.telephony.gsm.GsmCellLocation;
 import android.telephony.ims.ImsException;
 import android.telephony.ims.ProvisioningManager;
+import android.telephony.ims.RegistrationManager;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IImsConfig;
 import android.telephony.ims.aidl.IImsConfigCallback;
@@ -2926,18 +2927,87 @@
         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
         }
-        Binder.withCleanCallingIdentity(() -> {
-            try {
-                // TODO: Refactor to remove ImsManager dependence and query through ImsPhone.
-                ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
-                        .removeRegistrationCallbackForSubscription(c, subId);
-            } catch (ImsException e) {
-                Log.i(LOG_TAG, "unregisterImsRegistrationCallback: " + subId
-                        + "is inactive, ignoring unregister.");
-                // If the subscription is no longer active, just return, since the callback
-                // will already have been removed internally.
+        final long token = Binder.clearCallingIdentity();
+        try {
+            // TODO: Refactor to remove ImsManager dependence and query through ImsPhone.
+            ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
+                    .removeRegistrationCallbackForSubscription(c, subId);
+        } catch (ImsException e) {
+            Log.i(LOG_TAG, "unregisterImsRegistrationCallback: " + subId
+                    + "is inactive, ignoring unregister.");
+            // If the subscription is no longer active, just return, since the callback
+            // will already have been removed internally.
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    /**
+     * Get the IMS service registration state for the MmTelFeature associated with this sub id.
+     */
+    @Override
+    public void getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer) {
+        enforceReadPrivilegedPermission("getImsMmTelRegistrationState");
+        if (!ImsManager.isImsSupportedOnDevice(mApp)) {
+            throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                    "IMS not available on device.");
+        }
+        final long token = Binder.clearCallingIdentity();
+        try {
+            Phone phone = getPhone(subId);
+            if (phone == null) {
+                Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
+                        + subId + "'");
+                throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
             }
-        });
+            phone.getImsRegistrationState(regState -> {
+                try {
+                    consumer.accept((regState == null)
+                            ? RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED : regState);
+                } catch (RemoteException e) {
+                    // Ignore if the remote process is no longer available to call back.
+                    Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
+                }
+            });
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    /**
+     * Get the transport type for the IMS service registration state.
+     */
+    @Override
+    public void getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer) {
+        enforceReadPrivilegedPermission("getImsMmTelRegistrationTransportType");
+        if (!ImsManager.isImsSupportedOnDevice(mApp)) {
+            throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                    "IMS not available on device.");
+        }
+        final long token = Binder.clearCallingIdentity();
+        try {
+            Phone phone = getPhone(subId);
+            if (phone == null) {
+                Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
+                        + subId + "'");
+                throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
+            }
+            phone.getImsRegistrationTech(regTech -> {
+                // Convert registration tech from ImsRegistrationImplBase -> RegistrationManager
+                int regTechConverted = (regTech == null)
+                        ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : regTech;
+                regTechConverted = RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(
+                        regTechConverted);
+                try {
+                    consumer.accept(regTechConverted);
+                } catch (RemoteException e) {
+                    // Ignore if the remote process is no longer available to call back.
+                    Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
+                }
+            });
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     @Override
@@ -2963,22 +3033,23 @@
     @Override
     public void unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c) {
         enforceReadPrivilegedPermission("unregisterMmTelCapabilityCallback");
-
         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
         }
-        Binder.withCleanCallingIdentity(() -> {
-            try {
-                // TODO: Refactor to remove ImsManager dependence and query through ImsPhone.
-                ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            // TODO: Refactor to remove ImsManager dependence and query through ImsPhone.
+            ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
                         .removeCapabilitiesCallbackForSubscription(c, subId);
-            } catch (ImsException e) {
-                Log.i(LOG_TAG, "unregisterMmTelCapabilityCallback: " + subId
-                        + "is inactive, ignoring unregister.");
-                // If the subscription is no longer active, just return, since the callback
-                // will already have been removed internally.
-            }
-        });
+        } catch (ImsException e) {
+            Log.i(LOG_TAG, "unregisterMmTelCapabilityCallback: " + subId
+                     + "is inactive, ignoring unregister.");
+             // If the subscription is no longer active, just return, since the callback
+             // will already have been removed internally.
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     @Override
@@ -5601,6 +5672,21 @@
     }
 
     @Override
+    public int getSubIdForPhoneAccountHandle(
+            PhoneAccountHandle phoneAccountHandle, String callingPackage) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, getDefaultSubscription(),
+                callingPackage, "getSubIdForPhoneAccountHandle")) {
+            throw new SecurityException("Requires READ_PHONE_STATE permission.");
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
     public @Nullable PhoneAccountHandle getPhoneAccountHandleForSubscriptionId(int subscriptionId) {
         final long identity = Binder.clearCallingIdentity();
         try {
@@ -7262,10 +7348,8 @@
      */
     @Override
     public boolean isDataEnabledForApn(int apnType, int subId, String callingPackage) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "isDataEnabledForApn")) {
-            throw new SecurityException("Needs READ_PHONE_STATE for isDataEnabledForApn");
-        }
+        enforceReadPrivilegedPermission("Needs READ_PRIVILEGED_PHONE_STATE for "
+                + "isDataEnabledForApn");
 
         // Now that all security checks passes, perform the operation as ourselves.
         final long identity = Binder.clearCallingIdentity();
diff --git a/src/com/android/services/telephony/EmergencyTonePlayer.java b/src/com/android/services/telephony/EmergencyTonePlayer.java
index 8e26349..431f8d7 100644
--- a/src/com/android/services/telephony/EmergencyTonePlayer.java
+++ b/src/com/android/services/telephony/EmergencyTonePlayer.java
@@ -23,7 +23,6 @@
 import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.ToneGenerator;
-import android.os.SystemVibrator;
 import android.os.Vibrator;
 import android.provider.Settings;
 
@@ -49,11 +48,9 @@
                 .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
                 .build();
 
-    // We don't rely on getSystemService(Context.VIBRATOR_SERVICE) to make sure that this vibrator
-    // object will be isolated from others.
-    private final Vibrator mVibrator = new SystemVibrator();
     private final Context mContext;
     private final AudioManager mAudioManager;
+    private final Vibrator mVibrator;
 
     private ToneGenerator mToneGenerator;
     private int mSavedInCallVolume;
@@ -62,6 +59,7 @@
     EmergencyTonePlayer(Context context) {
         mContext = context;
         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
     }
 
     public void start() {
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 1e681e8..2e923ec 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -803,8 +803,10 @@
                 Log.i(this, "User changed, re-registering phone accounts.");
 
                 int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-                UserHandle currentUserHandle = new UserHandle(userHandleId);
-                mIsPrimaryUser = UserManager.get(mContext).getPrimaryUser().getUserHandle()
+                UserHandle currentUserHandle = UserHandle.of(userHandleId);
+                UserManager userManager =
+                        (UserManager) context.getSystemService(Context.USER_SERVICE);
+                mIsPrimaryUser = userManager.getPrimaryUser().getUserHandle()
                         .equals(currentUserHandle);
 
                 // Any time the user changes, re-register the accounts.
diff --git a/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/ImsRegistrationActivity.java b/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/ImsRegistrationActivity.java
index 4ee9355..139f8ac 100644
--- a/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/ImsRegistrationActivity.java
+++ b/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/ImsRegistrationActivity.java
@@ -24,6 +24,7 @@
 import android.telephony.ims.ImsException;
 import android.telephony.ims.ImsMmTelManager;
 import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.RegistrationManager;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.util.ArrayMap;
 import android.util.Log;
@@ -103,8 +104,8 @@
     }
 
 
-    private final ImsMmTelManager.RegistrationCallback mRegistrationCallback =
-            new ImsMmTelManager.RegistrationCallback() {
+    private final RegistrationManager.RegistrationCallback mRegistrationCallback =
+            new RegistrationManager.RegistrationCallback() {
 
         @Override
         public void onRegistered(int imsRadioTech) {
@@ -181,7 +182,7 @@
         try {
             mImsManager = ImsMmTelManager.createForSubscriptionId(
                     SubscriptionManager.getDefaultVoiceSubscriptionId());
-            mImsManager.registerImsRegistrationCallback(getMainExecutor(), mRegistrationCallback);
+            mImsManager.registerImsRegistrationCallback(mRegistrationCallback, getMainExecutor());
         } catch (IllegalArgumentException | ImsException e) {
             Log.w("ImsCallingActivity", "illegal subscription ID.");
         }