Merge "Move myself to emeritus section"
diff --git a/core/api/current.txt b/core/api/current.txt
index 7fd3bca..cd4e6f9 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -31480,6 +31480,7 @@
field public static final android.print.PrintAttributes.MediaSize JPN_HAGAKI;
field public static final android.print.PrintAttributes.MediaSize JPN_KAHU;
field public static final android.print.PrintAttributes.MediaSize JPN_KAKU2;
+ field @NonNull public static final android.print.PrintAttributes.MediaSize JPN_OE_PHOTO_L;
field public static final android.print.PrintAttributes.MediaSize JPN_OUFUKU;
field public static final android.print.PrintAttributes.MediaSize JPN_YOU4;
field @NonNull public static final android.print.PrintAttributes.MediaSize NA_ARCH_A;
@@ -31501,7 +31502,6 @@
field public static final android.print.PrintAttributes.MediaSize NA_QUARTO;
field @NonNull public static final android.print.PrintAttributes.MediaSize NA_SUPER_B;
field public static final android.print.PrintAttributes.MediaSize NA_TABLOID;
- field @NonNull public static final android.print.PrintAttributes.MediaSize OE_PHOTO_L;
field public static final android.print.PrintAttributes.MediaSize OM_DAI_PA_KAI;
field public static final android.print.PrintAttributes.MediaSize OM_JUURO_KU_KAI;
field public static final android.print.PrintAttributes.MediaSize OM_PA_KAI;
diff --git a/core/java/android/print/PrintAttributes.java b/core/java/android/print/PrintAttributes.java
index c198848..f508101 100644
--- a/core/java/android/print/PrintAttributes.java
+++ b/core/java/android/print/PrintAttributes.java
@@ -837,8 +837,8 @@
new MediaSize("JPN_YOU4", "android",
R.string.mediasize_japanese_you4, 4134, 9252);
/** Japanese Photo L media size: 89mm x 127mm (3.5 x 5") */
- public static final @NonNull MediaSize OE_PHOTO_L =
- new MediaSize("OE_PHOTO_L", "android",
+ public static final @NonNull MediaSize JPN_OE_PHOTO_L =
+ new MediaSize("JPN_OE_PHOTO_L", "android",
R.string.mediasize_japanese_l, 3500, 5000);
private final @NonNull String mId;
diff --git a/core/java/android/util/JsonReader.java b/core/java/android/util/JsonReader.java
index 50f63f8..c75e238 100644
--- a/core/java/android/util/JsonReader.java
+++ b/core/java/android/util/JsonReader.java
@@ -16,7 +16,7 @@
package android.util;
-import libcore.internal.StringPool;
+import com.android.internal.util.StringPool;
import java.io.Closeable;
import java.io.EOFException;
diff --git a/core/java/com/android/internal/compat/CompatibilityChangeConfig.java b/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
index 36bc229..182dba7 100644
--- a/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
+++ b/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
@@ -39,14 +39,14 @@
* Changes forced to be enabled.
*/
public Set<Long> enabledChanges() {
- return mChangeConfig.forceEnabledSet();
+ return mChangeConfig.getEnabledSet();
}
/**
* Changes forced to be disabled.
*/
public Set<Long> disabledChanges() {
- return mChangeConfig.forceDisabledSet();
+ return mChangeConfig.getDisabledSet();
}
/**
@@ -84,8 +84,8 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
- long[] enabled = mChangeConfig.forceEnabledChangesArray();
- long[] disabled = mChangeConfig.forceDisabledChangesArray();
+ long[] enabled = mChangeConfig.getEnabledChangesArray();
+ long[] disabled = mChangeConfig.getDisabledChangesArray();
dest.writeLongArray(enabled);
dest.writeLongArray(disabled);
diff --git a/core/java/com/android/internal/util/StringPool.java b/core/java/com/android/internal/util/StringPool.java
new file mode 100644
index 0000000..c5180a3
--- /dev/null
+++ b/core/java/com/android/internal/util/StringPool.java
@@ -0,0 +1,77 @@
+/*
+ * 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.util;
+
+/**
+ * A pool of string instances. Unlike the {@link String#intern() VM's
+ * interned strings}, this pool provides no guarantee of reference equality.
+ * It is intended only to save allocations. This class is not thread safe.
+ *
+ * @hide
+ */
+public final class StringPool {
+
+ private final String[] mPool = new String[512];
+
+ /**
+ * Constructs string pool.
+ */
+ public StringPool() {
+ }
+
+ private static boolean contentEquals(String s, char[] chars, int start, int length) {
+ if (s.length() != length) {
+ return false;
+ }
+ for (int i = 0; i < length; i++) {
+ if (chars[start + i] != s.charAt(i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns a string equal to {@code new String(array, start, length)}.
+ *
+ * @param array buffer containing string chars
+ * @param start offset in {@code array} where string starts
+ * @param length length of string
+ * @return string equal to {@code new String(array, start, length)}
+ */
+ public String get(char[] array, int start, int length) {
+ // Compute an arbitrary hash of the content
+ int hashCode = 0;
+ for (int i = start; i < start + length; i++) {
+ hashCode = (hashCode * 31) + array[i];
+ }
+
+ // Pick a bucket using Doug Lea's supplemental secondaryHash function (from HashMap)
+ hashCode ^= (hashCode >>> 20) ^ (hashCode >>> 12);
+ hashCode ^= (hashCode >>> 7) ^ (hashCode >>> 4);
+ int index = hashCode & (mPool.length - 1);
+
+ String pooled = mPool[index];
+ if (pooled != null && contentEquals(pooled, array, start, length)) {
+ return pooled;
+ }
+
+ String result = new String(array, start, length);
+ mPool[index] = result;
+ return result;
+ }
+}
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 855448b..114f395 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -630,6 +630,7 @@
char hotstartupsamplesOptsBuf[sizeof("-Xps-hot-startup-method-samples:")-1 + PROPERTY_VALUE_MAX];
char saveResolvedClassesDelayMsOptsBuf[
sizeof("-Xps-save-resolved-classes-delay-ms:")-1 + PROPERTY_VALUE_MAX];
+ char profileMinSavePeriodOptsBuf[sizeof("-Xps-min-save-period-ms:")-1 + PROPERTY_VALUE_MAX];
char madviseRandomOptsBuf[sizeof("-XX:MadviseRandomAccess:")-1 + PROPERTY_VALUE_MAX];
char madviseWillNeedFileSizeVdex[
sizeof("-XMadviseWillNeedVdexFileSize:")-1 + PROPERTY_VALUE_MAX];
@@ -662,6 +663,8 @@
char extraOptsBuf[PROPERTY_VALUE_MAX];
char voldDecryptBuf[PROPERTY_VALUE_MAX];
char perfettoHprofOptBuf[sizeof("-XX:PerfettoHprof=") + PROPERTY_VALUE_MAX];
+ char perfettoJavaHeapStackOptBuf[
+ sizeof("-XX:PerfettoJavaHeapStackProf=") + PROPERTY_VALUE_MAX];
enum {
kEMDefault,
kEMIntPortable,
@@ -776,6 +779,10 @@
parseRuntimeOption("dalvik.vm.perfetto_hprof", perfettoHprofOptBuf, "-XX:PerfettoHprof=",
"true");
+ // Enable PerfettoJavaHeapStackProf in the zygote
+ parseRuntimeOption("dalvik.vm.perfetto_javaheap", perfettoJavaHeapStackOptBuf,
+ "-XX:PerfettoJavaHeapStackProf=", "true");
+
if (primary_zygote) {
addOption("-Xprimaryzygote");
}
@@ -859,6 +866,9 @@
parseRuntimeOption("dalvik.vm.ps-resolved-classes-delay-ms", saveResolvedClassesDelayMsOptsBuf,
"-Xps-save-resolved-classes-delay-ms:");
+ parseRuntimeOption("dalvik.vm.ps-min-save-period-ms", profileMinSavePeriodOptsBuf,
+ "-Xps-min-save-period-ms:");
+
property_get("ro.config.low_ram", propBuf, "");
if (strcmp(propBuf, "true") == 0) {
addOption("-XX:LowMemoryMode");
diff --git a/core/tests/utiltests/src/com/android/internal/util/StringPoolTest.java b/core/tests/utiltests/src/com/android/internal/util/StringPoolTest.java
new file mode 100644
index 0000000..f67fd51
--- /dev/null
+++ b/core/tests/utiltests/src/com/android/internal/util/StringPoolTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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.util;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+@SmallTest
+public final class StringPoolTest extends AndroidTestCase {
+
+ public void testStringPool() {
+ StringPool stringPool = new StringPool();
+ String bcd = stringPool.get(new char[] { 'a', 'b', 'c', 'd', 'e' }, 1, 3);
+ assertEquals("bcd", bcd);
+ assertSame(bcd, stringPool.get(new char[] { 'a', 'b', 'c', 'd', 'e' }, 1, 3));
+ }
+
+ public void testHashCollision() {
+ StringPool stringPool = new StringPool();
+ char[] a = { (char) 1, (char) 0 };
+ char[] b = { (char) 0, (char) 31 };
+ assertEquals(new String(a).hashCode(), new String(b).hashCode());
+
+ String aString = stringPool.get(a, 0, 2);
+ assertEquals(new String(a), aString);
+ String bString = stringPool.get(b, 0, 2);
+ assertEquals(new String(b), bString);
+ assertSame(bString, stringPool.get(b, 0, 2));
+ assertNotSame(aString, stringPool.get(a, 0, 2));
+ }
+}
diff --git a/keystore/java/android/security/keystore/AttestationUtils.java b/keystore/java/android/security/keystore/AttestationUtils.java
index be865a0..3980d3a 100644
--- a/keystore/java/android/security/keystore/AttestationUtils.java
+++ b/keystore/java/android/security/keystore/AttestationUtils.java
@@ -293,6 +293,11 @@
} catch (SecurityException e) {
throw e;
} catch (Exception e) {
+ // If a DeviceIdAttestationException was previously wrapped with some other type,
+ // let's throw the original exception instead of wrapping it yet again.
+ if (e.getCause() instanceof DeviceIdAttestationException) {
+ throw (DeviceIdAttestationException) e.getCause();
+ }
throw new DeviceIdAttestationException("Unable to perform attestation", e);
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
index 60bcf37..18c38c5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
@@ -113,7 +113,8 @@
}
public DataUsageInfo getWifiDataUsageInfo() {
- NetworkTemplate template = NetworkTemplate.buildTemplateWifiWildcard();
+ NetworkTemplate template = NetworkTemplate.buildTemplateWifi(
+ NetworkTemplate.WIFI_NETWORKID_ALL, null);
return getDataUsageInfo(template);
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
index f7bee30..27d877d 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
@@ -89,7 +89,8 @@
mNetworkTemplate = NetworkTemplate.buildTemplateMobileAll(SUB_ID);
mNetworkTemplate2 = NetworkTemplate.buildTemplateMobileAll(SUB_ID_2);
- mWifiNetworkTemplate = NetworkTemplate.buildTemplateWifiWildcard();
+ mWifiNetworkTemplate = NetworkTemplate.buildTemplateWifi(
+ NetworkTemplate.WIFI_NETWORKID_ALL, null);
}
@Test
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index d9ecdda..8084de8 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -2873,6 +2873,8 @@
// If we're enforcing fine starting in Q, we also want to enforce coarse even for
// older SDK versions.
locationQueryBuilder.setMinSdkVersionForCoarse(0);
+ locationQueryBuilder.setMinSdkVersionForCoarse(0);
+ locationQueryBuilder.setMinSdkVersionForEnforcement(0);
shouldCheckLocationPermissions = true;
}
@@ -3001,6 +3003,14 @@
}
}
+ private boolean checkFineLocationAccess(Record r) {
+ return checkFineLocationAccess(r, Build.VERSION_CODES.BASE);
+ }
+
+ private boolean checkCoarseLocationAccess(Record r) {
+ return checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE);
+ }
+
/**
* Note -- this method should only be used at the site of a permission check if you need to
* explicitly allow apps below a certain SDK level access regardless of location permissions.
@@ -3016,6 +3026,8 @@
.setMethod("TelephonyRegistry push")
.setLogAsInfo(true) // we don't need to log an error every time we push
.setMinSdkVersionForFine(minSdk)
+ .setMinSdkVersionForCoarse(minSdk)
+ .setMinSdkVersionForEnforcement(minSdk)
.build();
return Binder.withCleanCallingIdentity(() -> {
@@ -3040,6 +3052,8 @@
.setMethod("TelephonyRegistry push")
.setLogAsInfo(true) // we don't need to log an error every time we push
.setMinSdkVersionForCoarse(minSdk)
+ .setMinSdkVersionForFine(Integer.MAX_VALUE)
+ .setMinSdkVersionForEnforcement(minSdk)
.build();
return Binder.withCleanCallingIdentity(() -> {
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index 45eb774..471d2af 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -87,6 +87,7 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
+import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
@@ -431,6 +432,7 @@
public void onNewSnapshot(@NonNull TelephonySubscriptionSnapshot snapshot) {
// Startup VCN instances
synchronized (mLock) {
+ final TelephonySubscriptionSnapshot oldSnapshot = mLastSnapshot;
mLastSnapshot = snapshot;
// Start any VCN instances as necessary
@@ -478,11 +480,29 @@
entry.getValue().updateSubscriptionSnapshot(mLastSnapshot);
}
}
+
+ final Map<ParcelUuid, Set<Integer>> oldSubGrpMappings =
+ getSubGroupToSubIdMappings(oldSnapshot);
+ final Map<ParcelUuid, Set<Integer>> currSubGrpMappings =
+ getSubGroupToSubIdMappings(mLastSnapshot);
+ if (!currSubGrpMappings.equals(oldSubGrpMappings)) {
+ notifyAllPolicyListenersLocked();
+ }
}
}
}
@GuardedBy("mLock")
+ private Map<ParcelUuid, Set<Integer>> getSubGroupToSubIdMappings(
+ @NonNull TelephonySubscriptionSnapshot snapshot) {
+ final Map<ParcelUuid, Set<Integer>> subGrpMappings = new ArrayMap<>();
+ for (ParcelUuid subGrp : mVcns.keySet()) {
+ subGrpMappings.put(subGrp, snapshot.getAllSubIdsInGroup(subGrp));
+ }
+ return subGrpMappings;
+ }
+
+ @GuardedBy("mLock")
private void stopVcnLocked(@NonNull ParcelUuid uuidToTeardown) {
final Vcn vcnToTeardown = mVcns.remove(uuidToTeardown);
if (vcnToTeardown == null) {
@@ -815,6 +835,8 @@
if (isVcnManagedNetwork) {
ncBuilder.removeCapability(
NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+ } else {
+ ncBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
}
if (isRestrictedCarrierWifi) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index c01a115..29c3dd9 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -6850,7 +6850,7 @@
.appendPath(record.getKey()).build())
.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
.putExtra(EXTRA_KEY, record.getKey()),
- PendingIntent.FLAG_UPDATE_CURRENT);
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,
mSystemClock.elapsedRealtime() + record.getNotification().getTimeoutAfter(),
pi);
@@ -7713,6 +7713,21 @@
int rank, int count, boolean wasPosted, String listenerName) {
final String canceledKey = r.getKey();
+ // Get pending intent used to create alarm, use FLAG_NO_CREATE if PendingIntent
+ // does not already exist, then null will be returned.
+ final PendingIntent pi = PendingIntent.getBroadcast(getContext(),
+ REQUEST_CODE_TIMEOUT,
+ new Intent(ACTION_NOTIFICATION_TIMEOUT)
+ .setData(new Uri.Builder().scheme(SCHEME_TIMEOUT)
+ .appendPath(r.getKey()).build())
+ .addFlags(Intent.FLAG_RECEIVER_FOREGROUND),
+ PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE);
+
+ // Cancel alarm corresponding to pi.
+ if (pi != null) {
+ mAlarmManager.cancel(pi);
+ }
+
// Record caller.
recordCallerLocked(r);
diff --git a/telephony/common/android/telephony/LocationAccessPolicy.java b/telephony/common/android/telephony/LocationAccessPolicy.java
index 25b062f..502bfa3 100644
--- a/telephony/common/android/telephony/LocationAccessPolicy.java
+++ b/telephony/common/android/telephony/LocationAccessPolicy.java
@@ -86,8 +86,9 @@
private String mCallingFeatureId;
private int mCallingUid;
private int mCallingPid;
- private int mMinSdkVersionForCoarse = Integer.MAX_VALUE;
- private int mMinSdkVersionForFine = Integer.MAX_VALUE;
+ private int mMinSdkVersionForCoarse = -1;
+ private int mMinSdkVersionForFine = -1;
+ private int mMinSdkVersionForEnforcement = -1;
private boolean mLogAsInfo = false;
private String mMethod;
@@ -125,7 +126,14 @@
/**
* Apps that target at least this sdk version will be checked for coarse location
- * permission. Defaults to INT_MAX (which means don't check)
+ * permission. This method MUST be called before calling {@link #build()}. Otherwise, an
+ * {@link IllegalArgumentException} will be thrown.
+ *
+ * Additionally, if both the argument to this method and
+ * {@link #setMinSdkVersionForFine} are greater than {@link Build.VERSION_CODES#BASE},
+ * you must call {@link #setMinSdkVersionForEnforcement} with the min of the two to
+ * affirm that you do not want any location checks below a certain SDK version.
+ * Otherwise, {@link #build} will throw an {@link IllegalArgumentException}.
*/
public Builder setMinSdkVersionForCoarse(
int minSdkVersionForCoarse) {
@@ -135,7 +143,14 @@
/**
* Apps that target at least this sdk version will be checked for fine location
- * permission. Defaults to INT_MAX (which means don't check)
+ * permission. This method MUST be called before calling {@link #build()}.
+ * Otherwise, an {@link IllegalArgumentException} will be thrown.
+ *
+ * Additionally, if both the argument to this method and
+ * {@link #setMinSdkVersionForCoarse} are greater than {@link Build.VERSION_CODES#BASE},
+ * you must call {@link #setMinSdkVersionForEnforcement} with the min of the two to
+ * affirm that you do not want any location checks below a certain SDK version.
+ * Otherwise, {@link #build} will throw an {@link IllegalArgumentException}.
*/
public Builder setMinSdkVersionForFine(
int minSdkVersionForFine) {
@@ -144,6 +159,17 @@
}
/**
+ * If both the argument to {@link #setMinSdkVersionForFine} and
+ * {@link #setMinSdkVersionForCoarse} are greater than {@link Build.VERSION_CODES#BASE},
+ * this method must be called with the min of the two to
+ * affirm that you do not want any location checks below a certain SDK version.
+ */
+ public Builder setMinSdkVersionForEnforcement(int minSdkVersionForEnforcement) {
+ mMinSdkVersionForEnforcement = minSdkVersionForEnforcement;
+ return this;
+ }
+
+ /**
* Optional, for logging purposes only.
*/
public Builder setMethod(String method) {
@@ -161,6 +187,26 @@
/** build LocationPermissionQuery */
public LocationPermissionQuery build() {
+ if (mMinSdkVersionForCoarse < 0 || mMinSdkVersionForFine < 0) {
+ throw new IllegalArgumentException("Must specify min sdk versions for"
+ + " enforcement for both coarse and fine permissions");
+ }
+ if (mMinSdkVersionForFine > Build.VERSION_CODES.BASE
+ && mMinSdkVersionForCoarse > Build.VERSION_CODES.BASE) {
+ if (mMinSdkVersionForEnforcement != Math.min(
+ mMinSdkVersionForCoarse, mMinSdkVersionForFine)) {
+ throw new IllegalArgumentException("setMinSdkVersionForEnforcement must be"
+ + " called.");
+ }
+ }
+
+ if (mMinSdkVersionForFine < mMinSdkVersionForCoarse) {
+ throw new IllegalArgumentException("Since fine location permission includes"
+ + " access to coarse location, the min sdk level for enforcement of"
+ + " the fine location permission must not be less than the min sdk"
+ + " level for enforcement of the coarse location permission.");
+ }
+
return new LocationPermissionQuery(mCallingPackage, mCallingFeatureId,
mCallingUid, mCallingPid, mMinSdkVersionForCoarse, mMinSdkVersionForFine,
mLogAsInfo, mMethod);
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index aa4b5f8..9ecd82f 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -77,6 +77,7 @@
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.util.ArraySet;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -98,6 +99,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
@@ -326,6 +328,17 @@
return subIdToGroupMap.get(invocation.getArgument(0));
}).when(snapshot).getGroupForSubId(anyInt());
+ doAnswer(invocation -> {
+ final ParcelUuid subGrp = invocation.getArgument(0);
+ final Set<Integer> subIds = new ArraySet<>();
+ for (Entry<Integer, ParcelUuid> entry : subIdToGroupMap.entrySet()) {
+ if (entry.getValue().equals(subGrp)) {
+ subIds.add(entry.getKey());
+ }
+ }
+ return subIds;
+ }).when(snapshot).getAllSubIdsInGroup(any());
+
final TelephonySubscriptionTrackerCallback cb = getTelephonySubscriptionTrackerCallback();
cb.onNewSnapshot(snapshot);
@@ -914,6 +927,18 @@
verify(mMockPolicyListener).onPolicyChanged();
}
+ @Test
+ public void testVcnSubIdChangeUpdatesPolicyListener() throws Exception {
+ startAndGetVcnInstance(TEST_UUID_2);
+ mVcnMgmtSvc.addVcnUnderlyingNetworkPolicyListener(mMockPolicyListener);
+
+ triggerSubscriptionTrackerCbAndGetSnapshot(
+ Collections.singleton(TEST_UUID_2),
+ Collections.singletonMap(TEST_SUBSCRIPTION_ID, TEST_UUID_2));
+
+ verify(mMockPolicyListener).onPolicyChanged();
+ }
+
private void triggerVcnSafeMode(
@NonNull ParcelUuid subGroup,
@NonNull TelephonySubscriptionSnapshot snapshot,