Merge "Small fixes for Kotlin 2." into main
diff --git a/Android.bp b/Android.bp
index b3c930a3..c1a8012 100644
--- a/Android.bp
+++ b/Android.bp
@@ -520,11 +520,7 @@
],
},
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 8a85406..a624994 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -6950,7 +6950,7 @@
Slog.w(TAG, "Low overhead tracing feature is not enabled");
break;
}
- VMDebug.startLowOverheadTrace();
+ VMDebug.startLowOverheadTraceForAllMethods();
break;
default:
try {
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 908f51b..ccac969 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 @@
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/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 af753e5..b62843c 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 @@
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 @@
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 0000000..b9f22eb
--- /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 0000000..4010550
--- /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)
+}