diff options
29 files changed, 403 insertions, 333 deletions
diff --git a/Android.bp b/Android.bp index b3c930a3d18b..c1a8012230df 100644 --- a/Android.bp +++ b/Android.bp @@ -520,11 +520,7 @@ java_library { ], }, jarjar_prefix: "com.android.internal.hidden_from_bootclasspath", - - jarjar_shards: select(release_flag("RELEASE_USE_SHARDED_JARJAR_ON_FRAMEWORK_MINUS_APEX"), { - true: "10", - default: "1", - }), + jarjar_shards: "10", } java_library { diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 8a8540602697..a624994d3571 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -6950,7 +6950,7 @@ public final class ActivityThread extends ClientTransactionHandler Slog.w(TAG, "Low overhead tracing feature is not enabled"); break; } - VMDebug.startLowOverheadTrace(); + VMDebug.startLowOverheadTraceForAllMethods(); break; default: try { diff --git a/core/java/android/hardware/usb/OWNERS b/core/java/android/hardware/usb/OWNERS index 37604bc2eb65..1de8a242acfc 100644 --- a/core/java/android/hardware/usb/OWNERS +++ b/core/java/android/hardware/usb/OWNERS @@ -1,7 +1,7 @@ # Bug component: 175220 -anothermark@google.com +vmartensson@google.com +nkapron@google.com febinthattil@google.com -aprasath@google.com +shubhankarm@google.com badhri@google.com -kumarashishg@google.com
\ No newline at end of file diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index ed75491b8e21..86dc20c497e6 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -149,6 +149,11 @@ public class Binder implements IBinder { private static volatile boolean sStackTrackingEnabled = false; /** + * The extension binder object + */ + private IBinder mExtension = null; + + /** * Enable Binder IPC stack tracking. If enabled, every binder transaction will be logged to * {@link TransactionTracker}. * @@ -1234,7 +1239,9 @@ public class Binder implements IBinder { /** @hide */ @Override - public final native @Nullable IBinder getExtension(); + public final @Nullable IBinder getExtension() { + return mExtension; + } /** * Set the binder extension. @@ -1242,7 +1249,12 @@ public class Binder implements IBinder { * * @hide */ - public final native void setExtension(@Nullable IBinder extension); + public final void setExtension(@Nullable IBinder extension) { + mExtension = extension; + setExtensionNative(extension); + } + + private final native void setExtensionNative(@Nullable IBinder extension); /** * Default implementation rewinds the parcels and calls onTransact. On diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java index 78773529294a..c91a3304c3df 100644 --- a/core/java/android/view/InsetsSourceControl.java +++ b/core/java/android/view/InsetsSourceControl.java @@ -190,7 +190,7 @@ public class InsetsSourceControl implements Parcelable { } public void release(Consumer<SurfaceControl> surfaceReleaseConsumer) { - if (mLeash != null) { + if (mLeash != null && mLeash.isValid()) { surfaceReleaseConsumer.accept(mLeash); } } diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index d12976230175..83750aca3766 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -1051,7 +1051,7 @@ public class LockPatternUtils { } final int patternSize = pattern.size(); - byte[] res = new byte[patternSize]; + byte[] res = newNonMovableByteArray(patternSize); for (int i = 0; i < patternSize; i++) { LockPatternView.Cell cell = pattern.get(i); res[i] = (byte) (cell.getRow() * 3 + cell.getColumn() + '1'); diff --git a/core/java/com/android/internal/widget/LockscreenCredential.java b/core/java/com/android/internal/widget/LockscreenCredential.java index 92ce990c67df..2a12c986ab04 100644 --- a/core/java/com/android/internal/widget/LockscreenCredential.java +++ b/core/java/com/android/internal/widget/LockscreenCredential.java @@ -81,9 +81,9 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { /** * Private constructor, use static builder methods instead. * - * <p> Builder methods should create a private copy of the credential bytes and pass in here. - * LockscreenCredential will only store the reference internally without copying. This is to - * minimize the number of extra copies introduced. + * <p> Builder methods should create a private copy of the credential bytes using a non-movable + * array and pass it in here. LockscreenCredential will only store the reference internally + * without copying. This is to minimize the number of extra copies introduced. */ private LockscreenCredential(int type, byte[] credential, boolean hasInvalidChars) { Objects.requireNonNull(credential); @@ -141,7 +141,7 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { */ public static LockscreenCredential createUnifiedProfilePassword(@NonNull byte[] password) { return new LockscreenCredential(CREDENTIAL_TYPE_PASSWORD, - Arrays.copyOf(password, password.length), /* hasInvalidChars= */ false); + copyOfArrayNonMovable(password), /* hasInvalidChars= */ false); } /** @@ -237,7 +237,7 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { /** Create a copy of the credential */ public LockscreenCredential duplicate() { return new LockscreenCredential(mType, - mCredential != null ? Arrays.copyOf(mCredential, mCredential.length) : null, + mCredential != null ? copyOfArrayNonMovable(mCredential) : null, mHasInvalidChars); } @@ -252,6 +252,15 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { } /** + * Copies the given array into a new non-movable array. + */ + private static byte[] copyOfArrayNonMovable(byte[] array) { + byte[] copy = LockPatternUtils.newNonMovableByteArray(array.length); + System.arraycopy(array, 0, copy, 0, array.length); + return copy; + } + + /** * Checks whether the credential meets basic requirements for setting it as a new credential. * * This is redundant if {@link android.app.admin.PasswordMetrics#validateCredential()}, which @@ -440,7 +449,7 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { * @return A byte array representing the input */ private static byte[] charsToBytesTruncating(CharSequence chars) { - byte[] bytes = new byte[chars.length()]; + byte[] bytes = LockPatternUtils.newNonMovableByteArray(chars.length()); for (int i = 0; i < chars.length(); i++) { bytes[i] = (byte) chars.charAt(i); } diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 8003bb7d442b..e85b33e2f7b7 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -74,6 +74,7 @@ static struct bindernative_offsets_t jmethodID mExecTransact; jmethodID mGetInterfaceDescriptor; jmethodID mTransactionCallback; + jmethodID mGetExtension; // Object state. jfieldID mObject; @@ -489,8 +490,12 @@ public: if (mVintf) { ::android::internal::Stability::markVintf(b.get()); } - if (mExtension != nullptr) { - b.get()->setExtension(mExtension); + if (mSetExtensionCalled) { + jobject javaIBinderObject = env->CallObjectMethod(obj, gBinderOffsets.mGetExtension); + sp<IBinder> extensionFromJava = ibinderForJavaObject(env, javaIBinderObject); + if (extensionFromJava != nullptr) { + b.get()->setExtension(extensionFromJava); + } } mBinder = b; ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n", @@ -516,21 +521,12 @@ public: mVintf = false; } - sp<IBinder> getExtension() { - AutoMutex _l(mLock); - sp<JavaBBinder> b = mBinder.promote(); - if (b != nullptr) { - return b.get()->getExtension(); - } - return mExtension; - } - void setExtension(const sp<IBinder>& extension) { AutoMutex _l(mLock); - mExtension = extension; + mSetExtensionCalled = true; sp<JavaBBinder> b = mBinder.promote(); if (b != nullptr) { - b.get()->setExtension(mExtension); + b.get()->setExtension(extension); } } @@ -542,8 +538,7 @@ private: // is too much binder state here, we can think about making JavaBBinder an // sp here (avoid recreating it) bool mVintf = false; - - sp<IBinder> mExtension; + bool mSetExtensionCalled = false; }; // ---------------------------------------------------------------------------- @@ -1249,10 +1244,6 @@ static void android_os_Binder_blockUntilThreadAvailable(JNIEnv* env, jobject cla return IPCThreadState::self()->blockUntilThreadAvailable(); } -static jobject android_os_Binder_getExtension(JNIEnv* env, jobject obj) { - JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject); - return javaObjectForIBinder(env, jbh->getExtension()); -} static void android_os_Binder_setExtension(JNIEnv* env, jobject obj, jobject extensionObject) { JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject); @@ -1295,8 +1286,7 @@ static const JNINativeMethod gBinderMethods[] = { { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder }, { "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer }, { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }, - { "getExtension", "()Landroid/os/IBinder;", (void*)android_os_Binder_getExtension }, - { "setExtension", "(Landroid/os/IBinder;)V", (void*)android_os_Binder_setExtension }, + { "setExtensionNative", "(Landroid/os/IBinder;)V", (void*)android_os_Binder_setExtension }, }; // clang-format on @@ -1313,6 +1303,8 @@ static int int_register_android_os_Binder(JNIEnv* env) gBinderOffsets.mTransactionCallback = GetStaticMethodIDOrDie(env, clazz, "transactionCallback", "(IIII)V"); gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J"); + gBinderOffsets.mGetExtension = GetMethodIDOrDie(env, clazz, "getExtension", + "()Landroid/os/IBinder;"); return RegisterMethodsOrDie( env, kBinderPathName, diff --git a/media/java/android/mtp/OWNERS b/media/java/android/mtp/OWNERS index 77ed08b1f9a5..c57265a91eff 100644 --- a/media/java/android/mtp/OWNERS +++ b/media/java/android/mtp/OWNERS @@ -1,9 +1,9 @@ set noparent -anothermark@google.com +vmartensson@google.com +nkapron@google.com febinthattil@google.com -aprasath@google.com +shubhankarm@google.com jsharkey@android.com jameswei@google.com rmojumder@google.com -kumarashishg@google.com diff --git a/media/jni/OWNERS b/media/jni/OWNERS index e12d828733fa..fdddf13a0a23 100644 --- a/media/jni/OWNERS +++ b/media/jni/OWNERS @@ -4,5 +4,5 @@ per-file android_mtp_*.cpp=aprasath@google.com,anothermark@google.com,kumarashis # extra for TV related files per-file android_media_tv_*=hgchen@google.com,quxiangfang@google.com -per-file android_media_JetPlayer.cpp,android_media_MediaDataSource.cpp,android_media_MediaDataSource.h,android_media_MediaPlayer.java=set noparent -per-file android_media_JetPlayer.cpp,android_media_MediaDataSource.cpp,android_media_MediaDataSource.h,android_media_MediaPlayer.java=file:platform/frameworks/av:/media/janitors/media_solutions_OWNERS +per-file android_media_JetPlayer.cpp,android_media_MediaDataSource.cpp,android_media_MediaDataSource.h,android_media_MediaPlayer.cpp=set noparent +per-file android_media_JetPlayer.cpp,android_media_MediaDataSource.cpp,android_media_MediaDataSource.h,android_media_MediaPlayer.cpp=file:platform/frameworks/av:/media/janitors/media_solutions_OWNERS diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp index a77bc9fe0570..a1ce495fe33d 100644 --- a/media/jni/android_mtp_MtpDatabase.cpp +++ b/media/jni/android_mtp_MtpDatabase.cpp @@ -910,7 +910,7 @@ MtpResponseCode MtpDatabase::getObjectInfo(MtpObjectHandle handle, case MTP_FORMAT_TIFF: case MTP_FORMAT_TIFF_EP: case MTP_FORMAT_DEFINED: { - String8 temp(path); + String8 temp {static_cast<std::string_view>(path)}; std::unique_ptr<FileStream> stream(new FileStream(temp)); piex::PreviewImageData image_data; if (!GetExifFromRawImage(stream.get(), temp, image_data)) { @@ -967,7 +967,7 @@ void* MtpDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) { case MTP_FORMAT_TIFF: case MTP_FORMAT_TIFF_EP: case MTP_FORMAT_DEFINED: { - String8 temp(path); + String8 temp {static_cast<std::string_view>(path)}; std::unique_ptr<FileStream> stream(new FileStream(temp)); piex::PreviewImageData image_data; if (!GetExifFromRawImage(stream.get(), temp, image_data)) { diff --git a/media/tests/MtpTests/OWNERS b/media/tests/MtpTests/OWNERS index bdb6cdbea332..c57265a91eff 100644 --- a/media/tests/MtpTests/OWNERS +++ b/media/tests/MtpTests/OWNERS @@ -1,9 +1,9 @@ set noparent -anothermark@google.com +vmartensson@google.com +nkapron@google.com febinthattil@google.com -aprasath@google.com +shubhankarm@google.com jsharkey@android.com jameswei@google.com rmojumder@google.com -kumarashishg@google.com
\ No newline at end of file diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java index ff08403a84fd..60fae3f1fea9 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java @@ -18,10 +18,13 @@ package com.android.providers.settings; import static android.os.Process.FIRST_APPLICATION_UID; +import static com.android.aconfig_new_storage.Flags.enableAconfigStorageDaemon; + import android.aconfig.Aconfig.flag_permission; import android.aconfig.Aconfig.flag_state; import android.aconfig.Aconfig.parsed_flag; import android.aconfig.Aconfig.parsed_flags; +import android.aconfigd.AconfigdFlagInfo; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; @@ -65,14 +68,10 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; -import java.io.InputStream; import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.attribute.PosixFileAttributes; -import java.nio.file.attribute.PosixFilePermission; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -84,18 +83,6 @@ import java.util.Objects; import java.util.Set; import java.util.concurrent.CountDownLatch; -// FOR ACONFIGD TEST MISSION AND ROLLOUT -import java.io.DataInputStream; -import java.io.DataOutputStream; -import android.util.proto.ProtoInputStream; -import android.aconfigd.Aconfigd.StorageRequestMessage; -import android.aconfigd.Aconfigd.StorageRequestMessages; -import android.aconfigd.Aconfigd.StorageReturnMessage; -import android.aconfigd.Aconfigd.StorageReturnMessages; -import android.aconfigd.AconfigdClientSocket; -import android.aconfigd.AconfigdFlagInfo; -import android.aconfigd.AconfigdJavaUtils; -import static com.android.aconfig_new_storage.Flags.enableAconfigStorageDaemon; /** * This class contains the state for one type of settings. It is responsible * for saving the state asynchronously to an XML file after a mutation and @@ -393,22 +380,6 @@ final class SettingsState { getAllAconfigFlagsFromSettings(mAconfigDefaultFlags); } } - - if (isConfigSettingsKey(mKey)) { - requests = handleBulkSyncToNewStorage(mAconfigDefaultFlags); - } - } - - if (enableAconfigStorageDaemon()) { - if (isConfigSettingsKey(mKey)){ - AconfigdClientSocket localSocket = AconfigdJavaUtils.getAconfigdClientSocket(); - if (requests != null) { - InputStream res = localSocket.send(requests.getBytes()); - if (res == null) { - Slog.w(LOG_TAG, "Bulk sync request to acongid failed."); - } - } - } } } @@ -482,87 +453,6 @@ final class SettingsState { return flag; } - - // TODO(b/341764371): migrate aconfig flag push to GMS core - @VisibleForTesting - @GuardedBy("mLock") - public ProtoOutputStream handleBulkSyncToNewStorage( - Map<String, AconfigdFlagInfo> aconfigFlagMap) { - // get marker or add marker if it does not exist - Setting markerSetting = mSettings.get(BULK_SYNC_MARKER); - int localCounter = 0; - if (markerSetting == null) { - markerSetting = new Setting(BULK_SYNC_MARKER, "0", false, "aconfig", "aconfig"); - mSettings.put(BULK_SYNC_MARKER, markerSetting); - } - try { - localCounter = Integer.parseInt(markerSetting.value); - } catch (NumberFormatException e) { - // reset local counter - markerSetting.value = "0"; - } - - if (enableAconfigStorageDaemon()) { - Setting bulkSyncCounter = mSettings.get(BULK_SYNC_TRIGGER_COUNTER); - int serverCounter = 0; - if (bulkSyncCounter != null) { - try { - serverCounter = Integer.parseInt(bulkSyncCounter.value); - } catch (NumberFormatException e) { - // reset the local value of server counter - bulkSyncCounter.value = "0"; - } - } - - boolean shouldSync = localCounter < serverCounter; - if (!shouldSync) { - // CASE 1, flag is on, bulk sync marker true, nothing to do - return null; - } else { - // CASE 2, flag is on, bulk sync marker false. Do following two tasks - // (1) Do bulk sync here. - // (2) After bulk sync, set marker to true. - - // first add storage reset request - ProtoOutputStream requests = new ProtoOutputStream(); - AconfigdJavaUtils.writeResetStorageRequest(requests); - - // loop over all settings and add flag override requests - for (AconfigdFlagInfo flag : aconfigFlagMap.values()) { - // don't sync read_only flags - if (!flag.getIsReadWrite()) { - continue; - } - - if (flag.getHasServerOverride()) { - AconfigdJavaUtils.writeFlagOverrideRequest( - requests, - flag.getPackageName(), - flag.getFlagName(), - flag.getServerFlagValue(), - StorageRequestMessage.SERVER_ON_REBOOT); - } - - if (flag.getHasLocalOverride()) { - AconfigdJavaUtils.writeFlagOverrideRequest( - requests, - flag.getPackageName(), - flag.getFlagName(), - flag.getLocalFlagValue(), - StorageRequestMessage.LOCAL_ON_REBOOT); - } - } - - // mark sync has been done - markerSetting.value = String.valueOf(serverCounter); - scheduleWriteIfNeededLocked(); - return requests; - } - } else { - return null; - } - } - @GuardedBy("mLock") private void loadAconfigDefaultValuesLocked(List<String> filePaths) { for (String fileName : filePaths) { diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java index f798a35012db..81e1aa88c95f 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java @@ -30,19 +30,20 @@ import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.util.Xml; -import android.util.proto.ProtoOutputStream; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import com.android.modules.utils.TypedXmlSerializer; -import android.platform.test.annotations.EnableFlags; -import android.platform.test.annotations.DisableFlags; -import android.platform.test.flag.junit.SetFlagsRule; - import com.google.common.base.Strings; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; @@ -51,11 +52,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public class SettingsStateTest { @@ -1084,124 +1080,6 @@ public class SettingsStateTest { assertTrue(flag1.getHasLocalOverride()); } - @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - - @Test - @EnableFlags(com.android.aconfig_new_storage.Flags.FLAG_ENABLE_ACONFIG_STORAGE_DAEMON) - public void testHandleBulkSyncWithAconfigdEnabled() { - int configKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_CONFIG, 0); - Object lock = new Object(); - SettingsState settingsState = - new SettingsState( - InstrumentationRegistry.getContext(), - lock, - mSettingsFile, - configKey, - SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, - Looper.getMainLooper()); - - Map<String, AconfigdFlagInfo> flags = new HashMap<>(); - flags.put( - "com.android.flags/flag1", - AconfigdFlagInfo.newBuilder() - .setPackageName("com.android.flags") - .setFlagName("flag1") - .setBootFlagValue("true") - .setIsReadWrite(true) - .build()); - - flags.put( - "com.android.flags/flag2", - AconfigdFlagInfo.newBuilder() - .setPackageName("com.android.flags") - .setFlagName("flag2") - .setBootFlagValue("true") - .setIsReadWrite(false) - .build()); - - String bulkSyncMarker = "aconfigd_marker/bulk_synced"; - String bulkSyncCounter = - "core_experiments_team_internal/" + - "BulkSyncTriggerCounterFlag__bulk_sync_trigger_counter"; - - synchronized (lock) { - settingsState.insertSettingLocked(bulkSyncMarker, "0", null, false, "aconfig"); - settingsState.insertSettingLocked(bulkSyncCounter, "1", null, false, - "com.google.android.platform.core_experiments_team_internal"); - - // first bulk sync - ProtoOutputStream requests = settingsState.handleBulkSyncToNewStorage(flags); - assertTrue(requests != null); - String value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); - assertEquals("1", value); - - // send time should no longer bulk sync - requests = settingsState.handleBulkSyncToNewStorage(flags); - assertNull(requests); - value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); - assertEquals("1", value); - - // won't sync if the marker is string - settingsState.insertSettingLocked(bulkSyncMarker, "true", null, false, "aconfig"); - settingsState.insertSettingLocked(bulkSyncCounter, "0", null, false, - "com.google.android.platform.core_experiments_team_internal"); - requests = settingsState.handleBulkSyncToNewStorage(flags); - assertNull(requests); - value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); - assertEquals("0", value); - - // won't sync if the marker and counter value are the same - settingsState.insertSettingLocked(bulkSyncMarker, "1", null, false, "aconfig"); - settingsState.insertSettingLocked(bulkSyncCounter, "1", null, false, - "com.google.android.platform.core_experiments_team_internal"); - requests = settingsState.handleBulkSyncToNewStorage(flags); - assertNull(requests); - value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); - assertEquals("1", value); - } - } - - @Test - @DisableFlags(com.android.aconfig_new_storage.Flags.FLAG_ENABLE_ACONFIG_STORAGE_DAEMON) - public void testHandleBulkSyncWithAconfigdDisabled() { - int configKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_CONFIG, 0); - Object lock = new Object(); - SettingsState settingsState = new SettingsState( - InstrumentationRegistry.getContext(), lock, mSettingsFile, configKey, - SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper()); - - Map<String, AconfigdFlagInfo> flags = new HashMap<>(); - String bulkSyncMarker = "aconfigd_marker/bulk_synced"; - String bulkSyncCounter = - "core_experiments_team_internal/" + - "BulkSyncTriggerCounterFlag__bulk_sync_trigger_counter"; - synchronized (lock) { - settingsState.insertSettingLocked("aconfigd_marker/bulk_synced", - "true", null, false, "aconfig"); - - // when aconfigd is off, should change the marker to false - ProtoOutputStream requests = settingsState.handleBulkSyncToNewStorage(flags); - assertNull(requests); - String value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); - assertEquals("0", value); - - // marker started with false value, after call, it should remain false - requests = settingsState.handleBulkSyncToNewStorage(flags); - assertNull(requests); - value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); - assertEquals("0", value); - - // won't sync - settingsState.insertSettingLocked(bulkSyncMarker, "0", null, false, "aconfig"); - settingsState.insertSettingLocked(bulkSyncCounter, "1", null, false, - "com.google.android.platform.core_experiments_team_internal"); - requests = settingsState.handleBulkSyncToNewStorage(flags); - assertNull(requests); - value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue(); - assertEquals("0", value); - } - } - @Test public void testGetAllAconfigFlagsFromSettings() throws Exception { final Object lock = new Object(); diff --git a/packages/SystemUI/accessibility/accessibilitymenu/aconfig/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/aconfig/Android.bp index 0ff856e0b91e..1d74774c7c11 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/aconfig/Android.bp +++ b/packages/SystemUI/accessibility/accessibilitymenu/aconfig/Android.bp @@ -5,7 +5,7 @@ package { aconfig_declarations { name: "com_android_a11y_menu_flags", package: "com.android.systemui.accessibility.accessibilitymenu", - container: "system", + container: "system_ext", srcs: [ "accessibility.aconfig", ], diff --git a/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig b/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig index 6d790114803a..bdf6d4242e68 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig +++ b/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig @@ -1,5 +1,5 @@ package: "com.android.systemui.accessibility.accessibilitymenu" -container: "system" +container: "system_ext" # NOTE: Keep alphabetized to help limit merge conflicts from multiple simultaneous editors. diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt index d0c5e7a102e0..49df1694d12b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt @@ -157,7 +157,7 @@ class MediaProjectionChipInteractorTest : SysuiTestCase() { if ( (it.arguments[0] as Intent).`package` == CAST_TO_OTHER_DEVICES_PACKAGE ) { - emptyList() + emptyList<ResolveInfo>() } else { listOf(mock<ResolveInfo>()) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt index 16061df1fa89..8a5797bab33b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt @@ -63,7 +63,7 @@ class CastDeviceTest : SysuiTestCase() { doAnswer { // See Utils.isHeadlessRemoteDisplayProvider if ((it.arguments[0] as Intent).`package` == HEADLESS_REMOTE_PACKAGE) { - emptyList() + emptyList<ResolveInfo>() } else { listOf(mock<ResolveInfo>()) } diff --git a/packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt b/packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt index 7e27b24f749c..33287b7f3449 100644 --- a/packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt +++ b/packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt @@ -1,2 +1,3 @@ rule android.net.vcn.persistablebundleutils.** android.net.connectivity.android.net.vcn.persistablebundleutils.@1 -rule android.net.vcn.util.** android.net.connectivity.android.net.vcn.util.@1
\ No newline at end of file +rule android.net.vcn.util.** android.net.connectivity.android.net.vcn.util.@1 +rule android.util.IndentingPrintWriter android.net.connectivity.android.util.IndentingPrintWriter
\ No newline at end of file diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp index 8e998426685b..adbb3afb4130 100644 --- a/ravenwood/Android.bp +++ b/ravenwood/Android.bp @@ -175,9 +175,9 @@ java_library { } java_device_for_host { - name: "ravenwood-junit-impl-for-ravenizer", + name: "ravenwood-junit-for-ravenizer", libs: [ - "ravenwood-junit-impl", + "ravenwood-junit", ], visibility: [":__subpackages__"], } diff --git a/ravenwood/tools/ravenizer/Android.bp b/ravenwood/tools/ravenizer/Android.bp index 2892d0778ec6..a52a04b44f2d 100644 --- a/ravenwood/tools/ravenizer/Android.bp +++ b/ravenwood/tools/ravenizer/Android.bp @@ -19,7 +19,7 @@ java_binary_host { "ow2-asm-tree", "ow2-asm-util", "junit", - "ravenwood-junit-impl-for-ravenizer", + "ravenwood-junit-for-ravenizer", ], visibility: ["//visibility:public"], } diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java index 8d8064fbf01b..ccc0a25633e5 100644 --- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java +++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java @@ -113,6 +113,7 @@ public class SettingsToPropertiesMapper { DeviceConfig.NAMESPACE_LMKD_NATIVE, DeviceConfig.NAMESPACE_MEDIA_NATIVE, DeviceConfig.NAMESPACE_MGLRU_NATIVE, + DeviceConfig.NAMESPACE_MMD_NATIVE, DeviceConfig.NAMESPACE_NETD_NATIVE, DeviceConfig.NAMESPACE_NNAPI_NATIVE, DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT, diff --git a/services/core/java/com/android/server/am/UidObserverController.java b/services/core/java/com/android/server/am/UidObserverController.java index 7eeec32cf24a..f13bfac58e77 100644 --- a/services/core/java/com/android/server/am/UidObserverController.java +++ b/services/core/java/com/android/server/am/UidObserverController.java @@ -77,6 +77,7 @@ public class UidObserverController { * This is for verifying the UID report flow. */ private static final boolean VALIDATE_UID_STATES = true; + @GuardedBy("mLock") private final ActiveUids mValidateUids; UidObserverController(@NonNull Handler handler) { @@ -282,31 +283,30 @@ public class UidObserverController { } mUidObservers.finishBroadcast(); - if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) { - for (int j = 0; j < numUidChanges; ++j) { - final ChangeRecord item = mActiveUidChanges[j]; - if ((item.change & UidRecord.CHANGE_GONE) != 0) { - mValidateUids.remove(item.uid); - } else { - UidRecord validateUid = mValidateUids.get(item.uid); - if (validateUid == null) { - validateUid = new UidRecord(item.uid, null); - mValidateUids.put(item.uid, validateUid); - } - if ((item.change & UidRecord.CHANGE_IDLE) != 0) { - validateUid.setIdle(true); - } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) { - validateUid.setIdle(false); + synchronized (mLock) { + if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) { + for (int j = 0; j < numUidChanges; ++j) { + final ChangeRecord item = mActiveUidChanges[j]; + if ((item.change & UidRecord.CHANGE_GONE) != 0) { + mValidateUids.remove(item.uid); + } else { + UidRecord validateUid = mValidateUids.get(item.uid); + if (validateUid == null) { + validateUid = new UidRecord(item.uid, null); + mValidateUids.put(item.uid, validateUid); + } + if ((item.change & UidRecord.CHANGE_IDLE) != 0) { + validateUid.setIdle(true); + } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) { + validateUid.setIdle(false); + } + validateUid.setSetProcState(item.procState); + validateUid.setCurProcState(item.procState); + validateUid.setSetCapability(item.capability); + validateUid.setCurCapability(item.capability); } - validateUid.setSetProcState(item.procState); - validateUid.setCurProcState(item.procState); - validateUid.setSetCapability(item.capability); - validateUid.setCurCapability(item.capability); } } - } - - synchronized (mLock) { for (int j = 0; j < numUidChanges; j++) { final ChangeRecord changeRecord = mActiveUidChanges[j]; changeRecord.isPending = false; @@ -433,7 +433,9 @@ public class UidObserverController { } UidRecord getValidateUidRecord(int uid) { - return mValidateUids.get(uid); + synchronized (mLock) { + return mValidateUids.get(uid); + } } void dump(@NonNull PrintWriter pw, @Nullable String dumpPackage) { @@ -488,12 +490,16 @@ public class UidObserverController { boolean dumpValidateUids(@NonNull PrintWriter pw, @Nullable String dumpPackage, int dumpAppId, @NonNull String header, boolean needSep) { - return mValidateUids.dump(pw, dumpPackage, dumpAppId, header, needSep); + synchronized (mLock) { + return mValidateUids.dump(pw, dumpPackage, dumpAppId, header, needSep); + } } void dumpValidateUidsProto(@NonNull ProtoOutputStream proto, @Nullable String dumpPackage, int dumpAppId, long fieldId) { - mValidateUids.dumpProto(proto, dumpPackage, dumpAppId, fieldId); + synchronized (mLock) { + mValidateUids.dumpProto(proto, dumpPackage, dumpAppId, fieldId); + } } static final class ChangeRecord { diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 5b9bab7eeaf0..b09a192990c8 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -12506,10 +12506,10 @@ public class AudioService extends IAudioService.Stub int uid = intent.getIntExtra(Intent.EXTRA_UID, Process.INVALID_UID); if (intent.getBooleanExtra(EXTRA_REPLACING, false) || intent.getBooleanExtra(EXTRA_ARCHIVAL, false)) return; - if (action.equals(ACTION_PACKAGE_ADDED)) { + if (ACTION_PACKAGE_ADDED.equals(action)) { audioserverExecutor.execute(() -> provider.onModifyPackageState(uid, pkgName, false /* isRemoved */)); - } else if (action.equals(ACTION_PACKAGE_REMOVED)) { + } else if (ACTION_PACKAGE_REMOVED.equals(action)) { audioserverExecutor.execute(() -> provider.onModifyPackageState(uid, pkgName, true /* isRemoved */)); } diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 908f51b9cba9..ccac96948b0a 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -1511,10 +1511,13 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D getUiState(displayId).setImeWindowState(vis, backDisposition, showImeSwitcher); mHandler.post(() -> { - if (mBar == null) return; - try { - mBar.setImeWindowStatus(displayId, vis, backDisposition, showImeSwitcher); - } catch (RemoteException ex) { } + IStatusBar bar = mBar; + if (bar != null) { + try { + bar.setImeWindowStatus(displayId, vis, backDisposition, showImeSwitcher); + } catch (RemoteException ex) { + } + } }); } } diff --git a/services/usb/OWNERS b/services/usb/OWNERS index 2dff392d4e34..259261252032 100644 --- a/services/usb/OWNERS +++ b/services/usb/OWNERS @@ -1,9 +1,9 @@ -anothermark@google.com +vmartensson@google.com +nkapron@google.com febinthattil@google.com -aprasath@google.com +shubhankarm@google.com badhri@google.com elaurent@google.com albertccwang@google.com jameswei@google.com howardyen@google.com -kumarashishg@google.com
\ No newline at end of file diff --git a/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt index af753e5963a3..b62843ca3ff4 100644 --- a/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt +++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt @@ -19,6 +19,7 @@ package com.google.android.lint import com.android.tools.lint.client.api.IssueRegistry import com.android.tools.lint.client.api.Vendor import com.android.tools.lint.detector.api.CURRENT_API +import com.google.android.lint.multiuser.PendingIntentGetActivityDetector import com.google.android.lint.parcel.SaferParcelChecker import com.google.auto.service.AutoService @@ -40,6 +41,7 @@ class AndroidFrameworkIssueRegistry : IssueRegistry() { PermissionMethodDetector.ISSUE_PERMISSION_METHOD_USAGE, PermissionMethodDetector.ISSUE_CAN_BE_PERMISSION_METHOD, FeatureAutomotiveDetector.ISSUE, + PendingIntentGetActivityDetector.ISSUE_PENDING_INTENT_GET_ACTIVITY, ) override val api: Int diff --git a/tools/lint/framework/checks/src/main/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetector.kt new file mode 100644 index 000000000000..b9f22ebfa8ec --- /dev/null +++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetector.kt @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2025 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.google.android.lint.multiuser + +import com.android.tools.lint.detector.api.Category +import com.android.tools.lint.detector.api.Detector +import com.android.tools.lint.detector.api.Implementation +import com.android.tools.lint.detector.api.Issue +import com.android.tools.lint.detector.api.JavaContext +import com.android.tools.lint.detector.api.Scope +import com.android.tools.lint.detector.api.Severity +import com.android.tools.lint.detector.api.SourceCodeScanner +import com.intellij.psi.PsiMethod +import java.util.EnumSet +import org.jetbrains.uast.UCallExpression + +/** + * Detector for flagging potential multiuser issues in `PendingIntent.getActivity()` calls. + * + * This detector checks for calls to `PendingIntent#getActivity()` and + * reports a warning if such a call is found, suggesting that the + * default user 0 context might not be the right one. + */ +class PendingIntentGetActivityDetector : Detector(), SourceCodeScanner { + + companion object { + + val description = """Flags potential multiuser issue in PendingIntent.getActivity() calls.""" + + val EXPLANATION = + """ + **Problem:** + + Calling `PendingIntent.getActivity()` in the `system_server` often accidentally uses the user 0 context. Moreover, since there's no explicit user parameter in the `getActivity` method, it can be hard to tell which user the `PendingIntent` activity is associated with, making the code error-prone and less readable. + + **Solution:** + + Always use the user aware methods to refer the correct user context. You can achieve this by: + + * **Using `PendingIntent.getActivityAsUser(...)`:** This API allows you to explicitly specify the user for the activity. + + ```java + PendingIntent.getActivityAsUser( + mContext, /*requestCode=*/0, intent, + PendingIntent.FLAG_IMMUTABLE, /*options=*/null, + UserHandle.of(mUserId)); + ``` + + **When to Ignore this Warning:** + + You can safely ignore this warning if you are certain that: + + * You've confirmed that the `PendingIntent` activity you're targeting is the correct one and is **rightly** associated with the context parameter passed into the `PendingIntent.getActivity` method. + + **Note:** If you are unsure about the user context, it's best to err on the side of caution and explicitly specify the user using the method specified above. + + **For any further questions, please reach out to go/multiuser-help.** + """.trimIndent() + + val ISSUE_PENDING_INTENT_GET_ACTIVITY: Issue = + Issue.create( + id = "PendingIntent#getActivity", + briefDescription = description, + explanation = EXPLANATION, + category = Category.SECURITY, + priority = 8, + severity = Severity.WARNING, + implementation = + Implementation( + PendingIntentGetActivityDetector::class.java, + EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES), + ), + ) + } + + override fun getApplicableMethodNames() = listOf("getActivity") + + override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) { + // Check if the method call is PendingIntent.getActivity + if ( + context.evaluator.isMemberInClass(method, "android.app.PendingIntent") && + method.name == "getActivity" + ) { + context.report( + ISSUE_PENDING_INTENT_GET_ACTIVITY, + node, + context.getLocation(node), + "Using `PendingIntent.getActivity(...)` might not be multiuser-aware. " + + "Consider using the user aware method `PendingIntent.getActivityAsUser(...)`.", + ) + } + } +} diff --git a/tools/lint/framework/checks/src/test/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetectorTest.kt new file mode 100644 index 000000000000..401055055232 --- /dev/null +++ b/tools/lint/framework/checks/src/test/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetectorTest.kt @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2025 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.google.android.lint.multiuser + +import com.android.tools.lint.checks.infrastructure.LintDetectorTest +import com.android.tools.lint.checks.infrastructure.TestFile +import com.android.tools.lint.checks.infrastructure.TestLintTask +import com.android.tools.lint.detector.api.Detector +import com.android.tools.lint.detector.api.Issue + +@Suppress("UnstableApiUsage") +class PendingIntentGetActivityDetectorTest : LintDetectorTest() { + + override fun getDetector(): Detector = PendingIntentGetActivityDetector() + + override fun getIssues(): List<Issue> = + listOf(PendingIntentGetActivityDetector.ISSUE_PENDING_INTENT_GET_ACTIVITY) + + override fun lint(): TestLintTask = super.lint().allowMissingSdk(true) + + fun testPendingIntentGetActivity() { + lint() + .files( + java( + """ + package test.pkg; + + import android.app.PendingIntent; + import android.content.Context; + import android.content.Intent; + + public class TestClass { + private Context mContext; + + public void testMethod(Intent intent) { + PendingIntent.getActivity( + mContext, /*requestCode=*/0, intent, + PendingIntent.FLAG_IMMUTABLE, /*options=*/null + ); + } + } + """ + ) + .indented(), + *stubs, + ) + .issues(PendingIntentGetActivityDetector.ISSUE_PENDING_INTENT_GET_ACTIVITY) + .run() + .expect( + """ + src/test/pkg/TestClass.java:11: Warning: Using PendingIntent.getActivity(...) might not be multiuser-aware. Consider using the user aware method PendingIntent.getActivityAsUser(...). [PendingIntent#getActivity] + PendingIntent.getActivity( + ^ + 0 errors, 1 warnings + """ + ) + } + + fun testPendingIntentGetActivityAsUser() { + lint() + .files( + java( + """ + package test.pkg; + + import android.app.PendingIntent; + import android.content.Context; + import android.content.Intent; + import android.os.UserHandle; + + public class TestClass { + private Context mContext; + + public void testMethod(Intent intent) { + PendingIntent.getActivityAsUser( + mContext, /*requestCode=*/0, intent, + 0, /*options=*/null, + UserHandle.CURRENT + ); + } + } + """ + ) + .indented(), + *stubs, + ) + .issues(PendingIntentGetActivityDetector.ISSUE_PENDING_INTENT_GET_ACTIVITY) + .run() + .expectClean() + } + + private val pendingIntentStub: TestFile = + java( + """ + package android.app; + + import android.content.Context; + import android.content.Intent; + import android.os.UserHandle; + + public class PendingIntent { + public static boolean getActivity(Context context, int requestCode, Intent intent, int flags) { + return true; + } + + public static boolean getActivityAsUser( + Context context, + int requestCode, + Intent intent, + int flags, + UserHandle userHandle + ) { + return true; + } + } + """ + ) + + private val contxtStub: TestFile = + java( + """ + package android.content; + + import android.os.UserHandle; + + public class Context { + + public Context createContextAsUser(UserHandle userHandle, int flags) { + return this; + } + } + + """ + ) + + private val userHandleStub: TestFile = + java( + """ + package android.os; + + public class UserHandle { + + } + + """ + ) + + private val intentStub: TestFile = + java( + """ + package android.content; + + public class Intent { + + } + """ + ) + + private val stubs = arrayOf(pendingIntentStub, contxtStub, userHandleStub, intentStub) +} |