diff options
24 files changed, 291 insertions, 133 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 7fd3bca595ff..cd4e6f9a826c 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -31480,6 +31480,7 @@ package android.print { 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 @@ package android.print { 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/app/admin/OWNERS b/core/java/android/app/admin/OWNERS index 8462cbe7497b..6acbef29bec3 100644 --- a/core/java/android/app/admin/OWNERS +++ b/core/java/android/app/admin/OWNERS @@ -3,9 +3,9 @@ # Android Enterprise team rubinxu@google.com sandness@google.com -eranm@google.com alexkershaw@google.com pgrafov@google.com # Emeritus yamasani@google.com +eranm@google.com diff --git a/core/java/android/print/PrintAttributes.java b/core/java/android/print/PrintAttributes.java index c19884805507..f5081012fe4c 100644 --- a/core/java/android/print/PrintAttributes.java +++ b/core/java/android/print/PrintAttributes.java @@ -837,8 +837,8 @@ public final class PrintAttributes implements Parcelable { 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 50f63f8db304..c75e23807432 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 36bc22906695..182dba71d0d7 100644 --- a/core/java/com/android/internal/compat/CompatibilityChangeConfig.java +++ b/core/java/com/android/internal/compat/CompatibilityChangeConfig.java @@ -39,14 +39,14 @@ public final class CompatibilityChangeConfig implements Parcelable { * 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 @@ public final class CompatibilityChangeConfig implements Parcelable { @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 000000000000..c5180a3fe8cf --- /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 855448b21069..114f3955fc86 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -630,6 +630,7 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p 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 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p 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 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p 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 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p 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/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java index dd60dd4c40f9..1a636604ed57 100644 --- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java +++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java @@ -44,8 +44,6 @@ import com.android.bandwidthtest.NetworkState; import com.android.bandwidthtest.NetworkState.StateTransitionDirection; import com.android.internal.util.AsyncChannel; -import junit.framework.Assert; - import java.io.IOException; import java.net.UnknownHostException; import java.util.List; @@ -76,7 +74,11 @@ public class ConnectionUtil { private WifiManager mWifiManager; private Context mContext; // Verify connectivity state - private static final int NUM_NETWORK_TYPES = ConnectivityManager.MAX_NETWORK_TYPE + 1; + // ConnectivityManager.TYPE_* is deprecated and no longer extended, so use the max public + // network type - TYPE_VPN should be enough. + // TODO: Replace registering CONNECTIVITY_ACTION with registering NetworkCallback and check + // network by NetworkCapabilities.TRANSPORT_* and NetworkCapabilities.hasTransport() instead. + private static final int NUM_NETWORK_TYPES = ConnectivityManager.TYPE_VPN + 1; private NetworkState[] mConnectivityState = new NetworkState[NUM_NETWORK_TYPES]; public ConnectionUtil(Context context) { 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 000000000000..f67fd516fcf6 --- /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 be865a02a945..3980d3a0203b 100644 --- a/keystore/java/android/security/keystore/AttestationUtils.java +++ b/keystore/java/android/security/keystore/AttestationUtils.java @@ -293,6 +293,11 @@ public abstract class AttestationUtils { } 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 60bcf37304a5..18c38c5a6494 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 class DataUsageController { } 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 f7bee30a087f..27d877db4952 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 @@ public class DataUsageControllerTest { 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/Android.bp b/services/Android.bp index 57a7bc52c057..1f4258dce312 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -156,13 +156,13 @@ droidstubs { defaults: ["services-stubs-default"], check_api: { current: { - api_file: "api/non-updatable-current.txt", - removed_api_file: "api/non-updatable-removed.txt", + api_file: "api/current.txt", + removed_api_file: "api/removed.txt", }, api_lint: { enabled: true, new_since: ":android-non-updatable.api.system-server.latest", - baseline_file: "api/non-updatable-lint-baseline.txt", + baseline_file: "api/lint-baseline.txt", }, }, dists: [ diff --git a/services/api/Android.bp b/services/api/Android.bp index bbc8c72b2eef..ee7d49fc99c8 100644 --- a/services/api/Android.bp +++ b/services/api/Android.bp @@ -24,12 +24,12 @@ package { filegroup { name: "non-updatable-system-server-current.txt", - srcs: ["non-updatable-current.txt"], + srcs: ["current.txt"], visibility: ["//frameworks/base/api"], } filegroup { name: "non-updatable-system-server-removed.txt", - srcs: ["non-updatable-removed.txt"], + srcs: ["removed.txt"], visibility: ["//frameworks/base/api"], } diff --git a/services/api/current.txt b/services/api/current.txt index 7c5c01ef6868..6419b7088fdb 100644 --- a/services/api/current.txt +++ b/services/api/current.txt @@ -1,49 +1,4 @@ // Signature format: 2.0 -package com.android.permission.persistence { - - public interface RuntimePermissionsPersistence { - method @NonNull public static com.android.permission.persistence.RuntimePermissionsPersistence createInstance(); - method public void deleteForUser(@NonNull android.os.UserHandle); - method @Nullable public com.android.permission.persistence.RuntimePermissionsState readForUser(@NonNull android.os.UserHandle); - method public void writeForUser(@NonNull com.android.permission.persistence.RuntimePermissionsState, @NonNull android.os.UserHandle); - } - - public final class RuntimePermissionsState { - ctor public RuntimePermissionsState(int, @Nullable String, @NonNull java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>>, @NonNull java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>>); - method @Nullable public String getFingerprint(); - method @NonNull public java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>> getPackagePermissions(); - method @NonNull public java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>> getSharedUserPermissions(); - method public int getVersion(); - field public static final int NO_VERSION = -1; // 0xffffffff - } - - public static final class RuntimePermissionsState.PermissionState { - ctor public RuntimePermissionsState.PermissionState(@NonNull String, boolean, int); - method public int getFlags(); - method @NonNull public String getName(); - method public boolean isGranted(); - } - -} - -package com.android.role.persistence { - - public interface RolesPersistence { - method @NonNull public static com.android.role.persistence.RolesPersistence createInstance(); - method public void deleteForUser(@NonNull android.os.UserHandle); - method @Nullable public com.android.role.persistence.RolesState readForUser(@NonNull android.os.UserHandle); - method public void writeForUser(@NonNull com.android.role.persistence.RolesState, @NonNull android.os.UserHandle); - } - - public final class RolesState { - ctor public RolesState(int, @Nullable String, @NonNull java.util.Map<java.lang.String,java.util.Set<java.lang.String>>); - method @Nullable public String getPackagesHash(); - method @NonNull public java.util.Map<java.lang.String,java.util.Set<java.lang.String>> getRoles(); - method public int getVersion(); - } - -} - package com.android.server { public final class LocalManagerRegistry { diff --git a/services/api/lint-baseline.txt b/services/api/lint-baseline.txt index e985ddb5352b..b46d21edd44c 100644 --- a/services/api/lint-baseline.txt +++ b/services/api/lint-baseline.txt @@ -1,4 +1,8 @@ // Baseline format: 1.0 +NotCloseable: com.android.server.wifi.SupplicantManager: + Classes that release resources (stop()) should implement AutoClosable and CloseGuard: class com.android.server.wifi.SupplicantManager + + ProtectedMember: com.android.server.SystemService#publishBinderService(String, android.os.IBinder): Protected methods not allowed; must be public: method com.android.server.SystemService.publishBinderService(String,android.os.IBinder)} ProtectedMember: com.android.server.SystemService#publishBinderService(String, android.os.IBinder, boolean): diff --git a/services/api/non-updatable-current.txt b/services/api/non-updatable-current.txt deleted file mode 100644 index 6419b7088fdb..000000000000 --- a/services/api/non-updatable-current.txt +++ /dev/null @@ -1,54 +0,0 @@ -// Signature format: 2.0 -package com.android.server { - - public final class LocalManagerRegistry { - method public static <T> void addManager(@NonNull Class<T>, @NonNull T); - method @Nullable public static <T> T getManager(@NonNull Class<T>); - } - - public abstract class SystemService { - ctor public SystemService(@NonNull android.content.Context); - method @NonNull public final android.content.Context getContext(); - method public boolean isUserSupported(@NonNull com.android.server.SystemService.TargetUser); - method public void onBootPhase(int); - method public abstract void onStart(); - method public void onUserStarting(@NonNull com.android.server.SystemService.TargetUser); - method public void onUserStopped(@NonNull com.android.server.SystemService.TargetUser); - method public void onUserStopping(@NonNull com.android.server.SystemService.TargetUser); - method public void onUserSwitching(@Nullable com.android.server.SystemService.TargetUser, @NonNull com.android.server.SystemService.TargetUser); - method public void onUserUnlocked(@NonNull com.android.server.SystemService.TargetUser); - method public void onUserUnlocking(@NonNull com.android.server.SystemService.TargetUser); - method protected final void publishBinderService(@NonNull String, @NonNull android.os.IBinder); - method protected final void publishBinderService(@NonNull String, @NonNull android.os.IBinder, boolean); - field public static final int PHASE_ACTIVITY_MANAGER_READY = 550; // 0x226 - field public static final int PHASE_BOOT_COMPLETED = 1000; // 0x3e8 - field public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520; // 0x208 - field public static final int PHASE_LOCK_SETTINGS_READY = 480; // 0x1e0 - field public static final int PHASE_SYSTEM_SERVICES_READY = 500; // 0x1f4 - field public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600; // 0x258 - field public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // 0x64 - } - - public static final class SystemService.TargetUser { - method @NonNull public android.os.UserHandle getUserHandle(); - } - -} - -package com.android.server.stats { - - public final class StatsHelper { - method public static void sendStatsdReadyBroadcast(@NonNull android.content.Context); - } - -} - -package com.android.server.wifi { - - public class SupplicantManager { - method public static void start(); - method public static void stop(); - } - -} - diff --git a/services/api/non-updatable-lint-baseline.txt b/services/api/non-updatable-lint-baseline.txt deleted file mode 100644 index b46d21edd44c..000000000000 --- a/services/api/non-updatable-lint-baseline.txt +++ /dev/null @@ -1,9 +0,0 @@ -// Baseline format: 1.0 -NotCloseable: com.android.server.wifi.SupplicantManager: - Classes that release resources (stop()) should implement AutoClosable and CloseGuard: class com.android.server.wifi.SupplicantManager - - -ProtectedMember: com.android.server.SystemService#publishBinderService(String, android.os.IBinder): - Protected methods not allowed; must be public: method com.android.server.SystemService.publishBinderService(String,android.os.IBinder)} -ProtectedMember: com.android.server.SystemService#publishBinderService(String, android.os.IBinder, boolean): - Protected methods not allowed; must be public: method com.android.server.SystemService.publishBinderService(String,android.os.IBinder,boolean)} diff --git a/services/api/non-updatable-removed.txt b/services/api/non-updatable-removed.txt deleted file mode 100644 index d802177e249b..000000000000 --- a/services/api/non-updatable-removed.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index d9ecddae558a..8084de856031 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -2873,6 +2873,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { // 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 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } + 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 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { .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 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { .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 45eb77453dbd..471d2af2784f 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.List; 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 class VcnManagementService extends IVcnManagementService.Stub { 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 @@ public class VcnManagementService extends IVcnManagementService.Stub { 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 @@ public class VcnManagementService extends IVcnManagementService.Stub { 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 c01a1151ee67..29c3dd91c6a3 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 @@ public class NotificationManagerService extends SystemService { .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 @@ public class NotificationManagerService extends SystemService { 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 25b062f85d3e..502bfa3749eb 100644 --- a/telephony/common/android/telephony/LocationAccessPolicy.java +++ b/telephony/common/android/telephony/LocationAccessPolicy.java @@ -86,8 +86,9 @@ public final class LocationAccessPolicy { 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 @@ public final class LocationAccessPolicy { /** * 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 @@ public final class LocationAccessPolicy { /** * 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 @@ public final class LocationAccessPolicy { } /** + * 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 @@ public final class LocationAccessPolicy { /** 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 aa4b5f8e208f..9ecd82ff6bcb 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.os.test.TestLooper; 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.io.FileNotFoundException; 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 @@ public class VcnManagementServiceTest { 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 @@ public class VcnManagementServiceTest { 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, |