summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/Instrumentation.java9
-rw-r--r--core/java/android/appwidget/AppWidgetHostView.java5
-rw-r--r--core/java/android/os/TestLooperManager.java1
-rw-r--r--core/tests/coretests/src/android/os/BundleTest.java9
-rw-r--r--core/tests/coretests/src/android/os/TestLooperManagerTest.java91
-rw-r--r--media/java/android/media/tv/interactive/ITvInteractiveAppClient.aidl2
-rw-r--r--media/java/android/media/tv/interactive/ITvInteractiveAppSessionCallback.aidl1
-rwxr-xr-xmedia/java/android/media/tv/interactive/TvInteractiveAppManager.java43
-rwxr-xr-xmedia/java/android/media/tv/interactive/TvInteractiveAppService.java44
-rw-r--r--ravenwood/Android.bp17
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java51
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodClassRule.java2
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java55
-rw-r--r--ravenwood/ravenwood-annotation-allowed-classes.txt3
-rw-r--r--services/core/java/com/android/server/SensitiveContentProtectionManagerService.java85
-rw-r--r--services/core/java/com/android/server/content/SyncManager.java9
-rw-r--r--services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java19
-rw-r--r--services/core/jni/com_android_server_am_CachedAppOptimizer.cpp4
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/MessageQueue_host.java8
19 files changed, 424 insertions, 34 deletions
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 2162e3a77f15..68512b8bd771 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -79,6 +79,7 @@ import java.util.concurrent.TimeoutException;
* implementation is described to the system through an AndroidManifest.xml's
* <instrumentation> tag.
*/
+@android.ravenwood.annotation.RavenwoodKeepPartialClass
public class Instrumentation {
/**
@@ -132,6 +133,7 @@ public class Instrumentation {
private UiAutomation mUiAutomation;
private final Object mAnimationCompleteLock = new Object();
+ @android.ravenwood.annotation.RavenwoodKeep
public Instrumentation() {
}
@@ -142,6 +144,7 @@ public class Instrumentation {
* reflection, but it will serve as noticeable discouragement from
* doing such a thing.
*/
+ @android.ravenwood.annotation.RavenwoodReplace
private void checkInstrumenting(String method) {
// Check if we have an instrumentation context, as init should only get called by
// the system in startup processes that are being instrumented.
@@ -151,6 +154,11 @@ public class Instrumentation {
}
}
+ private void checkInstrumenting$ravenwood(String method) {
+ // At the moment, Ravenwood doesn't attach a Context, but we're only ever
+ // running code as part of tests, so we continue quietly
+ }
+
/**
* Returns if it is being called in an instrumentation environment.
*
@@ -2504,6 +2512,7 @@ public class Instrumentation {
* Takes control of the execution of messages on the specified looper until
* {@link TestLooperManager#release} is called.
*/
+ @android.ravenwood.annotation.RavenwoodKeep
public TestLooperManager acquireLooperManager(Looper looper) {
checkInstrumenting("acquireLooperManager");
return new TestLooperManager(looper);
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index ec181dac6b36..1f19f817a0b3 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -907,7 +907,10 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
private InteractionHandler getHandler(InteractionHandler handler) {
return (view, pendingIntent, response) -> {
- AppWidgetManager.getInstance(mContext).noteAppWidgetTapped(mAppWidgetId);
+ AppWidgetManager manager = AppWidgetManager.getInstance(mContext);
+ if (manager != null) {
+ manager.noteAppWidgetTapped(mAppWidgetId);
+ }
if (handler != null) {
return handler.onInteraction(view, pendingIntent, response);
} else {
diff --git a/core/java/android/os/TestLooperManager.java b/core/java/android/os/TestLooperManager.java
index 5e7549fa67d8..4b16c1dce463 100644
--- a/core/java/android/os/TestLooperManager.java
+++ b/core/java/android/os/TestLooperManager.java
@@ -28,6 +28,7 @@ import java.util.concurrent.LinkedBlockingQueue;
* The test code may use {@link #next()} to acquire messages that have been queued to this
* {@link Looper}/{@link MessageQueue} and then {@link #execute} to run any that desires.
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public class TestLooperManager {
private static final ArraySet<Looper> sHeldLoopers = new ArraySet<>();
diff --git a/core/tests/coretests/src/android/os/BundleTest.java b/core/tests/coretests/src/android/os/BundleTest.java
index e7b5dff60110..93c2e0e40593 100644
--- a/core/tests/coretests/src/android/os/BundleTest.java
+++ b/core/tests/coretests/src/android/os/BundleTest.java
@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
@@ -121,6 +122,14 @@ public class BundleTest {
}
@Test
+ public void testEmpty() throws Exception {
+ assertNotNull(Bundle.EMPTY);
+ assertEquals(0, Bundle.EMPTY.size());
+
+ new Bundle(Bundle.EMPTY);
+ }
+
+ @Test
@IgnoreUnderRavenwood(blockedBy = ParcelFileDescriptor.class)
public void testCreateFromParcel() throws Exception {
boolean withFd;
diff --git a/core/tests/coretests/src/android/os/TestLooperManagerTest.java b/core/tests/coretests/src/android/os/TestLooperManagerTest.java
new file mode 100644
index 000000000000..5959444e49cc
--- /dev/null
+++ b/core/tests/coretests/src/android/os/TestLooperManagerTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.platform.test.ravenwood.RavenwoodRule;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class TestLooperManagerTest {
+ private static final String TAG = "TestLooperManagerTest";
+
+ @Rule
+ public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
+ .setProvideMainThread(true)
+ .build();
+
+ @Test
+ public void testMainThread() throws Exception {
+ doTest(Looper.getMainLooper());
+ }
+
+ @Test
+ public void testCustomThread() throws Exception {
+ final HandlerThread thread = new HandlerThread(TAG);
+ thread.start();
+ doTest(thread.getLooper());
+ }
+
+ private void doTest(Looper looper) throws Exception {
+ final TestLooperManager tlm =
+ InstrumentationRegistry.getInstrumentation().acquireLooperManager(looper);
+
+ final Handler handler = new Handler(looper);
+ final CountDownLatch latch = new CountDownLatch(1);
+
+ assertFalse(tlm.hasMessages(handler, null, 42));
+
+ handler.sendEmptyMessage(42);
+ handler.post(() -> {
+ latch.countDown();
+ });
+ assertTrue(tlm.hasMessages(handler, null, 42));
+ assertFalse(latch.await(100, TimeUnit.MILLISECONDS));
+
+ final Message first = tlm.next();
+ assertEquals(42, first.what);
+ assertNull(first.callback);
+ tlm.execute(first);
+ assertFalse(tlm.hasMessages(handler, null, 42));
+ assertFalse(latch.await(100, TimeUnit.MILLISECONDS));
+ tlm.recycle(first);
+
+ final Message second = tlm.next();
+ assertNotNull(second.callback);
+ tlm.execute(second);
+ assertFalse(tlm.hasMessages(handler, null, 42));
+ assertTrue(latch.await(100, TimeUnit.MILLISECONDS));
+ tlm.recycle(second);
+
+ tlm.release();
+ }
+}
diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppClient.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppClient.aidl
index 7b5853169923..1404d7c9841c 100644
--- a/media/java/android/media/tv/interactive/ITvInteractiveAppClient.aidl
+++ b/media/java/android/media/tv/interactive/ITvInteractiveAppClient.aidl
@@ -63,6 +63,8 @@ oneway interface ITvInteractiveAppClient {
void onRequestTvRecordingInfoList(in int type, int seq);
void onRequestSigning(in String id, in String algorithm, in String alias, in byte[] data,
int seq);
+ void onRequestSigning2(in String id, in String algorithm, in String host,
+ int port, in byte[] data, int seq);
void onRequestCertificate(in String host, int port, int seq);
void onAdRequest(in AdRequest request, int Seq);
}
diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppSessionCallback.aidl b/media/java/android/media/tv/interactive/ITvInteractiveAppSessionCallback.aidl
index cb89181fd714..3c91a3eeb1dc 100644
--- a/media/java/android/media/tv/interactive/ITvInteractiveAppSessionCallback.aidl
+++ b/media/java/android/media/tv/interactive/ITvInteractiveAppSessionCallback.aidl
@@ -61,6 +61,7 @@ oneway interface ITvInteractiveAppSessionCallback {
void onRequestTvRecordingInfo(in String recordingId);
void onRequestTvRecordingInfoList(in int type);
void onRequestSigning(in String id, in String algorithm, in String alias, in byte[] data);
+ void onRequestSigning2(in String id, in String algorithm, in String host, int port, in byte[] data);
void onRequestCertificate(in String host, int port);
void onAdRequest(in AdRequest request);
}
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
index 011744f94edb..498eec604b9c 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
@@ -657,6 +657,19 @@ public final class TvInteractiveAppManager {
}
@Override
+ public void onRequestSigning2(
+ String id, String algorithm, String host, int port, byte[] data, int seq) {
+ synchronized (mSessionCallbackRecordMap) {
+ SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+ if (record == null) {
+ Log.e(TAG, "Callback not found for seq " + seq);
+ return;
+ }
+ record.postRequestSigning(id, algorithm, host, port, data);
+ }
+ }
+
+ @Override
public void onRequestCertificate(String host, int port, int seq) {
synchronized (mSessionCallbackRecordMap) {
SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
@@ -2258,6 +2271,17 @@ public final class TvInteractiveAppManager {
});
}
+ void postRequestSigning(String id, String algorithm, String host, int port,
+ byte[] data) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mSessionCallback.onRequestSigning(mSession, id, algorithm, host,
+ port, data);
+ }
+ });
+ }
+
void postRequestCertificate(String host, int port) {
mHandler.post(new Runnable() {
@Override
@@ -2609,6 +2633,25 @@ public final class TvInteractiveAppManager {
}
/**
+ * This is called when
+ * {@link TvInteractiveAppService.Session#requestSigning(String, String, String, int, byte[])} is
+ * called.
+ *
+ * @param session A {@link TvInteractiveAppService.Session} associated with this callback.
+ * @param signingId the ID to identify the request.
+ * @param algorithm the standard name of the signature algorithm requested, such as
+ * MD5withRSA, SHA256withDSA, etc.
+ * @param host The host of the SSL CLient Authentication Server
+ * @param port The port of the SSL Client Authentication Server
+ * @param data the original bytes to be signed.
+ * @hide
+ */
+ public void onRequestSigning(
+ Session session, String signingId, String algorithm, String host,
+ int port, byte[] data) {
+ }
+
+ /**
* This is called when the service requests a SSL certificate for client validation.
*
* @param session A {@link TvInteractiveAppService.Session} associated with this callback.
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppService.java b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
index 054b272d820f..7b6dc38fe22c 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppService.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
@@ -1645,6 +1645,50 @@ public abstract class TvInteractiveAppService extends Service {
}
/**
+ * Requests signing of the given data.
+ *
+ * <p>This is used when the corresponding server of the broadcast-independent interactive
+ * app requires signing during handshaking, and the interactive app service doesn't have
+ * the built-in private key. The private key is provided by the content providers and
+ * pre-built in the related app, such as TV app.
+ *
+ * @param signingId the ID to identify the request. When a result is received, this ID can
+ * be used to correlate the result with the request.
+ * @param algorithm the standard name of the signature algorithm requested, such as
+ * MD5withRSA, SHA256withDSA, etc. The name is from standards like
+ * FIPS PUB 186-4 and PKCS #1.
+ * @param host the host of the SSL client authentication server.
+ * @param port the port of the SSL client authentication server.
+ * @param data the original bytes to be signed.
+ *
+ * @see #onSigningResult(String, byte[])
+ * @see TvInteractiveAppView#createBiInteractiveApp(Uri, Bundle)
+ * @see TvInteractiveAppView#BI_INTERACTIVE_APP_KEY_ALIAS
+ * @hide
+ */
+ @CallSuper
+ public void requestSigning(@NonNull String signingId, @NonNull String algorithm,
+ @NonNull String host, int port, @NonNull byte[] data) {
+ executeOrPostRunnableOnMainThread(new Runnable() {
+ @MainThread
+ @Override
+ public void run() {
+ try {
+ if (DEBUG) {
+ Log.d(TAG, "requestSigning");
+ }
+ if (mSessionCallback != null) {
+ mSessionCallback.onRequestSigning2(signingId, algorithm,
+ host, port, data);
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "error in requestSigning", e);
+ }
+ }
+ });
+ }
+
+ /**
* Requests a SSL certificate for client validation.
*
* @param host the host name of the SSL authentication server.
diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp
index e013a3e41896..1ac69f6c4fc8 100644
--- a/ravenwood/Android.bp
+++ b/ravenwood/Android.bp
@@ -30,6 +30,9 @@ java_library {
"junit-src/**/*.java",
"junit-impl-src/**/*.java",
],
+ static_libs: [
+ "androidx.test.monitor-for-device",
+ ],
libs: [
"framework-minus-apex.ravenwood",
"junit",
@@ -61,3 +64,17 @@ java_host_for_device {
"core-xml-for-host",
],
}
+
+java_host_for_device {
+ name: "androidx.test.monitor-for-device",
+ libs: [
+ "androidx.test.monitor-for-host",
+ ],
+}
+
+java_device_for_host {
+ name: "androidx.test.monitor-for-host",
+ libs: [
+ "androidx.test.monitor",
+ ],
+}
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java
index b3dbcde9d324..a797b1d61b2a 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java
@@ -16,12 +16,35 @@
package android.platform.test.ravenwood;
+import android.app.Instrumentation;
+import android.os.Bundle;
import android.os.HandlerThread;
import android.os.Looper;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import java.io.PrintStream;
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
public class RavenwoodRuleImpl {
private static final String MAIN_THREAD_NAME = "RavenwoodMain";
+ /**
+ * When enabled, attempt to dump all thread stacks just before we hit the
+ * overall Tradefed timeout, to aid in debugging deadlocks.
+ */
+ private static final boolean ENABLE_TIMEOUT_STACKS = false;
+ private static final int TIMEOUT_MILLIS = 9_000;
+
+ private static final ScheduledExecutorService sTimeoutExecutor =
+ Executors.newScheduledThreadPool(1);
+
+ private static ScheduledFuture<?> sPendingTimeout;
+
public static boolean isOnRavenwood() {
return true;
}
@@ -41,9 +64,22 @@ public class RavenwoodRuleImpl {
main.start();
Looper.setMainLooperForTest(main.getLooper());
}
+
+ InstrumentationRegistry.registerInstance(new Instrumentation(), Bundle.EMPTY);
+
+ if (ENABLE_TIMEOUT_STACKS) {
+ sPendingTimeout = sTimeoutExecutor.schedule(RavenwoodRuleImpl::dumpStacks,
+ TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+ }
}
public static void reset(RavenwoodRule rule) {
+ if (ENABLE_TIMEOUT_STACKS) {
+ sPendingTimeout.cancel(false);
+ }
+
+ InstrumentationRegistry.registerInstance(null, Bundle.EMPTY);
+
if (rule.mProvideMainThread) {
Looper.getMainLooper().quit();
Looper.clearMainLooperForTest();
@@ -55,4 +91,19 @@ public class RavenwoodRuleImpl {
android.os.Binder.reset$ravenwood();
android.os.Process.reset$ravenwood();
}
+
+ private static void dumpStacks() {
+ final PrintStream out = System.err;
+ out.println("-----BEGIN ALL THREAD STACKS-----");
+ final Map<Thread, StackTraceElement[]> stacks = Thread.getAllStackTraces();
+ for (Map.Entry<Thread, StackTraceElement[]> stack : stacks.entrySet()) {
+ out.println();
+ Thread t = stack.getKey();
+ out.println(t.toString() + " ID=" + t.getId());
+ for (StackTraceElement e : stack.getValue()) {
+ out.println("\tat " + e);
+ }
+ }
+ out.println("-----END ALL THREAD STACKS-----");
+ }
}
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodClassRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodClassRule.java
index 68b163ede89c..8d76970f9ad4 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodClassRule.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodClassRule.java
@@ -19,6 +19,7 @@ package android.platform.test.ravenwood;
import static android.platform.test.ravenwood.RavenwoodRule.ENABLE_PROBE_IGNORED;
import static android.platform.test.ravenwood.RavenwoodRule.IS_ON_RAVENWOOD;
import static android.platform.test.ravenwood.RavenwoodRule.shouldEnableOnRavenwood;
+import static android.platform.test.ravenwood.RavenwoodRule.shouldStillIgnoreInProbeIgnoreMode;
import android.platform.test.annotations.DisabledOnRavenwood;
import android.platform.test.annotations.EnabledOnRavenwood;
@@ -45,6 +46,7 @@ public class RavenwoodClassRule implements TestRule {
}
if (ENABLE_PROBE_IGNORED) {
+ Assume.assumeFalse(shouldStillIgnoreInProbeIgnoreMode(description));
// Pass through to possible underlying RavenwoodRule for both environment
// configuration and handling method-level annotations
return base;
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
index 952ee0e184b1..1e7cbf6d802d 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
@@ -27,7 +27,9 @@ import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
+import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.regex.Pattern;
/**
* {@code @Rule} that configures the Ravenwood test environment. This rule has no effect when
@@ -55,6 +57,43 @@ public class RavenwoodRule implements TestRule {
static final boolean ENABLE_PROBE_IGNORED = "1".equals(
System.getenv("RAVENWOOD_RUN_DISABLED_TESTS"));
+ /**
+ * When using ENABLE_PROBE_IGNORED, you may still want to skip certain tests,
+ * for example because the test would crash the JVM.
+ *
+ * This regex defines the tests that should still be disabled even if ENABLE_PROBE_IGNORED
+ * is set.
+ *
+ * Before running each test class and method, we check if this pattern can be found in
+ * the full test name (either [class full name], or [class full name] + "#" + [method name]),
+ * and if so, we skip it.
+ *
+ * For example, if you want to skip an entire test class, use:
+ * RAVENWOOD_REALLY_DISABLE='\.CustomTileDefaultsRepositoryTest$'
+ *
+ * For example, if you want to skip an entire test class, use:
+ * RAVENWOOD_REALLY_DISABLE='\.CustomTileDefaultsRepositoryTest#testSimple$'
+ *
+ * To ignore multiple classes, use (...|...), for example:
+ * RAVENWOOD_REALLY_DISABLE='\.(ClassA|ClassB)$'
+ *
+ * Because we use a regex-find, setting "." would disable all tests.
+ */
+ private static final Pattern REALLY_DISABLE_PATTERN = Pattern.compile(
+ Objects.requireNonNullElse(System.getenv("RAVENWOOD_REALLY_DISABLE"), ""));
+
+ private static final boolean ENABLE_REALLY_DISABLE_PATTERN =
+ !REALLY_DISABLE_PATTERN.pattern().isEmpty();
+
+ static {
+ if (ENABLE_PROBE_IGNORED) {
+ System.out.println("$RAVENWOOD_RUN_DISABLED_TESTS enabled: force running all tests");
+ if (ENABLE_REALLY_DISABLE_PATTERN) {
+ System.out.println("$RAVENWOOD_REALLY_DISABLE=" + REALLY_DISABLE_PATTERN.pattern());
+ }
+ }
+ }
+
private static final int SYSTEM_UID = 1000;
private static final int NOBODY_UID = 9999;
private static final int FIRST_APPLICATION_UID = 10000;
@@ -203,6 +242,21 @@ public class RavenwoodRule implements TestRule {
return true;
}
+ static boolean shouldStillIgnoreInProbeIgnoreMode(Description description) {
+ if (!ENABLE_REALLY_DISABLE_PATTERN) {
+ return false;
+ }
+
+ final var fullname = description.getTestClass().getName()
+ + (description.isTest() ? "#" + description.getMethodName() : "");
+
+ if (REALLY_DISABLE_PATTERN.matcher(fullname).find()) {
+ System.out.println("Still ignoring " + fullname);
+ return true;
+ }
+ return false;
+ }
+
@Override
public Statement apply(Statement base, Description description) {
// No special treatment when running outside Ravenwood; run tests as-is
@@ -245,6 +299,7 @@ public class RavenwoodRule implements TestRule {
return new Statement() {
@Override
public void evaluate() throws Throwable {
+ Assume.assumeFalse(shouldStillIgnoreInProbeIgnoreMode(description));
RavenwoodRuleImpl.init(RavenwoodRule.this);
try {
base.evaluate();
diff --git a/ravenwood/ravenwood-annotation-allowed-classes.txt b/ravenwood/ravenwood-annotation-allowed-classes.txt
index eaf01a32592e..b775f9ad47ad 100644
--- a/ravenwood/ravenwood-annotation-allowed-classes.txt
+++ b/ravenwood/ravenwood-annotation-allowed-classes.txt
@@ -72,6 +72,7 @@ android.os.Process
android.os.ServiceSpecificException
android.os.SystemClock
android.os.SystemProperties
+android.os.TestLooperManager
android.os.ThreadLocalWorkSource
android.os.TimestampedValue
android.os.Trace
@@ -141,6 +142,8 @@ android.graphics.RectF
android.content.ContentProvider
+android.app.Instrumentation
+
android.metrics.LogMaker
android.view.Display$HdrCapabilities
diff --git a/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java b/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java
index c3916422159e..f619ca3f66a2 100644
--- a/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java
+++ b/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java
@@ -27,6 +27,7 @@ import android.media.projection.MediaProjectionManager;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
+import android.os.Trace;
import android.os.UserHandle;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.RankingMap;
@@ -49,12 +50,12 @@ public final class SensitiveContentProtectionManagerService extends SystemServic
private static final String TAG = "SensitiveContentProtect";
private static final boolean DEBUG = false;
- @VisibleForTesting
- NotificationListener mNotificationListener;
+ @VisibleForTesting NotificationListener mNotificationListener;
private @Nullable MediaProjectionManager mProjectionManager;
private @Nullable WindowManagerInternal mWindowManager;
final Object mSensitiveContentProtectionLock = new Object();
+
@GuardedBy("mSensitiveContentProtectionLock")
private boolean mProjectionActive = false;
@@ -63,13 +64,24 @@ public final class SensitiveContentProtectionManagerService extends SystemServic
@Override
public void onStart(MediaProjectionInfo info) {
if (DEBUG) Log.d(TAG, "onStart projection: " + info);
- onProjectionStart();
+ Trace.beginSection(
+ "SensitiveContentProtectionManagerService.onProjectionStart");
+ try {
+ onProjectionStart();
+ } finally {
+ Trace.endSection();
+ }
}
@Override
public void onStop(MediaProjectionInfo info) {
if (DEBUG) Log.d(TAG, "onStop projection: " + info);
- onProjectionEnd();
+ Trace.beginSection("SensitiveContentProtectionManagerService.onProjectionStop");
+ try {
+ onProjectionEnd();
+ } finally {
+ Trace.endSection();
+ }
}
};
@@ -94,8 +106,7 @@ public final class SensitiveContentProtectionManagerService extends SystemServic
}
@VisibleForTesting
- void init(MediaProjectionManager projectionManager,
- WindowManagerInternal windowManager) {
+ void init(MediaProjectionManager projectionManager, WindowManagerInternal windowManager) {
if (DEBUG) Log.d(TAG, "init");
checkNotNull(projectionManager, "Failed to get valid MediaProjectionManager");
@@ -109,7 +120,8 @@ public final class SensitiveContentProtectionManagerService extends SystemServic
mProjectionManager.addCallback(mProjectionCallback, new Handler(Looper.getMainLooper()));
try {
- mNotificationListener.registerAsSystemService(getContext(),
+ mNotificationListener.registerAsSystemService(
+ getContext(),
new ComponentName(getContext(), NotificationListener.class),
UserHandle.USER_ALL);
} catch (RemoteException e) {
@@ -174,8 +186,8 @@ public final class SensitiveContentProtectionManagerService extends SystemServic
}
// notify windowmanager of any currently posted sensitive content notifications
- ArraySet<PackageInfo> packageInfos = getSensitivePackagesFromNotifications(
- notifications, rankingMap);
+ ArraySet<PackageInfo> packageInfos =
+ getSensitivePackagesFromNotifications(notifications, rankingMap);
mWindowManager.addBlockScreenCaptureForApps(packageInfos);
}
@@ -197,8 +209,8 @@ public final class SensitiveContentProtectionManagerService extends SystemServic
return sensitivePackages;
}
- private PackageInfo getSensitivePackageFromNotification(StatusBarNotification sbn,
- RankingMap rankingMap) {
+ private PackageInfo getSensitivePackageFromNotification(
+ StatusBarNotification sbn, RankingMap rankingMap) {
if (sbn == null) {
Log.w(TAG, "Unable to protect null notification");
return null;
@@ -220,38 +232,55 @@ public final class SensitiveContentProtectionManagerService extends SystemServic
@Override
public void onListenerConnected() {
super.onListenerConnected();
- // Projection started before notification listener was connected
- synchronized (mSensitiveContentProtectionLock) {
- if (mProjectionActive) {
- updateAppsThatShouldBlockScreenCapture();
+ Trace.beginSection("SensitiveContentProtectionManagerService.onListenerConnected");
+ try {
+ // Projection started before notification listener was connected
+ synchronized (mSensitiveContentProtectionLock) {
+ if (mProjectionActive) {
+ updateAppsThatShouldBlockScreenCapture();
+ }
}
+ } finally {
+ Trace.endSection();
}
}
@Override
public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
super.onNotificationPosted(sbn, rankingMap);
- synchronized (mSensitiveContentProtectionLock) {
- if (!mProjectionActive) {
- return;
- }
-
- // notify windowmanager of any currently posted sensitive content notifications
- PackageInfo packageInfo = getSensitivePackageFromNotification(sbn, rankingMap);
-
- if (packageInfo != null) {
- mWindowManager.addBlockScreenCaptureForApps(new ArraySet(Set.of(packageInfo)));
+ Trace.beginSection("SensitiveContentProtectionManagerService.onNotificationPosted");
+ try {
+ synchronized (mSensitiveContentProtectionLock) {
+ if (!mProjectionActive) {
+ return;
+ }
+
+ // notify windowmanager of any currently posted sensitive content notifications
+ PackageInfo packageInfo = getSensitivePackageFromNotification(sbn, rankingMap);
+
+ if (packageInfo != null) {
+ mWindowManager.addBlockScreenCaptureForApps(
+ new ArraySet(Set.of(packageInfo)));
+ }
}
+ } finally {
+ Trace.endSection();
}
}
@Override
public void onNotificationRankingUpdate(RankingMap rankingMap) {
super.onNotificationRankingUpdate(rankingMap);
- synchronized (mSensitiveContentProtectionLock) {
- if (mProjectionActive) {
- updateAppsThatShouldBlockScreenCapture(rankingMap);
+ Trace.beginSection(
+ "SensitiveContentProtectionManagerService.onNotificationRankingUpdate");
+ try {
+ synchronized (mSensitiveContentProtectionLock) {
+ if (mProjectionActive) {
+ updateAppsThatShouldBlockScreenCapture(rankingMap);
+ }
}
+ } finally {
+ Trace.endSection();
}
}
}
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index df179a9b6d65..5b23364cf546 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -138,6 +138,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Random;
import java.util.Set;
@@ -3870,8 +3871,12 @@ public class SyncManager {
final SyncStorageEngine.EndPoint info = syncOperation.target;
if (activeSyncContext.mIsLinkedToDeath) {
- activeSyncContext.mSyncAdapter.asBinder().unlinkToDeath(activeSyncContext, 0);
- activeSyncContext.mIsLinkedToDeath = false;
+ try {
+ activeSyncContext.mSyncAdapter.asBinder().unlinkToDeath(activeSyncContext, 0);
+ activeSyncContext.mIsLinkedToDeath = false;
+ } catch (NoSuchElementException e) {
+ Slog.wtf(TAG, "Failed to unlink active sync adapter to death", e);
+ }
}
final long elapsedTime = SystemClock.elapsedRealtime() - activeSyncContext.mStartTime;
String historyMessage;
diff --git a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
index b6d0ca19d484..eacd3f8d4d86 100644
--- a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
+++ b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
@@ -4152,6 +4152,25 @@ public class TvInteractiveAppManagerService extends SystemService {
}
@Override
+ public void onRequestSigning2(String id, String algorithm, String host,
+ int port, byte[] data) {
+ synchronized (mLock) {
+ if (DEBUG) {
+ Slogf.d(TAG, "onRequestSigning");
+ }
+ if (mSessionState.mSession == null || mSessionState.mClient == null) {
+ return;
+ }
+ try {
+ mSessionState.mClient.onRequestSigning2(
+ id, algorithm, host, port, data, mSessionState.mSeq);
+ } catch (RemoteException e) {
+ Slogf.e(TAG, "error in onRequestSigning", e);
+ }
+ }
+ }
+
+ @Override
public void onRequestCertificate(String host, int port) {
synchronized (mLock) {
if (DEBUG) {
diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
index 7b084132ed1c..4403bce484ad 100644
--- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
+++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
@@ -571,8 +571,8 @@ static jstring com_android_server_am_CachedAppOptimizer_getFreezerCheckPath(JNIE
}
static jboolean com_android_server_am_CachedAppOptimizer_isFreezerProfileValid(JNIEnv* env) {
- int uid = getuid();
- int pid = getpid();
+ uid_t uid = getuid();
+ pid_t pid = getpid();
return isProfileValidForProcess("Frozen", uid, pid) &&
isProfileValidForProcess("Unfrozen", uid, pid);
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/MessageQueue_host.java b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/MessageQueue_host.java
index 2e47d48f4fa0..65da4a144160 100644
--- a/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/MessageQueue_host.java
+++ b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/MessageQueue_host.java
@@ -28,6 +28,7 @@ public class MessageQueue_host {
private final Object mPoller = new Object();
private volatile boolean mPolling;
+ private volatile boolean mPendingWake;
private void validate() {
if (mDeleted) {
@@ -62,7 +63,9 @@ public class MessageQueue_host {
synchronized (q.mPoller) {
q.mPolling = true;
try {
- if (timeoutMillis == 0) {
+ if (q.mPendingWake) {
+ // Calling with pending wake returns immediately
+ } else if (timeoutMillis == 0) {
// Calling epoll_wait() with 0 returns immediately
} else if (timeoutMillis == -1) {
q.mPoller.wait();
@@ -72,6 +75,8 @@ public class MessageQueue_host {
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
+ // Any reason for returning counts as a "wake", so clear pending
+ q.mPendingWake = false;
q.mPolling = false;
}
}
@@ -79,6 +84,7 @@ public class MessageQueue_host {
public static void nativeWake(long ptr) {
var q = getInstance(ptr);
synchronized (q.mPoller) {
+ q.mPendingWake = true;
q.mPoller.notifyAll();
}
}