Replaced Xooglers am: 1eb878293b am: 4a54ae1378

Original change: https://android-review.googlesource.com/c/platform/packages/services/Mms/+/2700797

Change-Id: Id8e2c03fe164050ff0ce54130e7c87b67370381c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 87e7947..a19a11a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -26,6 +26,10 @@
     <uses-permission android:name="android.permission.BROADCAST_WAP_PUSH"/>
     <uses-permission android:name="android.permission.BIND_CARRIER_SERVICES"/>
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"/>
+    <!-- Needed to check if subscription is active. -->
+    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+    <!-- Needed to query user associated with a subscription. -->
+    <uses-permission android:name="android.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION"/>
 
     <protected-broadcast android:name="android.settings.ENABLE_MMS_DATA_REQUEST"/>
 
diff --git a/proto/src/persist_mms_atoms.proto b/proto/src/persist_mms_atoms.proto
index c562246..bde1cb9 100644
--- a/proto/src/persist_mms_atoms.proto
+++ b/proto/src/persist_mms_atoms.proto
@@ -50,6 +50,7 @@
   optional int64 mms_count = 9;
   optional int32 retry_id = 10;
   optional bool handled_by_carrier_app = 11;
+  optional bool is_managed_profile = 12;
 }
 
 message OutgoingMms {
@@ -65,4 +66,5 @@
   optional bool is_from_default_app = 10;
   optional int32 retry_id = 11;
   optional bool handled_by_carrier_app = 12;
-}
\ No newline at end of file
+  optional bool is_managed_profile = 13;
+}
diff --git a/src/com/android/mms/service/DownloadRequest.java b/src/com/android/mms/service/DownloadRequest.java
index d81b384..62fa9e6 100644
--- a/src/com/android/mms/service/DownloadRequest.java
+++ b/src/com/android/mms/service/DownloadRequest.java
@@ -298,10 +298,12 @@
             if (mCarrierMessagingServiceWrapper.bindToCarrierMessagingService(
                     context, carrierMessagingServicePackage, Runnable::run,
                     ()->onServiceReady())) {
-                LogUtil.v("bindService() for carrier messaging service succeeded. "
+                LogUtil.v("bindService() for carrier messaging service: "
+                        + carrierMessagingServicePackage + " succeeded. "
                         + MmsService.formatCrossStackMessageId(mMessageId));
             } else {
-                LogUtil.e("bindService() for carrier messaging service failed. "
+                LogUtil.e("bindService() for carrier messaging service: "
+                        + carrierMessagingServicePackage + " failed. "
                         + MmsService.formatCrossStackMessageId(mMessageId));
                 carrierDownloadCallback.onDownloadMmsComplete(
                         CarrierMessagingService.DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK);
diff --git a/src/com/android/mms/service/MmsConstants.java b/src/com/android/mms/service/MmsConstants.java
new file mode 100644
index 0000000..57ef5df
--- /dev/null
+++ b/src/com/android/mms/service/MmsConstants.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 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.mms.service;
+
+import java.util.UUID;
+
+public class MmsConstants {
+    // MMS anomaly uuid
+    public static final UUID MMS_ANOMALY_UUID = UUID.fromString(
+            "e4330975-17be-43b7-87d6-d9f281d33278");
+}
diff --git a/src/com/android/mms/service/MmsNetworkManager.java b/src/com/android/mms/service/MmsNetworkManager.java
index 52feb77..f21e510 100644
--- a/src/com/android/mms/service/MmsNetworkManager.java
+++ b/src/com/android/mms/service/MmsNetworkManager.java
@@ -96,7 +96,7 @@
 
     private final Dependencies mDeps;
 
-    private int mNetworkReleaseTimeoutMillis = (5 * 1000);
+    private int mNetworkReleaseTimeoutMillis;
     private EventHandler mEventHandler;
 
     private final class EventHandler extends Handler {
@@ -192,10 +192,6 @@
                 (CarrierConfigManager)
                         mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
         final PersistableBundle config = configManager.getConfigForSubId(mSubId);
-        if (config == null) {
-                LogUtil.e("MmsNetworkManager: handleCarrierConfigChanged() config is null");
-                return;
-        }
         mNetworkReleaseTimeoutMillis =
                 config.getInt(CarrierConfigManager.KEY_MMS_NETWORK_RELEASE_TIMEOUT_MILLIS_INT);
         LogUtil.d("MmsNetworkManager: handleCarrierConfigChanged() mNetworkReleaseTimeoutMillis "
diff --git a/src/com/android/mms/service/MmsRequest.java b/src/com/android/mms/service/MmsRequest.java
index 32e4c6e..dca77df 100644
--- a/src/com/android/mms/service/MmsRequest.java
+++ b/src/com/android/mms/service/MmsRequest.java
@@ -50,8 +50,6 @@
     private static final int RETRY_TIMES = 3;
     // Signal level threshold for both wifi and cellular
     private static final int SIGNAL_LEVEL_THRESHOLD = 2;
-    // MMS anomaly uuid
-    private final UUID mAnomalyUUID = UUID.fromString("e4330975-17be-43b7-87d6-d9f281d33278");
     public static final String EXTRA_LAST_CONNECTION_FAILURE_CAUSE_CODE
             = "android.telephony.extra.LAST_CONNECTION_FAILURE_CAUSE_CODE";
     public static final String EXTRA_HANDLED_BY_CARRIER_APP
@@ -325,8 +323,9 @@
     private UUID generateUUID(int result, int httpStatusCode) {
         long lresult = result;
         long lhttpStatusCode = httpStatusCode;
-        return new UUID(mAnomalyUUID.getMostSignificantBits(),
-                mAnomalyUUID.getLeastSignificantBits() + ((lhttpStatusCode << 32) + lresult));
+        return new UUID(MmsConstants.MMS_ANOMALY_UUID.getMostSignificantBits(),
+                MmsConstants.MMS_ANOMALY_UUID.getLeastSignificantBits()
+                        + ((lhttpStatusCode << 32) + lresult));
     }
 
     private boolean isPoorSignal() {
diff --git a/src/com/android/mms/service/MmsService.java b/src/com/android/mms/service/MmsService.java
index 2f3b3aa..ee88f09 100644
--- a/src/com/android/mms/service/MmsService.java
+++ b/src/com/android/mms/service/MmsService.java
@@ -41,6 +41,7 @@
 import android.provider.Telephony;
 import android.security.NetworkSecurityPolicy;
 import android.service.carrier.CarrierMessagingService;
+import android.telephony.AnomalyReporter;
 import android.telephony.SmsManager;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
@@ -183,6 +184,8 @@
         List<String> carrierPackages = telephonyManager.getCarrierPackageNamesForIntent(intent);
 
         if (carrierPackages == null || carrierPackages.size() != 1) {
+            LogUtil.d("getCarrierMessagingServicePackageIfExists - multiple ("
+                    + carrierPackages.size() + ") carrier apps installed, not using any.");
             return null;
         } else {
             return carrierPackages.get(0);
@@ -264,8 +267,9 @@
                     getCarrierMessagingServicePackageIfExists(subId);
 
             if (carrierMessagingServicePackage != null) {
-                LogUtil.d(request.toString(), "sending message by carrier app "
-                        + formatCrossStackMessageId(messageId));
+                LogUtil.d(request.toString(), "sending message by carrier app: "
+                        + carrierMessagingServicePackage
+                        + " " + formatCrossStackMessageId(messageId));
                 request.trySendingByCarrierApp(MmsService.this, carrierMessagingServicePackage);
                 return;
             }
@@ -362,8 +366,9 @@
                     getCarrierMessagingServicePackageIfExists(subId);
 
             if (carrierMessagingServicePackage != null) {
-                LogUtil.d(request.toString(), "downloading message by carrier app "
-                        + formatCrossStackMessageId(messageId));
+                LogUtil.d(request.toString(), "downloading message by carrier app: "
+                        + carrierMessagingServicePackage
+                        + " " + formatCrossStackMessageId(messageId));
                 request.tryDownloadingByCarrierApp(MmsService.this, carrierMessagingServicePackage);
                 return;
             }
@@ -596,6 +601,8 @@
                 MmsStats mmsStats) {
             sendErrorInPendingIntent(pendingIntent, resultCode);
             mmsStats.addAtomToStorage(resultCode);
+            String message = "MMS failed" + " with error " + resultCode;
+            AnomalyReporter.reportAnomaly(MmsConstants.MMS_ANOMALY_UUID, message);
         }
     };
 
diff --git a/src/com/android/mms/service/SendRequest.java b/src/com/android/mms/service/SendRequest.java
index 7e078a6..4f97d84 100644
--- a/src/com/android/mms/service/SendRequest.java
+++ b/src/com/android/mms/service/SendRequest.java
@@ -25,11 +25,13 @@
 import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.UserHandle;
 import android.provider.BlockedNumberContract;
 import android.provider.Telephony;
 import android.service.carrier.CarrierMessagingService;
 import android.service.carrier.CarrierMessagingServiceWrapper;
 import android.telephony.SmsManager;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 
@@ -174,10 +176,22 @@
     @Override
     protected Uri persistIfRequired(Context context, int result, byte[] response) {
         final String requestId = getRequestId();
-        if (!SmsApplication.shouldWriteMessageForPackage(mCreator, context)) {
-            // Not required to persist
+
+        SubscriptionManager subManager = context.getSystemService(SubscriptionManager.class);
+        UserHandle userHandle = null;
+        long identity = Binder.clearCallingIdentity();
+        try {
+            if ((subManager != null) && (subManager.isActiveSubscriptionId(mSubId))) {
+                userHandle = subManager.getSubscriptionUserHandle(mSubId);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+
+        if (!SmsApplication.shouldWriteMessageForPackageAsUser(mCreator, context, userHandle)) {
             return null;
         }
+
         LogUtil.d(requestId, "persistIfRequired. "
                 + MmsService.formatCrossStackMessageId(mMessageId));
         if (mPduData == null) {
@@ -185,7 +199,7 @@
                     + MmsService.formatCrossStackMessageId(mMessageId));
             return null;
         }
-        final long identity = Binder.clearCallingIdentity();
+        identity = Binder.clearCallingIdentity();
         try {
             final boolean supportContentDisposition =
                     mMmsConfig.getBoolean(SmsManager.MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION);
@@ -419,10 +433,12 @@
             if (mCarrierMessagingServiceWrapper.bindToCarrierMessagingService(
                     context, carrierMessagingServicePackage, Runnable::run,
                     () -> onServiceReady())) {
-                LogUtil.v("bindService() for carrier messaging service succeeded. "
+                LogUtil.v("bindService() for carrier messaging service: "
+                        + carrierMessagingServicePackage + " succeeded. "
                         + MmsService.formatCrossStackMessageId(mMessageId));
             } else {
-                LogUtil.e("bindService() for carrier messaging service failed. "
+                LogUtil.e("bindService() for carrier messaging service: "
+                        + carrierMessagingServicePackage + " failed. "
                         + MmsService.formatCrossStackMessageId(mMessageId));
                 carrierSendCompleteCallback.onSendMmsComplete(
                         CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK,
diff --git a/src/com/android/mms/service/metrics/MmsMetricsCollector.java b/src/com/android/mms/service/metrics/MmsMetricsCollector.java
index f20d61a..8da61ba 100644
--- a/src/com/android/mms/service/metrics/MmsMetricsCollector.java
+++ b/src/com/android/mms/service/metrics/MmsMetricsCollector.java
@@ -90,7 +90,8 @@
                 mms.getAvgIntervalMillis(),
                 mms.getMmsCount(),
                 mms.getRetryId(),
-                mms.getHandledByCarrierApp());
+                mms.getHandledByCarrierApp(),
+                mms.getIsManagedProfile());
     }
 
     private static StatsEvent buildStatsEvent(OutgoingMms mms) {
@@ -107,7 +108,8 @@
                 mms.getMmsCount(),
                 mms.getIsFromDefaultApp(),
                 mms.getRetryId(),
-                mms.getHandledByCarrierApp());
+                mms.getHandledByCarrierApp(),
+                mms.getIsManagedProfile());
     }
 
     @Override
diff --git a/src/com/android/mms/service/metrics/MmsStats.java b/src/com/android/mms/service/metrics/MmsStats.java
index 26e8967..7e98b0b 100644
--- a/src/com/android/mms/service/metrics/MmsStats.java
+++ b/src/com/android/mms/service/metrics/MmsStats.java
@@ -25,6 +25,8 @@
 import android.content.Context;
 import android.os.Binder;
 import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.UserManager;
 import android.telephony.ServiceState;
 import android.telephony.SmsManager;
 import android.telephony.SubscriptionInfo;
@@ -100,6 +102,7 @@
                 .setMmsCount(1)
                 .setRetryId(retryId)
                 .setHandledByCarrierApp(handledByCarrierApp)
+                .setIsManagedProfile(isManagedProfile())
                 .build();
         mPersistMmsAtomsStorage.addIncomingMms(incomingMms);
     }
@@ -119,10 +122,21 @@
                 .setIsFromDefaultApp(isDefaultMmsApp())
                 .setRetryId(retryId)
                 .setHandledByCarrierApp(handledByCarrierApp)
+                .setIsManagedProfile(isManagedProfile())
                 .build();
         mPersistMmsAtomsStorage.addOutgoingMms(outgoingMms);
     }
 
+    /** @return {@code true} if this SIM is dedicated to work profile */
+    private boolean isManagedProfile() {
+        SubscriptionManager subManager = mContext.getSystemService(SubscriptionManager.class);
+        if (subManager == null || !subManager.isActiveSubscriptionId(mSubId)) return false;
+        UserHandle userHandle = subManager.getSubscriptionUserHandle(mSubId);
+        UserManager userManager = mContext.getSystemService(UserManager.class);
+        if (userHandle == null || userManager == null) return false;
+        return userManager.isManagedProfile(userHandle.getIdentifier());
+    }
+
     /** Returns data network type of current subscription. */
     private int getDataNetworkType() {
         return mTelephonyManager.getDataNetworkType();
@@ -199,7 +213,12 @@
 
     /** Returns if the MMS was originated from the default MMS application. */
     private boolean isDefaultMmsApp() {
-        return SmsApplication.isDefaultMmsApplication(mContext, mCallingPkg);
+        UserHandle userHandle = null;
+        SubscriptionManager subManager = mContext.getSystemService(SubscriptionManager.class);
+        if ((subManager != null) && (subManager.isActiveSubscriptionId(mSubId))) {
+            userHandle = subManager.getSubscriptionUserHandle(mSubId);
+        }
+        return SmsApplication.isDefaultMmsApplicationAsUser(mContext, mCallingPkg, userHandle);
     }
 
     /**
@@ -210,4 +229,4 @@
     private long getInterval() {
         return (SystemClock.elapsedRealtime() - mTimestamp);
     }
-}
\ No newline at end of file
+}
diff --git a/tests/unittests/src/com/android/mms/service/metrics/MmsStatsTest.java b/tests/unittests/src/com/android/mms/service/metrics/MmsStatsTest.java
index f176b6b..2b2cae5 100644
--- a/tests/unittests/src/com/android/mms/service/metrics/MmsStatsTest.java
+++ b/tests/unittests/src/com/android/mms/service/metrics/MmsStatsTest.java
@@ -22,7 +22,9 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 
@@ -38,6 +40,7 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+
 import org.mockito.ArgumentCaptor;
 
 public class MmsStatsTest {
@@ -45,12 +48,17 @@
     private Context mContext;
     private PersistMmsAtomsStorage mPersistMmsAtomsStorage;
     private TelephonyManager mTelephonyManager;
+    private SubscriptionManager mSubscriptionManager;
 
     @Before
     public void setUp() {
         mContext = mock(Context.class);
         mPersistMmsAtomsStorage = mock(PersistMmsAtomsStorage.class);
         mTelephonyManager = mock(TelephonyManager.class);
+        mSubscriptionManager = mock(SubscriptionManager.class);
+
+        doReturn(mSubscriptionManager).when(mContext).getSystemService(
+                Context.TELEPHONY_SUBSCRIPTION_SERVICE);
     }
 
     @After
@@ -83,6 +91,7 @@
         assertThat(incomingMms.getMmsCount()).isEqualTo(1);
         assertThat(incomingMms.getRetryId()).isEqualTo(0);
         assertThat(incomingMms.getHandledByCarrierApp()).isEqualTo(false);
+        assertThat(incomingMms.getIsManagedProfile()).isEqualTo(false);
         verifyNoMoreInteractions(mPersistMmsAtomsStorage);
     }
 
@@ -110,6 +119,7 @@
         assertThat(outgoingMms.getRetryId()).isEqualTo(0);
         assertThat(outgoingMms.getHandledByCarrierApp()).isEqualTo(false);
         assertThat(outgoingMms.getIsFromDefaultApp()).isEqualTo(false);
+        assertThat(outgoingMms.getIsManagedProfile()).isEqualTo(false);
         verifyNoMoreInteractions(mPersistMmsAtomsStorage);
     }
 
@@ -126,4 +136,19 @@
         IncomingMms incomingMms = incomingMmsCaptor.getValue();
         assertThat(incomingMms.getRoaming()).isEqualTo(ServiceState.ROAMING_TYPE_NOT_ROAMING);
     }
+
+
+    @Test
+    public void isDefaultMmsApp_subId_inactive() {
+        int inactiveSubId = 123;
+        doReturn(false).when(mSubscriptionManager)
+                .isActiveSubscriptionId(eq(inactiveSubId));
+
+        MmsStats mmsStats = new MmsStats(mContext, mPersistMmsAtomsStorage, inactiveSubId,
+                mTelephonyManager, null, false);
+        mmsStats.addAtomToStorage(Activity.RESULT_OK);
+
+        // getSubscriptionUserHandle should not be called if subID is inactive.
+        verify(mSubscriptionManager, never()).getSubscriptionUserHandle(eq(inactiveSubId));
+    }
 }
\ No newline at end of file