Add api to show dialog to switch to work profile

* Show switch to managed profile dialog for MMS if subscription is
  associated with managed profile.

Bug: 258629881
Test: Manual
atest com.android.internal.telephony.SmsControllerTest

Change-Id: I40631bea9d8373ea9f431eaf4588cf25cb2f9365
diff --git a/services/core/java/com/android/server/MmsServiceBroker.java b/services/core/java/com/android/server/MmsServiceBroker.java
index f149fda..742c94a 100644
--- a/services/core/java/com/android/server/MmsServiceBroker.java
+++ b/services/core/java/com/android/server/MmsServiceBroker.java
@@ -46,6 +46,7 @@
 
 import com.android.internal.telephony.IMms;
 import com.android.internal.telephony.TelephonyPermissions;
+import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.server.uri.NeededUriGrants;
 import com.android.server.uri.UriGrantsManagerInternal;
 
@@ -342,8 +343,11 @@
             // Check if user is associated with the subscription
             if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId,
                     Binder.getCallingUserHandle())) {
-                // TODO(b/258629881): Display error dialog.
-		return;
+                if (TelephonyUtils.isUidForeground(mContext, Binder.getCallingUid())) {
+                    TelephonyUtils.showErrorIfSubscriptionAssociatedWithManagedProfile(mContext,
+                            subId);
+                }
+                return;
             }
 
             if (getAppOpsManager().noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),
diff --git a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
index 3dc7111..cbac34f 100644
--- a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
+++ b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
@@ -19,6 +19,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityManager;
 import android.content.Context;
 import android.content.pm.ComponentInfo;
 import android.content.pm.PackageManager;
@@ -26,10 +27,16 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.PersistableBundle;
+import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyFrameworkInitializer;
 import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import com.android.internal.telephony.ITelephony;
 
 import java.io.PrintWriter;
 import java.util.Collections;
@@ -43,6 +50,8 @@
  * This class provides various util functions
  */
 public final class TelephonyUtils {
+    private static final String LOG_TAG = "TelephonyUtils";
+
     public static boolean IS_USER = "user".equals(android.os.Build.TYPE);
     public static boolean IS_DEBUGGABLE = SystemProperties.getInt("ro.debuggable", 0) == 1;
 
@@ -240,4 +249,59 @@
         }
         return userHandle;
     }
+
+    /**
+     * Show switch to managed profile dialog if subscription is associated with managed profile.
+     *
+     * @param context Context object
+     * @param subId   subscription id
+     */
+    public static void showErrorIfSubscriptionAssociatedWithManagedProfile(Context context,
+            int subId) {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            SubscriptionManager subscriptionManager = context.getSystemService(
+                    SubscriptionManager.class);
+            UserHandle associatedUserHandle = subscriptionManager.getSubscriptionUserHandle(subId);
+            UserManager um = context.getSystemService(UserManager.class);
+
+            if (associatedUserHandle != null && um.isManagedProfile(
+                    associatedUserHandle.getIdentifier())) {
+
+                ITelephony iTelephony = ITelephony.Stub.asInterface(
+                        TelephonyFrameworkInitializer
+                                .getTelephonyServiceManager()
+                                .getTelephonyServiceRegisterer()
+                                .get());
+                if (iTelephony != null) {
+                    try {
+                        iTelephony.showSwitchToManagedProfileDialog();
+                    } catch (RemoteException e) {
+                        Log.e(LOG_TAG, "Failed to launch switch to managed profile dialog.");
+                    }
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    /**
+     * Check if the process with given uid is foreground.
+     *
+     * @param context context
+     * @param uid     the caller uid
+     * @return true if the process with uid is foreground, false otherwise.
+     */
+    public static boolean isUidForeground(Context context, int uid) {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            ActivityManager am = context.getSystemService(ActivityManager.class);
+            boolean result = am != null && am.getUidImportance(uid)
+                    == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
+            return result;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
 }
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 6099cb1..48b1657 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -2209,6 +2209,11 @@
         IIntegerConsumer subIdResult);
 
     /**
+     * Show error dialog to switch to managed profile.
+     */
+    oneway void showSwitchToManagedProfileDialog();
+
+    /**
      * Returns the MMS user agent.
      */
     String getMmsUserAgent(int subId);