Merge "Copy isEmailAddress"
diff --git a/api/system-current.txt b/api/system-current.txt
index e056419..5da2db8 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -9903,6 +9903,7 @@
 
   public class SubscriptionManager {
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean canDisablePhysicalSubscription();
+    method public boolean canManageSubscription(@Nullable android.telephony.SubscriptionInfo, @Nullable String);
     method public java.util.List<android.telephony.SubscriptionInfo> getAvailableSubscriptionInfoList();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEnabledSubscriptionId(int);
     method @NonNull public static android.content.res.Resources getResourcesForSubId(@NonNull android.content.Context, int);
diff --git a/core/java/android/app/StatsManager.java b/core/java/android/app/StatsManager.java
index 2d851e0..b9893aa 100644
--- a/core/java/android/app/StatsManager.java
+++ b/core/java/android/app/StatsManager.java
@@ -38,6 +38,7 @@
 import android.util.StatsEventParcel;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -121,8 +122,17 @@
      **/
     public static final int PULL_SKIP = 1;
 
-    private static final long DEFAULT_COOL_DOWN_NS = 1_000_000_000L; // 1 second.
-    private static final long DEFAULT_TIMEOUT_NS = 10_000_000_000L; // 10 seconds.
+    /**
+     * @hide
+     **/
+    @VisibleForTesting
+    public static final long DEFAULT_COOL_DOWN_NS = 1_000_000_000L; // 1 second.
+
+    /**
+     * @hide
+     **/
+    @VisibleForTesting
+    public static final long DEFAULT_TIMEOUT_NS = 10_000_000_000L; // 10 seconds.
 
     /**
      * Constructor for StatsManagerClient.
@@ -677,6 +687,30 @@
                 return new PullAtomMetadata(mCoolDownNs, mTimeoutNs, mAdditiveFields);
             }
         }
+
+        /**
+         * @hide
+         */
+        @VisibleForTesting
+        public long getCoolDownNs() {
+            return mCoolDownNs;
+        }
+
+        /**
+         * @hide
+         */
+        @VisibleForTesting
+        public long getTimeoutNs() {
+            return mTimeoutNs;
+        }
+
+        /**
+         * @hide
+         */
+        @VisibleForTesting
+        public int[] getAdditiveFields() {
+            return mAdditiveFields;
+        }
     }
 
     /**
diff --git a/core/tests/coretests/src/android/app/PullAtomMetadataTest.java b/core/tests/coretests/src/android/app/PullAtomMetadataTest.java
new file mode 100644
index 0000000..2e3f892
--- /dev/null
+++ b/core/tests/coretests/src/android/app/PullAtomMetadataTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2019 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 android.app;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.StatsManager.PullAtomMetadata;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class PullAtomMetadataTest {
+
+    @Test
+    public void testEmpty() {
+        PullAtomMetadata metadata = PullAtomMetadata.newBuilder().build();
+        assertThat(metadata.getTimeoutNs()).isEqualTo(StatsManager.DEFAULT_TIMEOUT_NS);
+        assertThat(metadata.getCoolDownNs()).isEqualTo(StatsManager.DEFAULT_COOL_DOWN_NS);
+        assertThat(metadata.getAdditiveFields()).isNull();
+    }
+
+    @Test
+    public void testSetTimeoutNs() {
+        long timeoutNs = 500_000_000L;
+        PullAtomMetadata metadata =
+                PullAtomMetadata.newBuilder().setTimeoutNs(timeoutNs).build();
+        assertThat(metadata.getTimeoutNs()).isEqualTo(timeoutNs);
+        assertThat(metadata.getCoolDownNs()).isEqualTo(StatsManager.DEFAULT_COOL_DOWN_NS);
+        assertThat(metadata.getAdditiveFields()).isNull();
+    }
+
+    @Test
+    public void testSetCoolDownNs() {
+        long coolDownNs = 10_000_000_000L;
+        PullAtomMetadata metadata =
+                PullAtomMetadata.newBuilder().setCoolDownNs(coolDownNs).build();
+        assertThat(metadata.getTimeoutNs()).isEqualTo(StatsManager.DEFAULT_TIMEOUT_NS);
+        assertThat(metadata.getCoolDownNs()).isEqualTo(coolDownNs);
+        assertThat(metadata.getAdditiveFields()).isNull();
+    }
+
+    @Test
+    public void testSetAdditiveFields() {
+        int[] fields = {2, 4, 6};
+        PullAtomMetadata metadata =
+                PullAtomMetadata.newBuilder().setAdditiveFields(fields).build();
+        assertThat(metadata.getTimeoutNs()).isEqualTo(StatsManager.DEFAULT_TIMEOUT_NS);
+        assertThat(metadata.getCoolDownNs()).isEqualTo(StatsManager.DEFAULT_COOL_DOWN_NS);
+        assertThat(metadata.getAdditiveFields()).isEqualTo(fields);
+    }
+
+    @Test
+    public void testSetAllElements() {
+        long timeoutNs = 300L;
+        long coolDownNs = 9572L;
+        int[] fields = {3, 2};
+        PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+                .setTimeoutNs(timeoutNs)
+                .setCoolDownNs(coolDownNs)
+                .setAdditiveFields(fields)
+                .build();
+        assertThat(metadata.getTimeoutNs()).isEqualTo(timeoutNs);
+        assertThat(metadata.getCoolDownNs()).isEqualTo(coolDownNs);
+        assertThat(metadata.getAdditiveFields()).isEqualTo(fields);
+    }
+}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 15398ca..ef6ae50 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -2655,8 +2655,7 @@
 
     /**
      * Checks whether the app with the given context is authorized to manage the given subscription
-     * according to its metadata. Only supported for embedded subscriptions (if
-     * {@code SubscriptionInfo#isEmbedded} returns true).
+     * according to its metadata.
      *
      * @param info The subscription to check.
      * @return whether the app is authorized to manage this subscription per its metadata.
@@ -2669,16 +2668,16 @@
      * Checks whether the given app is authorized to manage the given subscription. An app can only
      * be authorized if it is included in the {@link android.telephony.UiccAccessRule} of the
      * {@link android.telephony.SubscriptionInfo} with the access status.
-     * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded}
-     * returns true).
      *
      * @param info The subscription to check.
      * @param packageName Package name of the app to check.
      * @return whether the app is authorized to manage this subscription per its access rules.
      * @hide
      */
-    public boolean canManageSubscription(SubscriptionInfo info, String packageName) {
-        if (info == null || info.getAllAccessRules() == null) {
+    @SystemApi
+    public boolean canManageSubscription(@Nullable SubscriptionInfo info,
+            @Nullable String packageName) {
+        if (info == null || info.getAllAccessRules() == null || packageName == null) {
             return false;
         }
         PackageManager packageManager = mContext.getPackageManager();