diff options
27 files changed, 476 insertions, 53 deletions
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index bd9ab86fa8d1..6473cd815824 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -2310,7 +2310,6 @@ public abstract class NotificationListenerService extends Service { // -- parcelable interface -- private RankingMap(Parcel in) { - final ClassLoader cl = getClass().getClassLoader(); final int count = in.readInt(); mOrderedKeys.ensureCapacity(count); mRankings.ensureCapacity(count); diff --git a/core/java/android/service/voice/OWNERS b/core/java/android/service/voice/OWNERS index 5f9f6bde3129..b6f0270dfbbc 100644 --- a/core/java/android/service/voice/OWNERS +++ b/core/java/android/service/voice/OWNERS @@ -1,6 +1,6 @@ # Bug component: 533220 - include /core/java/android/app/assist/OWNERS +atneya@google.com # The owner here should not be assist owner adudani@google.com diff --git a/core/tests/coretests/src/android/os/BinderProxyTest.java b/core/tests/coretests/src/android/os/BinderProxyTest.java index a903ed91cb3d..335791c031b4 100644 --- a/core/tests/coretests/src/android/os/BinderProxyTest.java +++ b/core/tests/coretests/src/android/os/BinderProxyTest.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.annotation.Nullable; +import android.app.ActivityManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -42,7 +43,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) -@IgnoreUnderRavenwood(blockedBy = PowerManager.class) +@IgnoreUnderRavenwood(blockedBy = ActivityManager.class) public class BinderProxyTest { private static class CountingListener implements Binder.ProxyTransactListener { int mStartedCount; @@ -62,7 +63,7 @@ public class BinderProxyTest { public final RavenwoodRule mRavenwood = new RavenwoodRule(); private Context mContext; - private PowerManager mPowerManager; + private ActivityManager mActivityManager; /** * Setup any common data for the upcoming tests. @@ -70,7 +71,7 @@ public class BinderProxyTest { @Before public void setUp() throws Exception { mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); - mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); + mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); } @Test @@ -80,7 +81,7 @@ public class BinderProxyTest { Binder.setProxyTransactListener(listener); Binder.setProxyTransactListener(null); - mPowerManager.isInteractive(); + mActivityManager.isUserRunning(7); // something which does a binder call assertEquals(0, listener.mStartedCount); assertEquals(0, listener.mEndedCount); @@ -92,7 +93,7 @@ public class BinderProxyTest { CountingListener listener = new CountingListener(); Binder.setProxyTransactListener(listener); - mPowerManager.isInteractive(); + mActivityManager.isUserRunning(27); // something which does a binder call assertEquals(1, listener.mStartedCount); assertEquals(1, listener.mEndedCount); @@ -112,7 +113,7 @@ public class BinderProxyTest { }); // Check it does not throw.. - mPowerManager.isInteractive(); + mActivityManager.isUserRunning(47); // something which does a binder call } private IBinder mRemoteBinder = null; diff --git a/native/android/OWNERS b/native/android/OWNERS index f0db2ea236ea..1fde7d268517 100644 --- a/native/android/OWNERS +++ b/native/android/OWNERS @@ -2,7 +2,7 @@ jreck@google.com #{LAST_RESORT_SUGGESTION} # General NDK API reviewers per-file libandroid.map.txt = danalbert@google.com, etalvala@google.com, michaelwr@google.com -per-file libandroid.map.txt = jreck@google.com, zyy@google.com +per-file libandroid.map.txt = jreck@google.com, zyy@google.com, mattbuckley@google.com # Networking per-file libandroid_net.map.txt, net.c = set noparent diff --git a/nfc/tests/src/android/nfc/NdefRecordTest.java b/nfc/tests/src/android/nfc/NdefRecordTest.java new file mode 100644 index 000000000000..231e939b4fbe --- /dev/null +++ b/nfc/tests/src/android/nfc/NdefRecordTest.java @@ -0,0 +1,59 @@ +/* + * 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.nfc; + +import static com.google.common.truth.Truth.assertThat; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class NdefRecordTest { + + @Test + public void testNdefRecordConstructor() throws FormatException { + NdefRecord applicationRecord = NdefRecord + .createApplicationRecord("com.android.test"); + NdefRecord ndefRecord = new NdefRecord(applicationRecord.toByteArray()); + assertThat(ndefRecord).isNotNull(); + assertThat(ndefRecord.toByteArray().length).isGreaterThan(0); + assertThat(ndefRecord.getType()).isEqualTo("android.com:pkg".getBytes()); + assertThat(ndefRecord.getPayload()).isEqualTo("com.android.test".getBytes()); + } + + @Test + public void testCreateExternal() { + NdefRecord ndefRecord = NdefRecord.createExternal("test", + "android.com:pkg", "com.android.test".getBytes()); + assertThat(ndefRecord).isNotNull(); + assertThat(ndefRecord.getType()).isEqualTo("test:android.com:pkg".getBytes()); + assertThat(ndefRecord.getPayload()).isEqualTo("com.android.test".getBytes()); + } + + @Test + public void testCreateUri() { + NdefRecord ndefRecord = NdefRecord.createUri("http://www.example.com"); + assertThat(ndefRecord).isNotNull(); + assertThat(ndefRecord.getTnf()).isEqualTo(NdefRecord.TNF_WELL_KNOWN); + assertThat(ndefRecord.getType()).isEqualTo(NdefRecord.RTD_URI); + } + +} diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java index de3c5f2c23ab..9644a52a749e 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java @@ -63,8 +63,6 @@ import java.util.function.BiConsumer; * - Handle {@link android.platform.test.annotations.DisabledOnRavenwood}. */ public final class RavenwoodAwareTestRunner extends RavenwoodAwareTestRunnerBase { - public static final String TAG = "Ravenwood"; - /** Scope of a hook. */ public enum Scope { Class, diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java index 239c8061b757..9eff20ad70e6 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java @@ -45,7 +45,7 @@ import java.util.concurrent.Executor; import java.util.function.Supplier; public class RavenwoodContext extends RavenwoodBaseContext { - private static final String TAG = "Ravenwood"; + private static final String TAG = com.android.ravenwood.common.RavenwoodCommonUtils.TAG; private final Object mLock = new Object(); private final String mPackageName; diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodEnablementChecker.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodEnablementChecker.java index 77275c445dd9..3cb2c67adf09 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodEnablementChecker.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodEnablementChecker.java @@ -27,8 +27,6 @@ import org.junit.runner.Description; * Calculates which tests need to be executed on Ravenwood. */ public class RavenwoodEnablementChecker { - private static final String TAG = "RavenwoodDisablementChecker"; - private RavenwoodEnablementChecker() { } diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java index 6dfcf4ce03cf..a5d0bfd51a0f 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java @@ -40,7 +40,7 @@ import java.util.Set; * All members must be called from the runner's main thread. */ public final class RavenwoodRunnerState { - private static final String TAG = "RavenwoodRunnerState"; + private static final String TAG = com.android.ravenwood.common.RavenwoodCommonUtils.TAG; private static final String RAVENWOOD_RULE_ERROR = "RavenwoodRule(s) are not executed in the correct order"; diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java index 172cec3b8e13..930914f586eb 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java @@ -96,7 +96,7 @@ import java.util.function.Supplier; * Responsible for initializing and the environment. */ public class RavenwoodRuntimeEnvironmentController { - private static final String TAG = "RavenwoodRuntimeEnvironmentController"; + private static final String TAG = com.android.ravenwood.common.RavenwoodCommonUtils.TAG; private RavenwoodRuntimeEnvironmentController() { } @@ -105,6 +105,9 @@ public class RavenwoodRuntimeEnvironmentController { private static final String LIBRAVENWOOD_INITIALIZER_NAME = "ravenwood_initializer"; private static final String RAVENWOOD_NATIVE_RUNTIME_NAME = "ravenwood_runtime"; + private static final String ANDROID_LOG_TAGS = "ANDROID_LOG_TAGS"; + private static final String RAVENWOOD_ANDROID_LOG_TAGS = "RAVENWOOD_" + ANDROID_LOG_TAGS; + /** * When enabled, attempt to dump all thread stacks just before we hit the * overall Tradefed timeout, to aid in debugging deadlocks. @@ -232,20 +235,22 @@ public class RavenwoodRuntimeEnvironmentController { // Make sure libravenwood_runtime is loaded. System.load(RavenwoodCommonUtils.getJniLibraryPath(RAVENWOOD_NATIVE_RUNTIME_NAME)); + Log_ravenwood.setLogLevels(getLogTags()); Log_ravenwood.onRavenwoodRuntimeNativeReady(); // Do the basic set up for the android sysprops. RavenwoodSystemProperties.initialize(); + // Enable all log levels for native logging, until we'll have a way to change the native + // side log level at runtime. // Do this after loading RAVENWOOD_NATIVE_RUNTIME_NAME (which backs Os.setenv()), // before loadFrameworkNativeCode() (which uses $ANDROID_LOG_TAGS). - if (RAVENWOOD_VERBOSE_LOGGING) { - RavenwoodCommonUtils.log(TAG, "Force enabling verbose logging"); - try { - Os.setenv("ANDROID_LOG_TAGS", "*:v", true); - } catch (ErrnoException e) { - throw new RuntimeException(e); - } + // This would also prevent libbase from crashing the process (b/381112373) because + // the string format it accepts is very limited. + try { + Os.setenv("ANDROID_LOG_TAGS", "*:v", true); + } catch (ErrnoException e) { + throw new RuntimeException(e); } // Make sure libandroid_runtime is loaded. @@ -333,6 +338,18 @@ public class RavenwoodRuntimeEnvironmentController { initializeCompatIds(); } + /** + * Get log tags from environmental variable. + */ + @Nullable + private static String getLogTags() { + var logTags = System.getenv(RAVENWOOD_ANDROID_LOG_TAGS); + if (logTags == null) { + logTags = System.getenv(ANDROID_LOG_TAGS); + } + return logTags; + } + private static void loadRavenwoodProperties() { var props = RavenwoodSystemProperties.readProperties("ravenwood.properties"); diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java index 99b38ed4c92c..fac07910be11 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java @@ -34,7 +34,7 @@ import java.util.Set; * A class to manage the core default system properties of the Ravenwood environment. */ public class RavenwoodSystemProperties { - private static final String TAG = "RavenwoodSystemProperties"; + private static final String TAG = com.android.ravenwood.common.RavenwoodCommonUtils.TAG; /** We pull in properties from this file. */ private static final String RAVENWOOD_BUILD_PROP = "ravenwood-data/ravenwood-build.prop"; diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java index 787058545fed..c8b10d20843f 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java @@ -41,7 +41,7 @@ import java.util.Map; * `/tmp/Ravenwood-stats_[TEST-MODULE=NAME]_latest.csv`. */ public class RavenwoodTestStats { - private static final String TAG = "RavenwoodTestStats"; + private static final String TAG = com.android.ravenwood.common.RavenwoodCommonUtils.TAG; private static final String HEADER = "Module,Class,OuterClass,Passed,Failed,Skipped"; private static RavenwoodTestStats sInstance; diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerBase.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerBase.java index 31a14164bd51..f3688d664142 100644 --- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerBase.java +++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerBase.java @@ -35,7 +35,7 @@ import org.junit.runners.model.RunnerBuilder; import org.junit.runners.model.TestClass; abstract class RavenwoodAwareTestRunnerBase extends Runner implements Filterable, Orderable { - private static final String TAG = "Ravenwood"; + public static final String TAG = com.android.ravenwood.common.RavenwoodCommonUtils.TAG; boolean mRealRunnerTakesRunnerBuilder = false; diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java index e49d3d934e9f..d8cde0e029c9 100644 --- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java +++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java @@ -41,7 +41,7 @@ import java.util.regex.Pattern; */ @Deprecated public final class RavenwoodRule implements TestRule { - private static final String TAG = "RavenwoodRule"; + private static final String TAG = com.android.ravenwood.common.RavenwoodCommonUtils.TAG; static final boolean IS_ON_RAVENWOOD = RavenwoodCommonUtils.isOnRavenwood(); @@ -193,6 +193,12 @@ public final class RavenwoodRule implements TestRule { return IS_ON_RAVENWOOD; } + private static void ensureOnRavenwood(String featureName) { + if (!IS_ON_RAVENWOOD) { + throw new RuntimeException(featureName + " is only supported on Ravenwood."); + } + } + /** * @deprecated Use * {@code androidx.test.platform.app.InstrumentationRegistry.getInstrumentation().getContext()} @@ -242,6 +248,40 @@ public final class RavenwoodRule implements TestRule { return System.currentTimeMillis(); } + /** + * Equivalent to setting the ANDROID_LOG_TAGS environmental variable. + * + * See https://developer.android.com/tools/logcat#filteringOutput for the string format. + * + * NOTE: this works only on Ravenwood. + */ + public static void setAndroidLogTags(@Nullable String androidLogTags) { + ensureOnRavenwood("RavenwoodRule.setAndroidLogTags()"); + try { + Class<?> logRavenwoodClazz = Class.forName("android.util.Log_ravenwood"); + var setter = logRavenwoodClazz.getMethod("setLogLevels", String.class); + setter.invoke(null, androidLogTags); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + /** + * Set a log level for a given tag. Pass NULL to {@code tag} to change the default level. + * + * NOTE: this works only on Ravenwood. + */ + public static void setLogLevel(@Nullable String tag, int level) { + ensureOnRavenwood("RavenwoodRule.setLogLevel()"); + try { + Class<?> logRavenwoodClazz = Class.forName("android.util.Log_ravenwood"); + var setter = logRavenwoodClazz.getMethod("setLogLevel", String.class, int.class); + setter.invoke(null, tag, level); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + // Below are internal to ravenwood. Don't use them from normal tests... public static class RavenwoodPrivate { diff --git a/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java b/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java index b4b751788c6e..8d9bcd5b242f 100644 --- a/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java +++ b/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java @@ -31,8 +31,6 @@ import org.junit.runners.model.TestClass; * This is only used when a real device-side test has Ravenizer enabled. */ public class RavenwoodAwareTestRunner extends RavenwoodAwareTestRunnerBase { - private static final String TAG = "Ravenwood"; - private static class NopRule implements TestRule { @Override public Statement apply(Statement base, Description description) { diff --git a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java b/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java index 2a04d4469ef4..a967a3fff0d7 100644 --- a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java +++ b/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java @@ -33,7 +33,7 @@ import java.util.Arrays; import java.util.function.Supplier; public class RavenwoodCommonUtils { - private static final String TAG = "RavenwoodCommonUtils"; + public static final String TAG = "Ravenwood"; private RavenwoodCommonUtils() { } diff --git a/ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java b/ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java index 7b26fe531e7e..7ab9cda378b7 100644 --- a/ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java +++ b/ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java @@ -15,8 +15,10 @@ */ package android.util; +import android.annotation.Nullable; import android.util.Log.Level; +import com.android.internal.annotations.GuardedBy; import com.android.internal.os.RuntimeInit; import com.android.ravenwood.RavenwoodRuntimeNative; import com.android.ravenwood.common.RavenwoodCommonUtils; @@ -24,7 +26,9 @@ import com.android.ravenwood.common.RavenwoodCommonUtils; import java.io.PrintStream; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.HashMap; import java.util.Locale; +import java.util.Map; /** * Ravenwood "native substitution" class for {@link android.util.Log}. @@ -35,16 +39,100 @@ import java.util.Locale; */ public class Log_ravenwood { - public static final SimpleDateFormat sTimestampFormat = + private static final SimpleDateFormat sTimestampFormat = new SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.US); - public static boolean isLoggable(String tag, @Level int level) { - return true; + private static final Object sLock = new Object(); + + @GuardedBy("sLock") + private static int sDefaultLogLevel; + + @GuardedBy("sLock") + private static final Map<String, Integer> sTagLogLevels = new HashMap<>(); + + /** + * Used by {@link android.platform.test.ravenwood.RavenwoodRule#setAndroidLogTags(String)} + * via reflections. + */ + public static void setLogLevels(String androidLogTags) { + var map = parseLogLevels(androidLogTags); + + synchronized (sLock) { + sTagLogLevels.clear(); + sTagLogLevels.putAll(map); + + var def = map.get("*"); + sDefaultLogLevel = def != null ? def : Log.VERBOSE; + } + } + + private static Map<String, Integer> parseLogLevels(String androidLogTags) { + final Map<String, Integer> ret = new HashMap<>(); + + if (androidLogTags == null) { + return ret; + } + + String[] tagPairs = androidLogTags.trim().split("\\s+"); + for (String tagPair : tagPairs) { + String[] parts = tagPair.split(":"); + if (parts.length == 2) { + String tag = parts[0]; + try { + int priority = switch (parts[1].toUpperCase(Locale.ROOT)) { + case "V": yield Log.VERBOSE; + case "D": yield Log.DEBUG; + case "I": yield Log.INFO; + case "W": yield Log.WARN; + case "E": yield Log.ERROR; + case "F": yield Log.ERROR + 1; // Not used in the java side. + case "S": yield Integer.MAX_VALUE; // Silent + default: throw new IllegalArgumentException( + "Invalid priority level for tag: " + tag); + }; + + ret.put(tag, priority); + } catch (IllegalArgumentException e) { + System.err.println(e.getMessage()); + } + } else { + System.err.println("Invalid tag format: " + tagPair); + } + } + + return ret; + } + + /** + * Used by {@link android.platform.test.ravenwood.RavenwoodRule#setLogLevel(String, int)} + * via reflections. Pass NULL to {@code tag} to set the default level. + */ + public static void setLogLevel(@Nullable String tag, int level) { + synchronized (sLock) { + if (tag == null) { + sDefaultLogLevel = level; + } else { + sTagLogLevels.put(tag, level); + } + } + } + + /** + * Replaces {@link Log#isLoggable}. + */ + public static boolean isLoggable(String tag, @Level int priority) { + synchronized (sLock) { + var threshold = sTagLogLevels.get(tag); + if (threshold == null) { + threshold = sDefaultLogLevel; + } + return priority >= threshold; + } } public static int println_native(int bufID, int priority, String tag, String msg) { - if (priority < Log.INFO && !RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING) { - return msg.length(); // No verbose logging. + if (!isLoggable(tag, priority)) { + return msg.length(); } final String prio; diff --git a/ravenwood/scripts/extract-last-soong-commands.py b/ravenwood/scripts/extract-last-soong-commands.py new file mode 100755 index 000000000000..bdc1de0c44f4 --- /dev/null +++ b/ravenwood/scripts/extract-last-soong-commands.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python3 +# 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. + + +# This script extracts all the commands executed in the last soong run, +# and write them into a script file, and print the filename. +# +# All the commands are commented out. Uncomment what you want to execute as +# needed before running it. + +import datetime +import gzip +import os +import re +import shlex +import sys + +re_command = re.compile(r''' ^\[.*?\] \s* (.*) ''', re.X) + +HEADER = r'''#!/bin/bash + +set -e # Stop on a failed command + +cd "${ANDROID_BUILD_TOP:?}" + +''' + +OUT_SCRIPT_DIR = "/tmp/" +OUT_SCRIPT_FORMAT = "soong-rerun-%Y-%m-%d_%H-%M-%S.sh" + +def main(args): + log = os.environ["ANDROID_BUILD_TOP"] + "/out/verbose.log.gz" + outdir = "/tmp/" + outfile = outdir + datetime.datetime.now().strftime(OUT_SCRIPT_FORMAT) + + with open(outfile, "w") as out: + out.write(HEADER) + + with gzip.open(log) as f: + for line in f: + s = line.decode("utf-8") + + if s.startswith("verbose"): + continue + if re.match('^\[.*bootstrap blueprint', s): + continue + + s = s.rstrip() + + m = re_command.search(s) + if m: + command = m.groups()[0] + + out.write('#========\n') + + # Show the full command line before executing it. + out.write('#echo ' + shlex.quote(command) + '\n') + out.write('\n') + + # Execute the command. + out.write('#' + command + '\n') + + out.write('\n') + + continue + + if s.startswith("FAILED:"): + break + + os.chmod(outfile, 0o755) + print(outfile) + + return 0 + + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodLogLevelTest.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodLogLevelTest.java new file mode 100644 index 000000000000..74c1f3f686aa --- /dev/null +++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodLogLevelTest.java @@ -0,0 +1,108 @@ +/* + * 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 com.android.ravenwoodtest.coretest; + +import static org.junit.Assert.assertEquals; + +import android.platform.test.ravenwood.RavenwoodRule; +import android.util.Log; + +import com.android.ravenwood.common.RavenwoodCommonUtils; + +import org.junit.Test; + +public class RavenwoodLogLevelTest { + /** + * Assert that the `priority` is loggable, but one level below is not. + */ + private void assertBarelyLoggable(String tag, int priority) { + assertEquals(true, Log.isLoggable(tag, priority)); + assertEquals(false, Log.isLoggable(tag, priority - 1)); + } + + @Test + public void testDefaultLogTags() { + RavenwoodRule.setAndroidLogTags(null); + + // Info should always be loggable. + assertEquals(true, Log.isLoggable("TAG1", Log.INFO)); + assertEquals(true, Log.isLoggable("TAG2", Log.INFO)); + + assertEquals(true, Log.isLoggable("TAG1", Log.DEBUG)); + assertEquals(true, Log.isLoggable("TAG2", Log.VERBOSE)); + } + + @Test + public void testAllVerbose() { + RavenwoodRule.setAndroidLogTags("*:V"); + + assertEquals(true, Log.isLoggable("TAG1", Log.INFO)); + assertEquals(true, Log.isLoggable("TAG2", Log.INFO)); + + assertEquals(true, Log.isLoggable("TAG1", Log.DEBUG)); + assertEquals(true, Log.isLoggable("TAG2", Log.VERBOSE)); + } + + @Test + public void testAllSilent() { + RavenwoodRule.setAndroidLogTags("*:S"); + + assertEquals(false, Log.isLoggable("TAG1", Log.ASSERT)); + assertEquals(false, Log.isLoggable("TAG2", Log.ASSERT)); + } + + @Test + public void testComplex() { + RavenwoodRule.setAndroidLogTags("TAG1:W TAG2:D *:I"); + + assertBarelyLoggable("TAG1", Log.WARN); + assertBarelyLoggable("TAG2", Log.DEBUG); + assertBarelyLoggable("TAG3", Log.INFO); + } + + @Test + public void testAllVerbose_setLogLevel() { + RavenwoodRule.setAndroidLogTags(null); + RavenwoodRule.setLogLevel(null, Log.VERBOSE); + + assertEquals(true, Log.isLoggable("TAG1", Log.INFO)); + assertEquals(true, Log.isLoggable("TAG2", Log.INFO)); + + assertEquals(true, Log.isLoggable("TAG1", Log.DEBUG)); + assertEquals(true, Log.isLoggable("TAG2", Log.VERBOSE)); + } + + @Test + public void testAllSilent_setLogLevel() { + RavenwoodRule.setAndroidLogTags(null); + RavenwoodRule.setLogLevel(null, Log.ASSERT + 1); + + assertEquals(false, Log.isLoggable("TAG1", Log.ASSERT)); + assertEquals(false, Log.isLoggable("TAG2", Log.ASSERT)); + } + + @Test + public void testComplex_setLogLevel() { + RavenwoodRule.setAndroidLogTags(null); + RavenwoodRule.setLogLevel(null, Log.INFO); + RavenwoodRule.setLogLevel("TAG1", Log.WARN); + RavenwoodRule.setLogLevel("TAG2", Log.DEBUG); + + assertBarelyLoggable("TAG1", Log.WARN); + assertBarelyLoggable("TAG2", Log.DEBUG); + assertBarelyLoggable("TAG3", Log.INFO); + } +} diff --git a/ravenwood/texts/ravenwood-common-policies.txt b/ravenwood/texts/ravenwood-common-policies.txt index 08f5397730da..83c31512eb70 100644 --- a/ravenwood/texts/ravenwood-common-policies.txt +++ b/ravenwood/texts/ravenwood-common-policies.txt @@ -14,7 +14,7 @@ class :r keepclass # Support APIs not available in standard JRE class java.io.FileDescriptor keep - method getInt$ ()I @com.android.ravenwood.RavenwoodJdkPatch.getInt$ - method setInt$ (I)V @com.android.ravenwood.RavenwoodJdkPatch.setInt$ + method getInt$ @com.android.ravenwood.RavenwoodJdkPatch.getInt$ + method setInt$ @com.android.ravenwood.RavenwoodJdkPatch.setInt$ class java.util.LinkedHashMap keep - method eldest ()Ljava/util/Map$Entry; @com.android.ravenwood.RavenwoodJdkPatch.eldest + method eldest @com.android.ravenwood.RavenwoodJdkPatch.eldest diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt index 59fa464a7212..fc885d6f463b 100644 --- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt +++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt @@ -66,6 +66,9 @@ class InMemoryOutputFilter( methodName: String, descriptor: String ) { + if (descriptor == "*") { + return + } if (classes.findMethod(className, methodName, descriptor) == null) { log.w("Unknown method $className.$methodName$descriptor") } @@ -92,7 +95,8 @@ class InMemoryOutputFilter( descriptor: String, ): FilterPolicyWithReason { return mPolicies[getMethodKey(className, methodName, descriptor)] - ?: super.getPolicyForMethod(className, methodName, descriptor) + ?: mPolicies[getMethodKey(className, methodName, "*")] + ?: super.getPolicyForMethod(className, methodName, descriptor) } fun setPolicyForMethod( @@ -107,7 +111,8 @@ class InMemoryOutputFilter( override fun getRenameTo(className: String, methodName: String, descriptor: String): String? { return mRenames[getMethodKey(className, methodName, descriptor)] - ?: super.getRenameTo(className, methodName, descriptor) + ?: mRenames[getMethodKey(className, methodName, "*")] + ?: super.getRenameTo(className, methodName, descriptor) } fun setRenameTo(className: String, methodName: String, descriptor: String, toName: String) { diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt index caf80ebec0c9..7462a8ce12c5 100644 --- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt +++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt @@ -303,12 +303,21 @@ class TextFileFilterPolicyParser( } private fun parseMethod(fields: Array<String>) { - if (fields.size < 4) { - throw ParseException("Method ('m') expects 3 fields.") + if (fields.size < 3 || fields.size > 4) { + throw ParseException("Method ('m') expects 3 or 4 fields.") } val name = fields[1] - val signature = fields[2] - val policy = parsePolicy(fields[3]) + val signature: String + val policyStr: String + if (fields.size <= 3) { + signature = "*" + policyStr = fields[2] + } else { + signature = fields[2] + policyStr = fields[3] + } + + val policy = parsePolicy(policyStr) if (!policy.isUsableWithMethods) { throw ParseException("Method can't have policy '$policy'") @@ -321,7 +330,7 @@ class TextFileFilterPolicyParser( policy.withReason(FILTER_REASON) ) if (policy == FilterPolicy.Substitute) { - val fromName = fields[3].substring(1) + val fromName = policyStr.substring(1) if (fromName == name) { throw ParseException( diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyMethodReplaceFilter.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyMethodReplaceFilter.kt index d45f41407a52..a3f934cacc2c 100644 --- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyMethodReplaceFilter.kt +++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyMethodReplaceFilter.kt @@ -48,10 +48,11 @@ class TextFilePolicyMethodReplaceFilter( // Maybe use 'Tri' if we end up having too many replacements. spec.forEach { if (className == it.fromClass && - methodName == it.fromMethod && - descriptor == it.fromDescriptor + methodName == it.fromMethod ) { - return MethodReplaceTarget(it.toClass, it.toMethod) + if (it.fromDescriptor == "*" || descriptor == it.fromDescriptor) { + return MethodReplaceTarget(it.toClass, it.toMethod) + } } } return null diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt index 3c138d21b75d..2f35d35d608d 100644 --- a/ravenwood/tools/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt +++ b/ravenwood/tools/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt @@ -3,11 +3,11 @@ class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy keep # field remove remove # Implicitly remove method <init> ()V keep method addOne (I)I keep - method addOneInner (I)I keep + method addOneInner keep method toBeRemoved (Ljava/lang/String;)V remove method addTwo (I)I @addTwo_host # method addTwo_host (I)I # used as a substitute - method nativeAddThree (I)I @addThree_host + method nativeAddThree @addThree_host # method addThree_host (I)I # used as a substitute method unsupportedMethod ()Ljava/lang/String; throw method visibleButUsesUnsupportedMethod ()Ljava/lang/String; keep diff --git a/services/core/java/com/android/server/SecurityStateManagerService.java b/services/core/java/com/android/server/SecurityStateManagerService.java index 98039be20897..fe21fbda7130 100644 --- a/services/core/java/com/android/server/SecurityStateManagerService.java +++ b/services/core/java/com/android/server/SecurityStateManagerService.java @@ -22,6 +22,7 @@ import static android.os.SecurityStateManager.KEY_VENDOR_SPL; import android.content.Context; import android.content.pm.PackageManager; +import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.ISecurityStateManager; @@ -56,6 +57,15 @@ public class SecurityStateManagerService extends ISecurityStateManager.Stub { @Override public Bundle getGlobalSecurityState() { + final long token = Binder.clearCallingIdentity(); + try { + return getGlobalSecurityStateInternal(); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + private Bundle getGlobalSecurityStateInternal() { Bundle globalSecurityState = new Bundle(); globalSecurityState.putString(KEY_SYSTEM_SPL, Build.VERSION.SECURITY_PATCH); globalSecurityState.putString(KEY_VENDOR_SPL, diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java index e49dc8250bc7..976999cf6ae0 100644 --- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java +++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java @@ -426,6 +426,7 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { private static final int TRON_COMPILATION_REASON_PREBUILT = 23; private static final int TRON_COMPILATION_REASON_VDEX = 24; private static final int TRON_COMPILATION_REASON_BOOT_AFTER_MAINLINE_UPDATE = 25; + private static final int TRON_COMPILATION_REASON_CLOUD = 26; // The annotation to add as a suffix to the compilation reason when dexopt was // performed with dex metadata. @@ -460,6 +461,8 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { return TRON_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED; case "install-bulk-secondary-downgraded" : return TRON_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED; + case "cloud": + return TRON_COMPILATION_REASON_CLOUD; // These are special markers for dex metadata installation that do not // have an equivalent as a system property. case "install" + DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION : diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index fc7d3dca1c29..673d82d4d35f 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2728,7 +2728,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP * Expands the given rectangle by the region of window resize handle for freeform window. * @param inOutRect The rectangle to update. */ - private void adjustRegionInFreefromWindowMode(Rect inOutRect) { + private void adjustRegionInFreeformWindowMode(Rect inOutRect) { if (!inFreeformWindowingMode()) { return; } @@ -2772,7 +2772,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } } } - adjustRegionInFreefromWindowMode(mTmpRect); + adjustRegionInFreeformWindowMode(mTmpRect); outRegion.set(mTmpRect); cropRegionToRootTaskBoundsIfNeeded(outRegion); } @@ -3546,7 +3546,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } rootTask.getDimBounds(mTmpRect); - adjustRegionInFreefromWindowMode(mTmpRect); + adjustRegionInFreeformWindowMode(mTmpRect); region.op(mTmpRect, Region.Op.INTERSECT); } |