diff options
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(); } } |