Merge "Initial porting of View and Res for AccessibilityMenu"
diff --git a/Android.bp b/Android.bp
index d031284..cfab18e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -110,6 +110,7 @@
":android.security.maintenance-java-source",
":android.security.metrics-java-source",
":android.system.keystore2-V3-java-source",
+ ":android.hardware.cas-V1-java-source",
":credstore_aidl",
":dumpstate_aidl",
":framework_native_aidl",
@@ -200,6 +201,7 @@
"updatable-driver-protos",
"ota_metadata_proto_java",
"android.hidl.base-V1.0-java",
+ "android.hardware.cas-V1-java", // AIDL
"android.hardware.cas-V1.0-java",
"android.hardware.cas-V1.1-java",
"android.hardware.cas-V1.2-java",
@@ -692,3 +694,12 @@
"ProtoLibraries.bp",
"TestProtoLibraries.bp",
]
+
+java_api_contribution {
+ name: "api-stubs-docs-non-updatable-public-stubs",
+ api_surface: "public",
+ api_file: "core/api/current.txt",
+ visibility: [
+ "//build/orchestrator/apis",
+ ],
+}
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 272b4f6..fc046fb 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -378,6 +378,67 @@
},
}
+java_library {
+ name: "android_stubs_private_jar",
+ defaults: ["android.jar_defaults"],
+ visibility: [
+ "//visibility:override",
+ "//visibility:private",
+ ],
+ static_libs: [
+ "stable.core.platform.api.stubs",
+ "core-lambda-stubs-for-system-modules",
+ "core-generated-annotation-stubs",
+ "framework",
+ "ext",
+ "framework-res-package-jar",
+ // The order of this matters, it has to be last to provide a
+ // package-private androidx.annotation.RecentlyNonNull without
+ // overriding the public android.annotation.Nullable in framework.jar
+ // with its own package-private android.annotation.Nullable.
+ "private-stub-annotations-jar",
+ ],
+}
+
+java_genrule {
+ name: "android_stubs_private_hjar",
+ visibility: ["//visibility:private"],
+ srcs: [":android_stubs_private_jar{.hjar}"],
+ out: ["android_stubs_private.jar"],
+ cmd: "cp $(in) $(out)",
+}
+
+java_library {
+ name: "android_stubs_private",
+ defaults: ["android_stubs_dists_default"],
+ visibility: ["//visibility:private"],
+ sdk_version: "none",
+ system_modules: "none",
+ static_libs: ["android_stubs_private_hjar"],
+ dist: {
+ dir: "apistubs/android/private",
+ },
+}
+
+java_genrule {
+ name: "android_stubs_private_framework_aidl",
+ visibility: ["//visibility:private"],
+ tools: ["sdkparcelables"],
+ srcs: [":android_stubs_private"],
+ out: ["framework.aidl"],
+ cmd: "rm -f $(genDir)/framework.aidl.merged && " +
+ "for i in $(in); do " +
+ " rm -f $(genDir)/framework.aidl.tmp && " +
+ " $(location sdkparcelables) $$i $(genDir)/framework.aidl.tmp && " +
+ " cat $(genDir)/framework.aidl.tmp >> $(genDir)/framework.aidl.merged; " +
+ "done && " +
+ "sort -u $(genDir)/framework.aidl.merged > $(out)",
+ dist: {
+ targets: ["sdk"],
+ dir: "apistubs/android/private",
+ },
+}
+
////////////////////////////////////////////////////////////////////////
// api-versions.xml generation, for public and system. This API database
// also contains the android.test.* APIs.
@@ -537,3 +598,12 @@
],
visibility: ["//visibility:public"],
}
+
+java_api_contribution {
+ name: "frameworks-base-core-api-module-lib-stubs",
+ api_surface: "module-lib",
+ api_file: "core/api/module-lib-current.txt",
+ visibility: [
+ "//build/orchestrator/apis",
+ ],
+}
diff --git a/apct-tests/perftests/packagemanager/AndroidManifest.xml b/apct-tests/perftests/packagemanager/AndroidManifest.xml
index 3b9431f..b4a34b8 100644
--- a/apct-tests/perftests/packagemanager/AndroidManifest.xml
+++ b/apct-tests/perftests/packagemanager/AndroidManifest.xml
@@ -26,6 +26,7 @@
<permission android:name="com.android.perftests.packagemanager.TestPermission" />
<uses-permission android:name="com.android.perftests.packagemanager.TestPermission" />
+ <uses-permission android:name="android.permission.GET_APP_METADATA" />
<queries>
<package android:name="com.android.perftests.appenumeration0" />
diff --git a/apct-tests/perftests/packagemanager/src/android/os/PackageManagerPerfTest.java b/apct-tests/perftests/packagemanager/src/android/os/PackageManagerPerfTest.java
index 673c6a3..4bcc8c4 100644
--- a/apct-tests/perftests/packagemanager/src/android/os/PackageManagerPerfTest.java
+++ b/apct-tests/perftests/packagemanager/src/android/os/PackageManagerPerfTest.java
@@ -19,10 +19,15 @@
import static libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
import static libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+import static org.junit.Assert.assertEquals;
+
+import android.Manifest;
import android.compat.testing.PlatformCompatChangeRule;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
@@ -31,11 +36,19 @@
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.compatibility.common.util.AdoptShellPermissionsRule;
+import com.android.cts.install.lib.Install;
+import com.android.cts.install.lib.InstallUtils;
+import com.android.cts.install.lib.LocalIntentSender;
+import com.android.cts.install.lib.TestApp;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.io.IOException;
+
@RunWith(AndroidJUnit4.class)
@LargeTest
public class PackageManagerPerfTest {
@@ -46,6 +59,8 @@
private static final ComponentName TEST_ACTIVITY =
new ComponentName("com.android.perftests.packagemanager",
"android.perftests.utils.PerfTestActivity");
+ private static final String TEST_FIELD = "test";
+ private static final String TEST_VALUE = "value";
@Rule
public final PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
@@ -53,9 +68,39 @@
@Rule
public final PlatformCompatChangeRule mPlatformCompatChangeRule =
new PlatformCompatChangeRule();
+ @Rule
+ public AdoptShellPermissionsRule mAdoptShellPermissionsRule = new AdoptShellPermissionsRule(
+ InstrumentationRegistry.getInstrumentation().getUiAutomation(),
+ Manifest.permission.INSTALL_PACKAGES,
+ Manifest.permission.DELETE_PACKAGES);
+
+ final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
+ private PackageInstaller mPackageInstaller;
public PackageManagerPerfTest() throws PackageManager.NameNotFoundException {
- final Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ mPackageInstaller = mContext.getPackageManager().getPackageInstaller();
+ }
+
+ private void installTestApp(TestApp testApp) throws IOException, InterruptedException {
+ Install install = Install.single(testApp);
+ final int expectedSessionId = install.createSession();
+ PackageInstaller.Session session =
+ InstallUtils.openPackageInstallerSession(expectedSessionId);
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putString(TEST_FIELD, TEST_VALUE);
+ session.setAppMetadata(bundle);
+ LocalIntentSender localIntentSender = new LocalIntentSender();
+ session.commit(localIntentSender.getIntentSender());
+ Intent intent = localIntentSender.getResult();
+ InstallUtils.assertStatusSuccess(intent);
+ }
+
+ private void uninstallTestApp(String packageName) throws InterruptedException {
+ LocalIntentSender localIntentSender = new LocalIntentSender();
+ IntentSender intentSender = localIntentSender.getIntentSender();
+ mPackageInstaller.uninstall(packageName, intentSender);
+ Intent intent = localIntentSender.getResult();
+ InstallUtils.assertStatusSuccess(intent);
}
@Before
@@ -65,6 +110,24 @@
}
@Test
+ public void testGetAppMetadata() throws Exception {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ installTestApp(TestApp.A1);
+ final PackageManager pm =
+ InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageManager();
+ final String packageName = TestApp.A1.getPackageName();
+
+ while (state.keepRunning()) {
+ PersistableBundle bundle = pm.getAppMetadata(packageName);
+ state.pauseTiming();
+ assertEquals(bundle.size(), 1);
+ assertEquals(bundle.getString(TEST_FIELD), TEST_VALUE);
+ state.resumeTiming();
+ }
+ uninstallTestApp(packageName);
+ }
+
+ @Test
@DisableCompatChanges(PackageManager.FILTER_APPLICATION_QUERY)
public void testCheckPermissionExists() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobServiceEngine.java b/apex/jobscheduler/framework/java/android/app/job/JobServiceEngine.java
index 53e452f..697641e 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobServiceEngine.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobServiceEngine.java
@@ -418,11 +418,12 @@
/**
* Call in to engine to report data transfer progress.
*
- * @hide
* @see JobService#updateTransferredNetworkBytes(JobParameters, long, long)
+ * @see JobService#updateTransferredNetworkBytes(JobParameters, JobWorkItem, long, long)
*/
public void updateTransferredNetworkBytes(@NonNull JobParameters params,
- @Nullable JobWorkItem item, long downloadBytes, long uploadBytes) {
+ @Nullable JobWorkItem item,
+ @BytesLong long downloadBytes, @BytesLong long uploadBytes) {
if (params == null) {
throw new NullPointerException("params");
}
@@ -437,11 +438,11 @@
/**
* Call in to engine to report data transfer progress.
*
- * @hide
+ * @see JobService#updateEstimatedNetworkBytes(JobParameters, long, long)
* @see JobService#updateEstimatedNetworkBytes(JobParameters, JobWorkItem, long, long)
*/
public void updateEstimatedNetworkBytes(@NonNull JobParameters params,
- @NonNull JobWorkItem item,
+ @Nullable JobWorkItem item,
@BytesLong long downloadBytes, @BytesLong long uploadBytes) {
if (params == null) {
throw new NullPointerException("params");
@@ -457,7 +458,6 @@
/**
* Give JobScheduler a notification to tie to this job's lifecycle.
*
- * @hide
* @see JobService#setNotification(JobParameters, int, Notification, int)
*/
public void setNotification(@NonNull JobParameters params, int notificationId,
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
index b806ef8..e0e0b4b 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
@@ -17,6 +17,7 @@
package com.android.server.job;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
+import static android.util.DataUnit.GIGABYTES;
import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX;
import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
@@ -58,6 +59,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.app.procstats.ProcessStats;
+import com.android.internal.util.MemInfoReader;
import com.android.internal.util.StatLogger;
import com.android.server.JobSchedulerBackgroundThread;
import com.android.server.LocalServices;
@@ -85,11 +87,33 @@
private static final boolean DEBUG = JobSchedulerService.DEBUG;
/** The maximum number of concurrent jobs we'll aim to run at one time. */
- public static final int STANDARD_CONCURRENCY_LIMIT = 16;
+ @VisibleForTesting
+ static final int MAX_CONCURRENCY_LIMIT = 64;
/** The maximum number of objects we should retain in memory when not in use. */
- private static final int MAX_RETAINED_OBJECTS = (int) (1.5 * STANDARD_CONCURRENCY_LIMIT);
+ private static final int MAX_RETAINED_OBJECTS = (int) (1.5 * MAX_CONCURRENCY_LIMIT);
static final String CONFIG_KEY_PREFIX_CONCURRENCY = "concurrency_";
+ private static final String KEY_CONCURRENCY_LIMIT = CONFIG_KEY_PREFIX_CONCURRENCY + "limit";
+ @VisibleForTesting
+ static final int DEFAULT_CONCURRENCY_LIMIT;
+
+ static {
+ if (ActivityManager.isLowRamDeviceStatic()) {
+ DEFAULT_CONCURRENCY_LIMIT = 8;
+ } else {
+ final long ramBytes = new MemInfoReader().getTotalSize();
+ if (ramBytes <= GIGABYTES.toBytes(6)) {
+ DEFAULT_CONCURRENCY_LIMIT = 16;
+ } else if (ramBytes <= GIGABYTES.toBytes(8)) {
+ DEFAULT_CONCURRENCY_LIMIT = 20;
+ } else if (ramBytes <= GIGABYTES.toBytes(12)) {
+ DEFAULT_CONCURRENCY_LIMIT = 32;
+ } else {
+ DEFAULT_CONCURRENCY_LIMIT = 40;
+ }
+ }
+ }
+
private static final String KEY_SCREEN_OFF_ADJUSTMENT_DELAY_MS =
CONFIG_KEY_PREFIX_CONCURRENCY + "screen_off_adjustment_delay_ms";
private static final long DEFAULT_SCREEN_OFF_ADJUSTMENT_DELAY_MS = 30_000;
@@ -100,7 +124,7 @@
@VisibleForTesting
static final String KEY_PKG_CONCURRENCY_LIMIT_REGULAR =
CONFIG_KEY_PREFIX_CONCURRENCY + "pkg_concurrency_limit_regular";
- private static final int DEFAULT_PKG_CONCURRENCY_LIMIT_REGULAR = STANDARD_CONCURRENCY_LIMIT / 2;
+ private static final int DEFAULT_PKG_CONCURRENCY_LIMIT_REGULAR = DEFAULT_CONCURRENCY_LIMIT / 2;
@VisibleForTesting
static final String KEY_ENABLE_MAX_WAIT_TIME_BYPASS =
CONFIG_KEY_PREFIX_CONCURRENCY + "enable_max_wait_time_bypass";
@@ -209,84 +233,100 @@
private static final WorkConfigLimitsPerMemoryTrimLevel CONFIG_LIMITS_SCREEN_ON =
new WorkConfigLimitsPerMemoryTrimLevel(
- new WorkTypeConfig("screen_on_normal", 11,
+ new WorkTypeConfig("screen_on_normal", DEFAULT_CONCURRENCY_LIMIT,
+ /* defaultMaxTotal */ DEFAULT_CONCURRENCY_LIMIT * 3 / 4,
// defaultMin
- List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_FGS, 1),
- Pair.create(WORK_TYPE_EJ, 3), Pair.create(WORK_TYPE_BG, 2),
- Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1)),
+ List.of(Pair.create(WORK_TYPE_TOP, .4f),
+ Pair.create(WORK_TYPE_FGS, .2f),
+ Pair.create(WORK_TYPE_EJ, .2f), Pair.create(WORK_TYPE_BG, .1f),
+ Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .1f)),
// defaultMax
- List.of(Pair.create(WORK_TYPE_BG, 6),
- Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 2),
- Pair.create(WORK_TYPE_BGUSER, 3))
+ List.of(Pair.create(WORK_TYPE_BG, .5f),
+ Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .25f),
+ Pair.create(WORK_TYPE_BGUSER, .2f))
),
- new WorkTypeConfig("screen_on_moderate", 9,
+ new WorkTypeConfig("screen_on_moderate", DEFAULT_CONCURRENCY_LIMIT,
+ /* defaultMaxTotal */ DEFAULT_CONCURRENCY_LIMIT / 2,
// defaultMin
- List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_FGS, 1),
- Pair.create(WORK_TYPE_EJ, 2), Pair.create(WORK_TYPE_BG, 1),
- Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1)),
+ List.of(Pair.create(WORK_TYPE_TOP, .4f),
+ Pair.create(WORK_TYPE_FGS, .1f),
+ Pair.create(WORK_TYPE_EJ, .1f), Pair.create(WORK_TYPE_BG, .1f),
+ Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .1f)),
// defaultMax
- List.of(Pair.create(WORK_TYPE_BG, 4),
- Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1),
- Pair.create(WORK_TYPE_BGUSER, 1))
+ List.of(Pair.create(WORK_TYPE_BG, .4f),
+ Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .1f),
+ Pair.create(WORK_TYPE_BGUSER, .1f))
),
- new WorkTypeConfig("screen_on_low", 6,
+ new WorkTypeConfig("screen_on_low", DEFAULT_CONCURRENCY_LIMIT,
+ /* defaultMaxTotal */ DEFAULT_CONCURRENCY_LIMIT * 4 / 10,
// defaultMin
- List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_FGS, 1),
- Pair.create(WORK_TYPE_EJ, 1)),
+ List.of(Pair.create(WORK_TYPE_TOP, 2.0f / 3),
+ Pair.create(WORK_TYPE_FGS, .1f),
+ Pair.create(WORK_TYPE_EJ, .1f)),
// defaultMax
- List.of(Pair.create(WORK_TYPE_BG, 2),
- Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1),
- Pair.create(WORK_TYPE_BGUSER, 1))
+ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1.0f / 6),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 6))
),
- new WorkTypeConfig("screen_on_critical", 6,
+ new WorkTypeConfig("screen_on_critical", DEFAULT_CONCURRENCY_LIMIT,
+ /* defaultMaxTotal */ DEFAULT_CONCURRENCY_LIMIT * 4 / 10,
// defaultMin
- List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_FGS, 1),
- Pair.create(WORK_TYPE_EJ, 1)),
+ List.of(Pair.create(WORK_TYPE_TOP, 2.0f / 3),
+ Pair.create(WORK_TYPE_FGS, .1f),
+ Pair.create(WORK_TYPE_EJ, .1f)),
// defaultMax
- List.of(Pair.create(WORK_TYPE_BG, 1),
- Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1),
- Pair.create(WORK_TYPE_BGUSER, 1))
+ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 6),
+ Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1.0f / 6),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 6))
)
);
private static final WorkConfigLimitsPerMemoryTrimLevel CONFIG_LIMITS_SCREEN_OFF =
new WorkConfigLimitsPerMemoryTrimLevel(
- new WorkTypeConfig("screen_off_normal", 16,
+ new WorkTypeConfig("screen_off_normal", DEFAULT_CONCURRENCY_LIMIT,
+ /* defaultMaxTotal */ DEFAULT_CONCURRENCY_LIMIT,
// defaultMin
- List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_FGS, 2),
- Pair.create(WORK_TYPE_EJ, 3), Pair.create(WORK_TYPE_BG, 2),
- Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1)),
+ List.of(Pair.create(WORK_TYPE_TOP, .3f),
+ Pair.create(WORK_TYPE_FGS, .2f),
+ Pair.create(WORK_TYPE_EJ, .3f), Pair.create(WORK_TYPE_BG, .2f),
+ Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .1f)),
// defaultMax
- List.of(Pair.create(WORK_TYPE_BG, 10),
- Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 2),
- Pair.create(WORK_TYPE_BGUSER, 3))
+ List.of(Pair.create(WORK_TYPE_BG, .6f),
+ Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .2f),
+ Pair.create(WORK_TYPE_BGUSER, .2f))
),
- new WorkTypeConfig("screen_off_moderate", 14,
+ new WorkTypeConfig("screen_off_moderate", DEFAULT_CONCURRENCY_LIMIT,
+ /* defaultMaxTotal */ DEFAULT_CONCURRENCY_LIMIT * 9 / 10,
// defaultMin
- List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_FGS, 2),
- Pair.create(WORK_TYPE_EJ, 3), Pair.create(WORK_TYPE_BG, 2),
- Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1)),
+ List.of(Pair.create(WORK_TYPE_TOP, .3f),
+ Pair.create(WORK_TYPE_FGS, .2f),
+ Pair.create(WORK_TYPE_EJ, .3f), Pair.create(WORK_TYPE_BG, .2f),
+ Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .1f)),
// defaultMax
- List.of(Pair.create(WORK_TYPE_BG, 7),
- Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1),
- Pair.create(WORK_TYPE_BGUSER, 1))
+ List.of(Pair.create(WORK_TYPE_BG, .5f),
+ Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .1f),
+ Pair.create(WORK_TYPE_BGUSER, .1f))
),
- new WorkTypeConfig("screen_off_low", 9,
+ new WorkTypeConfig("screen_off_low", DEFAULT_CONCURRENCY_LIMIT,
+ /* defaultMaxTotal */ DEFAULT_CONCURRENCY_LIMIT * 6 / 10,
// defaultMin
- List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_FGS, 1),
- Pair.create(WORK_TYPE_EJ, 2), Pair.create(WORK_TYPE_BG, 1)),
+ List.of(Pair.create(WORK_TYPE_TOP, .4f),
+ Pair.create(WORK_TYPE_FGS, .1f),
+ Pair.create(WORK_TYPE_EJ, .2f), Pair.create(WORK_TYPE_BG, .1f)),
// defaultMax
- List.of(Pair.create(WORK_TYPE_BG, 3),
- Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1),
- Pair.create(WORK_TYPE_BGUSER, 1))
+ List.of(Pair.create(WORK_TYPE_BG, .25f),
+ Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .1f),
+ Pair.create(WORK_TYPE_BGUSER, .1f))
),
- new WorkTypeConfig("screen_off_critical", 6,
+ new WorkTypeConfig("screen_off_critical", DEFAULT_CONCURRENCY_LIMIT,
+ /* defaultMaxTotal */ DEFAULT_CONCURRENCY_LIMIT * 4 / 10,
// defaultMin
- List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_FGS, 1),
- Pair.create(WORK_TYPE_EJ, 1)),
+ List.of(Pair.create(WORK_TYPE_TOP, .5f),
+ Pair.create(WORK_TYPE_FGS, .1f),
+ Pair.create(WORK_TYPE_EJ, .1f)),
// defaultMax
- List.of(Pair.create(WORK_TYPE_BG, 1),
- Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1),
- Pair.create(WORK_TYPE_BGUSER, 1))
+ List.of(Pair.create(WORK_TYPE_BG, .1f),
+ Pair.create(WORK_TYPE_BGUSER_IMPORTANT, .1f),
+ Pair.create(WORK_TYPE_BGUSER, .1f))
)
);
@@ -358,6 +398,12 @@
private long mScreenOffAdjustmentDelayMs = DEFAULT_SCREEN_OFF_ADJUSTMENT_DELAY_MS;
/**
+ * The maximum number of jobs we'll attempt to have running at one time. This may occasionally
+ * be exceeded based on other factors.
+ */
+ private int mSteadyStateConcurrencyLimit = DEFAULT_CONCURRENCY_LIMIT;
+
+ /**
* The maximum number of expedited jobs a single userId-package can have running simultaneously.
* TOP apps are not limited.
*/
@@ -451,7 +497,7 @@
void onThirdPartyAppsCanStart() {
final IBatteryStats batteryStats = IBatteryStats.Stub.asInterface(
ServiceManager.getService(BatteryStats.SERVICE_NAME));
- for (int i = 0; i < STANDARD_CONCURRENCY_LIMIT; i++) {
+ for (int i = 0; i < mSteadyStateConcurrencyLimit; ++i) {
mIdleContexts.add(
mInjector.createJobServiceContext(mService, this,
mNotificationCoordinator, batteryStats,
@@ -778,13 +824,14 @@
}
preferredUidOnly.sort(sDeterminationComparator);
stoppable.sort(sDeterminationComparator);
- for (int i = numRunningJobs; i < STANDARD_CONCURRENCY_LIMIT; ++i) {
+ for (int i = numRunningJobs; i < mSteadyStateConcurrencyLimit; ++i) {
final JobServiceContext jsc;
final int numIdleContexts = mIdleContexts.size();
if (numIdleContexts > 0) {
jsc = mIdleContexts.removeAt(numIdleContexts - 1);
} else {
- Slog.wtf(TAG, "Had fewer than " + STANDARD_CONCURRENCY_LIMIT + " in existence");
+ // This could happen if the config is changed at runtime.
+ Slog.w(TAG, "Had fewer than " + mSteadyStateConcurrencyLimit + " in existence");
jsc = createNewJobServiceContext();
}
@@ -850,7 +897,7 @@
ContextAssignment selectedContext = null;
final int allWorkTypes = getJobWorkTypes(nextPending);
final boolean pkgConcurrencyOkay = !isPkgConcurrencyLimitedLocked(nextPending);
- final boolean isInOverage = projectedRunningCount > STANDARD_CONCURRENCY_LIMIT;
+ final boolean isInOverage = projectedRunningCount > mSteadyStateConcurrencyLimit;
boolean startingJob = false;
if (idle.size() > 0) {
final int idx = idle.size() - 1;
@@ -1398,7 +1445,7 @@
noteConcurrency();
return;
}
- if (mActiveServices.size() >= STANDARD_CONCURRENCY_LIMIT) {
+ if (mActiveServices.size() >= mSteadyStateConcurrencyLimit) {
final boolean respectConcurrencyLimit;
if (!mMaxWaitTimeBypassEnabled) {
respectConcurrencyLimit = true;
@@ -1801,23 +1848,27 @@
DeviceConfig.Properties properties =
DeviceConfig.getProperties(DeviceConfig.NAMESPACE_JOB_SCHEDULER);
+ // Concurrency limit should be in the range [8, MAX_CONCURRENCY_LIMIT].
+ mSteadyStateConcurrencyLimit = Math.max(8, Math.min(MAX_CONCURRENCY_LIMIT,
+ properties.getInt(KEY_CONCURRENCY_LIMIT, DEFAULT_CONCURRENCY_LIMIT)));
+
mScreenOffAdjustmentDelayMs = properties.getLong(
KEY_SCREEN_OFF_ADJUSTMENT_DELAY_MS, DEFAULT_SCREEN_OFF_ADJUSTMENT_DELAY_MS);
- CONFIG_LIMITS_SCREEN_ON.normal.update(properties);
- CONFIG_LIMITS_SCREEN_ON.moderate.update(properties);
- CONFIG_LIMITS_SCREEN_ON.low.update(properties);
- CONFIG_LIMITS_SCREEN_ON.critical.update(properties);
+ CONFIG_LIMITS_SCREEN_ON.normal.update(properties, mSteadyStateConcurrencyLimit);
+ CONFIG_LIMITS_SCREEN_ON.moderate.update(properties, mSteadyStateConcurrencyLimit);
+ CONFIG_LIMITS_SCREEN_ON.low.update(properties, mSteadyStateConcurrencyLimit);
+ CONFIG_LIMITS_SCREEN_ON.critical.update(properties, mSteadyStateConcurrencyLimit);
- CONFIG_LIMITS_SCREEN_OFF.normal.update(properties);
- CONFIG_LIMITS_SCREEN_OFF.moderate.update(properties);
- CONFIG_LIMITS_SCREEN_OFF.low.update(properties);
- CONFIG_LIMITS_SCREEN_OFF.critical.update(properties);
+ CONFIG_LIMITS_SCREEN_OFF.normal.update(properties, mSteadyStateConcurrencyLimit);
+ CONFIG_LIMITS_SCREEN_OFF.moderate.update(properties, mSteadyStateConcurrencyLimit);
+ CONFIG_LIMITS_SCREEN_OFF.low.update(properties, mSteadyStateConcurrencyLimit);
+ CONFIG_LIMITS_SCREEN_OFF.critical.update(properties, mSteadyStateConcurrencyLimit);
- // Package concurrency limits must in the range [1, STANDARD_CONCURRENCY_LIMIT].
- mPkgConcurrencyLimitEj = Math.max(1, Math.min(STANDARD_CONCURRENCY_LIMIT,
+ // Package concurrency limits must in the range [1, mSteadyStateConcurrencyLimit].
+ mPkgConcurrencyLimitEj = Math.max(1, Math.min(mSteadyStateConcurrencyLimit,
properties.getInt(KEY_PKG_CONCURRENCY_LIMIT_EJ, DEFAULT_PKG_CONCURRENCY_LIMIT_EJ)));
- mPkgConcurrencyLimitRegular = Math.max(1, Math.min(STANDARD_CONCURRENCY_LIMIT,
+ mPkgConcurrencyLimitRegular = Math.max(1, Math.min(mSteadyStateConcurrencyLimit,
properties.getInt(
KEY_PKG_CONCURRENCY_LIMIT_REGULAR, DEFAULT_PKG_CONCURRENCY_LIMIT_REGULAR)));
@@ -1838,6 +1889,7 @@
try {
pw.println("Configuration:");
pw.increaseIndent();
+ pw.print(KEY_CONCURRENCY_LIMIT, mSteadyStateConcurrencyLimit).println();
pw.print(KEY_SCREEN_OFF_ADJUSTMENT_DELAY_MS, mScreenOffAdjustmentDelayMs).println();
pw.print(KEY_PKG_CONCURRENCY_LIMIT_EJ, mPkgConcurrencyLimitEj).println();
pw.print(KEY_PKG_CONCURRENCY_LIMIT_REGULAR, mPkgConcurrencyLimitRegular).println();
@@ -2041,130 +2093,181 @@
@VisibleForTesting
static class WorkTypeConfig {
- @VisibleForTesting
- static final String KEY_PREFIX_MAX = CONFIG_KEY_PREFIX_CONCURRENCY + "max_";
- @VisibleForTesting
- static final String KEY_PREFIX_MIN = CONFIG_KEY_PREFIX_CONCURRENCY + "min_";
+ private static final String KEY_PREFIX_MAX = CONFIG_KEY_PREFIX_CONCURRENCY + "max_";
+ private static final String KEY_PREFIX_MIN = CONFIG_KEY_PREFIX_CONCURRENCY + "min_";
@VisibleForTesting
static final String KEY_PREFIX_MAX_TOTAL = CONFIG_KEY_PREFIX_CONCURRENCY + "max_total_";
- private static final String KEY_PREFIX_MAX_TOP = CONFIG_KEY_PREFIX_CONCURRENCY + "max_top_";
- private static final String KEY_PREFIX_MAX_FGS = CONFIG_KEY_PREFIX_CONCURRENCY + "max_fgs_";
- private static final String KEY_PREFIX_MAX_EJ = CONFIG_KEY_PREFIX_CONCURRENCY + "max_ej_";
- private static final String KEY_PREFIX_MAX_BG = CONFIG_KEY_PREFIX_CONCURRENCY + "max_bg_";
- private static final String KEY_PREFIX_MAX_BGUSER =
- CONFIG_KEY_PREFIX_CONCURRENCY + "max_bguser_";
- private static final String KEY_PREFIX_MAX_BGUSER_IMPORTANT =
- CONFIG_KEY_PREFIX_CONCURRENCY + "max_bguser_important_";
- private static final String KEY_PREFIX_MIN_TOP = CONFIG_KEY_PREFIX_CONCURRENCY + "min_top_";
- private static final String KEY_PREFIX_MIN_FGS = CONFIG_KEY_PREFIX_CONCURRENCY + "min_fgs_";
- private static final String KEY_PREFIX_MIN_EJ = CONFIG_KEY_PREFIX_CONCURRENCY + "min_ej_";
- private static final String KEY_PREFIX_MIN_BG = CONFIG_KEY_PREFIX_CONCURRENCY + "min_bg_";
- private static final String KEY_PREFIX_MIN_BGUSER =
- CONFIG_KEY_PREFIX_CONCURRENCY + "min_bguser_";
- private static final String KEY_PREFIX_MIN_BGUSER_IMPORTANT =
- CONFIG_KEY_PREFIX_CONCURRENCY + "min_bguser_important_";
+ @VisibleForTesting
+ static final String KEY_PREFIX_MAX_RATIO = KEY_PREFIX_MAX + "ratio_";
+ private static final String KEY_PREFIX_MAX_RATIO_TOP = KEY_PREFIX_MAX_RATIO + "top_";
+ private static final String KEY_PREFIX_MAX_RATIO_FGS = KEY_PREFIX_MAX_RATIO + "fgs_";
+ private static final String KEY_PREFIX_MAX_RATIO_EJ = KEY_PREFIX_MAX_RATIO + "ej_";
+ private static final String KEY_PREFIX_MAX_RATIO_BG = KEY_PREFIX_MAX_RATIO + "bg_";
+ private static final String KEY_PREFIX_MAX_RATIO_BGUSER = KEY_PREFIX_MAX_RATIO + "bguser_";
+ private static final String KEY_PREFIX_MAX_RATIO_BGUSER_IMPORTANT =
+ KEY_PREFIX_MAX_RATIO + "bguser_important_";
+ @VisibleForTesting
+ static final String KEY_PREFIX_MIN_RATIO = KEY_PREFIX_MIN + "ratio_";
+ private static final String KEY_PREFIX_MIN_RATIO_TOP = KEY_PREFIX_MIN_RATIO + "top_";
+ private static final String KEY_PREFIX_MIN_RATIO_FGS = KEY_PREFIX_MIN_RATIO + "fgs_";
+ private static final String KEY_PREFIX_MIN_RATIO_EJ = KEY_PREFIX_MIN_RATIO + "ej_";
+ private static final String KEY_PREFIX_MIN_RATIO_BG = KEY_PREFIX_MIN_RATIO + "bg_";
+ private static final String KEY_PREFIX_MIN_RATIO_BGUSER = KEY_PREFIX_MIN_RATIO + "bguser_";
+ private static final String KEY_PREFIX_MIN_RATIO_BGUSER_IMPORTANT =
+ KEY_PREFIX_MIN_RATIO + "bguser_important_";
private final String mConfigIdentifier;
private int mMaxTotal;
private final SparseIntArray mMinReservedSlots = new SparseIntArray(NUM_WORK_TYPES);
private final SparseIntArray mMaxAllowedSlots = new SparseIntArray(NUM_WORK_TYPES);
private final int mDefaultMaxTotal;
- private final SparseIntArray mDefaultMinReservedSlots = new SparseIntArray(NUM_WORK_TYPES);
- private final SparseIntArray mDefaultMaxAllowedSlots = new SparseIntArray(NUM_WORK_TYPES);
+ // We use SparseIntArrays to store floats because there is currently no SparseFloatArray
+ // available, and it doesn't seem worth it to add such a data structure just for this
+ // use case. We don't use SparseDoubleArrays because DeviceConfig only supports floats and
+ // converting between floats and ints is more straightforward than floats and doubles.
+ private final SparseIntArray mDefaultMinReservedSlotsRatio =
+ new SparseIntArray(NUM_WORK_TYPES);
+ private final SparseIntArray mDefaultMaxAllowedSlotsRatio =
+ new SparseIntArray(NUM_WORK_TYPES);
- WorkTypeConfig(@NonNull String configIdentifier, int defaultMaxTotal,
- List<Pair<Integer, Integer>> defaultMin, List<Pair<Integer, Integer>> defaultMax) {
+ WorkTypeConfig(@NonNull String configIdentifier,
+ int steadyStateConcurrencyLimit, int defaultMaxTotal,
+ List<Pair<Integer, Float>> defaultMinRatio,
+ List<Pair<Integer, Float>> defaultMaxRatio) {
mConfigIdentifier = configIdentifier;
- mDefaultMaxTotal = mMaxTotal = Math.min(defaultMaxTotal, STANDARD_CONCURRENCY_LIMIT);
+ mDefaultMaxTotal = mMaxTotal = Math.min(defaultMaxTotal, steadyStateConcurrencyLimit);
int numReserved = 0;
- for (int i = defaultMin.size() - 1; i >= 0; --i) {
- mDefaultMinReservedSlots.put(defaultMin.get(i).first, defaultMin.get(i).second);
- numReserved += defaultMin.get(i).second;
+ for (int i = defaultMinRatio.size() - 1; i >= 0; --i) {
+ final float ratio = defaultMinRatio.get(i).second;
+ final int wt = defaultMinRatio.get(i).first;
+ if (ratio < 0 || 1 <= ratio) {
+ // 1 means to reserve everything. This shouldn't be allowed.
+ // We only create new configs on boot, so this should trigger during development
+ // (before the code gets checked in), so this makes sure the hard-coded defaults
+ // make sense. DeviceConfig values will be handled gracefully in update().
+ throw new IllegalArgumentException("Invalid default min ratio: wt=" + wt
+ + " minRatio=" + ratio);
+ }
+ mDefaultMinReservedSlotsRatio.put(wt, Float.floatToRawIntBits(ratio));
+ numReserved += mMaxTotal * ratio;
}
if (mDefaultMaxTotal < 0 || numReserved > mDefaultMaxTotal) {
// We only create new configs on boot, so this should trigger during development
// (before the code gets checked in), so this makes sure the hard-coded defaults
// make sense. DeviceConfig values will be handled gracefully in update().
throw new IllegalArgumentException("Invalid default config: t=" + defaultMaxTotal
- + " min=" + defaultMin + " max=" + defaultMax);
+ + " min=" + defaultMinRatio + " max=" + defaultMaxRatio);
}
- for (int i = defaultMax.size() - 1; i >= 0; --i) {
- mDefaultMaxAllowedSlots.put(defaultMax.get(i).first, defaultMax.get(i).second);
+ for (int i = defaultMaxRatio.size() - 1; i >= 0; --i) {
+ final float ratio = defaultMaxRatio.get(i).second;
+ final int wt = defaultMaxRatio.get(i).first;
+ final float minRatio =
+ Float.intBitsToFloat(mDefaultMinReservedSlotsRatio.get(wt, 0));
+ if (ratio < minRatio || ratio <= 0) {
+ // Max ratio shouldn't be <= 0 or less than minRatio.
+ throw new IllegalArgumentException("Invalid default config:"
+ + " t=" + defaultMaxTotal
+ + " min=" + defaultMinRatio + " max=" + defaultMaxRatio);
+ }
+ mDefaultMaxAllowedSlotsRatio.put(wt, Float.floatToRawIntBits(ratio));
}
update(new DeviceConfig.Properties.Builder(
- DeviceConfig.NAMESPACE_JOB_SCHEDULER).build());
+ DeviceConfig.NAMESPACE_JOB_SCHEDULER).build(), steadyStateConcurrencyLimit);
}
- void update(@NonNull DeviceConfig.Properties properties) {
- // Ensure total in the range [1, STANDARD_CONCURRENCY_LIMIT].
- mMaxTotal = Math.max(1, Math.min(STANDARD_CONCURRENCY_LIMIT,
+ void update(@NonNull DeviceConfig.Properties properties, int steadyStateConcurrencyLimit) {
+ // Ensure total in the range [1, mSteadyStateConcurrencyLimit].
+ mMaxTotal = Math.max(1, Math.min(steadyStateConcurrencyLimit,
properties.getInt(KEY_PREFIX_MAX_TOTAL + mConfigIdentifier, mDefaultMaxTotal)));
+ final int oneIntBits = Float.floatToIntBits(1);
+
mMaxAllowedSlots.clear();
// Ensure they're in the range [1, total].
- final int maxTop = Math.max(1, Math.min(mMaxTotal,
- properties.getInt(KEY_PREFIX_MAX_TOP + mConfigIdentifier,
- mDefaultMaxAllowedSlots.get(WORK_TYPE_TOP, mMaxTotal))));
+ final int maxTop = getMaxValue(properties,
+ KEY_PREFIX_MAX_RATIO_TOP + mConfigIdentifier, WORK_TYPE_TOP, oneIntBits);
mMaxAllowedSlots.put(WORK_TYPE_TOP, maxTop);
- final int maxFgs = Math.max(1, Math.min(mMaxTotal,
- properties.getInt(KEY_PREFIX_MAX_FGS + mConfigIdentifier,
- mDefaultMaxAllowedSlots.get(WORK_TYPE_FGS, mMaxTotal))));
+ final int maxFgs = getMaxValue(properties,
+ KEY_PREFIX_MAX_RATIO_FGS + mConfigIdentifier, WORK_TYPE_FGS, oneIntBits);
mMaxAllowedSlots.put(WORK_TYPE_FGS, maxFgs);
- final int maxEj = Math.max(1, Math.min(mMaxTotal,
- properties.getInt(KEY_PREFIX_MAX_EJ + mConfigIdentifier,
- mDefaultMaxAllowedSlots.get(WORK_TYPE_EJ, mMaxTotal))));
+ final int maxEj = getMaxValue(properties,
+ KEY_PREFIX_MAX_RATIO_EJ + mConfigIdentifier, WORK_TYPE_EJ, oneIntBits);
mMaxAllowedSlots.put(WORK_TYPE_EJ, maxEj);
- final int maxBg = Math.max(1, Math.min(mMaxTotal,
- properties.getInt(KEY_PREFIX_MAX_BG + mConfigIdentifier,
- mDefaultMaxAllowedSlots.get(WORK_TYPE_BG, mMaxTotal))));
+ final int maxBg = getMaxValue(properties,
+ KEY_PREFIX_MAX_RATIO_BG + mConfigIdentifier, WORK_TYPE_BG, oneIntBits);
mMaxAllowedSlots.put(WORK_TYPE_BG, maxBg);
- final int maxBgUserImp = Math.max(1, Math.min(mMaxTotal,
- properties.getInt(KEY_PREFIX_MAX_BGUSER_IMPORTANT + mConfigIdentifier,
- mDefaultMaxAllowedSlots.get(WORK_TYPE_BGUSER_IMPORTANT, mMaxTotal))));
+ final int maxBgUserImp = getMaxValue(properties,
+ KEY_PREFIX_MAX_RATIO_BGUSER_IMPORTANT + mConfigIdentifier,
+ WORK_TYPE_BGUSER_IMPORTANT, oneIntBits);
mMaxAllowedSlots.put(WORK_TYPE_BGUSER_IMPORTANT, maxBgUserImp);
- final int maxBgUser = Math.max(1, Math.min(mMaxTotal,
- properties.getInt(KEY_PREFIX_MAX_BGUSER + mConfigIdentifier,
- mDefaultMaxAllowedSlots.get(WORK_TYPE_BGUSER, mMaxTotal))));
+ final int maxBgUser = getMaxValue(properties,
+ KEY_PREFIX_MAX_RATIO_BGUSER + mConfigIdentifier, WORK_TYPE_BGUSER, oneIntBits);
mMaxAllowedSlots.put(WORK_TYPE_BGUSER, maxBgUser);
int remaining = mMaxTotal;
mMinReservedSlots.clear();
// Ensure top is in the range [1, min(maxTop, total)]
- final int minTop = Math.max(1, Math.min(Math.min(maxTop, mMaxTotal),
- properties.getInt(KEY_PREFIX_MIN_TOP + mConfigIdentifier,
- mDefaultMinReservedSlots.get(WORK_TYPE_TOP))));
+ final int minTop = getMinValue(properties,
+ KEY_PREFIX_MIN_RATIO_TOP + mConfigIdentifier, WORK_TYPE_TOP,
+ 1, Math.min(maxTop, mMaxTotal));
mMinReservedSlots.put(WORK_TYPE_TOP, minTop);
remaining -= minTop;
// Ensure fgs is in the range [0, min(maxFgs, remaining)]
- final int minFgs = Math.max(0, Math.min(Math.min(maxFgs, remaining),
- properties.getInt(KEY_PREFIX_MIN_FGS + mConfigIdentifier,
- mDefaultMinReservedSlots.get(WORK_TYPE_FGS))));
+ final int minFgs = getMinValue(properties,
+ KEY_PREFIX_MIN_RATIO_FGS + mConfigIdentifier, WORK_TYPE_FGS,
+ 0, Math.min(maxFgs, remaining));
mMinReservedSlots.put(WORK_TYPE_FGS, minFgs);
remaining -= minFgs;
// Ensure ej is in the range [0, min(maxEj, remaining)]
- final int minEj = Math.max(0, Math.min(Math.min(maxEj, remaining),
- properties.getInt(KEY_PREFIX_MIN_EJ + mConfigIdentifier,
- mDefaultMinReservedSlots.get(WORK_TYPE_EJ))));
+ final int minEj = getMinValue(properties,
+ KEY_PREFIX_MIN_RATIO_EJ + mConfigIdentifier, WORK_TYPE_EJ,
+ 0, Math.min(maxEj, remaining));
mMinReservedSlots.put(WORK_TYPE_EJ, minEj);
remaining -= minEj;
// Ensure bg is in the range [0, min(maxBg, remaining)]
- final int minBg = Math.max(0, Math.min(Math.min(maxBg, remaining),
- properties.getInt(KEY_PREFIX_MIN_BG + mConfigIdentifier,
- mDefaultMinReservedSlots.get(WORK_TYPE_BG))));
+ final int minBg = getMinValue(properties,
+ KEY_PREFIX_MIN_RATIO_BG + mConfigIdentifier, WORK_TYPE_BG,
+ 0, Math.min(maxBg, remaining));
mMinReservedSlots.put(WORK_TYPE_BG, minBg);
remaining -= minBg;
// Ensure bg user imp is in the range [0, min(maxBgUserImp, remaining)]
- final int minBgUserImp = Math.max(0, Math.min(Math.min(maxBgUserImp, remaining),
- properties.getInt(KEY_PREFIX_MIN_BGUSER_IMPORTANT + mConfigIdentifier,
- mDefaultMinReservedSlots.get(WORK_TYPE_BGUSER_IMPORTANT, 0))));
+ final int minBgUserImp = getMinValue(properties,
+ KEY_PREFIX_MIN_RATIO_BGUSER_IMPORTANT + mConfigIdentifier,
+ WORK_TYPE_BGUSER_IMPORTANT, 0, Math.min(maxBgUserImp, remaining));
mMinReservedSlots.put(WORK_TYPE_BGUSER_IMPORTANT, minBgUserImp);
+ remaining -= minBgUserImp;
// Ensure bg user is in the range [0, min(maxBgUser, remaining)]
- final int minBgUser = Math.max(0, Math.min(Math.min(maxBgUser, remaining),
- properties.getInt(KEY_PREFIX_MIN_BGUSER + mConfigIdentifier,
- mDefaultMinReservedSlots.get(WORK_TYPE_BGUSER, 0))));
+ final int minBgUser = getMinValue(properties,
+ KEY_PREFIX_MIN_RATIO_BGUSER + mConfigIdentifier, WORK_TYPE_BGUSER,
+ 0, Math.min(maxBgUser, remaining));
mMinReservedSlots.put(WORK_TYPE_BGUSER, minBgUser);
}
+ /**
+ * Return the calculated max value for the work type.
+ * @param defaultFloatInIntBits A {@code float} value in int bits representation (using
+ * {@link Float#floatToIntBits(float)}.
+ */
+ private int getMaxValue(@NonNull DeviceConfig.Properties properties, @NonNull String key,
+ int workType, int defaultFloatInIntBits) {
+ final float maxRatio = Math.min(1, properties.getFloat(key,
+ Float.intBitsToFloat(
+ mDefaultMaxAllowedSlotsRatio.get(workType, defaultFloatInIntBits))));
+ // Max values should be in the range [1, total].
+ return Math.max(1, (int) (mMaxTotal * maxRatio));
+ }
+
+ /**
+ * Return the calculated min value for the work type.
+ */
+ private int getMinValue(@NonNull DeviceConfig.Properties properties, @NonNull String key,
+ int workType, int lowerLimit, int upperLimit) {
+ final float minRatio = Math.min(1,
+ properties.getFloat(key,
+ Float.intBitsToFloat(mDefaultMinReservedSlotsRatio.get(workType))));
+ return Math.max(lowerLimit, Math.min(upperLimit, (int) (mMaxTotal * minRatio)));
+ }
+
int getMaxTotal() {
return mMaxTotal;
}
@@ -2179,29 +2282,37 @@
void dump(IndentingPrintWriter pw) {
pw.print(KEY_PREFIX_MAX_TOTAL + mConfigIdentifier, mMaxTotal).println();
- pw.print(KEY_PREFIX_MIN_TOP + mConfigIdentifier, mMinReservedSlots.get(WORK_TYPE_TOP))
+ pw.print(KEY_PREFIX_MIN_RATIO_TOP + mConfigIdentifier,
+ mMinReservedSlots.get(WORK_TYPE_TOP))
.println();
- pw.print(KEY_PREFIX_MAX_TOP + mConfigIdentifier, mMaxAllowedSlots.get(WORK_TYPE_TOP))
+ pw.print(KEY_PREFIX_MAX_RATIO_TOP + mConfigIdentifier,
+ mMaxAllowedSlots.get(WORK_TYPE_TOP))
.println();
- pw.print(KEY_PREFIX_MIN_FGS + mConfigIdentifier, mMinReservedSlots.get(WORK_TYPE_FGS))
+ pw.print(KEY_PREFIX_MIN_RATIO_FGS + mConfigIdentifier,
+ mMinReservedSlots.get(WORK_TYPE_FGS))
.println();
- pw.print(KEY_PREFIX_MAX_FGS + mConfigIdentifier, mMaxAllowedSlots.get(WORK_TYPE_FGS))
+ pw.print(KEY_PREFIX_MAX_RATIO_FGS + mConfigIdentifier,
+ mMaxAllowedSlots.get(WORK_TYPE_FGS))
.println();
- pw.print(KEY_PREFIX_MIN_EJ + mConfigIdentifier, mMinReservedSlots.get(WORK_TYPE_EJ))
+ pw.print(KEY_PREFIX_MIN_RATIO_EJ + mConfigIdentifier,
+ mMinReservedSlots.get(WORK_TYPE_EJ))
.println();
- pw.print(KEY_PREFIX_MAX_EJ + mConfigIdentifier, mMaxAllowedSlots.get(WORK_TYPE_EJ))
+ pw.print(KEY_PREFIX_MAX_RATIO_EJ + mConfigIdentifier,
+ mMaxAllowedSlots.get(WORK_TYPE_EJ))
.println();
- pw.print(KEY_PREFIX_MIN_BG + mConfigIdentifier, mMinReservedSlots.get(WORK_TYPE_BG))
+ pw.print(KEY_PREFIX_MIN_RATIO_BG + mConfigIdentifier,
+ mMinReservedSlots.get(WORK_TYPE_BG))
.println();
- pw.print(KEY_PREFIX_MAX_BG + mConfigIdentifier, mMaxAllowedSlots.get(WORK_TYPE_BG))
+ pw.print(KEY_PREFIX_MAX_RATIO_BG + mConfigIdentifier,
+ mMaxAllowedSlots.get(WORK_TYPE_BG))
.println();
- pw.print(KEY_PREFIX_MIN_BGUSER + mConfigIdentifier,
+ pw.print(KEY_PREFIX_MIN_RATIO_BGUSER + mConfigIdentifier,
mMinReservedSlots.get(WORK_TYPE_BGUSER_IMPORTANT)).println();
- pw.print(KEY_PREFIX_MAX_BGUSER + mConfigIdentifier,
+ pw.print(KEY_PREFIX_MAX_RATIO_BGUSER + mConfigIdentifier,
mMaxAllowedSlots.get(WORK_TYPE_BGUSER_IMPORTANT)).println();
- pw.print(KEY_PREFIX_MIN_BGUSER + mConfigIdentifier,
+ pw.print(KEY_PREFIX_MIN_RATIO_BGUSER + mConfigIdentifier,
mMinReservedSlots.get(WORK_TYPE_BGUSER)).println();
- pw.print(KEY_PREFIX_MAX_BGUSER + mConfigIdentifier,
+ pw.print(KEY_PREFIX_MAX_RATIO_BGUSER + mConfigIdentifier,
mMaxAllowedSlots.get(WORK_TYPE_BGUSER)).println();
}
}
diff --git a/core/api/current.txt b/core/api/current.txt
index dd3d6eb..3cc5631 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -88,6 +88,7 @@
field public static final String DIAGNOSTIC = "android.permission.DIAGNOSTIC";
field public static final String DISABLE_KEYGUARD = "android.permission.DISABLE_KEYGUARD";
field public static final String DUMP = "android.permission.DUMP";
+ field public static final String ENFORCE_UPDATE_OWNERSHIP = "android.permission.ENFORCE_UPDATE_OWNERSHIP";
field public static final String EXPAND_STATUS_BAR = "android.permission.EXPAND_STATUS_BAR";
field public static final String FACTORY_TEST = "android.permission.FACTORY_TEST";
field public static final String FOREGROUND_SERVICE = "android.permission.FOREGROUND_SERVICE";
@@ -384,6 +385,7 @@
field public static final int allowTaskReparenting = 16843268; // 0x1010204
field public static final int allowUndo = 16843999; // 0x10104df
field public static final int allowUntrustedActivityEmbedding = 16844393; // 0x1010669
+ field public static final int allowUpdateOwnership;
field public static final int alpha = 16843551; // 0x101031f
field public static final int alphabeticModifiers = 16844110; // 0x101054e
field public static final int alphabeticShortcut = 16843235; // 0x10101e3
@@ -5903,7 +5905,7 @@
ctor public LocaleConfig(@NonNull android.content.Context);
ctor public LocaleConfig(@NonNull android.os.LocaleList);
method public int describeContents();
- method @NonNull public static android.app.LocaleConfig fromResources(@NonNull android.content.Context);
+ method @NonNull public static android.app.LocaleConfig fromContextIgnoringOverride(@NonNull android.content.Context);
method public int getStatus();
method @Nullable public android.os.LocaleList getSupportedLocales();
method public void writeToParcel(@NonNull android.os.Parcel, int);
@@ -8640,6 +8642,9 @@
method public void jobFinished(android.app.job.JobParameters, boolean);
method public abstract boolean onStartJob(android.app.job.JobParameters);
method public abstract boolean onStopJob(android.app.job.JobParameters);
+ method public void setNotification(@NonNull android.app.job.JobParameters, int, @NonNull android.app.Notification, int);
+ method public void updateEstimatedNetworkBytes(@NonNull android.app.job.JobParameters, @Nullable android.app.job.JobWorkItem, long, long);
+ method public void updateTransferredNetworkBytes(@NonNull android.app.job.JobParameters, @Nullable android.app.job.JobWorkItem, long, long);
}
public final class JobWorkItem implements android.os.Parcelable {
@@ -9226,15 +9231,18 @@
}
public final class CompanionDeviceManager {
+ method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public void addOnAssociationsChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.companion.CompanionDeviceManager.OnAssociationsChangedListener);
method @RequiresPermission(anyOf={android.Manifest.permission.REQUEST_COMPANION_PROFILE_WATCH, android.Manifest.permission.REQUEST_COMPANION_PROFILE_COMPUTER, android.Manifest.permission.REQUEST_COMPANION_PROFILE_APP_STREAMING, android.Manifest.permission.REQUEST_COMPANION_PROFILE_AUTOMOTIVE_PROJECTION}, conditional=true) public void associate(@NonNull android.companion.AssociationRequest, @NonNull android.companion.CompanionDeviceManager.Callback, @Nullable android.os.Handler);
method @RequiresPermission(anyOf={android.Manifest.permission.REQUEST_COMPANION_PROFILE_WATCH, android.Manifest.permission.REQUEST_COMPANION_PROFILE_COMPUTER, android.Manifest.permission.REQUEST_COMPANION_PROFILE_APP_STREAMING, android.Manifest.permission.REQUEST_COMPANION_PROFILE_AUTOMOTIVE_PROJECTION}, conditional=true) public void associate(@NonNull android.companion.AssociationRequest, @NonNull java.util.concurrent.Executor, @NonNull android.companion.CompanionDeviceManager.Callback);
method @Nullable public android.content.IntentSender buildAssociationCancellationIntent();
method @Nullable public android.content.IntentSender buildPermissionTransferUserConsentIntent(int) throws android.companion.DeviceNotAssociatedException;
method @Deprecated public void disassociate(@NonNull String);
method public void disassociate(int);
+ method @NonNull @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public java.util.List<android.companion.AssociationInfo> getAllAssociations();
method @Deprecated @NonNull public java.util.List<java.lang.String> getAssociations();
method @NonNull public java.util.List<android.companion.AssociationInfo> getMyAssociations();
method @Deprecated public boolean hasNotificationAccess(android.content.ComponentName);
+ method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public void removeOnAssociationsChangedListener(@NonNull android.companion.CompanionDeviceManager.OnAssociationsChangedListener);
method public void requestNotificationAccess(android.content.ComponentName);
method @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void startObservingDevicePresence(@NonNull String) throws android.companion.DeviceNotAssociatedException;
method @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void stopObservingDevicePresence(@NonNull String) throws android.companion.DeviceNotAssociatedException;
@@ -9255,6 +9263,10 @@
method public abstract void onFailure(@Nullable CharSequence);
}
+ public static interface CompanionDeviceManager.OnAssociationsChangedListener {
+ method public void onAssociationsChanged(@NonNull java.util.List<android.companion.AssociationInfo>);
+ }
+
public abstract class CompanionDeviceService extends android.app.Service {
ctor public CompanionDeviceService();
method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
@@ -11688,6 +11700,7 @@
method @Nullable public String getInstallingPackageName();
method @Nullable public String getOriginatingPackageName();
method public int getPackageSource();
+ method @Nullable public String getUpdateOwnerPackageName();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.InstallSourceInfo> CREATOR;
}
@@ -11870,6 +11883,7 @@
public class PackageInstaller {
method public void abandonSession(int);
method public void checkInstallConstraints(@NonNull java.util.List<java.lang.String>, @NonNull android.content.pm.PackageInstaller.InstallConstraints, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.content.pm.PackageInstaller.InstallConstraintsResult>);
+ method public void commitSessionAfterInstallConstraintsAreMet(int, @NonNull android.content.IntentSender, @NonNull android.content.pm.PackageInstaller.InstallConstraints, long);
method public int createSession(@NonNull android.content.pm.PackageInstaller.SessionParams) throws java.io.IOException;
method @Deprecated @Nullable public android.content.pm.PackageInstaller.SessionInfo getActiveStagedSession();
method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getActiveStagedSessions();
@@ -11914,6 +11928,7 @@
field public static final int STATUS_FAILURE_INCOMPATIBLE = 7; // 0x7
field public static final int STATUS_FAILURE_INVALID = 4; // 0x4
field public static final int STATUS_FAILURE_STORAGE = 6; // 0x6
+ field public static final int STATUS_FAILURE_TIMEOUT = 8; // 0x8
field public static final int STATUS_PENDING_USER_ACTION = -1; // 0xffffffff
field public static final int STATUS_SUCCESS = 0; // 0x0
}
@@ -11978,6 +11993,7 @@
method public int getParentSessionId();
method public boolean isKeepApplicationEnabledSetting();
method public boolean isMultiPackage();
+ method public boolean isRequestUpdateOwnership();
method public boolean isStaged();
method @NonNull public java.io.InputStream openRead(@NonNull String) throws java.io.IOException;
method @NonNull public java.io.OutputStream openWrite(@NonNull String, long, long) throws java.io.IOException;
@@ -12033,6 +12049,7 @@
method public boolean isCommitted();
method public boolean isKeepApplicationEnabledSetting();
method public boolean isMultiPackage();
+ method public boolean isRequestUpdateOwnership();
method public boolean isSealed();
method public boolean isStaged();
method public boolean isStagedSessionActive();
@@ -12071,6 +12088,7 @@
method public void setOriginatingUri(@Nullable android.net.Uri);
method public void setPackageSource(int);
method public void setReferrerUri(@Nullable android.net.Uri);
+ method @RequiresPermission(android.Manifest.permission.ENFORCE_UPDATE_OWNERSHIP) public void setRequestUpdateOwnership(boolean);
method public void setRequireUserAction(int);
method public void setSize(long);
method public void setWhitelistedRestrictedPermissions(@Nullable java.util.Set<java.lang.String>);
@@ -12249,6 +12267,7 @@
method @NonNull public java.util.List<android.content.pm.PackageManager.Property> queryProviderProperty(@NonNull String);
method @NonNull public java.util.List<android.content.pm.PackageManager.Property> queryReceiverProperty(@NonNull String);
method @NonNull public java.util.List<android.content.pm.PackageManager.Property> queryServiceProperty(@NonNull String);
+ method public void relinquishUpdateOwnership(@NonNull String);
method @Deprecated public abstract void removePackageFromPreferred(@NonNull String);
method public abstract void removePermission(@NonNull String);
method @RequiresPermission(value="android.permission.WHITELIST_RESTRICTED_PERMISSIONS", conditional=true) public boolean removeWhitelistedRestrictedPermission(@NonNull String, @NonNull String, int);
@@ -12683,7 +12702,7 @@
field public static final int FLAG_USE_APP_ZYGOTE = 8; // 0x8
field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_CAMERA}, anyOf={android.Manifest.permission.CAMERA}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_CAMERA = 64; // 0x40
field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE}, anyOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.CHANGE_NETWORK_STATE, android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.CHANGE_WIFI_MULTICAST_STATE, android.Manifest.permission.NFC, android.Manifest.permission.TRANSMIT_IR}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE = 16; // 0x10
- field @Deprecated @RequiresPermission(value=android.Manifest.permission.FOREGROUND_SERVICE_DATA_SYNC, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_DATA_SYNC = 1; // 0x1
+ field @RequiresPermission(value=android.Manifest.permission.FOREGROUND_SERVICE_DATA_SYNC, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_DATA_SYNC = 1; // 0x1
field @RequiresPermission(android.Manifest.permission.FOREGROUND_SERVICE_FILE_MANAGEMENT) public static final int FOREGROUND_SERVICE_TYPE_FILE_MANAGEMENT = 4096; // 0x1000
field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_HEALTH}, anyOf={android.Manifest.permission.ACTIVITY_RECOGNITION, android.Manifest.permission.BODY_SENSORS, android.Manifest.permission.HIGH_SAMPLING_RATE_SENSORS}) public static final int FOREGROUND_SERVICE_TYPE_HEALTH = 256; // 0x100
field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_LOCATION}, anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_LOCATION = 8; // 0x8
@@ -13248,6 +13267,7 @@
ctor public ClearCredentialStateException(@NonNull String, @Nullable Throwable);
ctor public ClearCredentialStateException(@NonNull String);
method @NonNull public String getType();
+ field @NonNull public static final String TYPE_UNKNOWN = "android.credentials.ClearCredentialStateException.TYPE_UNKNOWN";
}
public final class ClearCredentialStateRequest implements android.os.Parcelable {
@@ -13264,7 +13284,10 @@
ctor public CreateCredentialException(@NonNull String, @Nullable Throwable);
ctor public CreateCredentialException(@NonNull String);
method @NonNull public String getType();
+ field @NonNull public static final String TYPE_INTERRUPTED = "android.credentials.CreateCredentialException.TYPE_INTERRUPTED";
field @NonNull public static final String TYPE_NO_CREDENTIAL = "android.credentials.CreateCredentialException.TYPE_NO_CREDENTIAL";
+ field @NonNull public static final String TYPE_UNKNOWN = "android.credentials.CreateCredentialException.TYPE_UNKNOWN";
+ field @NonNull public static final String TYPE_USER_CANCELED = "android.credentials.CreateCredentialException.TYPE_USER_CANCELED";
}
public final class CreateCredentialRequest implements android.os.Parcelable {
@@ -13308,7 +13331,10 @@
ctor public GetCredentialException(@NonNull String, @Nullable Throwable);
ctor public GetCredentialException(@NonNull String);
method @NonNull public String getType();
+ field @NonNull public static final String TYPE_INTERRUPTED = "android.credentials.GetCredentialException.TYPE_INTERRUPTED";
field @NonNull public static final String TYPE_NO_CREDENTIAL = "android.credentials.GetCredentialException.TYPE_NO_CREDENTIAL";
+ field @NonNull public static final String TYPE_UNKNOWN = "android.credentials.GetCredentialException.TYPE_UNKNOWN";
+ field @NonNull public static final String TYPE_USER_CANCELED = "android.credentials.GetCredentialException.TYPE_USER_CANCELED";
}
public final class GetCredentialOption implements android.os.Parcelable {
@@ -17715,8 +17741,8 @@
method public boolean flush(android.hardware.SensorEventListener);
method public static float getAltitude(float, float);
method public static void getAngleChange(float[], float[], float[]);
- method public android.hardware.Sensor getDefaultSensor(int);
- method public android.hardware.Sensor getDefaultSensor(int, boolean);
+ method @Nullable public android.hardware.Sensor getDefaultSensor(int);
+ method @Nullable public android.hardware.Sensor getDefaultSensor(int, boolean);
method public java.util.List<android.hardware.Sensor> getDynamicSensorList(int);
method public static float getInclination(float[]);
method public static float[] getOrientation(float[], float[]);
@@ -21956,6 +21982,7 @@
field public static final int PLUGIN_STATUS_PHYSICAL_MODULE_CHANGED = 0; // 0x0
field public static final int PLUGIN_STATUS_SESSION_NUMBER_CHANGED = 1; // 0x1
field public static final int SCRAMBLING_MODE_AES128 = 9; // 0x9
+ field public static final int SCRAMBLING_MODE_AES_CBC = 14; // 0xe
field public static final int SCRAMBLING_MODE_AES_ECB = 10; // 0xa
field public static final int SCRAMBLING_MODE_AES_SCTE52 = 11; // 0xb
field public static final int SCRAMBLING_MODE_DVB_CISSA_V1 = 6; // 0x6
@@ -33194,6 +33221,7 @@
field public static final String DISALLOW_CONFIG_CELL_BROADCASTS = "no_config_cell_broadcasts";
field public static final String DISALLOW_CONFIG_CREDENTIALS = "no_config_credentials";
field public static final String DISALLOW_CONFIG_DATE_TIME = "no_config_date_time";
+ field public static final String DISALLOW_CONFIG_DEFAULT_APPS = "disallow_config_default_apps";
field public static final String DISALLOW_CONFIG_LOCALE = "no_config_locale";
field public static final String DISALLOW_CONFIG_LOCATION = "no_config_location";
field public static final String DISALLOW_CONFIG_MOBILE_NETWORKS = "no_config_mobile_networks";
@@ -36397,6 +36425,7 @@
field public static final String ACTION_PROCESS_WIFI_EASY_CONNECT_URI = "android.settings.PROCESS_WIFI_EASY_CONNECT_URI";
field public static final String ACTION_QUICK_ACCESS_WALLET_SETTINGS = "android.settings.QUICK_ACCESS_WALLET_SETTINGS";
field public static final String ACTION_QUICK_LAUNCH_SETTINGS = "android.settings.QUICK_LAUNCH_SETTINGS";
+ field public static final String ACTION_REGIONAL_PREFERENCES_SETTINGS = "android.settings.REGIONAL_PREFERENCES_SETTINGS";
field public static final String ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
field public static final String ACTION_REQUEST_MANAGE_MEDIA = "android.settings.REQUEST_MANAGE_MEDIA";
field public static final String ACTION_REQUEST_SCHEDULE_EXACT_ALARM = "android.settings.REQUEST_SCHEDULE_EXACT_ALARM";
@@ -39919,6 +39948,7 @@
method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
method public abstract void onClearCredentialState(@NonNull android.service.credentials.ClearCredentialStateRequest, @NonNull android.os.CancellationSignal, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.credentials.ClearCredentialStateException>);
field public static final String CAPABILITY_META_DATA_KEY = "android.credentials.capabilities";
+ field public static final String EXTRA_BEGIN_GET_CREDENTIAL_REQUEST = "android.service.credentials.extra.BEGIN_GET_CREDENTIAL_REQUEST";
field public static final String EXTRA_CREATE_CREDENTIAL_EXCEPTION = "android.service.credentials.extra.CREATE_CREDENTIAL_EXCEPTION";
field public static final String EXTRA_CREATE_CREDENTIAL_REQUEST = "android.service.credentials.extra.CREATE_CREDENTIAL_REQUEST";
field public static final String EXTRA_CREATE_CREDENTIAL_RESPONSE = "android.service.credentials.extra.CREATE_CREDENTIAL_RESPONSE";
@@ -40437,7 +40467,7 @@
method public void onTileRemoved();
method public static final void requestListeningState(android.content.Context, android.content.ComponentName);
method public final void showDialog(android.app.Dialog);
- method public final void startActivityAndCollapse(android.content.Intent);
+ method @Deprecated public final void startActivityAndCollapse(android.content.Intent);
method public final void startActivityAndCollapse(@NonNull android.app.PendingIntent);
method public final void unlockAndRun(Runnable);
field public static final String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
@@ -41306,6 +41336,7 @@
method public void disconnect(@NonNull android.telecom.DisconnectCause, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallException>);
method @NonNull public android.os.ParcelUuid getCallId();
method public void rejectCall(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallException>);
+ method public void requestCallEndpointChange(@NonNull android.telecom.CallEndpoint, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallException>);
method public void setActive(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallException>);
method public void setInactive(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallException>);
method public void startCallStreaming(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallException>);
@@ -41343,10 +41374,12 @@
public interface CallEventCallback {
method public void onAnswer(int, @NonNull java.util.function.Consumer<java.lang.Boolean>);
- method public void onCallAudioStateChanged(@NonNull android.telecom.CallAudioState);
+ method public void onAvailableCallEndpointsChanged(@NonNull java.util.List<android.telecom.CallEndpoint>);
+ method public void onCallEndpointChanged(@NonNull android.telecom.CallEndpoint);
method public void onCallStreamingFailed(int);
method public void onCallStreamingStarted(@NonNull java.util.function.Consumer<java.lang.Boolean>);
method public void onDisconnect(@NonNull java.util.function.Consumer<java.lang.Boolean>);
+ method public void onMuteStateChanged(boolean);
method public void onReject(@NonNull java.util.function.Consumer<java.lang.Boolean>);
method public void onSetActive(@NonNull java.util.function.Consumer<java.lang.Boolean>);
method public void onSetInactive(@NonNull java.util.function.Consumer<java.lang.Boolean>);
@@ -46612,8 +46645,8 @@
field public static final int DONE = -1; // 0xffffffff
}
- public static class SegmentFinder.DefaultSegmentFinder extends android.text.SegmentFinder {
- ctor public SegmentFinder.DefaultSegmentFinder(@NonNull int[]);
+ public static class SegmentFinder.PrescribedSegmentFinder extends android.text.SegmentFinder {
+ ctor public SegmentFinder.PrescribedSegmentFinder(@NonNull int[]);
method public int nextEndBoundary(@IntRange(from=0) int);
method public int nextStartBoundary(@IntRange(from=0) int);
method public int previousEndBoundary(@IntRange(from=0) int);
@@ -50536,6 +50569,8 @@
field public static final int AXIS_GENERIC_7 = 38; // 0x26
field public static final int AXIS_GENERIC_8 = 39; // 0x27
field public static final int AXIS_GENERIC_9 = 40; // 0x28
+ field public static final int AXIS_GESTURE_SCROLL_X_DISTANCE = 50; // 0x32
+ field public static final int AXIS_GESTURE_SCROLL_Y_DISTANCE = 51; // 0x33
field public static final int AXIS_GESTURE_X_OFFSET = 48; // 0x30
field public static final int AXIS_GESTURE_Y_OFFSET = 49; // 0x31
field public static final int AXIS_HAT_X = 15; // 0xf
@@ -53763,6 +53798,7 @@
method public int getDisplayId();
method public int getId();
method public int getLayer();
+ method @NonNull public android.os.LocaleList getLocales();
method public android.view.accessibility.AccessibilityWindowInfo getParent();
method public void getRegionInScreen(@NonNull android.graphics.Region);
method public android.view.accessibility.AccessibilityNodeInfo getRoot();
@@ -54572,14 +54608,6 @@
public abstract class HandwritingGesture {
method @Nullable public final String getFallbackText();
- field public static final int GESTURE_TYPE_DELETE = 4; // 0x4
- field public static final int GESTURE_TYPE_DELETE_RANGE = 64; // 0x40
- field public static final int GESTURE_TYPE_INSERT = 2; // 0x2
- field public static final int GESTURE_TYPE_JOIN_OR_SPLIT = 16; // 0x10
- field public static final int GESTURE_TYPE_NONE = 0; // 0x0
- field public static final int GESTURE_TYPE_REMOVE_SPACE = 8; // 0x8
- field public static final int GESTURE_TYPE_SELECT = 1; // 0x1
- field public static final int GESTURE_TYPE_SELECT_RANGE = 32; // 0x20
field public static final int GRANULARITY_CHARACTER = 2; // 0x2
field public static final int GRANULARITY_WORD = 1; // 0x1
}
@@ -55079,15 +55107,15 @@
public final class TextBoundsInfo implements android.os.Parcelable {
method public int describeContents();
method @IntRange(from=0, to=125) public int getCharacterBidiLevel(int);
- method @NonNull public android.graphics.RectF getCharacterBounds(int);
+ method @NonNull public void getCharacterBounds(int, @NonNull android.graphics.RectF);
method public int getCharacterFlags(int);
- method public int getEnd();
+ method public int getEndIndex();
method @NonNull public android.text.SegmentFinder getGraphemeSegmentFinder();
method @NonNull public android.text.SegmentFinder getLineSegmentFinder();
- method @NonNull public android.graphics.Matrix getMatrix();
+ method @NonNull public void getMatrix(@NonNull android.graphics.Matrix);
method public int getOffsetForPosition(float, float);
method @Nullable public int[] getRangeForRect(@NonNull android.graphics.RectF, @NonNull android.text.SegmentFinder, @NonNull android.text.Layout.TextInclusionStrategy);
- method public int getStart();
+ method public int getStartIndex();
method @NonNull public android.text.SegmentFinder getWordSegmentFinder();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.view.inputmethod.TextBoundsInfo> CREATOR;
@@ -55098,7 +55126,7 @@
}
public static final class TextBoundsInfo.Builder {
- ctor public TextBoundsInfo.Builder();
+ ctor public TextBoundsInfo.Builder(int, int);
method @NonNull public android.view.inputmethod.TextBoundsInfo build();
method @NonNull public android.view.inputmethod.TextBoundsInfo.Builder clear();
method @NonNull public android.view.inputmethod.TextBoundsInfo.Builder setCharacterBidiLevel(@NonNull int[]);
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 447b113..3216bd1 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -171,6 +171,7 @@
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_STACK) public void setHfpEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_STACK) public void setHfpSamplingRate(int);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_STACK) public void setHfpVolume(int);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_STACK) public void setLeAudioSuspended(boolean);
method public void setStreamVolumeForUid(int, int, int, @NonNull String, int, int, int);
field public static final int FLAG_FROM_KEY = 4096; // 0x1000
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 4f50415d..85f8813 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -806,10 +806,12 @@
method @Nullable public android.content.IntentFilter getDeliveryGroupMatchingFilter();
method @Nullable public String getDeliveryGroupMatchingKey();
method public int getDeliveryGroupPolicy();
+ method public boolean isDeferUntilActive();
method public boolean isPendingIntentBackgroundActivityLaunchAllowed();
method public static android.app.BroadcastOptions makeBasic();
method @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS) public void recordResponseEventWhileInBackground(@IntRange(from=0) long);
method @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND) public void setBackgroundActivityStartsAllowed(boolean);
+ method @NonNull public android.app.BroadcastOptions setDeferUntilActive(boolean);
method @NonNull public android.app.BroadcastOptions setDeliveryGroupMatchingFilter(@NonNull android.content.IntentFilter);
method @NonNull public android.app.BroadcastOptions setDeliveryGroupMatchingKey(@NonNull String, @NonNull String);
method @NonNull public android.app.BroadcastOptions setDeliveryGroupPolicy(int);
@@ -2973,18 +2975,11 @@
}
public final class CompanionDeviceManager {
- method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public void addOnAssociationsChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.companion.CompanionDeviceManager.OnAssociationsChangedListener);
method @RequiresPermission(android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES) public void associate(@NonNull String, @NonNull android.net.MacAddress, @NonNull byte[]);
method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean canPairWithoutPrompt(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
- method @NonNull @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public java.util.List<android.companion.AssociationInfo> getAllAssociations();
method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean isDeviceAssociatedForWifiConnection(@NonNull String, @NonNull android.net.MacAddress, @NonNull android.os.UserHandle);
method @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED) public void notifyDeviceAppeared(int);
method @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED) public void notifyDeviceDisappeared(int);
- method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public void removeOnAssociationsChangedListener(@NonNull android.companion.CompanionDeviceManager.OnAssociationsChangedListener);
- }
-
- public static interface CompanionDeviceManager.OnAssociationsChangedListener {
- method public void onAssociationsChanged(@NonNull java.util.List<android.companion.AssociationInfo>);
}
}
@@ -3025,7 +3020,7 @@
method public int getDeviceId();
method @Nullable public android.companion.virtual.sensor.VirtualSensor getVirtualSensor(int, @NonNull String);
method public void launchPendingIntent(int, @NonNull android.app.PendingIntent, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.IntConsumer);
- method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void registerIntentInterceptor(@NonNull java.util.concurrent.Executor, @NonNull android.content.IntentFilter, @NonNull android.companion.virtual.VirtualDeviceManager.IntentInterceptorCallback);
+ method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void registerIntentInterceptor(@NonNull android.content.IntentFilter, @NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.IntentInterceptorCallback);
method public void removeActivityListener(@NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener);
method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void setShowPointerIcon(boolean);
method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void unregisterIntentInterceptor(@NonNull android.companion.virtual.VirtualDeviceManager.IntentInterceptorCallback);
@@ -3592,6 +3587,9 @@
field public static final int LOCATION_DATA_APP = 0; // 0x0
field public static final int LOCATION_MEDIA_DATA = 2; // 0x2
field public static final int LOCATION_MEDIA_OBB = 1; // 0x1
+ field public static final int REASON_CONFIRM_PACKAGE_CHANGE = 0; // 0x0
+ field public static final int REASON_OWNERSHIP_CHANGED = 1; // 0x1
+ field public static final int REASON_REMIND_OWNERSHIP = 2; // 0x2
}
public static class PackageInstaller.InstallInfo {
@@ -3621,6 +3619,7 @@
method public boolean getInstallAsFullApp(boolean);
method public boolean getInstallAsInstantApp(boolean);
method public boolean getInstallAsVirtualPreload();
+ method public int getPendingUserActionReason();
method public boolean getRequestDowngrade();
method public int getRollbackDataPolicy();
method @NonNull public java.util.Set<java.lang.String> getWhitelistedRestrictedPermissions();
@@ -5771,6 +5770,19 @@
package android.hardware.usb {
+ public final class DisplayPortAltModeInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getCableStatus();
+ method public int getNumberOfLanes();
+ method public int getPartnerSinkStatus();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.hardware.usb.DisplayPortAltModeInfo> CREATOR;
+ field public static final int DISPLAYPORT_ALT_MODE_STATUS_CAPABLE = 2; // 0x2
+ field public static final int DISPLAYPORT_ALT_MODE_STATUS_ENABLED = 3; // 0x3
+ field public static final int DISPLAYPORT_ALT_MODE_STATUS_NOT_CAPABLE = 1; // 0x1
+ field public static final int DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN = 0; // 0x0
+ }
+
public class UsbDeviceConnection {
method public boolean resetDevice();
}
@@ -5779,8 +5791,10 @@
method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public long getCurrentFunctions();
method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_USB) public java.util.List<android.hardware.usb.UsbPort> getPorts();
method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void grantPermission(android.hardware.usb.UsbDevice, String);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public boolean registerDisplayPortAltModeInfoListener(@NonNull java.util.concurrent.Executor, @NonNull android.hardware.usb.UsbManager.DisplayPortAltModeInfoListener);
method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void resetUsbGadget();
method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void setCurrentFunctions(long);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void unregisterDisplayPortAltModeInfoListener(@NonNull android.hardware.usb.UsbManager.DisplayPortAltModeInfoListener);
field @RequiresPermission(android.Manifest.permission.MANAGE_USB) public static final String ACTION_USB_ACCESSORY_HANDSHAKE = "android.hardware.usb.action.USB_ACCESSORY_HANDSHAKE";
field @RequiresPermission(android.Manifest.permission.MANAGE_USB) public static final String ACTION_USB_PORT_CHANGED = "android.hardware.usb.action.USB_PORT_CHANGED";
field @RequiresPermission(android.Manifest.permission.MANAGE_USB) public static final String ACTION_USB_PORT_COMPLIANCE_CHANGED = "android.hardware.usb.action.USB_PORT_COMPLIANCE_CHANGED";
@@ -5804,11 +5818,16 @@
field public static final String USB_FUNCTION_RNDIS = "rndis";
}
+ public static interface UsbManager.DisplayPortAltModeInfoListener {
+ method public void onDisplayPortAltModeInfoChanged(@NonNull String, @NonNull android.hardware.usb.DisplayPortAltModeInfo);
+ }
+
public final class UsbPort {
method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public int enableLimitPowerTransfer(boolean);
method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public int enableUsbData(boolean);
method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public int enableUsbDataWhileDocked();
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USB) public android.hardware.usb.UsbPortStatus getStatus();
+ method public boolean isAltModeSupported(int);
method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void resetUsbPort(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void setRoles(int, int);
method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public boolean supportsComplianceWarnings();
@@ -5828,6 +5847,7 @@
field public static final int ENABLE_USB_DATA_WHILE_DOCKED_ERROR_OTHER = 5; // 0x5
field public static final int ENABLE_USB_DATA_WHILE_DOCKED_ERROR_PORT_MISMATCH = 3; // 0x3
field public static final int ENABLE_USB_DATA_WHILE_DOCKED_SUCCESS = 0; // 0x0
+ field public static final int FLAG_ALT_MODE_TYPE_DISPLAYPORT = 1; // 0x1
field public static final int RESET_USB_PORT_ERROR_INTERNAL = 1; // 0x1
field public static final int RESET_USB_PORT_ERROR_NOT_SUPPORTED = 2; // 0x2
field public static final int RESET_USB_PORT_ERROR_OTHER = 4; // 0x4
@@ -5841,6 +5861,8 @@
method public int getCurrentDataRole();
method public int getCurrentMode();
method public int getCurrentPowerRole();
+ method @Nullable public android.hardware.usb.DisplayPortAltModeInfo getDisplayPortAltModeInfo();
+ method public int getPlugState();
method public int getPowerBrickConnectionStatus();
method public int getSupportedRoleCombinations();
method public int getUsbDataStatus();
@@ -5870,6 +5892,11 @@
field public static final int MODE_DFP = 2; // 0x2
field public static final int MODE_NONE = 0; // 0x0
field public static final int MODE_UFP = 1; // 0x1
+ field public static final int PLUG_STATE_PLUGGED_ORIENTATION_FLIPPED = 4; // 0x4
+ field public static final int PLUG_STATE_PLUGGED_ORIENTATION_NORMAL = 3; // 0x3
+ field public static final int PLUG_STATE_PLUGGED_ORIENTATION_UNKNOWN = 2; // 0x2
+ field public static final int PLUG_STATE_UNKNOWN = 0; // 0x0
+ field public static final int PLUG_STATE_UNPLUGGED = 1; // 0x1
field public static final int POWER_BRICK_STATUS_CONNECTED = 1; // 0x1
field public static final int POWER_BRICK_STATUS_DISCONNECTED = 2; // 0x2
field public static final int POWER_BRICK_STATUS_UNKNOWN = 0; // 0x0
@@ -10388,6 +10415,7 @@
field public static final String DISALLOW_RUN_IN_BACKGROUND = "no_run_in_background";
field public static final int REMOVE_RESULT_ALREADY_BEING_REMOVED = 2; // 0x2
field public static final int REMOVE_RESULT_DEFERRED = 1; // 0x1
+ field public static final int REMOVE_RESULT_ERROR_MAIN_USER_PERMANENT_ADMIN = -5; // 0xfffffffb
field public static final int REMOVE_RESULT_ERROR_SYSTEM_USER = -4; // 0xfffffffc
field public static final int REMOVE_RESULT_ERROR_UNKNOWN = -1; // 0xffffffff
field public static final int REMOVE_RESULT_ERROR_USER_NOT_FOUND = -3; // 0xfffffffd
@@ -11740,6 +11768,7 @@
method public int onEraseSubscriptions(int, @android.telephony.euicc.EuiccCardManager.ResetOption int);
method public abstract android.service.euicc.GetDefaultDownloadableSubscriptionListResult onGetDefaultDownloadableSubscriptionList(int, boolean);
method public abstract android.service.euicc.GetDownloadableSubscriptionMetadataResult onGetDownloadableSubscriptionMetadata(int, android.telephony.euicc.DownloadableSubscription, boolean);
+ method @NonNull public android.service.euicc.GetDownloadableSubscriptionMetadataResult onGetDownloadableSubscriptionMetadata(int, int, @NonNull android.telephony.euicc.DownloadableSubscription, boolean);
method public abstract String onGetEid(int);
method @NonNull public abstract android.telephony.euicc.EuiccInfo onGetEuiccInfo(int);
method @NonNull public abstract android.service.euicc.GetEuiccProfileInfoListResult onGetEuiccProfileInfoList(int);
@@ -16502,6 +16531,7 @@
public abstract class AccessibilityDisplayProxy {
ctor public AccessibilityDisplayProxy(int, @NonNull java.util.concurrent.Executor, @NonNull java.util.List<android.accessibilityservice.AccessibilityServiceInfo>);
+ method @Nullable public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
method public int getDisplayId();
method @NonNull public final java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getInstalledAndEnabledServices();
method @NonNull public java.util.List<android.view.accessibility.AccessibilityWindowInfo> getWindows();
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index e3554a5..d25c3f5 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1246,7 +1246,7 @@
public final class CameraManager {
method public String[] getCameraIdListNoLazy() throws android.hardware.camera2.CameraAccessException;
method @RequiresPermission(allOf={android.Manifest.permission.SYSTEM_CAMERA, android.Manifest.permission.CAMERA}) public void openCamera(@NonNull String, int, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraDevice.StateCallback) throws android.hardware.camera2.CameraAccessException;
- field public static final long OVERRIDE_FRONT_CAMERA_APP_COMPAT = 250678880L; // 0xef10e60L
+ field public static final long OVERRIDE_CAMERA_LANDSCAPE_TO_PORTRAIT = 250678880L; // 0xef10e60L
}
public abstract static class CameraManager.AvailabilityCallback {
@@ -3322,6 +3322,14 @@
public abstract class HandwritingGesture {
method public final int getGestureType();
+ field public static final int GESTURE_TYPE_DELETE = 4; // 0x4
+ field public static final int GESTURE_TYPE_DELETE_RANGE = 64; // 0x40
+ field public static final int GESTURE_TYPE_INSERT = 2; // 0x2
+ field public static final int GESTURE_TYPE_JOIN_OR_SPLIT = 16; // 0x10
+ field public static final int GESTURE_TYPE_NONE = 0; // 0x0
+ field public static final int GESTURE_TYPE_REMOVE_SPACE = 8; // 0x8
+ field public static final int GESTURE_TYPE_SELECT = 1; // 0x1
+ field public static final int GESTURE_TYPE_SELECT_RANGE = 32; // 0x20
}
public final class InlineSuggestion implements android.os.Parcelable {
@@ -3664,14 +3672,13 @@
ctor public WindowContainerTransaction();
method @NonNull public android.window.WindowContainerTransaction clearLaunchAdjacentFlagRoot(@NonNull android.window.WindowContainerToken);
method @NonNull public android.window.WindowContainerTransaction createTaskFragment(@NonNull android.window.TaskFragmentCreationParams);
- method @NonNull public android.window.WindowContainerTransaction deleteTaskFragment(@NonNull android.window.WindowContainerToken);
+ method @NonNull public android.window.WindowContainerTransaction deleteTaskFragment(@NonNull android.os.IBinder);
method public int describeContents();
method @NonNull public android.window.WindowContainerTransaction finishActivity(@NonNull android.os.IBinder);
method @NonNull public android.window.WindowContainerTransaction removeTask(@NonNull android.window.WindowContainerToken);
method @NonNull public android.window.WindowContainerTransaction reorder(@NonNull android.window.WindowContainerToken, boolean);
method @NonNull public android.window.WindowContainerTransaction reparent(@NonNull android.window.WindowContainerToken, @Nullable android.window.WindowContainerToken, boolean);
method @NonNull public android.window.WindowContainerTransaction reparentActivityToTaskFragment(@NonNull android.os.IBinder, @NonNull android.os.IBinder);
- method @NonNull public android.window.WindowContainerTransaction reparentChildren(@NonNull android.window.WindowContainerToken, @Nullable android.window.WindowContainerToken);
method @NonNull public android.window.WindowContainerTransaction reparentTasks(@Nullable android.window.WindowContainerToken, @Nullable android.window.WindowContainerToken, @Nullable int[], @Nullable int[], boolean);
method @NonNull public android.window.WindowContainerTransaction requestFocusOnTaskFragment(@NonNull android.os.IBinder);
method @NonNull public android.window.WindowContainerTransaction scheduleFinishEnterPip(@NonNull android.window.WindowContainerToken, @NonNull android.graphics.Rect);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 32d88b2..c0239e8 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -9085,6 +9085,25 @@
state, sourceSpec, targetSpec, viewIds, uiTranslationSpec);
}
+ /**
+ * If set, any activity launch in the same task will be overridden to the locale of activity
+ * that started the task.
+ *
+ * <p>Currently, Android supports per app languages, and system apps are able to start
+ * activities of another package on the same task, which may cause users to set different
+ * languages in different apps and display two different languages in one app.</p>
+ *
+ * <p>The <a href="https://developer.android.com/guide/topics/large-screens/activity-embedding">
+ * activity embedding feature</a> will align the locale with root activity automatically, but
+ * it doesn't land on the phone yet. If activity embedding land on the phone in the future,
+ * please consider adapting activity embedding directly.</p>
+ *
+ * @hide
+ */
+ public void enableTaskLocaleOverride() {
+ ActivityClient.getInstance().enableTaskLocaleOverride(mToken);
+ }
+
class HostCallbacks extends FragmentHostCallback<Activity> {
public HostCallbacks() {
super(Activity.this /*activity*/);
diff --git a/core/java/android/app/ActivityClient.java b/core/java/android/app/ActivityClient.java
index 558dae5..aa868a7 100644
--- a/core/java/android/app/ActivityClient.java
+++ b/core/java/android/app/ActivityClient.java
@@ -563,6 +563,14 @@
}
}
+ void enableTaskLocaleOverride(IBinder token) {
+ try {
+ getActivityClientController().enableTaskLocaleOverride(token);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+
/**
* Shows or hides a Camera app compat toggle for stretched issues with the requested state.
*
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 6826b67..3e21124 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -20,6 +20,8 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.PermissionMethod;
+import android.annotation.PermissionName;
import android.annotation.UserIdInt;
import android.app.ActivityManager.ProcessCapability;
import android.app.ActivityManager.RestrictionLevel;
@@ -31,8 +33,6 @@
import android.content.pm.ActivityInfo;
import android.content.pm.ActivityPresentationInfo;
import android.content.pm.ApplicationInfo;
-import android.content.pm.PermissionMethod;
-import android.content.pm.PermissionName;
import android.content.pm.UserInfo;
import android.net.Uri;
import android.os.Bundle;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 86482c0..3f27964 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4558,7 +4558,11 @@
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
if (!service.isUiContext()) { // WindowProviderService is a UI Context.
- service.updateDeviceId(mLastReportedDeviceId);
+ VirtualDeviceManager vdm = context.getSystemService(VirtualDeviceManager.class);
+ if (mLastReportedDeviceId == VirtualDeviceManager.DEVICE_ID_DEFAULT
+ || vdm.isValidVirtualDeviceId(mLastReportedDeviceId)) {
+ service.updateDeviceId(mLastReportedDeviceId);
+ }
}
service.onCreate();
mServicesData.put(data.token, data);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index a7a4b35..c11961e 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -3890,4 +3890,14 @@
return Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.SHOW_NEW_APP_INSTALLED_NOTIFICATION_ENABLED, 0) == 1;
}
+
+ @Override
+ public void relinquishUpdateOwnership(String targetPackage) {
+ Objects.requireNonNull(targetPackage);
+ try {
+ mPM.relinquishUpdateOwnership(targetPackage);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
index e202760..5cf10d0 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -63,6 +63,7 @@
private long mRequireCompatChangeId = CHANGE_INVALID;
private boolean mRequireCompatChangeEnabled = true;
private boolean mIsAlarmBroadcast = false;
+ private boolean mIsDeferUntilActive = false;
private long mIdForResponseEvent;
private @Nullable IntentFilter mRemoveMatchingFilter;
private @DeliveryGroupPolicy int mDeliveryGroupPolicy;
@@ -201,6 +202,12 @@
"android:broadcast.removeMatchingFilter";
/**
+ * Corresponds to {@link #setDeferUntilActive(boolean)}.
+ */
+ private static final String KEY_DEFER_UNTIL_ACTIVE =
+ "android:broadcast.deferuntilactive";
+
+ /**
* Corresponds to {@link #setDeliveryGroupPolicy(int)}.
*/
private static final String KEY_DELIVERY_GROUP_POLICY =
@@ -320,6 +327,7 @@
BundleMerger.class);
mDeliveryGroupMatchingFilter = opts.getParcelable(KEY_DELIVERY_GROUP_MATCHING_FILTER,
IntentFilter.class);
+ mIsDeferUntilActive = opts.getBoolean(KEY_DEFER_UNTIL_ACTIVE, false);
}
/**
@@ -700,6 +708,41 @@
}
/**
+ * Sets whether the broadcast should not run until the process is in an active process state
+ * (ie, a process exists for the app and the app is not in a cached process state).
+ *
+ * Whether an app's process state is considered active is independent of its standby bucket.
+ *
+ * A broadcast that is deferred until the process is active will not execute until the process
+ * is brought to an active state by some other action, like a job, alarm, or service binding. As
+ * a result, the broadcast may be delayed indefinitely. This deferral only applies to runtime
+ * registered receivers of a broadcast. Any manifest receivers will run immediately, similar to
+ * how a manifest receiver would start a new process in order to run a broadcast receiver.
+ *
+ * Ordered broadcasts, alarm broadcasts, interactive broadcasts, and manifest broadcasts are
+ * never deferred.
+ *
+ * Unordered broadcasts and unordered broadcasts with completion callbacks may be
+ * deferred. Completion callbacks for broadcasts deferred until active are
+ * best-effort. Completion callbacks will run when all eligible processes have finished
+ * executing the broadcast. Processes in inactive process states that defer the broadcast are
+ * not considered eligible and may not execute the broadcast prior to the completion callback.
+ *
+ * @hide
+ */
+ @SystemApi
+ public @NonNull BroadcastOptions setDeferUntilActive(boolean shouldDefer) {
+ mIsDeferUntilActive = shouldDefer;
+ return this;
+ }
+
+ /** @hide */
+ @SystemApi
+ public boolean isDeferUntilActive() {
+ return mIsDeferUntilActive;
+ }
+
+ /**
* When enqueuing this broadcast, remove all pending broadcasts previously
* sent by this app which match the given filter.
* <p>
@@ -963,6 +1006,9 @@
if (mDeliveryGroupMatchingFilter != null) {
b.putParcelable(KEY_DELIVERY_GROUP_MATCHING_FILTER, mDeliveryGroupMatchingFilter);
}
+ if (mIsDeferUntilActive) {
+ b.putBoolean(KEY_DEFER_UNTIL_ACTIVE, mIsDeferUntilActive);
+ }
return b.isEmpty() ? null : b;
}
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 240dbe1..befe833a 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -26,9 +26,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UiContext;
-import android.companion.virtual.VirtualDevice;
import android.companion.virtual.VirtualDeviceManager;
-import android.companion.virtual.VirtualDeviceParams;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.AttributionSource;
import android.content.AutofillOptions;
@@ -2742,9 +2740,12 @@
@Override
public @NonNull Context createDeviceContext(int deviceId) {
- if (!isValidDeviceId(deviceId)) {
- throw new IllegalArgumentException(
- "Not a valid ID of the default device or any virtual device: " + deviceId);
+ if (deviceId != VirtualDeviceManager.DEVICE_ID_DEFAULT) {
+ VirtualDeviceManager vdm = getSystemService(VirtualDeviceManager.class);
+ if (!vdm.isValidVirtualDeviceId(deviceId)) {
+ throw new IllegalArgumentException(
+ "Not a valid ID of the default device or any virtual device: " + deviceId);
+ }
}
ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mParams,
@@ -2757,31 +2758,6 @@
return context;
}
- /**
- * Checks whether the passed {@code deviceId} is valid or not.
- * {@link VirtualDeviceManager#DEVICE_ID_DEFAULT} is valid as it is the ID of the default
- * device when no additional virtual devices exist. If {@code deviceId} is the id of
- * a virtual device, it should correspond to a virtual device created by
- * {@link VirtualDeviceManager#createVirtualDevice(int, VirtualDeviceParams)}.
- */
- private boolean isValidDeviceId(int deviceId) {
- if (deviceId == VirtualDeviceManager.DEVICE_ID_DEFAULT) {
- return true;
- }
- if (deviceId > VirtualDeviceManager.DEVICE_ID_DEFAULT) {
- VirtualDeviceManager vdm = getSystemService(VirtualDeviceManager.class);
- if (vdm != null) {
- List<VirtualDevice> virtualDevices = vdm.getVirtualDevices();
- for (int i = 0; i < virtualDevices.size(); i++) {
- if (virtualDevices.get(i).getDeviceId() == deviceId) {
- return true;
- }
- }
- }
- }
- return false;
- }
-
@NonNull
@Override
public WindowContext createWindowContext(@WindowType int type,
@@ -3044,10 +3020,13 @@
@Override
public void updateDeviceId(int updatedDeviceId) {
- if (!isValidDeviceId(updatedDeviceId)) {
- throw new IllegalArgumentException(
- "Not a valid ID of the default device or any virtual device: "
- + updatedDeviceId);
+ if (updatedDeviceId != VirtualDeviceManager.DEVICE_ID_DEFAULT) {
+ VirtualDeviceManager vdm = getSystemService(VirtualDeviceManager.class);
+ if (!vdm.isValidVirtualDeviceId(updatedDeviceId)) {
+ throw new IllegalArgumentException(
+ "Not a valid ID of the default device or any virtual device: "
+ + updatedDeviceId);
+ }
}
if (mIsExplicitDeviceId) {
throw new UnsupportedOperationException(
diff --git a/core/java/android/app/ForegroundServiceTypePolicy.java b/core/java/android/app/ForegroundServiceTypePolicy.java
index 877177c..f0c39ab 100644
--- a/core/java/android/app/ForegroundServiceTypePolicy.java
+++ b/core/java/android/app/ForegroundServiceTypePolicy.java
@@ -117,14 +117,10 @@
* The FGS type enforcement:
* deprecating the {@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_DATA_SYNC}.
*
- * <p>Starting a FGS with this type from apps with targetSdkVersion
- * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or later will
- * result in a warning in the log.</p>
- *
* @hide
*/
@ChangeId
- @EnabledAfter(targetSdkVersion = android.os.Build.VERSION_CODES.TIRAMISU)
+ @Disabled
@Overridable
public static final long FGS_TYPE_DATA_SYNC_DEPRECATION_CHANGE_ID = 255039210L;
@@ -132,13 +128,8 @@
* The FGS type enforcement:
* disabling the {@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_DATA_SYNC}.
*
- * <p>Starting a FGS with this type from apps with targetSdkVersion
- * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or later will
- * result in an exception.</p>
- *
* @hide
*/
- // TODO (b/254661666): Change to @EnabledSince(U) in next OS release
@ChangeId
@Disabled
@Overridable
diff --git a/core/java/android/app/IActivityClientController.aidl b/core/java/android/app/IActivityClientController.aidl
index ecea46a..03646c6 100644
--- a/core/java/android/app/IActivityClientController.aidl
+++ b/core/java/android/app/IActivityClientController.aidl
@@ -171,4 +171,10 @@
*/
oneway void requestCompatCameraControl(in IBinder token, boolean showControl,
boolean transformationApplied, in ICompatCameraControlCallback callback);
+
+ /**
+ * If set, any activity launch in the same task will be overridden to the locale of activity
+ * that started the task.
+ */
+ void enableTaskLocaleOverride(in IBinder token);
}
diff --git a/core/java/android/app/LocaleConfig.java b/core/java/android/app/LocaleConfig.java
index 50ba7db..69693fc 100644
--- a/core/java/android/app/LocaleConfig.java
+++ b/core/java/android/app/LocaleConfig.java
@@ -110,7 +110,7 @@
* @see Context#createPackageContext(String, int).
*/
@NonNull
- public static LocaleConfig fromResources(@NonNull Context context) {
+ public static LocaleConfig fromContextIgnoringOverride(@NonNull Context context) {
return new LocaleConfig(context, false);
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index ad17e0d..1633073 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2417,6 +2417,7 @@
* applied (cross profile intent filters updated). Only usesd for CTS tests.
* @hide
*/
+ @SuppressLint("ActionValue")
@TestApi
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_DATA_SHARING_RESTRICTION_APPLIED =
@@ -2427,6 +2428,7 @@
* has been changed.
* @hide
*/
+ @SuppressLint("ActionValue")
@TestApi
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_DEVICE_POLICY_CONSTANTS_CHANGED =
@@ -6979,6 +6981,8 @@
* {@link #ENCRYPTION_STATUS_UNSUPPORTED}, {@link #ENCRYPTION_STATUS_INACTIVE},
* {@link #ENCRYPTION_STATUS_ACTIVATING}, {@link #ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY},
* {@link #ENCRYPTION_STATUS_ACTIVE}, or {@link #ENCRYPTION_STATUS_ACTIVE_PER_USER}.
+ *
+ * @throws SecurityException if called on a parent instance.
*/
public int getStorageEncryptionStatus() {
throwIfParentInstance("getStorageEncryptionStatus");
diff --git a/core/java/android/app/time/UnixEpochTime.java b/core/java/android/app/time/UnixEpochTime.java
index 61cbc5e..0b8f7ee 100644
--- a/core/java/android/app/time/UnixEpochTime.java
+++ b/core/java/android/app/time/UnixEpochTime.java
@@ -124,7 +124,7 @@
@Override
public String toString() {
return "UnixEpochTime{"
- + "mElapsedRealtimeTimeMillis=" + mElapsedRealtimeMillis
+ + "mElapsedRealtimeMillis=" + mElapsedRealtimeMillis
+ ", mUnixEpochTimeMillis=" + mUnixEpochTimeMillis
+ '}';
}
diff --git a/core/java/android/app/timedetector/TimeDetector.java b/core/java/android/app/timedetector/TimeDetector.java
index f95d6d3..50a7da1 100644
--- a/core/java/android/app/timedetector/TimeDetector.java
+++ b/core/java/android/app/timedetector/TimeDetector.java
@@ -73,6 +73,18 @@
String SHELL_COMMAND_SUGGEST_NETWORK_TIME = "suggest_network_time";
/**
+ * A shell command that prints the current network time information.
+ * @hide
+ */
+ String SHELL_COMMAND_GET_NETWORK_TIME = "get_network_time";
+
+ /**
+ * A shell command that clears the detector's network time information.
+ * @hide
+ */
+ String SHELL_COMMAND_CLEAR_NETWORK_TIME = "clear_network_time";
+
+ /**
* A shell command that injects a GNSS time suggestion.
* @hide
*/
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index 63f4bcf..d31124d 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -662,9 +662,7 @@
* @return the associations list
* @see #addOnAssociationsChangedListener(Executor, OnAssociationsChangedListener)
* @see #removeOnAssociationsChangedListener(OnAssociationsChangedListener)
- * @hide
*/
- @SystemApi
@UserHandleAware
@RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES)
public @NonNull List<AssociationInfo> getAllAssociations() {
@@ -678,10 +676,7 @@
/**
* Listener for any changes to {@link AssociationInfo}.
- *
- * @hide
*/
- @SystemApi
public interface OnAssociationsChangedListener {
/**
* Invoked when a change occurs to any of the associations for the user (including adding
@@ -696,9 +691,7 @@
* Register listener for any changes to {@link AssociationInfo}.
*
* @see #getAllAssociations()
- * @hide
*/
- @SystemApi
@UserHandleAware
@RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES)
public void addOnAssociationsChangedListener(
@@ -720,9 +713,7 @@
* Unregister listener for any changes to {@link AssociationInfo}.
*
* @see #getAllAssociations()
- * @hide
*/
- @SystemApi
@UserHandleAware
@RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES)
public void removeOnAssociationsChangedListener(
diff --git a/core/java/android/companion/virtual/IVirtualDeviceManager.aidl b/core/java/android/companion/virtual/IVirtualDeviceManager.aidl
index f0d23ac..e96a2c1 100644
--- a/core/java/android/companion/virtual/IVirtualDeviceManager.aidl
+++ b/core/java/android/companion/virtual/IVirtualDeviceManager.aidl
@@ -56,6 +56,14 @@
*/
int getDeviceIdForDisplayId(int displayId);
+ /**
+ * Checks whether the passed {@code deviceId} is a valid virtual device ID or not.
+ * {@link VirtualDeviceManager#DEVICE_ID_DEFAULT} is not valid as it is the ID of the default
+ * device which is not a virtual device. {@code deviceId} must correspond to a virtual device
+ * created by {@link VirtualDeviceManager#createVirtualDevice(int, VirtualDeviceParams)}.
+ */
+ boolean isValidVirtualDeviceId(int deviceId);
+
/**
* Returns the device policy for the given virtual device and policy type.
*/
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index adf59fb..3bc1628 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -258,6 +258,26 @@
}
/**
+ * Checks whether the passed {@code deviceId} is a valid virtual device ID or not.
+ * {@link VirtualDeviceManager#DEVICE_ID_DEFAULT} is not valid as it is the ID of the default
+ * device which is not a virtual device. {@code deviceId} must correspond to a virtual device
+ * created by {@link VirtualDeviceManager#createVirtualDevice(int, VirtualDeviceParams)}.
+ *
+ * @hide
+ */
+ public boolean isValidVirtualDeviceId(int deviceId) {
+ if (mService == null) {
+ Log.w(TAG, "Failed to retrieve virtual devices; no virtual device manager service.");
+ return false;
+ }
+ try {
+ return mService.isValidVirtualDeviceId(deviceId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Returns device-specific audio session id for audio playback.
*
* @param deviceId - id of the virtual audio device
@@ -931,16 +951,16 @@
* when matching the provided IntentFilter and calls the callback with the intercepted
* intent.
*
- * @param executor The executor where the interceptor is executed on.
* @param interceptorFilter The filter to match intents intended for interception.
+ * @param executor The executor where the interceptor is executed on.
* @param interceptorCallback The callback called when an intent matching interceptorFilter
* is intercepted.
* @see #unregisterIntentInterceptor(IntentInterceptorCallback)
*/
@RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
public void registerIntentInterceptor(
- @CallbackExecutor @NonNull Executor executor,
@NonNull IntentFilter interceptorFilter,
+ @CallbackExecutor @NonNull Executor executor,
@NonNull IntentInterceptorCallback interceptorCallback) {
Objects.requireNonNull(executor);
Objects.requireNonNull(interceptorFilter);
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 12a2cae..74c3f45 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -26,6 +26,8 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.PermissionMethod;
+import android.annotation.PermissionName;
import android.annotation.RequiresPermission;
import android.annotation.StringDef;
import android.annotation.StringRes;
@@ -53,8 +55,6 @@
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PermissionMethod;
-import android.content.pm.PermissionName;
import android.content.res.AssetManager;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
@@ -408,7 +408,12 @@
* will cause the isolated service to be co-located in the same shared isolated process.
*
* Note that the shared isolated process is scoped to the calling app; once created, only
- * the calling app can bind additional isolated services into the shared process.
+ * the calling app can bind additional isolated services into the shared process. However,
+ * the services themselves can come from different APKs and therefore different vendors.
+ *
+ * Only services that set the {@link android.R.attr#allowSharedIsolatedProcess} attribute
+ * to {@code true} are allowed to be bound into a shared isolated process.
+ *
*/
public static final int BIND_SHARED_ISOLATED_PROCESS = 0x00002000;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 7ee8f60..4318c39 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -11601,7 +11601,7 @@
private void toUriInner(StringBuilder uri, String scheme, String defAction,
String defPackage, int flags) {
if (scheme != null) {
- uri.append("scheme=").append(scheme).append(';');
+ uri.append("scheme=").append(Uri.encode(scheme)).append(';');
}
if (mAction != null && !mAction.equals(defAction)) {
uri.append("action=").append(Uri.encode(mAction)).append(';');
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index a9f55bc..8fd905e 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -1102,6 +1102,41 @@
public static final long ALWAYS_SANDBOX_DISPLAY_APIS = 185004937L; // buganizer id
/**
+ * This change id excludes the packages it is applied to from the camera compat force rotation
+ * treatment. See com.android.server.wm.DisplayRotationCompatPolicy for context.
+ * @hide
+ */
+ @ChangeId
+ @Overridable
+ @Disabled
+ public static final long OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION =
+ 263959004L; // buganizer id
+
+ /**
+ * This change id excludes the packages it is applied to from activity refresh after camera
+ * compat force rotation treatment. See com.android.server.wm.DisplayRotationCompatPolicy for
+ * context.
+ * @hide
+ */
+ @ChangeId
+ @Overridable
+ @Disabled
+ public static final long OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH = 264304459L; // buganizer id
+
+ /**
+ * This change id makes the packages it is applied to do activity refresh after camera compat
+ * force rotation treatment using "resumed -> paused -> resumed" cycle rather than "resumed ->
+ * ... -> stopped -> ... -> resumed" cycle. See
+ * com.android.server.wm.DisplayRotationCompatPolicy for context.
+ * @hide
+ */
+ @ChangeId
+ @Overridable
+ @Disabled
+ public static final long OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE =
+ 264301586L; // buganizer id
+
+ /**
* This change id is the gatekeeper for all treatments that force a given min aspect ratio.
* Enabling this change will allow the following min aspect ratio treatments to be applied:
* OVERRIDE_MIN_ASPECT_RATIO_MEDIUM
diff --git a/core/java/android/content/pm/IPackageInstallerSession.aidl b/core/java/android/content/pm/IPackageInstallerSession.aidl
index 60a7b13..9dd9c0f 100644
--- a/core/java/android/content/pm/IPackageInstallerSession.aidl
+++ b/core/java/android/content/pm/IPackageInstallerSession.aidl
@@ -46,6 +46,8 @@
void commit(in IntentSender statusReceiver, boolean forTransferred);
void transfer(in String packageName);
void abandon();
+ void seal();
+ List<String> fetchPackageNames();
DataLoaderParamsParcel getDataLoaderParams();
void addFile(int location, String name, long lengthBytes, in byte[] metadata, in byte[] signature);
@@ -63,6 +65,7 @@
void requestUserPreapproval(in PackageInstaller.PreapprovalDetails details, in IntentSender statusReceiver);
boolean isKeepApplicationEnabledSetting();
+ boolean isRequestUpdateOwnership();
ParcelFileDescriptor getAppMetadataFd();
ParcelFileDescriptor openWriteAppMetadata();
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 54ca1e5..0e37c87 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -214,6 +214,8 @@
@UnsupportedAppUsage
void setInstallerPackageName(in String targetPackage, in String installerPackageName);
+ void relinquishUpdateOwnership(in String targetPackage);
+
void setApplicationCategoryHint(String packageName, int categoryHint, String callerPackageName);
/** @deprecated rawr, don't call AIDL methods directly! */
diff --git a/core/java/android/content/pm/InstallSourceInfo.java b/core/java/android/content/pm/InstallSourceInfo.java
index 88f1a16..67123e8 100644
--- a/core/java/android/content/pm/InstallSourceInfo.java
+++ b/core/java/android/content/pm/InstallSourceInfo.java
@@ -35,6 +35,8 @@
@Nullable private final String mInstallingPackageName;
+ @Nullable private final String mUpdateOwnerPackageName;
+
@Nullable private final int mPackageSource;
/** @hide */
@@ -42,18 +44,20 @@
@Nullable SigningInfo initiatingPackageSigningInfo,
@Nullable String originatingPackageName, @Nullable String installingPackageName) {
this(initiatingPackageName, initiatingPackageSigningInfo, originatingPackageName,
- installingPackageName, PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
+ installingPackageName, null /* updateOwnerPackageName */,
+ PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
}
/** @hide */
public InstallSourceInfo(@Nullable String initiatingPackageName,
@Nullable SigningInfo initiatingPackageSigningInfo,
@Nullable String originatingPackageName, @Nullable String installingPackageName,
- int packageSource) {
+ @Nullable String updateOwnerPackageName, int packageSource) {
mInitiatingPackageName = initiatingPackageName;
mInitiatingPackageSigningInfo = initiatingPackageSigningInfo;
mOriginatingPackageName = originatingPackageName;
mInstallingPackageName = installingPackageName;
+ mUpdateOwnerPackageName = updateOwnerPackageName;
mPackageSource = packageSource;
}
@@ -69,6 +73,7 @@
dest.writeParcelable(mInitiatingPackageSigningInfo, flags);
dest.writeString(mOriginatingPackageName);
dest.writeString(mInstallingPackageName);
+ dest.writeString8(mUpdateOwnerPackageName);
dest.writeInt(mPackageSource);
}
@@ -77,6 +82,7 @@
mInitiatingPackageSigningInfo = source.readParcelable(SigningInfo.class.getClassLoader(), android.content.pm.SigningInfo.class);
mOriginatingPackageName = source.readString();
mInstallingPackageName = source.readString();
+ mUpdateOwnerPackageName = source.readString8();
mPackageSource = source.readInt();
}
@@ -137,6 +143,21 @@
}
/**
+ * The name of the package that is the update owner, or null if not available.
+ *
+ * This indicates the update ownership enforcement is enabled for this app,
+ * and which package is the update owner.
+ *
+ * Returns null if the update ownership enforcement is disabled for the app.
+ *
+ * @see PackageInstaller.SessionParams#setRequestUpdateOwnership
+ */
+ @Nullable
+ public String getUpdateOwnerPackageName() {
+ return mUpdateOwnerPackageName;
+ }
+
+ /**
* Information about the package source when installer installed this app.
*/
public @PackageInstaller.PackageSourceType int getPackageSource() {
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 703a9252..df1340d 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -44,8 +44,11 @@
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.ActivityManager;
+import android.app.ActivityThread;
import android.app.AppGlobals;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.IIntentReceiver;
+import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager.DeleteFlags;
@@ -59,9 +62,11 @@
import android.icu.util.ULocale;
import android.net.Uri;
import android.os.Build;
+import android.os.Bundle;
import android.os.FileBridge;
import android.os.Handler;
import android.os.HandlerExecutor;
+import android.os.IBinder;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
@@ -226,8 +231,8 @@
* {@link #STATUS_PENDING_USER_ACTION}, {@link #STATUS_SUCCESS},
* {@link #STATUS_FAILURE}, {@link #STATUS_FAILURE_ABORTED},
* {@link #STATUS_FAILURE_BLOCKED}, {@link #STATUS_FAILURE_CONFLICT},
- * {@link #STATUS_FAILURE_INCOMPATIBLE}, {@link #STATUS_FAILURE_INVALID}, or
- * {@link #STATUS_FAILURE_STORAGE}.
+ * {@link #STATUS_FAILURE_INCOMPATIBLE}, {@link #STATUS_FAILURE_INVALID},
+ * {@link #STATUS_FAILURE_STORAGE}, or {@link #STATUS_FAILURE_TIMEOUT}.
* <p>
* More information about a status may be available through additional
* extras; see the individual status documentation for details.
@@ -441,6 +446,13 @@
public static final int STATUS_FAILURE_INCOMPATIBLE = 7;
/**
+ * The operation failed because it didn't complete within the specified timeout.
+ *
+ * @see #EXTRA_STATUS_MESSAGE
+ */
+ public static final int STATUS_FAILURE_TIMEOUT = 8;
+
+ /**
* Default value, non-streaming installation session.
*
* @see #EXTRA_DATA_LOADER_TYPE
@@ -544,6 +556,46 @@
@Retention(RetentionPolicy.SOURCE)
@interface PackageSourceType{}
+ /**
+ * Indicate the user intervention is required when the installer attempts to commit the session.
+ * This is the default case.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int REASON_CONFIRM_PACKAGE_CHANGE = 0;
+
+ /**
+ * Indicate the user intervention is required because the update ownership enforcement is
+ * enabled, and the update owner will change.
+ *
+ * @see PackageInstaller.SessionParams#setRequestUpdateOwnership
+ * @see InstallSourceInfo#getUpdateOwnerPackageName
+ * @hide
+ */
+ @SystemApi
+ public static final int REASON_OWNERSHIP_CHANGED = 1;
+
+ /**
+ * Indicate the user intervention is required because the update ownership enforcement is
+ * enabled, and remind the update owner will retain.
+ *
+ * @see PackageInstaller.SessionParams#setRequestUpdateOwnership
+ * @see InstallSourceInfo#getUpdateOwnerPackageName
+ * @hide
+ */
+ @SystemApi
+ public static final int REASON_REMIND_OWNERSHIP = 2;
+
+ /** @hide */
+ @IntDef(prefix = { "REASON_" }, value = {
+ REASON_CONFIRM_PACKAGE_CHANGE,
+ REASON_OWNERSHIP_CHANGED,
+ REASON_REMIND_OWNERSHIP,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface UserActionReason {}
+
/** Default set of checksums - includes all available checksums.
* @see Session#requestChecksums */
private static final int DEFAULT_CHECKSUMS =
@@ -976,6 +1028,61 @@
}
/**
+ * Commit the session when all constraints are satisfied. This is a convenient method to
+ * combine {@link #waitForInstallConstraints(List, InstallConstraints, IntentSender, long)}
+ * and {@link Session#commit(IntentSender)}.
+ * <p>
+ * Once this method is called, the session is sealed and no additional mutations
+ * may be performed on the session. In the case of timeout, you may commit the
+ * session again using this method or {@link Session#commit(IntentSender)} for retries.
+ *
+ * @param statusReceiver Called when the state of the session changes. Intents
+ * sent to this receiver contain {@link #EXTRA_STATUS}.
+ * Refer to the individual status codes on how to handle them.
+ * @param constraints The requirements to satisfy before committing the session.
+ * @param timeoutMillis The maximum time to wait, in milliseconds until the
+ * constraints are satisfied. The caller will be notified via
+ * {@code statusReceiver} if timeout happens before commit.
+ */
+ public void commitSessionAfterInstallConstraintsAreMet(int sessionId,
+ @NonNull IntentSender statusReceiver, @NonNull InstallConstraints constraints,
+ @DurationMillisLong long timeoutMillis) {
+ try {
+ var session = mInstaller.openSession(sessionId);
+ session.seal();
+ var packageNames = session.fetchPackageNames();
+ var intentSender = new IntentSender((IIntentSender) new IIntentSender.Stub() {
+ @Override
+ public void send(int code, Intent intent, String resolvedType,
+ IBinder allowlistToken, IIntentReceiver finishedReceiver,
+ String requiredPermission, Bundle options) {
+ var result = intent.getParcelableExtra(
+ PackageInstaller.EXTRA_INSTALL_CONSTRAINTS_RESULT,
+ InstallConstraintsResult.class);
+ try {
+ if (result.isAllConstraintsSatisfied()) {
+ session.commit(statusReceiver, false);
+ } else {
+ // timeout
+ final Intent fillIn = new Intent();
+ fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
+ fillIn.putExtra(PackageInstaller.EXTRA_STATUS, STATUS_FAILURE_TIMEOUT);
+ fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
+ "Install constraints not satisfied within timeout");
+ statusReceiver.sendIntent(
+ ActivityThread.currentApplication(), 0, fillIn, null, null);
+ }
+ } catch (Exception ignore) {
+ }
+ }
+ });
+ waitForInstallConstraints(packageNames, constraints, intentSender, timeoutMillis);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Events for observing session lifecycle.
* <p>
* A typical session lifecycle looks like this:
@@ -1910,6 +2017,20 @@
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * @return {@code true} if the installer requested the update ownership enforcement
+ * for the packages in this session.
+ *
+ * @see PackageInstaller.SessionParams#setRequestUpdateOwnership
+ */
+ public boolean isRequestUpdateOwnership() {
+ try {
+ return mSession.isRequestUpdateOwnership();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
/**
@@ -2672,9 +2793,18 @@
* Android S ({@link android.os.Build.VERSION_CODES#S API 31})</li>
* </ul>
* </li>
- * <li>The installer is the {@link InstallSourceInfo#getInstallingPackageName()
- * installer of record} of an existing version of the app (in other words, this install
- * session is an app update) or the installer is updating itself.</li>
+ * <li>The installer is:
+ * <ul>
+ * <li>The {@link InstallSourceInfo#getUpdateOwnerPackageName() update owner}
+ * of an existing version of the app (in other words, this install session is
+ * an app update) if the update ownership enforcement is enabled.</li>
+ * <li>The {@link InstallSourceInfo#getInstallingPackageName() installer of
+ * record} of an existing version of the app (in other words, this install
+ * session is an app update) if the update ownership enforcement isn't
+ * enabled.</li>
+ * <li>Updating itself.</li>
+ * </ul>
+ * </li>>
* <li>The installer declares the
* {@link android.Manifest.permission#UPDATE_PACKAGES_WITHOUT_USER_ACTION
* UPDATE_PACKAGES_WITHOUT_USER_ACTION} permission.</li>
@@ -2713,6 +2843,30 @@
this.keepApplicationEnabledSetting = true;
}
+ /**
+ * Optionally indicate whether the package being installed needs the update ownership
+ * enforcement. Once the update ownership enforcement is enabled, the other installers
+ * will need the user action to update the package even if the installers have been
+ * granted the {@link android.Manifest.permission#INSTALL_PACKAGES INSTALL_PACKAGES}
+ * permission. Default to {@code false}.
+ *
+ * The update ownership enforcement can only be enabled on initial installation. Set
+ * this to {@code true} on package update indicates the installer package wants to be
+ * the update owner if the update ownership enforcement has enabled.
+ *
+ * Note: To enable the update ownership enforcement, the installer must have the
+ * {@link android.Manifest.permission#ENFORCE_UPDATE_OWNERSHIP ENFORCE_UPDATE_OWNERSHIP}
+ * permission.
+ */
+ @RequiresPermission(Manifest.permission.ENFORCE_UPDATE_OWNERSHIP)
+ public void setRequestUpdateOwnership(boolean enable) {
+ if (enable) {
+ this.installFlags |= PackageManager.INSTALL_REQUEST_UPDATE_OWNERSHIP;
+ } else {
+ this.installFlags &= ~PackageManager.INSTALL_REQUEST_UPDATE_OWNERSHIP;
+ }
+ }
+
/** {@hide} */
public void dump(IndentingPrintWriter pw) {
pw.printPair("mode", mode);
@@ -2987,6 +3141,9 @@
/** @hide */
public boolean keepApplicationEnabledSetting;
+ /** @hide */
+ public int pendingUserActionReason;
+
/** {@hide} */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public SessionInfo() {
@@ -3041,6 +3198,7 @@
installerUid = source.readInt();
packageSource = source.readInt();
keepApplicationEnabledSetting = source.readBoolean();
+ pendingUserActionReason = source.readInt();
}
/**
@@ -3585,6 +3743,25 @@
return isPreapprovalRequested;
}
+ /**
+ * @return {@code true} if the installer requested the update ownership enforcement
+ * for the packages in this session.
+ *
+ * @see PackageInstaller.SessionParams#setRequestUpdateOwnership
+ */
+ public boolean isRequestUpdateOwnership() {
+ return (installFlags & PackageManager.INSTALL_REQUEST_UPDATE_OWNERSHIP) != 0;
+ }
+
+ /**
+ * Return the reason for requiring the user action.
+ * @hide
+ */
+ @SystemApi
+ public @UserActionReason int getPendingUserActionReason() {
+ return pendingUserActionReason;
+ }
+
@Override
public int describeContents() {
return 0;
@@ -3635,6 +3812,7 @@
dest.writeInt(installerUid);
dest.writeInt(packageSource);
dest.writeBoolean(keepApplicationEnabledSetting);
+ dest.writeInt(pendingUserActionReason);
}
public static final Parcelable.Creator<SessionInfo>
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 4ad657e..fe06366 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1355,6 +1355,7 @@
INSTALL_ENABLE_ROLLBACK,
INSTALL_ALLOW_DOWNGRADE,
INSTALL_STAGED,
+ INSTALL_REQUEST_UPDATE_OWNERSHIP,
})
@Retention(RetentionPolicy.SOURCE)
public @interface InstallFlags {}
@@ -1545,6 +1546,21 @@
*/
public static final int INSTALL_DISABLE_ALLOWED_APEX_UPDATE_CHECK = 0x00800000;
+ /**
+ * Flag parameter for {@link #installPackage} to bypass the low targer sdk version block
+ * for this install.
+ *
+ * @hide
+ */
+ public static final int INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK = 0x00800000;
+
+ /**
+ * Flag parameter for {@link PackageInstaller.SessionParams} to indicate that the
+ * update ownership enforcement is requested.
+ * @hide
+ */
+ public static final int INSTALL_REQUEST_UPDATE_OWNERSHIP = 1 << 25;
+
/** @hide */
@IntDef(flag = true, value = {
DONT_KILL_APP,
@@ -2233,6 +2249,15 @@
*/
public static final int INSTALL_FAILED_PRE_APPROVAL_NOT_AVAILABLE = -129;
+ /**
+ * Installation return code: this is passed in the {@link PackageInstaller#EXTRA_LEGACY_STATUS}
+ * if the new package declares bad certificate digest for a shared library in the package
+ * manifest.
+ *
+ * @hide
+ */
+ public static final int INSTALL_FAILED_SHARED_LIBRARY_BAD_CERTIFICATE_DIGEST = -130;
+
/** @hide */
@IntDef(flag = true, prefix = { "DELETE_" }, value = {
DELETE_KEEP_DATA,
@@ -9681,6 +9706,8 @@
case INSTALL_FAILED_WRONG_INSTALLED_VERSION: return "INSTALL_FAILED_WRONG_INSTALLED_VERSION";
case INSTALL_FAILED_PROCESS_NOT_DEFINED: return "INSTALL_FAILED_PROCESS_NOT_DEFINED";
case INSTALL_FAILED_SESSION_INVALID: return "INSTALL_FAILED_SESSION_INVALID";
+ case INSTALL_FAILED_SHARED_LIBRARY_BAD_CERTIFICATE_DIGEST:
+ return "INSTALL_FAILED_SHARED_LIBRARY_BAD_CERTIFICATE_DIGEST";
default: return Integer.toString(status);
}
}
@@ -10850,4 +10877,16 @@
throw new UnsupportedOperationException(
"isShowNewAppInstalledNotificationEnabled not implemented in subclass");
}
+
+ /**
+ * Attempt to relinquish the update ownership of the given package. Only the current
+ * update owner of the given package can use this API or a SecurityException will be
+ * thrown.
+ *
+ * @param targetPackage The installed package whose update owner will be changed.
+ */
+ public void relinquishUpdateOwnership(@NonNull String targetPackage) {
+ throw new UnsupportedOperationException(
+ "relinquishUpdateOwnership not implemented in subclass");
+ }
}
diff --git a/core/java/android/content/pm/PermissionMethod.java b/core/java/android/content/pm/PermissionMethod.java
deleted file mode 100644
index 647c696..0000000
--- a/core/java/android/content/pm/PermissionMethod.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2022 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.content.pm;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.CLASS;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Documents that the subject method's job is to look
- * up whether the provided or calling uid/pid has the requested permission.
- *
- * <p>Methods should either return `void`, but potentially throw {@link SecurityException},
- * or return {@link android.content.pm.PackageManager.PermissionResult} `int`.
- *
- * @hide
- */
-@Retention(CLASS)
-@Target({METHOD})
-public @interface PermissionMethod {
- /**
- * Hard-coded list of permissions checked by this method
- */
- @PermissionName String[] value() default {};
- /**
- * If true, the check passes if the caller
- * has any ONE of the supplied permissions
- */
- boolean anyOf() default false;
- /**
- * Signifies that the permission check passes if
- * the calling process OR the current process has
- * the permission
- */
- boolean orSelf() default false;
-}
diff --git a/core/java/android/content/pm/PermissionName.java b/core/java/android/content/pm/PermissionName.java
deleted file mode 100644
index 719e13b..0000000
--- a/core/java/android/content/pm/PermissionName.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2022 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.content.pm;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.CLASS;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that the annotated {@link String} represents a permission name.
- *
- * @hide
- */
-@Retention(CLASS)
-@Target({PARAMETER, METHOD, LOCAL_VARIABLE, FIELD})
-public @interface PermissionName {}
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
index 4ade8a8..4e2acc0 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -133,20 +133,15 @@
* Data(photo, file, account) upload/download, backup/restore, import/export, fetch,
* transfer over network between device and cloud.
*
- * <p>Apps targeting API level {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and
- * later should NOT use this type:
- * calling {@link android.app.Service#startForeground(int, android.app.Notification, int)} with
- * this type on devices running {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} is still
- * allowed, but calling it with this type on devices running future platform releases may get a
- * {@link android.app.InvalidForegroundServiceTypeException}.</p>
- *
- * @deprecated Use {@link android.app.job.JobInfo.Builder} data transfer APIs instead.
+ * <p class="note">
+ * Use the {@link android.app.job.JobInfo.Builder#setDataTransfer} API for data transfers
+ * that can be deferred until conditions are ideal for the app or device.
+ * </p>
*/
@RequiresPermission(
value = Manifest.permission.FOREGROUND_SERVICE_DATA_SYNC,
conditional = true
)
- @Deprecated
public static final int FOREGROUND_SERVICE_TYPE_DATA_SYNC = 1 << 0;
/**
diff --git a/core/java/android/content/pm/UserProperties.java b/core/java/android/content/pm/UserProperties.java
index 7f0f44b..51662af 100644
--- a/core/java/android/content/pm/UserProperties.java
+++ b/core/java/android/content/pm/UserProperties.java
@@ -50,6 +50,8 @@
"updateCrossProfileIntentFiltersOnOTA";
private static final String ATTR_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL =
"crossProfileIntentFilterAccessControl";
+ private static final String ATTR_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY =
+ "crossProfileIntentResolutionStrategy";
/** Index values of each property (to indicate whether they are present in this object). */
@IntDef(prefix = "INDEX_", value = {
@@ -59,7 +61,8 @@
INDEX_INHERIT_DEVICE_POLICY,
INDEX_USE_PARENTS_CONTACTS,
INDEX_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA,
- INDEX_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL
+ INDEX_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL,
+ INDEX_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY
})
@Retention(RetentionPolicy.SOURCE)
private @interface PropertyIndex {
@@ -71,6 +74,7 @@
private static final int INDEX_USE_PARENTS_CONTACTS = 4;
private static final int INDEX_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA = 5;
private static final int INDEX_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL = 6;
+ private static final int INDEX_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY = 7;
/** A bit set, mapping each PropertyIndex to whether it is present (1) or absent (0). */
private long mPropertiesPresent = 0;
@@ -219,6 +223,39 @@
public static final int CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM_ADD_ONLY = 20;
/**
+ * Possible values for cross profile intent resolution strategy.
+ *
+ * @hide
+ */
+ @IntDef(prefix = {"CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_"}, value = {
+ CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_DEFAULT,
+ CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_NO_FILTERING
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CrossProfileIntentResolutionStrategy {
+ }
+
+ /**
+ * Signifies to use {@link DefaultCrossProfileResolver} strategy, which
+ * check if it needs to skip the initiating profile, resolves intent in target profile.
+ * {@link DefaultCrossProfileResolver} also filters the {@link ResolveInfo} after intent
+ * resolution based on their domain approval level
+ *
+ * @hide
+ */
+ public static final int CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_DEFAULT = 0;
+
+ /**
+ * Signifies that there is no need to filter {@link ResolveInfo} after cross profile intent
+ * resolution across. This strategy is for profile acting transparent to end-user and resolves
+ * all allowed intent without giving any profile priority.
+ *
+ * @hide
+ */
+ public static final int CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_NO_FILTERING = 1;
+
+
+ /**
* Creates a UserProperties (intended for the SystemServer) that stores a reference to the given
* default properties, which it uses for any property not subsequently set.
* @hide
@@ -255,6 +292,7 @@
setUpdateCrossProfileIntentFiltersOnOTA(orig.getUpdateCrossProfileIntentFiltersOnOTA());
setCrossProfileIntentFilterAccessControl(
orig.getCrossProfileIntentFilterAccessControl());
+ setCrossProfileIntentResolutionStrategy(orig.getCrossProfileIntentResolutionStrategy());
}
if (hasManagePermission) {
// Add items that require MANAGE_USERS or stronger.
@@ -466,6 +504,36 @@
}
private @CrossProfileIntentFilterAccessControlLevel int mCrossProfileIntentFilterAccessControl;
+ /**
+ * Returns the user's {@link CrossProfileIntentResolutionStrategy}. If not explicitly
+ * configured, default value is {@link #CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_DEFAULT}.
+ * @return user's {@link CrossProfileIntentResolutionStrategy}.
+ *
+ * @hide
+ */
+ public @CrossProfileIntentResolutionStrategy int getCrossProfileIntentResolutionStrategy() {
+ if (isPresent(INDEX_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY)) {
+ return mCrossProfileIntentResolutionStrategy;
+ }
+ if (mDefaultProperties != null) {
+ return mDefaultProperties.mCrossProfileIntentResolutionStrategy;
+ }
+ throw new SecurityException("You don't have permission to query "
+ + "crossProfileIntentResolutionStrategy");
+ }
+ /**
+ * Sets {@link CrossProfileIntentResolutionStrategy} for the user.
+ * @param val resolution strategy for user
+ * @hide
+ */
+ public void setCrossProfileIntentResolutionStrategy(
+ @CrossProfileIntentResolutionStrategy int val) {
+ this.mCrossProfileIntentResolutionStrategy = val;
+ setPresent(INDEX_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY);
+ }
+ private @CrossProfileIntentResolutionStrategy int mCrossProfileIntentResolutionStrategy;
+
+
@Override
public String toString() {
// Please print in increasing order of PropertyIndex.
@@ -480,6 +548,8 @@
+ getUpdateCrossProfileIntentFiltersOnOTA()
+ ", mCrossProfileIntentFilterAccessControl="
+ getCrossProfileIntentFilterAccessControl()
+ + ", mCrossProfileIntentResolutionStrategy="
+ + getCrossProfileIntentResolutionStrategy()
+ "}";
}
@@ -500,6 +570,8 @@
+ getUpdateCrossProfileIntentFiltersOnOTA());
pw.println(prefix + " mCrossProfileIntentFilterAccessControl="
+ getCrossProfileIntentFilterAccessControl());
+ pw.println(prefix + " mCrossProfileIntentResolutionStrategy="
+ + getCrossProfileIntentResolutionStrategy());
}
/**
@@ -554,6 +626,9 @@
case ATTR_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL:
setCrossProfileIntentFilterAccessControl(parser.getAttributeInt(i));
break;
+ case ATTR_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY:
+ setCrossProfileIntentResolutionStrategy(parser.getAttributeInt(i));
+ break;
default:
Slog.w(LOG_TAG, "Skipping unknown property " + attributeName);
}
@@ -597,6 +672,10 @@
serializer.attributeInt(null, ATTR_CROSS_PROFILE_INTENT_FILTER_ACCESS_CONTROL,
mCrossProfileIntentFilterAccessControl);
}
+ if (isPresent(INDEX_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY)) {
+ serializer.attributeInt(null, ATTR_CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY,
+ mCrossProfileIntentResolutionStrategy);
+ }
}
// For use only with an object that has already had any permission-lacking fields stripped out.
@@ -610,6 +689,7 @@
dest.writeBoolean(mUseParentsContacts);
dest.writeBoolean(mUpdateCrossProfileIntentFiltersOnOTA);
dest.writeInt(mCrossProfileIntentFilterAccessControl);
+ dest.writeInt(mCrossProfileIntentResolutionStrategy);
}
/**
@@ -627,6 +707,7 @@
mUseParentsContacts = source.readBoolean();
mUpdateCrossProfileIntentFiltersOnOTA = source.readBoolean();
mCrossProfileIntentFilterAccessControl = source.readInt();
+ mCrossProfileIntentResolutionStrategy = source.readInt();
}
@Override
@@ -660,6 +741,8 @@
private @CrossProfileIntentFilterAccessControlLevel int
mCrossProfileIntentFilterAccessControl =
CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_ALL;
+ private @CrossProfileIntentResolutionStrategy int mCrossProfileIntentResolutionStrategy =
+ CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_DEFAULT;
public Builder setShowInLauncher(@ShowInLauncher int showInLauncher) {
mShowInLauncher = showInLauncher;
@@ -704,6 +787,13 @@
return this;
}
+ /** Sets the value for {@link #mCrossProfileIntentResolutionStrategy} */
+ public Builder setCrossProfileIntentResolutionStrategy(@CrossProfileIntentResolutionStrategy
+ int crossProfileIntentResolutionStrategy) {
+ mCrossProfileIntentResolutionStrategy = crossProfileIntentResolutionStrategy;
+ return this;
+ }
+
/** Builds a UserProperties object with *all* values populated. */
public UserProperties build() {
return new UserProperties(
@@ -713,7 +803,8 @@
mInheritDevicePolicy,
mUseParentsContacts,
mUpdateCrossProfileIntentFiltersOnOTA,
- mCrossProfileIntentFilterAccessControl);
+ mCrossProfileIntentFilterAccessControl,
+ mCrossProfileIntentResolutionStrategy);
}
} // end Builder
@@ -724,7 +815,8 @@
@ShowInSettings int showInSettings,
@InheritDevicePolicy int inheritDevicePolicy,
boolean useParentsContacts, boolean updateCrossProfileIntentFiltersOnOTA,
- @CrossProfileIntentFilterAccessControlLevel int crossProfileIntentFilterAccessControl) {
+ @CrossProfileIntentFilterAccessControlLevel int crossProfileIntentFilterAccessControl,
+ @CrossProfileIntentResolutionStrategy int crossProfileIntentResolutionStrategy) {
mDefaultProperties = null;
setShowInLauncher(showInLauncher);
@@ -734,5 +826,6 @@
setUseParentsContacts(useParentsContacts);
setUpdateCrossProfileIntentFiltersOnOTA(updateCrossProfileIntentFiltersOnOTA);
setCrossProfileIntentFilterAccessControl(crossProfileIntentFilterAccessControl);
+ setCrossProfileIntentResolutionStrategy(crossProfileIntentResolutionStrategy);
}
}
diff --git a/core/java/android/credentials/ClearCredentialStateException.java b/core/java/android/credentials/ClearCredentialStateException.java
index c518461..78fe203 100644
--- a/core/java/android/credentials/ClearCredentialStateException.java
+++ b/core/java/android/credentials/ClearCredentialStateException.java
@@ -31,6 +31,12 @@
* CancellationSignal, Executor, OutcomeReceiver)} operation.
*/
public class ClearCredentialStateException extends Exception {
+ /**
+ * The error type value for when the given operation failed due to an unknown reason.
+ */
+ @NonNull
+ public static final String TYPE_UNKNOWN =
+ "android.credentials.ClearCredentialStateException.TYPE_UNKNOWN";
@NonNull
private final String mType;
diff --git a/core/java/android/credentials/CreateCredentialException.java b/core/java/android/credentials/CreateCredentialException.java
index cb32690..fefa60a 100644
--- a/core/java/android/credentials/CreateCredentialException.java
+++ b/core/java/android/credentials/CreateCredentialException.java
@@ -33,6 +33,13 @@
*/
public class CreateCredentialException extends Exception {
/**
+ * The error type value for when the given operation failed due to an unknown reason.
+ */
+ @NonNull
+ public static final String TYPE_UNKNOWN =
+ "android.credentials.CreateCredentialException.TYPE_UNKNOWN";
+
+ /**
* The error type value for when no credential is available for the given {@link
* CredentialManager#executeCreateCredential(CreateCredentialRequest, Activity,
* CancellationSignal, Executor, OutcomeReceiver)} request.
@@ -40,6 +47,22 @@
@NonNull
public static final String TYPE_NO_CREDENTIAL =
"android.credentials.CreateCredentialException.TYPE_NO_CREDENTIAL";
+ /**
+ * The error type value for when the user intentionally cancelled the request.
+ *
+ * <p>This is a strong indicator that your app should refrain from making the same api call for
+ * a certain amount of time to provide a better user experience.
+ */
+ @NonNull
+ public static final String TYPE_USER_CANCELED =
+ "android.credentials.CreateCredentialException.TYPE_USER_CANCELED";
+ /**
+ * The error type value for when the given operation failed due to internal interruption.
+ * Retrying the same operation should fix the error.
+ */
+ @NonNull
+ public static final String TYPE_INTERRUPTED =
+ "android.credentials.CreateCredentialException.TYPE_INTERRUPTED";
@NonNull
private final String mType;
diff --git a/core/java/android/credentials/GetCredentialException.java b/core/java/android/credentials/GetCredentialException.java
index 5d6e4df..478afff 100644
--- a/core/java/android/credentials/GetCredentialException.java
+++ b/core/java/android/credentials/GetCredentialException.java
@@ -33,6 +33,13 @@
*/
public class GetCredentialException extends Exception {
/**
+ * The error type value for when the given operation failed due to an unknown reason.
+ */
+ @NonNull
+ public static final String TYPE_UNKNOWN =
+ "android.credentials.GetCredentialException.TYPE_UNKNOWN";
+
+ /**
* The error type value for when no credential is found available for the given {@link
* CredentialManager#executeGetCredential(GetCredentialRequest, Activity, CancellationSignal,
* Executor, OutcomeReceiver)} request.
@@ -40,6 +47,22 @@
@NonNull
public static final String TYPE_NO_CREDENTIAL =
"android.credentials.GetCredentialException.TYPE_NO_CREDENTIAL";
+ /**
+ * The error type value for when the user intentionally cancelled the request.
+ *
+ * <p>This is a strong indicator that your app should refrain from making the same api call for
+ * a certain amount of time to provide a better user experience.
+ */
+ @NonNull
+ public static final String TYPE_USER_CANCELED =
+ "android.credentials.GetCredentialException.TYPE_USER_CANCELED";
+ /**
+ * The error type value for when the given operation failed due to internal interruption.
+ * Retrying the same operation should fix the error.
+ */
+ @NonNull
+ public static final String TYPE_INTERRUPTED =
+ "android.credentials.GetCredentialException.TYPE_INTERRUPTED";
@NonNull
private final String mType;
diff --git a/core/java/android/credentials/ui/Entry.java b/core/java/android/credentials/ui/Entry.java
index 9f2edae..37a5724 100644
--- a/core/java/android/credentials/ui/Entry.java
+++ b/core/java/android/credentials/ui/Entry.java
@@ -88,6 +88,7 @@
/** Constructor to be used for an entry that requires a pending intent to be invoked
* when clicked.
*/
+ // TODO: Remove this constructor as it is no longer used
public Entry(@NonNull String key, @NonNull String subkey, @NonNull Slice slice,
@NonNull PendingIntent pendingIntent, @NonNull Intent intent) {
this(key, subkey, slice);
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index c716f319..81d6ba9 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -24,7 +24,6 @@
import android.annotation.SdkConstant.SdkConstantType;
import android.app.ActivityThread;
import android.app.AppOpsManager;
-import android.app.compat.CompatChanges;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.graphics.ImageFormat;
@@ -42,7 +41,6 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.SystemProperties;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RSIllegalArgumentException;
@@ -279,14 +277,6 @@
*/
public native static int getNumberOfCameras();
- private static final boolean sLandscapeToPortrait =
- SystemProperties.getBoolean(CameraManager.LANDSCAPE_TO_PORTRAIT_PROP, false);
-
- private static boolean shouldOverrideToPortrait() {
- return CompatChanges.isChangeEnabled(CameraManager.OVERRIDE_FRONT_CAMERA_APP_COMPAT)
- && sLandscapeToPortrait;
- }
-
/**
* Returns the information about a particular camera.
* If {@link #getNumberOfCameras()} returns N, the valid id is 0 to N-1.
@@ -296,7 +286,8 @@
* low-level failure).
*/
public static void getCameraInfo(int cameraId, CameraInfo cameraInfo) {
- boolean overrideToPortrait = shouldOverrideToPortrait();
+ boolean overrideToPortrait = CameraManager.shouldOverrideToPortrait(
+ ActivityThread.currentApplication().getApplicationContext());
_getCameraInfo(cameraId, overrideToPortrait, cameraInfo);
IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
@@ -493,7 +484,8 @@
mEventHandler = null;
}
- boolean overrideToPortrait = shouldOverrideToPortrait();
+ boolean overrideToPortrait = CameraManager.shouldOverrideToPortrait(
+ ActivityThread.currentApplication().getApplicationContext());
return native_setup(new WeakReference<Camera>(this), cameraId,
ActivityThread.currentOpPackageName(), overrideToPortrait);
}
diff --git a/core/java/android/hardware/OverlayProperties.java b/core/java/android/hardware/OverlayProperties.java
index 1ce1361..8bfc2f7 100644
--- a/core/java/android/hardware/OverlayProperties.java
+++ b/core/java/android/hardware/OverlayProperties.java
@@ -59,6 +59,16 @@
}
/**
+ * @return True if the device can support mixed colorspaces, false otherwise.
+ */
+ public boolean supportMixedColorSpaces() {
+ if (mNativeObject == 0) {
+ return false;
+ }
+ return nSupportMixedColorSpaces(mNativeObject);
+ }
+
+ /**
* Release the local reference.
*/
public void release() {
@@ -106,6 +116,7 @@
private static native long nGetDestructor();
private static native boolean nSupportFp16ForHdr(long nativeObject);
+ private static native boolean nSupportMixedColorSpaces(long nativeObject);
private static native void nWriteOverlayPropertiesToParcel(long nativeObject, Parcel dest);
private static native long nReadOverlayPropertiesFromParcel(Parcel in);
}
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index dec424c..6d8c4a9 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -16,6 +16,7 @@
package android.hardware;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.compat.annotation.UnsupportedAppUsage;
@@ -496,7 +497,7 @@
* @see #getSensorList(int)
* @see Sensor
*/
- public Sensor getDefaultSensor(int type) {
+ public @Nullable Sensor getDefaultSensor(int type) {
// TODO: need to be smarter, for now, just return the 1st sensor
List<Sensor> l = getSensorList(type);
boolean wakeUpSensor = false;
@@ -544,7 +545,7 @@
* and the application has the necessary permissions, or null otherwise.
* @see Sensor#isWakeUpSensor()
*/
- public Sensor getDefaultSensor(int type, boolean wakeUp) {
+ public @Nullable Sensor getDefaultSensor(int type, boolean wakeUp) {
List<Sensor> l = getSensorList(type);
for (Sensor sensor : l) {
if (sensor.isWakeUpSensor() == wakeUp) {
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 5b6e288..b5a58b2 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -115,7 +115,14 @@
@Overridable
@EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.BASE)
@TestApi
- public static final long OVERRIDE_FRONT_CAMERA_APP_COMPAT = 250678880L;
+ public static final long OVERRIDE_CAMERA_LANDSCAPE_TO_PORTRAIT = 250678880L;
+
+ /**
+ * Package-level opt in/out for the above.
+ * @hide
+ */
+ public static final String PROPERTY_COMPAT_OVERRIDE_LANDSCAPE_TO_PORTRAIT =
+ "android.camera.PROPERTY_COMPAT_OVERRIDE_LANDSCAPE_TO_PORTRAIT";
/**
* System property for allowing the above
@@ -607,7 +614,7 @@
try {
Size displaySize = getDisplaySize();
- boolean overrideToPortrait = shouldOverrideToPortrait();
+ boolean overrideToPortrait = shouldOverrideToPortrait(mContext);
CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId,
mContext.getApplicationInfo().targetSdkVersion, overrideToPortrait);
try {
@@ -727,7 +734,7 @@
"Camera service is currently unavailable");
}
- boolean overrideToPortrait = shouldOverrideToPortrait();
+ boolean overrideToPortrait = shouldOverrideToPortrait(mContext);
cameraUser = cameraService.connectDevice(callbacks, cameraId,
mContext.getOpPackageName(), mContext.getAttributionTag(), uid,
oomScoreOffset, mContext.getApplicationInfo().targetSdkVersion,
@@ -1159,9 +1166,26 @@
return CameraManagerGlobal.get().getTorchStrengthLevel(cameraId);
}
- private static boolean shouldOverrideToPortrait() {
- return CompatChanges.isChangeEnabled(OVERRIDE_FRONT_CAMERA_APP_COMPAT)
- && CameraManagerGlobal.sLandscapeToPortrait;
+ /**
+ * @hide
+ */
+ public static boolean shouldOverrideToPortrait(@Nullable Context context) {
+ if (!CameraManagerGlobal.sLandscapeToPortrait) {
+ return false;
+ }
+
+ if (context != null) {
+ PackageManager packageManager = context.getPackageManager();
+
+ try {
+ return packageManager.getProperty(context.getOpPackageName(),
+ PROPERTY_COMPAT_OVERRIDE_LANDSCAPE_TO_PORTRAIT).getBoolean();
+ } catch (PackageManager.NameNotFoundException e) {
+ // No such property
+ }
+ }
+
+ return CompatChanges.isChangeEnabled(OVERRIDE_CAMERA_LANDSCAPE_TO_PORTRAIT);
}
/**
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 8d742b5..9640b0e 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -1037,6 +1037,19 @@
return fixedFaceRectangles;
}
+ private boolean setLensShadingMap(LensShadingMap lensShadingMap) {
+ if (lensShadingMap == null) {
+ return false;
+ }
+ float[] lsmArray = new float[lensShadingMap.getGainFactorCount()];
+ lensShadingMap.copyGainFactors(lsmArray, 0);
+ setBase(CaptureResult.STATISTICS_LENS_SHADING_MAP, lsmArray);
+
+ Size s = new Size(lensShadingMap.getRowCount(), lensShadingMap.getColumnCount());
+ setBase(CameraCharacteristics.LENS_INFO_SHADING_MAP_SIZE, s);
+ return true;
+ }
+
private LensShadingMap getLensShadingMap() {
float[] lsmArray = getBase(CaptureResult.STATISTICS_LENS_SHADING_MAP);
Size s = get(CameraCharacteristics.LENS_INFO_SHADING_MAP_SIZE);
@@ -1916,6 +1929,13 @@
metadata.setAERegions(value);
}
});
+ sSetCommandMap.put(CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP.getNativeKey(),
+ new SetCommand() {
+ @Override
+ public <T> void setValue(CameraMetadataNative metadata, T value) {
+ metadata.setLensShadingMap((LensShadingMap) value);
+ }
+ });
}
private boolean setAvailableFormats(int[] value) {
diff --git a/core/java/android/hardware/devicestate/DeviceStateManager.java b/core/java/android/hardware/devicestate/DeviceStateManager.java
index dba1a5e..6a667fe 100644
--- a/core/java/android/hardware/devicestate/DeviceStateManager.java
+++ b/core/java/android/hardware/devicestate/DeviceStateManager.java
@@ -251,6 +251,10 @@
@Nullable
private Boolean lastResult;
+ public FoldStateListener(Context context) {
+ this(context, folded -> {});
+ }
+
public FoldStateListener(Context context, Consumer<Boolean> listener) {
mFoldedDeviceStates = context.getResources().getIntArray(
com.android.internal.R.array.config_foldedDeviceStates);
@@ -266,5 +270,10 @@
mDelegate.accept(folded);
}
}
+
+ @Nullable
+ public Boolean getFolded() {
+ return lastResult;
+ }
}
}
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index 2bf187a..5fcc31e 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -43,7 +43,7 @@
byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer);
// Retrieve static sensor properties for all face sensors
- @EnforcePermission("MANAGE_BIOMETRIC")
+ @EnforcePermission("USE_BIOMETRIC_INTERNAL")
List<FaceSensorPropertiesInternal> getSensorPropertiesInternal(String opPackageName);
// Retrieve static sensor properties for the specified sensor
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index a748b60..04a204a 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -464,6 +464,12 @@
* @param remaining The number of remaining steps
*/
public void onEnrollmentProgress(int remaining) { }
+
+ /**
+ * Called when a fingerprint image has been acquired.
+ * @param isAcquiredGood whether the fingerprint image was good.
+ */
+ public void onAcquired(boolean isAcquiredGood){ }
}
/**
@@ -1392,6 +1398,9 @@
if (mAuthenticationCallback != null) {
mAuthenticationCallback.onAuthenticationAcquired(acquireInfo);
}
+ if (mEnrollmentCallback != null) {
+ mEnrollmentCallback.onAcquired(acquireInfo == FINGERPRINT_ACQUIRED_GOOD);
+ }
final String msg = getAcquiredString(mContext, acquireInfo, vendorCode);
if (msg == null) {
return;
diff --git a/core/java/android/hardware/usb/DisplayPortAltModeInfo.aidl b/core/java/android/hardware/usb/DisplayPortAltModeInfo.aidl
new file mode 100644
index 0000000..14986d0
--- /dev/null
+++ b/core/java/android/hardware/usb/DisplayPortAltModeInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2022 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.hardware.usb;
+
+parcelable DisplayPortAltModeInfo;
\ No newline at end of file
diff --git a/core/java/android/hardware/usb/DisplayPortAltModeInfo.java b/core/java/android/hardware/usb/DisplayPortAltModeInfo.java
new file mode 100644
index 0000000..febc643
--- /dev/null
+++ b/core/java/android/hardware/usb/DisplayPortAltModeInfo.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2022 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.hardware.usb;
+
+import android.Manifest;
+import android.annotation.CheckResult;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Holds information related to DisplayPort Alt Mode statuses
+ *
+ * @hide
+ */
+@SystemApi
+public final class DisplayPortAltModeInfo implements Parcelable {
+ private final @DisplayPortAltModeStatus int mPartnerSinkStatus;
+ private final @DisplayPortAltModeStatus int mCableStatus;
+ private final int mNumLanes;
+
+ /**
+ * Port Partners:
+ * The port partner status is currently unknown for one of the following reasons:
+ * <ul>
+ * <li> No port partner is connected to the device
+ * <li> The USB Power Delivery Discover Identity command has not been issued to the port
+ * partner via SOP messaging.
+ * </ul>
+ * <p>
+ * Cables:
+ * The cable’s capabilities are not yet known to the device, or no cable is plugged in.
+ */
+ public static final int DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN = 0;
+
+ /**
+ * Port Partners:
+ * The current port partner does not list DisplayPort as one of its Alt Modes, or does not list
+ * the capability to act as a DisplayPort Source or Sink device, or a compatible configuration
+ * could not be established.
+ * <p>
+ * Cables:
+ * The cable/adapter’s capabilities do not list DisplayPort as one of its Alt Modes, or a
+ * compatible configuration could not be established.
+ */
+ public static final int DISPLAYPORT_ALT_MODE_STATUS_NOT_CAPABLE = 1;
+
+ /**
+ * Port Partners:
+ * The current port partner lists compatible DisplayPort capabilities with the device, however
+ * may not yet have entered DisplayPort Alt Mode or has configured its port for data
+ * transmission.
+ * <p>
+ * Cables:
+ * The Type-C cable/adapter’s capabilities have been discovered and list DisplayPort Alt Mode
+ * as one of its capabilities, however may not yet have entered DisplayPort Alt Mode or has been
+ * configured for data transmission.
+ */
+ public static final int DISPLAYPORT_ALT_MODE_STATUS_CAPABLE = 2;
+
+ /**
+ * Port Partners:
+ * The port partner and device are both configured for DisplayPort Alt Mode.
+ * <p>
+ * Cables:
+ * The Type-C cable/adapter is configured for DisplayPort Alt Mode.
+ */
+ public static final int DISPLAYPORT_ALT_MODE_STATUS_ENABLED = 3;
+
+ /** @hide */
+ @IntDef(prefix = { "DISPLAYPORT_ALT_MODE_STATUS_" }, value = {
+ DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN,
+ DISPLAYPORT_ALT_MODE_STATUS_NOT_CAPABLE,
+ DISPLAYPORT_ALT_MODE_STATUS_CAPABLE,
+ DISPLAYPORT_ALT_MODE_STATUS_ENABLED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DisplayPortAltModeStatus {}
+
+ /** @hide */
+ public DisplayPortAltModeInfo() {
+ mPartnerSinkStatus = DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN;
+ mCableStatus = DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN;
+ mNumLanes = 0;
+ }
+
+ /** @hide */
+ public DisplayPortAltModeInfo(int partnerSinkStatus, int cableStatus,
+ int numLanes) {
+ mPartnerSinkStatus = partnerSinkStatus;
+ mCableStatus = cableStatus;
+ mNumLanes = numLanes;
+ }
+
+ /**
+ * Returns the DisplayPort Alt Mode Status for a port partner acting as a sink.
+ *
+ * @return {@link #DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN}
+ * or {@link #DISPLAYPORT_ALT_MODE_STATUS_NOT_CAPABLE}
+ * or {@link #DISPLAYPORT_ALT_MODE_STATUS_CAPABLE}
+ * or {@link #DISPLAYPORT_ALT_MODE_STATUS_ENABLED}
+ */
+ public @DisplayPortAltModeStatus int getPartnerSinkStatus() {
+ return mPartnerSinkStatus;
+ }
+
+ /**
+ * Returns the DisplayPort Alt Mode Status for the attached cable
+ *
+ * @return {@link #DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN}
+ * or {@link #DISPLAYPORT_ALT_MODE_STATUS_NOT_CAPABLE}
+ * or {@link #DISPLAYPORT_ALT_MODE_STATUS_CAPABLE}
+ * or {@link #DISPLAYPORT_ALT_MODE_STATUS_ENABLED}
+ */
+ public @DisplayPortAltModeStatus int getCableStatus() {
+ return mCableStatus;
+ }
+
+ /**
+ * Returns the number of lanes used to transmit display data.
+ *
+ */
+ public int getNumberOfLanes() {
+ return mNumLanes;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mPartnerSinkStatus);
+ dest.writeInt(mCableStatus);
+ dest.writeInt(mNumLanes);
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "DisplayPortAltModeInfo{partnerSink="
+ + mPartnerSinkStatus
+ + " cable="
+ + mCableStatus
+ + " numLanes="
+ + mNumLanes
+ + "}";
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof DisplayPortAltModeInfo)) {
+ return false;
+ }
+ DisplayPortAltModeInfo other = (DisplayPortAltModeInfo) o;
+ return this.mPartnerSinkStatus == other.mPartnerSinkStatus
+ && this.mCableStatus == other.mCableStatus
+ && this.mNumLanes == other.mNumLanes;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mPartnerSinkStatus, mCableStatus, mNumLanes);
+ }
+
+ public static final @NonNull Parcelable.Creator<DisplayPortAltModeInfo> CREATOR =
+ new Parcelable.Creator<DisplayPortAltModeInfo>() {
+ @Override
+ public DisplayPortAltModeInfo createFromParcel(Parcel in) {
+ int partnerSinkStatus = in.readInt();
+ int cableStatus = in.readInt();
+ int numLanes = in.readInt();
+ return new DisplayPortAltModeInfo(partnerSinkStatus, cableStatus, numLanes);
+ }
+
+ @Override
+ public DisplayPortAltModeInfo[] newArray(int size) {
+ return new DisplayPortAltModeInfo[size];
+ }
+ };
+}
diff --git a/core/java/android/hardware/usb/IDisplayPortAltModeInfoListener.aidl b/core/java/android/hardware/usb/IDisplayPortAltModeInfoListener.aidl
new file mode 100644
index 0000000..e93e0fb
--- /dev/null
+++ b/core/java/android/hardware/usb/IDisplayPortAltModeInfoListener.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 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.hardware.usb;
+
+import android.hardware.usb.DisplayPortAltModeInfo;
+
+/**
+ * @hide
+ */
+oneway interface IDisplayPortAltModeInfoListener {
+ void onDisplayPortAltModeInfoChanged(in String portId,
+ in DisplayPortAltModeInfo DisplayPortAltModeInfo);
+}
\ No newline at end of file
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index 248b5d0..21b00e3 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -18,6 +18,7 @@
import android.app.PendingIntent;
import android.content.ComponentName;
+import android.hardware.usb.IDisplayPortAltModeInfoListener;
import android.hardware.usb.IUsbOperationInternal;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbDevice;
@@ -184,4 +185,15 @@
/* Sets USB device connection handler. */
void setUsbDeviceConnectionHandler(in ComponentName usbDeviceConnectionHandler);
+
+ /* Registers callback for Usb events */
+ @JavaPassthrough(annotation=
+ "@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_USB)")
+ boolean registerForDisplayPortEvents(IDisplayPortAltModeInfoListener listener);
+
+ /* Unregisters Usb event callback */
+ @JavaPassthrough(annotation=
+ "@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_USB)")
+ void unregisterForDisplayPortEvents(IDisplayPortAltModeInfoListener listener);
+
}
diff --git a/core/java/android/hardware/usb/ParcelableUsbPort.java b/core/java/android/hardware/usb/ParcelableUsbPort.java
index 7fc282c..eb6501a 100644
--- a/core/java/android/hardware/usb/ParcelableUsbPort.java
+++ b/core/java/android/hardware/usb/ParcelableUsbPort.java
@@ -35,12 +35,14 @@
private final boolean mSupportsEnableContaminantPresenceProtection;
private final boolean mSupportsEnableContaminantPresenceDetection;
private final boolean mSupportsComplianceWarnings;
+ private final int mSupportedAltModesMask;
private ParcelableUsbPort(@NonNull String id, int supportedModes,
int supportedContaminantProtectionModes,
boolean supportsEnableContaminantPresenceProtection,
boolean supportsEnableContaminantPresenceDetection,
- boolean supportsComplianceWarnings) {
+ boolean supportsComplianceWarnings,
+ int supportedAltModesMask) {
mId = id;
mSupportedModes = supportedModes;
mSupportedContaminantProtectionModes = supportedContaminantProtectionModes;
@@ -50,6 +52,7 @@
supportsEnableContaminantPresenceDetection;
mSupportsComplianceWarnings =
supportsComplianceWarnings;
+ mSupportedAltModesMask = supportedAltModesMask;
}
/**
@@ -64,7 +67,8 @@
port.getSupportedContaminantProtectionModes(),
port.supportsEnableContaminantPresenceProtection(),
port.supportsEnableContaminantPresenceDetection(),
- port.supportsComplianceWarnings());
+ port.supportsComplianceWarnings(),
+ port.getSupportedAltModesMask());
}
/**
@@ -78,7 +82,8 @@
return new UsbPort(usbManager, mId, mSupportedModes, mSupportedContaminantProtectionModes,
mSupportsEnableContaminantPresenceProtection,
mSupportsEnableContaminantPresenceDetection,
- mSupportsComplianceWarnings);
+ mSupportsComplianceWarnings,
+ mSupportedAltModesMask);
}
@Override
@@ -94,6 +99,7 @@
dest.writeBoolean(mSupportsEnableContaminantPresenceProtection);
dest.writeBoolean(mSupportsEnableContaminantPresenceDetection);
dest.writeBoolean(mSupportsComplianceWarnings);
+ dest.writeInt(mSupportedAltModesMask);
}
public static final @android.annotation.NonNull Creator<ParcelableUsbPort> CREATOR =
@@ -106,12 +112,14 @@
boolean supportsEnableContaminantPresenceProtection = in.readBoolean();
boolean supportsEnableContaminantPresenceDetection = in.readBoolean();
boolean supportsComplianceWarnings = in.readBoolean();
+ int supportedAltModesMask = in.readInt();
return new ParcelableUsbPort(id, supportedModes,
supportedContaminantProtectionModes,
supportsEnableContaminantPresenceProtection,
supportsEnableContaminantPresenceDetection,
- supportsComplianceWarnings);
+ supportsComplianceWarnings,
+ supportedAltModesMask);
}
@Override
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 7a8117c..909d147 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -20,6 +20,7 @@
import static android.hardware.usb.UsbPortStatus.DATA_STATUS_DISABLED_FORCE;
import android.Manifest;
+import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.LongDef;
import android.annotation.NonNull;
@@ -44,16 +45,24 @@
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
+import android.util.ArrayMap;
import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.StringJoiner;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.Executor;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
/**
* This class allows you to access the state of USB and communicate with USB devices.
@@ -724,8 +733,60 @@
})
public @interface UsbHalVersion {}
+ /**
+ * Listener to register for when the {@link DisplayPortAltModeInfo} changes on a
+ * {@link UsbPort}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public interface DisplayPortAltModeInfoListener {
+ /**
+ * Callback to be executed when the {@link DisplayPortAltModeInfo} changes on a
+ * {@link UsbPort}.
+ *
+ * @param portId String describing the {@link UsbPort} that was changed.
+ * @param info New {@link DisplayPortAltModeInfo} for the corresponding portId.
+ */
+ public void onDisplayPortAltModeInfoChanged(@NonNull String portId,
+ @NonNull DisplayPortAltModeInfo info);
+ }
+
+ /**
+ * Holds callback and executor data to be passed across UsbService.
+ */
+ private class DisplayPortAltModeInfoDispatchingListener extends
+ IDisplayPortAltModeInfoListener.Stub {
+
+ public void onDisplayPortAltModeInfoChanged(String portId,
+ DisplayPortAltModeInfo displayPortAltModeInfo) {
+ synchronized (mDisplayPortListenersLock) {
+ for (Map.Entry<DisplayPortAltModeInfoListener, Executor> entry :
+ mDisplayPortListeners.entrySet()) {
+ Executor executor = entry.getValue();
+ DisplayPortAltModeInfoListener callback = entry.getKey();
+ final long token = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> callback.onDisplayPortAltModeInfoChanged(portId,
+ displayPortAltModeInfo));
+ } catch (Exception e) {
+ Slog.e(TAG, "Exception during onDisplayPortAltModeInfoChanged from "
+ + "executor: " + executor, e);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ }
+ }
+ }
+
private final Context mContext;
private final IUsbManager mService;
+ private final Object mDisplayPortListenersLock = new Object();
+ @GuardedBy("mDisplayPortListenersLock")
+ private ArrayMap<DisplayPortAltModeInfoListener, Executor> mDisplayPortListeners;
+ @GuardedBy("mDisplayPortListenersLock")
+ private DisplayPortAltModeInfoDispatchingListener mDisplayPortServiceListener;
/**
* @hide
@@ -1524,6 +1585,109 @@
}
}
+ @GuardedBy("mDisplayPortListenersLock")
+ @RequiresPermission(Manifest.permission.MANAGE_USB)
+ private boolean registerDisplayPortAltModeEventsIfNeededLocked() {
+ DisplayPortAltModeInfoDispatchingListener displayPortDispatchingListener =
+ new DisplayPortAltModeInfoDispatchingListener();
+ try {
+ if (mService.registerForDisplayPortEvents(displayPortDispatchingListener)) {
+ mDisplayPortServiceListener = displayPortDispatchingListener;
+ return true;
+ }
+ return false;
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Registers the given listener to listen for DisplayPort Alt Mode changes.
+ * <p>
+ * If this method returns true, the caller should ensure to call
+ * {@link #unregisterDisplayPortAltModeListener} when it no longer requires updates.
+ *
+ * @param executor Executor on which to run the listener.
+ * @param listener DisplayPortAltModeInfoListener invoked on DisplayPortAltModeInfo
+ * changes. See {@link #DisplayPortAltModeInfoListener} for listener
+ * details.
+ *
+ * @return true on successful register, false on failed register due to listener already being
+ * registered or an internal error.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.MANAGE_USB)
+ public boolean registerDisplayPortAltModeInfoListener(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull DisplayPortAltModeInfoListener listener) {
+ Objects.requireNonNull(executor, "registerDisplayPortAltModeInfoListener: "
+ + "executor must not be null.");
+ Objects.requireNonNull(listener, "registerDisplayPortAltModeInfoListener: "
+ + "listener must not be null.");
+
+ synchronized (mDisplayPortListenersLock) {
+ if (mDisplayPortListeners == null) {
+ mDisplayPortListeners = new ArrayMap<DisplayPortAltModeInfoListener,
+ Executor>();
+ }
+
+ if (mDisplayPortServiceListener == null) {
+ if (!registerDisplayPortAltModeEventsIfNeededLocked()) {
+ return false;
+ }
+ }
+ if (mDisplayPortListeners.containsKey(listener)) {
+ return false;
+ }
+
+ mDisplayPortListeners.put(listener, executor);
+ return true;
+ }
+ }
+
+ @GuardedBy("mDisplayPortListenersLock")
+ @RequiresPermission(Manifest.permission.MANAGE_USB)
+ private void unregisterDisplayPortAltModeEventsLocked() {
+ if (mDisplayPortServiceListener != null) {
+ try {
+ mService.unregisterForDisplayPortEvents(mDisplayPortServiceListener);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } finally {
+ // If there was a RemoteException, the system server may have died,
+ // and this listener probably became unregistered, so clear it for re-registration.
+ mDisplayPortServiceListener = null;
+ }
+ }
+ }
+
+ /**
+ * Unregisters the given listener if it was previously passed to
+ * registerDisplayPortAltModeInfoListener.
+ *
+ * @param listener DisplayPortAltModeInfoListener used to register the listener
+ * in registerDisplayPortAltModeInfoListener.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.MANAGE_USB)
+ public void unregisterDisplayPortAltModeInfoListener(
+ @NonNull DisplayPortAltModeInfoListener listener) {
+ synchronized (mDisplayPortListenersLock) {
+ if (mDisplayPortListeners == null) {
+ return;
+ }
+ mDisplayPortListeners.remove(listener);
+ if (mDisplayPortListeners.isEmpty()) {
+ unregisterDisplayPortAltModeEventsLocked();
+ }
+ }
+ return;
+ }
+
/**
* Sets the component that will handle USB device connection.
* <p>
diff --git a/core/java/android/hardware/usb/UsbPort.java b/core/java/android/hardware/usb/UsbPort.java
index cdd67b7..73dcb36 100644
--- a/core/java/android/hardware/usb/UsbPort.java
+++ b/core/java/android/hardware/usb/UsbPort.java
@@ -52,6 +52,10 @@
import static android.hardware.usb.UsbPortStatus.COMPLIANCE_WARNING_BC_1_2;
import static android.hardware.usb.UsbPortStatus.COMPLIANCE_WARNING_MISSING_RP;
import static android.hardware.usb.UsbPortStatus.COMPLIANCE_WARNING_OTHER;
+import static android.hardware.usb.DisplayPortAltModeInfo.DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN;
+import static android.hardware.usb.DisplayPortAltModeInfo.DISPLAYPORT_ALT_MODE_STATUS_NOT_CAPABLE;
+import static android.hardware.usb.DisplayPortAltModeInfo.DISPLAYPORT_ALT_MODE_STATUS_CAPABLE;
+import static android.hardware.usb.DisplayPortAltModeInfo.DISPLAYPORT_ALT_MODE_STATUS_ENABLED;
import android.Manifest;
import android.annotation.CallbackExecutor;
@@ -90,6 +94,7 @@
private final boolean mSupportsEnableContaminantPresenceProtection;
private final boolean mSupportsEnableContaminantPresenceDetection;
private final boolean mSupportsComplianceWarnings;
+ private final @AltModeType int mSupportedAltModes;
private static final int NUM_DATA_ROLES = Constants.PortDataRole.NUM_DATA_ROLES;
/**
@@ -252,6 +257,18 @@
@Retention(RetentionPolicy.SOURCE)
@interface EnableUsbDataWhileDockedStatus{}
+ /**
+ * Indicates that the Alt Mode being described is DisplayPort.
+ */
+ public static final int FLAG_ALT_MODE_TYPE_DISPLAYPORT = 1 << 0;
+
+ /** @hide */
+ @IntDef(prefix = { "FLAG_ALT_MODE_TYPE_" }, flag = true, value = {
+ FLAG_ALT_MODE_TYPE_DISPLAYPORT,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AltModeType {}
+
/** @hide */
public UsbPort(@NonNull UsbManager usbManager, @NonNull String id, int supportedModes,
int supportedContaminantProtectionModes,
@@ -260,7 +277,7 @@
this(usbManager, id, supportedModes, supportedContaminantProtectionModes,
supportsEnableContaminantPresenceProtection,
supportsEnableContaminantPresenceDetection,
- false);
+ false, 0);
}
/** @hide */
@@ -268,7 +285,8 @@
int supportedContaminantProtectionModes,
boolean supportsEnableContaminantPresenceProtection,
boolean supportsEnableContaminantPresenceDetection,
- boolean supportsComplianceWarnings) {
+ boolean supportsComplianceWarnings,
+ int supportedAltModes) {
Objects.requireNonNull(id);
Preconditions.checkFlagsArgument(supportedModes,
MODE_DFP | MODE_UFP | MODE_AUDIO_ACCESSORY | MODE_DEBUG_ACCESSORY);
@@ -282,6 +300,7 @@
mSupportsEnableContaminantPresenceDetection =
supportsEnableContaminantPresenceDetection;
mSupportsComplianceWarnings = supportsComplianceWarnings;
+ mSupportedAltModes = supportedAltModes;
}
/**
@@ -366,6 +385,27 @@
}
/**
+ * Returns all Alt Modes supported by the port.
+ *
+ * @hide
+ */
+ public @AltModeType int getSupportedAltModesMask() {
+ return mSupportedAltModes;
+ }
+
+ /**
+ * Returns whether all Alt Mode types in a given mask are supported
+ * by the port.
+ *
+ * @return true if all given Alt Modes are supported, false otherwise.
+ *
+ */
+ public boolean isAltModeSupported(@AltModeType int typeMask) {
+ return (mSupportedAltModes & typeMask) == typeMask;
+ }
+
+
+ /**
* Sets the desired role combination of the port.
* <p>
* The supported role combinations depend on what is connected to the port and may be
@@ -761,6 +801,22 @@
}
/** @hide */
+ public static String dpAltModeStatusToString(int dpAltModeStatus) {
+ switch (dpAltModeStatus) {
+ case DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN:
+ return "Unknown";
+ case DISPLAYPORT_ALT_MODE_STATUS_NOT_CAPABLE:
+ return "Not Capable";
+ case DISPLAYPORT_ALT_MODE_STATUS_CAPABLE:
+ return "Capable";
+ case DISPLAYPORT_ALT_MODE_STATUS_ENABLED:
+ return "Enabled";
+ default:
+ return Integer.toString(dpAltModeStatus);
+ }
+ }
+
+ /** @hide */
public static void checkMode(int powerRole) {
Preconditions.checkArgumentInRange(powerRole, Constants.PortMode.NONE,
Constants.PortMode.NUM_MODES - 1, "portMode");
diff --git a/core/java/android/hardware/usb/UsbPortStatus.java b/core/java/android/hardware/usb/UsbPortStatus.java
index e61703d..8c13307 100644
--- a/core/java/android/hardware/usb/UsbPortStatus.java
+++ b/core/java/android/hardware/usb/UsbPortStatus.java
@@ -20,6 +20,7 @@
import android.annotation.CheckResult;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.os.Parcel;
@@ -27,6 +28,7 @@
import com.android.internal.annotations.Immutable;
+import java.lang.StringBuilder;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -49,6 +51,13 @@
private final @UsbDataStatus int mUsbDataStatus;
private final @PowerBrickConnectionStatus int mPowerBrickConnectionStatus;
private final @NonNull @ComplianceWarning int[] mComplianceWarnings;
+ private final @PlugState int mPlugState;
+ /**
+ * Holds the DisplayPort Alt Mode info for the Port. This field
+ * is null if the device does not support DisplayPort Alt Mode.
+ */
+ private final @Nullable DisplayPortAltModeInfo mDisplayPortAltModeInfo;
+
/**
* Power role: This USB port does not have a power role.
@@ -300,6 +309,35 @@
*/
public static final int COMPLIANCE_WARNING_MISSING_RP = 4;
+ /**
+ * Indicates that the Type-C plug orientation cannot be
+ * determined.
+ */
+ public static final int PLUG_STATE_UNKNOWN = 0;
+
+ /**
+ * Indicates no Type-C plug is inserted into the device.
+ */
+ public static final int PLUG_STATE_UNPLUGGED = 1;
+
+ /**
+ * Indicates a Type-C plug is inserted into the device, but
+ * the orientation cannot be determined.
+ */
+ public static final int PLUG_STATE_PLUGGED_ORIENTATION_UNKNOWN = 2;
+
+ /**
+ * Indicates that the connected plug uses its CC1
+ * pin to manage the Source-to-Sink connection.
+ */
+ public static final int PLUG_STATE_PLUGGED_ORIENTATION_NORMAL = 3;
+
+ /**
+ * Indicates that the connected plug uses its CC2
+ * pin to manage the Source-to-Sink connection.
+ */
+ public static final int PLUG_STATE_PLUGGED_ORIENTATION_FLIPPED = 4;
+
@IntDef(prefix = { "CONTAMINANT_DETECTION_" }, value = {
CONTAMINANT_DETECTION_NOT_SUPPORTED,
CONTAMINANT_DETECTION_DISABLED,
@@ -338,6 +376,16 @@
@Retention(RetentionPolicy.SOURCE)
@interface ComplianceWarning{}
+ @IntDef(prefix = { "PLUG_STATE_" }, value = {
+ PLUG_STATE_UNKNOWN,
+ PLUG_STATE_UNPLUGGED,
+ PLUG_STATE_PLUGGED_ORIENTATION_UNKNOWN,
+ PLUG_STATE_PLUGGED_ORIENTATION_NORMAL,
+ PLUG_STATE_PLUGGED_ORIENTATION_FLIPPED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface PlugState{}
+
/** @hide */
@IntDef(prefix = { "DATA_STATUS_" }, flag = true, value = {
DATA_STATUS_UNKNOWN,
@@ -348,7 +396,7 @@
DATA_STATUS_DISABLED_DOCK_HOST_MODE,
DATA_STATUS_DISABLED_DOCK_DEVICE_MODE,
DATA_STATUS_DISABLED_FORCE,
- DATA_STATUS_DISABLED_DEBUG
+ DATA_STATUS_DISABLED_DEBUG,
})
@Retention(RetentionPolicy.SOURCE)
@interface UsbDataStatus{}
@@ -368,7 +416,9 @@
int contaminantDetectionStatus, @UsbDataStatus int usbDataStatus,
boolean powerTransferLimited,
@PowerBrickConnectionStatus int powerBrickConnectionStatus,
- @NonNull @ComplianceWarning int[] complianceWarnings) {
+ @NonNull @ComplianceWarning int[] complianceWarnings,
+ int plugState,
+ @Nullable DisplayPortAltModeInfo displayPortAltModeInfo) {
mCurrentMode = currentMode;
mCurrentPowerRole = currentPowerRole;
mCurrentDataRole = currentDataRole;
@@ -393,6 +443,8 @@
mPowerTransferLimited = powerTransferLimited;
mPowerBrickConnectionStatus = powerBrickConnectionStatus;
mComplianceWarnings = complianceWarnings;
+ mPlugState = plugState;
+ mDisplayPortAltModeInfo = displayPortAltModeInfo;
}
/** @hide */
@@ -404,7 +456,7 @@
this(currentMode, currentPowerRole, currentDataRole, supportedRoleCombinations,
contaminantProtectionStatus, contaminantDetectionStatus,
usbDataStatus, powerTransferLimited, powerBrickConnectionStatus,
- new int[] {});
+ new int[] {}, PLUG_STATE_UNKNOWN, null);
}
/** @hide */
@@ -414,7 +466,7 @@
this(currentMode, currentPowerRole, currentDataRole, supportedRoleCombinations,
contaminantProtectionStatus, contaminantDetectionStatus,
DATA_STATUS_UNKNOWN, false, POWER_BRICK_STATUS_UNKNOWN,
- new int[] {});
+ new int[] {}, PLUG_STATE_UNKNOWN, null);
}
/**
@@ -547,10 +599,34 @@
return mComplianceWarnings;
}
+ /**
+ * Returns the orientation state of the attached cable/adapter.
+ *
+ * @return one of {@link #PLUG_STATE_UNKNOWN},
+ * {@link #PLUG_STATE_UNPLUGGED},
+ * {@link #PLUG_STATE_PLUGGED_ORIENTATION_UNKNOWN},
+ * {@link #PLUG_STATE_PLUGGED_ORIENTATION_NORMAL},
+ * {@link #PLUG_STATE_PLUGGED_ORIENTATION_FLIPPED},
+ */
+ public @PlugState int getPlugState() {
+ return mPlugState;
+ }
+
+ /**
+ * Returns the DisplayPortInfo of the USB Port, if applicable.
+ *
+ * @return an instance of type DisplayPortInfo
+ * or null if not applicable.
+ */
+ @Nullable
+ public DisplayPortAltModeInfo getDisplayPortAltModeInfo() {
+ return (mDisplayPortAltModeInfo == null) ? null : mDisplayPortAltModeInfo;
+ }
+
@NonNull
@Override
public String toString() {
- return "UsbPortStatus{connected=" + isConnected()
+ StringBuilder mString = new StringBuilder("UsbPortStatus{connected=" + isConnected()
+ ", currentMode=" + UsbPort.modeToString(mCurrentMode)
+ ", currentPowerRole=" + UsbPort.powerRoleToString(mCurrentPowerRole)
+ ", currentDataRole=" + UsbPort.dataRoleToString(mCurrentDataRole)
@@ -569,7 +645,12 @@
.powerBrickConnectionStatusToString(getPowerBrickConnectionStatus())
+ ", complianceWarnings="
+ UsbPort.complianceWarningsToString(getComplianceWarnings())
- + "}";
+ + ", plugState="
+ + getPlugState()
+ + ", displayPortAltModeInfo="
+ + mDisplayPortAltModeInfo
+ + "}");
+ return mString.toString();
}
@Override
@@ -589,6 +670,13 @@
dest.writeBoolean(mPowerTransferLimited);
dest.writeInt(mPowerBrickConnectionStatus);
dest.writeIntArray(mComplianceWarnings);
+ dest.writeInt(mPlugState);
+ if (mDisplayPortAltModeInfo == null) {
+ dest.writeBoolean(false);
+ } else {
+ dest.writeBoolean(true);
+ mDisplayPortAltModeInfo.writeToParcel(dest, 0);
+ }
}
public static final @NonNull Parcelable.Creator<UsbPortStatus> CREATOR =
@@ -605,11 +693,19 @@
boolean powerTransferLimited = in.readBoolean();
int powerBrickConnectionStatus = in.readInt();
@ComplianceWarning int[] complianceWarnings = in.createIntArray();
+ int plugState = in.readInt();
+ boolean supportsDisplayPortAltMode = in.readBoolean();
+ DisplayPortAltModeInfo displayPortAltModeInfo;
+ if (supportsDisplayPortAltMode) {
+ displayPortAltModeInfo = DisplayPortAltModeInfo.CREATOR.createFromParcel(in);
+ } else {
+ displayPortAltModeInfo = null;
+ }
return new UsbPortStatus(currentMode, currentPowerRole, currentDataRole,
supportedRoleCombinations, contaminantProtectionStatus,
contaminantDetectionStatus, usbDataStatus, powerTransferLimited,
powerBrickConnectionStatus,
- complianceWarnings);
+ complianceWarnings, plugState, displayPortAltModeInfo);
}
@Override
@@ -634,6 +730,8 @@
private @UsbDataStatus int mUsbDataStatus;
private @PowerBrickConnectionStatus int mPowerBrickConnectionStatus;
private @ComplianceWarning int[] mComplianceWarnings;
+ private @PlugState int mPlugState;
+ private @Nullable DisplayPortAltModeInfo mDisplayPortAltModeInfo;
public Builder() {
mCurrentMode = MODE_NONE;
@@ -644,6 +742,8 @@
mUsbDataStatus = DATA_STATUS_UNKNOWN;
mPowerBrickConnectionStatus = POWER_BRICK_STATUS_UNKNOWN;
mComplianceWarnings = new int[] {};
+ mPlugState = PLUG_STATE_UNKNOWN;
+ mDisplayPortAltModeInfo = null;
}
/**
@@ -742,6 +842,28 @@
return this;
}
+ /**
+ * Sets the plug orientation of {@link UsbPortStatus}
+ *
+ * @return Instance of {@link Builder}
+ */
+ @NonNull
+ public Builder setPlugState(int plugState) {
+ mPlugState = plugState;
+ return this;
+ }
+
+ /**
+ * Sets the plug orientation of {@link UsbPortStatus}
+ *
+ * @return Instance of {@link Builder}
+ */
+ @NonNull
+ public Builder setDisplayPortAltModeInfo(
+ @Nullable DisplayPortAltModeInfo displayPortAltModeInfo) {
+ mDisplayPortAltModeInfo = displayPortAltModeInfo;
+ return this;
+ }
/**
* Creates the {@link UsbPortStatus} object.
@@ -751,7 +873,8 @@
UsbPortStatus status = new UsbPortStatus(mCurrentMode, mCurrentPowerRole,
mCurrentDataRole, mSupportedRoleCombinations, mContaminantProtectionStatus,
mContaminantDetectionStatus, mUsbDataStatus, mPowerTransferLimited,
- mPowerBrickConnectionStatus, mComplianceWarnings);
+ mPowerBrickConnectionStatus, mComplianceWarnings,
+ mPlugState, mDisplayPortAltModeInfo);
return status;
}
};
diff --git a/core/java/android/inputmethodservice/IRemoteInputConnectionInvoker.java b/core/java/android/inputmethodservice/IRemoteInputConnectionInvoker.java
index 8759a6a..8e6f6dc 100644
--- a/core/java/android/inputmethodservice/IRemoteInputConnectionInvoker.java
+++ b/core/java/android/inputmethodservice/IRemoteInputConnectionInvoker.java
@@ -767,20 +767,20 @@
/**
* Invokes {@link IRemoteInputConnection#requestTextBoundsInfo(InputConnectionCommandHeader,
* RectF, ResultReceiver)}
- * @param rectF {@code rectF} parameter to be passed.
+ * @param bounds {@code rectF} parameter to be passed.
* @param executor {@code Executor} parameter to be passed.
* @param consumer {@code Consumer} parameter to be passed.
*/
@AnyThread
public void requestTextBoundsInfo(
- @NonNull RectF rectF, @NonNull @CallbackExecutor Executor executor,
+ @NonNull RectF bounds, @NonNull @CallbackExecutor Executor executor,
@NonNull Consumer<TextBoundsInfoResult> consumer) {
Objects.requireNonNull(executor);
Objects.requireNonNull(consumer);
final ResultReceiver resultReceiver = new TextBoundsInfoResultReceiver(executor, consumer);
try {
- mConnection.requestTextBoundsInfo(createHeader(), rectF, resultReceiver);
+ mConnection.requestTextBoundsInfo(createHeader(), bounds, resultReceiver);
} catch (RemoteException e) {
executor.execute(() -> consumer.accept(new TextBoundsInfoResult(CODE_CANCELLED)));
}
diff --git a/core/java/android/inputmethodservice/RemoteInputConnection.java b/core/java/android/inputmethodservice/RemoteInputConnection.java
index f93f9ab..ec26ace 100644
--- a/core/java/android/inputmethodservice/RemoteInputConnection.java
+++ b/core/java/android/inputmethodservice/RemoteInputConnection.java
@@ -476,9 +476,9 @@
@AnyThread
public void requestTextBoundsInfo(
- @NonNull RectF rectF, @NonNull @CallbackExecutor Executor executor,
+ @NonNull RectF bounds, @NonNull @CallbackExecutor Executor executor,
@NonNull Consumer<TextBoundsInfoResult> consumer) {
- mInvoker.requestTextBoundsInfo(rectF, executor, consumer);
+ mInvoker.requestTextBoundsInfo(bounds, executor, consumer);
}
@AnyThread
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index def0cbd..00676f3 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -358,16 +358,16 @@
* Return the Linux UID assigned to the process that sent the transaction
* currently being processed.
*
- * Logs WTF if the current thread is not currently
+ * Slog.wtf if the current thread is not currently
* executing an incoming transaction and the calling identity has not been
* explicitly set with {@link #clearCallingIdentity()}
*
* @hide
*/
- public static final int getCallingUidOrWtf() {
+ public static final int getCallingUidOrWtf(String message) {
if (!isDirectlyHandlingTransaction() && !hasExplicitIdentity()) {
- Log.wtfStack(TAG,
- "Thread is not in a binder transaction, "
+ Slog.wtf(TAG,
+ message + ": Thread is not in a binder transaction, "
+ "and the calling identity has not been "
+ "explicitly set with clearCallingIdentity");
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index fc02524..b016c781 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1472,6 +1472,21 @@
public static final String DISALLOW_BIOMETRIC = "disallow_biometric";
/**
+ * Specifies whether the user is allowed to modify default apps in settings.
+ *
+ * <p>This restriction can be set by device or profile owner.
+ *
+ * <p>The default value is <code>false</code>.
+ *
+ * <p>Key for user restrictions.
+ * <p>Type: Boolean
+ * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
+ * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
+ * @see #getUserRestrictions()
+ */
+ public static final String DISALLOW_CONFIG_DEFAULT_APPS = "disallow_config_default_apps";
+
+ /**
* Application restriction key that is used to indicate the pending arrival
* of real restrictions for the app.
*
@@ -1827,6 +1842,15 @@
public static final int REMOVE_RESULT_ERROR_SYSTEM_USER = -4;
/**
+ * A response code from {@link #removeUserWhenPossible(UserHandle, boolean)} indicating that
+ * user being removed is a {@link UserInfo#FLAG_MAIN} user and can't be removed because
+ * system property {@link com.android.internal.R.bool.isMainUserPermanentAdmin} is true.
+ * @hide
+ */
+ @SystemApi
+ public static final int REMOVE_RESULT_ERROR_MAIN_USER_PERMANENT_ADMIN = -5;
+
+ /**
* Possible response codes from {@link #removeUserWhenPossible(UserHandle, boolean)}.
*
* @hide
@@ -1838,6 +1862,7 @@
REMOVE_RESULT_ERROR_USER_RESTRICTION,
REMOVE_RESULT_ERROR_USER_NOT_FOUND,
REMOVE_RESULT_ERROR_SYSTEM_USER,
+ REMOVE_RESULT_ERROR_MAIN_USER_PERMANENT_ADMIN,
REMOVE_RESULT_ERROR_UNKNOWN,
})
@Retention(RetentionPolicy.SOURCE)
@@ -5236,8 +5261,9 @@
* @return the {@link RemoveResult} code: {@link #REMOVE_RESULT_REMOVED},
* {@link #REMOVE_RESULT_DEFERRED}, {@link #REMOVE_RESULT_ALREADY_BEING_REMOVED},
* {@link #REMOVE_RESULT_ERROR_USER_RESTRICTION}, {@link #REMOVE_RESULT_ERROR_USER_NOT_FOUND},
- * {@link #REMOVE_RESULT_ERROR_SYSTEM_USER}, or {@link #REMOVE_RESULT_ERROR_UNKNOWN}. All error
- * codes have negative values.
+ * {@link #REMOVE_RESULT_ERROR_SYSTEM_USER},
+ * {@link #REMOVE_RESULT_ERROR_MAIN_USER_PERMANENT_ADMIN}, or
+ * {@link #REMOVE_RESULT_ERROR_UNKNOWN}. All error codes have negative values.
*
* @hide
*/
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 55967e6..ec3ef9d 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -22,6 +22,8 @@
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.PermissionMethod;
+import android.annotation.PermissionName;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
@@ -48,7 +50,6 @@
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PermissionName;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -1079,6 +1080,17 @@
"android.settings.APP_LOCALE_SETTINGS";
/**
+ * Activity Action: Show settings to allow configuration of regional preferences
+ * <p>
+ * Input: Nothing
+ * <p>
+ * Output: Nothing.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_REGIONAL_PREFERENCES_SETTINGS =
+ "android.settings.REGIONAL_PREFERENCES_SETTINGS";
+
+ /**
* Activity Action: Show settings to allow configuration of lockscreen.
* <p>
* In some cases, a matching Activity may not exist, so ensure you
@@ -9975,11 +9987,10 @@
"fingerprint_side_fps_auth_downtime";
/**
- * Whether or not a SFPS device is required to be interactive for auth to unlock the device.
+ * Whether or not a SFPS device is enabling the performant auth setting.
* @hide
*/
- public static final String SFPS_REQUIRE_SCREEN_ON_TO_AUTH_ENABLED =
- "sfps_require_screen_on_to_auth_enabled";
+ public static final String SFPS_PERFORMANT_AUTH_ENABLED = "sfps_performant_auth_enabled";
/**
* Whether or not debugging is enabled.
@@ -18492,6 +18503,8 @@
* @see #checkCallingPermission
* @hide
*/
+ @PermissionMethod(orSelf = true)
+ @PackageManager.PermissionResult
public static int checkCallingOrSelfPermission(@NonNull @PermissionName String permission) {
return ActivityThread.currentApplication()
.getApplicationContext().checkCallingOrSelfPermission(permission);
diff --git a/core/java/android/security/rkp/IRegistration.aidl b/core/java/android/security/rkp/IRegistration.aidl
index 6522a45..8ec13b9 100644
--- a/core/java/android/security/rkp/IRegistration.aidl
+++ b/core/java/android/security/rkp/IRegistration.aidl
@@ -17,6 +17,7 @@
package android.security.rkp;
import android.security.rkp.IGetKeyCallback;
+import android.security.rkp.IStoreUpgradedKeyCallback;
/**
* This interface is associated with the registration of an
@@ -70,16 +71,18 @@
* mechanism, see the documentation for IKeyMintDevice.upgradeKey.
*
* Once a key has been upgraded, the IRegistration where the key is stored
- * needs to be told about the new blob. After calling storeUpgradedKey,
+ * needs to be told about the new blob. After calling storeUpgradedKeyAsync,
* getKey will return the new key blob instead of the old one.
*
* Note that this function does NOT extend the lifetime of key blobs. The
* certificate for the key is unchanged, and the key will still expire at
- * the same time it would have if storeUpgradedKey had never been called.
+ * the same time it would have if storeUpgradedKeyAsync had never been called.
*
* @param oldKeyBlob The old key blob to be replaced by {@code newKeyBlob}.
- *
* @param newKeyblob The new blob to replace {@code oldKeyBlob}.
+ * @param callback Receives the result of the call. A callback must only
+ * be used with one {@code storeUpgradedKeyAsync} call at a time.
*/
- void storeUpgradedKey(in byte[] oldKeyBlob, in byte[] newKeyBlob);
+ void storeUpgradedKeyAsync(
+ in byte[] oldKeyBlob, in byte[] newKeyBlob, IStoreUpgradedKeyCallback callback);
}
diff --git a/core/java/android/security/rkp/IStoreUpgradedKeyCallback.aidl b/core/java/android/security/rkp/IStoreUpgradedKeyCallback.aidl
new file mode 100644
index 0000000..7f72fa0
--- /dev/null
+++ b/core/java/android/security/rkp/IStoreUpgradedKeyCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 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.security.rkp;
+
+/**
+ * Callback interface for storing an upgraded remotely provisioned key blob.
+ * {@link IRegistration}.
+ *
+ * @hide
+ */
+oneway interface IStoreUpgradedKeyCallback {
+ /**
+ * Called in response to {@link IRegistration.storeUpgradedKeyAsync}, indicating
+ * a remotely-provisioned key is available.
+ */
+ void onSuccess();
+
+ /**
+ * Called when an error has occurred while trying to store an upgraded
+ * remotely provisioned key.
+ *
+ * @param error A description of what failed, suitable for logging.
+ */
+ void onError(String error);
+}
diff --git a/core/java/android/service/credentials/CredentialProviderInfo.java b/core/java/android/service/credentials/CredentialProviderInfo.java
index f89ad8e..6a10a6a 100644
--- a/core/java/android/service/credentials/CredentialProviderInfo.java
+++ b/core/java/android/service/credentials/CredentialProviderInfo.java
@@ -24,6 +24,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
@@ -58,6 +59,7 @@
private final Drawable mIcon;
@Nullable
private final CharSequence mLabel;
+ private final boolean mIsSystemProvider;
/**
* Constructs an information instance of the credential provider.
@@ -65,13 +67,14 @@
* @param context the context object
* @param serviceComponent the serviceComponent of the provider service
* @param userId the android userId for which the current process is running
+ * @param isSystemProvider whether this provider is a system provider
* @throws PackageManager.NameNotFoundException If provider service is not found
* @throws SecurityException If provider does not require the relevant permission
*/
public CredentialProviderInfo(@NonNull Context context,
- @NonNull ComponentName serviceComponent, int userId)
+ @NonNull ComponentName serviceComponent, int userId, boolean isSystemProvider)
throws PackageManager.NameNotFoundException {
- this(context, getServiceInfoOrThrow(serviceComponent, userId));
+ this(context, getServiceInfoOrThrow(serviceComponent, userId), isSystemProvider);
}
/**
@@ -79,8 +82,11 @@
* @param context the context object
* @param serviceInfo the service info for the provider app. This must be retrieved from the
* {@code PackageManager}
+ * @param isSystemProvider whether the provider is a system app or not
*/
- public CredentialProviderInfo(@NonNull Context context, @NonNull ServiceInfo serviceInfo) {
+ public CredentialProviderInfo(@NonNull Context context,
+ @NonNull ServiceInfo serviceInfo,
+ boolean isSystemProvider) {
if (!Manifest.permission.BIND_CREDENTIAL_PROVIDER_SERVICE.equals(serviceInfo.permission)) {
Log.i(TAG, "Credential Provider Service from : " + serviceInfo.packageName
+ "does not require permission"
@@ -95,6 +101,7 @@
mLabel = mServiceInfo.loadSafeLabel(
mContext.getPackageManager(), 0 /* do not ellipsize */,
TextUtils.SAFE_STRING_FLAG_FIRST_LINE | TextUtils.SAFE_STRING_FLAG_TRIM);
+ mIsSystemProvider = isSystemProvider;
Log.i(TAG, "mLabel is : " + mLabel + ", for: " + mServiceInfo.getComponentName()
.flattenToString());
populateProviderCapabilities(context, serviceInfo);
@@ -147,6 +154,42 @@
}
/**
+ * Returns the valid credential provider services available for the user with the
+ * given {@code userId}.
+ */
+ @NonNull
+ public static List<CredentialProviderInfo> getAvailableSystemServices(
+ @NonNull Context context,
+ @UserIdInt int userId) {
+ final List<CredentialProviderInfo> services = new ArrayList<>();
+
+ final List<ResolveInfo> resolveInfos =
+ context.getPackageManager().queryIntentServicesAsUser(
+ new Intent(CredentialProviderService.SYSTEM_SERVICE_INTERFACE),
+ PackageManager.ResolveInfoFlags.of(PackageManager.GET_META_DATA),
+ userId);
+ for (ResolveInfo resolveInfo : resolveInfos) {
+ final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
+ try {
+ ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(
+ serviceInfo.packageName,
+ PackageManager.ApplicationInfoFlags.of(PackageManager.MATCH_SYSTEM_ONLY));
+ if (appInfo != null
+ && context.checkPermission(Manifest.permission.SYSTEM_CREDENTIAL_PROVIDER,
+ /*pId=*/-1, appInfo.uid) == PackageManager.PERMISSION_GRANTED) {
+ services.add(new CredentialProviderInfo(context, serviceInfo,
+ /*isSystemProvider=*/true));
+ }
+ } catch (SecurityException e) {
+ Log.i(TAG, "Error getting info for " + serviceInfo + ": " + e);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.i(TAG, "Error getting info for " + serviceInfo + ": " + e);
+ }
+ }
+ return services;
+ }
+
+ /**
* Returns true if the service supports the given {@code credentialType}, false otherwise.
*/
@NonNull
@@ -160,6 +203,10 @@
return mServiceInfo;
}
+ public boolean isSystemProvider() {
+ return mIsSystemProvider;
+ }
+
/** Returns the service icon. */
@Nullable
public Drawable getServiceIcon() {
@@ -195,7 +242,8 @@
for (ResolveInfo resolveInfo : resolveInfos) {
final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
try {
- services.add(new CredentialProviderInfo(context, serviceInfo));
+ services.add(new CredentialProviderInfo(context,
+ serviceInfo, false));
} catch (SecurityException e) {
Log.w(TAG, "Error getting info for " + serviceInfo + ": " + e);
}
diff --git a/core/java/android/service/credentials/CredentialProviderService.java b/core/java/android/service/credentials/CredentialProviderService.java
index 70dd16c..ee386c3 100644
--- a/core/java/android/service/credentials/CredentialProviderService.java
+++ b/core/java/android/service/credentials/CredentialProviderService.java
@@ -125,6 +125,33 @@
public static final String EXTRA_CREATE_CREDENTIAL_EXCEPTION =
"android.service.credentials.extra.CREATE_CREDENTIAL_EXCEPTION";
+ /**
+ * Intent extra: The {@link BeginGetCredentialRequest} attached with
+ * the {@code pendingIntent} that is invoked when the user selects an
+ * authentication entry (intending to unlock the provider app) on the UI.
+ *
+ * <p>When a provider app receives a {@link BeginGetCredentialRequest} through the
+ * {@link CredentialProviderService#onBeginGetCredential} call, it can construct the
+ * {@link BeginGetCredentialResponse} with either an authentication {@link Action} (if the app
+ * is locked), or a {@link CredentialsResponseContent} (if the app is unlocked). In the former
+ * case, i.e. the app is locked, user will be shown the authentication action. When selected,
+ * the underlying {@link PendingIntent} will be invoked which will lead the user to provider's
+ * unlock activity. This pending intent will also contain the original
+ * {@link BeginGetCredentialRequest} to be retrieved and processed after the unlock
+ * flow is complete.
+ *
+ * <p>After the app is unlocked, the {@link BeginGetCredentialResponse} must be constructed
+ * using a {@link CredentialsResponseContent}, which must be set on an {@link Intent} as an
+ * intent extra against CredentialProviderService#EXTRA_CREDENTIALS_RESPONSE_CONTENT}.
+ * This intent should then be set as a result through {@link android.app.Activity#setResult}
+ * before finishing the activity.
+ *
+ * <p>
+ * Type: {@link BeginGetCredentialRequest}
+ */
+ public static final String EXTRA_BEGIN_GET_CREDENTIAL_REQUEST =
+ "android.service.credentials.extra.BEGIN_GET_CREDENTIAL_REQUEST";
+
private static final String TAG = "CredProviderService";
public static final String CAPABILITY_META_DATA_KEY = "android.credentials.capabilities";
@@ -140,6 +167,20 @@
public static final String SERVICE_INTERFACE =
"android.service.credentials.CredentialProviderService";
+ /**
+ * The {@link Intent} that must be declared as handled by a system credential provider
+ * service.
+ *
+ * <p>The service must also require the
+ * {android.Manifest.permission#BIND_CREDENTIAL_PROVIDER_SERVICE} permission
+ * so that only the system can bind to it.
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ public static final String SYSTEM_SERVICE_INTERFACE =
+ "android.service.credentials.system.CredentialProviderService";
+
@CallSuper
@Override
public void onCreate() {
diff --git a/core/java/android/service/dreams/DreamActivity.java b/core/java/android/service/dreams/DreamActivity.java
index a2fa139..a389223 100644
--- a/core/java/android/service/dreams/DreamActivity.java
+++ b/core/java/android/service/dreams/DreamActivity.java
@@ -58,11 +58,13 @@
setTitle(title);
}
- final Bundle extras = getIntent().getExtras();
- mCallback = (DreamService.DreamActivityCallbacks) extras.getBinder(EXTRA_CALLBACK);
-
- if (mCallback != null) {
+ final Object callback = getIntent().getExtras().getBinder(EXTRA_CALLBACK);
+ if (callback instanceof DreamService.DreamActivityCallbacks) {
+ mCallback = (DreamService.DreamActivityCallbacks) callback;
mCallback.onActivityCreated(this);
+ } else {
+ mCallback = null;
+ finishAndRemoveTask();
}
}
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index 7b6ff97..d957029 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -24,6 +24,9 @@
import android.app.PendingIntent;
import android.app.Service;
import android.app.StatusBarManager;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -166,6 +169,17 @@
*/
public static final String EXTRA_STATE = "state";
+ /**
+ * The method {@link TileService#startActivityAndCollapse(Intent)} will verify that only
+ * apps targeting {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or higher will
+ * not be allowed to use it.
+ *
+ * @hide
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ public static final long START_ACTIVITY_NEEDS_PENDING_INTENT = 241766793L;
+
private final H mHandler = new H(Looper.getMainLooper());
private boolean mListening = false;
@@ -251,7 +265,6 @@
* This will collapse the Quick Settings panel and show the dialog.
*
* @param dialog Dialog to show.
- *
* @see #isLocked()
*/
public final void showDialog(Dialog dialog) {
@@ -330,8 +343,19 @@
/**
* Start an activity while collapsing the panel.
+ *
+ * @deprecated for versions {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and up,
+ * use {@link TileService#startActivityAndCollapse(PendingIntent)} instead.
+ * @throws UnsupportedOperationException if called in versions
+ * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and up
*/
+ @Deprecated
public final void startActivityAndCollapse(Intent intent) {
+ if (CompatChanges.isChangeEnabled(START_ACTIVITY_NEEDS_PENDING_INTENT)) {
+ throw new UnsupportedOperationException(
+ "startActivityAndCollapse: Starting activity from TileService using an Intent"
+ + " is not allowed.");
+ }
startActivity(intent);
try {
mService.onStartActivity(mTileToken);
@@ -410,7 +434,7 @@
}
@Override
- public void onUnlockComplete() throws RemoteException{
+ public void onUnlockComplete() throws RemoteException {
mHandler.sendEmptyMessage(H.MSG_UNLOCK_COMPLETE);
}
};
diff --git a/core/java/android/text/SegmentFinder.java b/core/java/android/text/SegmentFinder.java
index be0094b..047d07a 100644
--- a/core/java/android/text/SegmentFinder.java
+++ b/core/java/android/text/SegmentFinder.java
@@ -74,7 +74,7 @@
/**
* The default {@link SegmentFinder} implementation based on given segment ranges.
*/
- public static class DefaultSegmentFinder extends SegmentFinder {
+ public static class PrescribedSegmentFinder extends SegmentFinder {
private final int[] mSegments;
/**
@@ -87,7 +87,7 @@
* @throws IllegalArgumentException if the given segments array's length is not even; the
* given segments are not sorted or there are segments overlap with others.
*/
- public DefaultSegmentFinder(@NonNull int[] segments) {
+ public PrescribedSegmentFinder(@NonNull int[] segments) {
checkSegmentsValid(segments);
mSegments = segments;
}
diff --git a/core/java/android/text/TextShaper.java b/core/java/android/text/TextShaper.java
index a1d6cc8..6da0b63 100644
--- a/core/java/android/text/TextShaper.java
+++ b/core/java/android/text/TextShaper.java
@@ -173,7 +173,7 @@
private TextShaper() {}
/**
- * An consumer interface for accepting text shape result.
+ * A consumer interface for accepting text shape result.
*/
public interface GlyphsConsumer {
/**
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 493c800..70b04a1 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -158,6 +158,14 @@
*/
public static final String SETTINGS_FLASH_ALERTS = "settings_flash_alerts";
+ /**
+ * Flag to disable/enable showing udfps enroll view in settings. If it's disabled, udfps enroll
+ * view is shown in system ui.
+ * @hide
+ */
+ public static final String SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS =
+ "settings_show_udfps_enroll_in_settings";
+
private static final Map<String, String> DEFAULT_FLAGS;
static {
@@ -198,6 +206,7 @@
DEFAULT_FLAGS.put(SETTINGS_PREFER_ACCESSIBILITY_MENU_IN_SYSTEM, "false");
DEFAULT_FLAGS.put(SETTINGS_AUDIO_ROUTING, "false");
DEFAULT_FLAGS.put(SETTINGS_FLASH_ALERTS, "false");
+ DEFAULT_FLAGS.put(SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, "false");
}
private static final Set<String> PERSISTENT_FLAGS;
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 5a9a252..8683cc2 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -555,6 +555,7 @@
private String mKeyboardLanguageTag = null;
private String mKeyboardLayoutType = null;
private boolean mSupportsUsi = false;
+ private List<MotionRange> mMotionRanges = new ArrayList<>();
/** @see InputDevice#getId() */
public Builder setId(int id) {
@@ -670,12 +671,50 @@
return this;
}
+ /** @see InputDevice#getMotionRanges() */
+ public Builder addMotionRange(int axis, int source,
+ float min, float max, float flat, float fuzz, float resolution) {
+ mMotionRanges.add(new MotionRange(axis, source, min, max, flat, fuzz, resolution));
+ return this;
+ }
+
/** Build {@link InputDevice}. */
public InputDevice build() {
- return new InputDevice(mId, mGeneration, mControllerNumber, mName, mVendorId,
- mProductId, mDescriptor, mIsExternal, mSources, mKeyboardType, mKeyCharacterMap,
- mKeyboardLanguageTag, mKeyboardLayoutType, mHasVibrator, mHasMicrophone,
- mHasButtonUnderPad, mHasSensor, mHasBattery, mSupportsUsi);
+ InputDevice device = new InputDevice(
+ mId,
+ mGeneration,
+ mControllerNumber,
+ mName,
+ mVendorId,
+ mProductId,
+ mDescriptor,
+ mIsExternal,
+ mSources,
+ mKeyboardType,
+ mKeyCharacterMap,
+ mKeyboardLanguageTag,
+ mKeyboardLayoutType,
+ mHasVibrator,
+ mHasMicrophone,
+ mHasButtonUnderPad,
+ mHasSensor,
+ mHasBattery,
+ mSupportsUsi);
+
+ final int numRanges = mMotionRanges.size();
+ for (int i = 0; i < numRanges; i++) {
+ final MotionRange range = mMotionRanges.get(i);
+ device.addMotionRange(
+ range.getAxis(),
+ range.getSource(),
+ range.getMin(),
+ range.getMax(),
+ range.getFlat(),
+ range.getFuzz(),
+ range.getResolution());
+ }
+
+ return device;
}
}
@@ -1378,7 +1417,8 @@
out.writeInt(mHasBattery ? 1 : 0);
out.writeInt(mSupportsUsi ? 1 : 0);
- final int numRanges = mMotionRanges.size();
+ int numRanges = mMotionRanges.size();
+ numRanges = numRanges > MAX_RANGES ? MAX_RANGES : numRanges;
out.writeInt(numRanges);
for (int i = 0; i < numRanges; i++) {
MotionRange range = mMotionRanges.get(i);
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 5bc9847..b91019c 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -1293,6 +1293,23 @@
*/
public static final int AXIS_GESTURE_Y_OFFSET = 49;
+ /**
+ * Axis constant: X scroll distance axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a touch pad, reports the distance that should be scrolled in the X axis as a result
+ * of the user's two-finger scroll gesture, in display pixels.
+ * </ul>
+ */
+ public static final int AXIS_GESTURE_SCROLL_X_DISTANCE = 50;
+
+ /**
+ * Axis constant: Y scroll distance axis of a motion event.
+ *
+ * The same as {@link #AXIS_GESTURE_SCROLL_X_DISTANCE}, but for the Y axis.
+ */
+ public static final int AXIS_GESTURE_SCROLL_Y_DISTANCE = 51;
+
// NOTE: If you add a new axis here you must also add it to:
// frameworks/native/include/android/input.h
// frameworks/native/libs/input/InputEventLabels.cpp
@@ -1350,6 +1367,8 @@
names.append(AXIS_GENERIC_16, "AXIS_GENERIC_16");
names.append(AXIS_GESTURE_X_OFFSET, "AXIS_GESTURE_X_OFFSET");
names.append(AXIS_GESTURE_Y_OFFSET, "AXIS_GESTURE_Y_OFFSET");
+ names.append(AXIS_GESTURE_SCROLL_X_DISTANCE, "AXIS_GESTURE_SCROLL_X_DISTANCE");
+ names.append(AXIS_GESTURE_SCROLL_Y_DISTANCE, "AXIS_GESTURE_SCROLL_Y_DISTANCE");
}
/**
diff --git a/core/java/android/view/MotionPredictor.java b/core/java/android/view/MotionPredictor.java
new file mode 100644
index 0000000..3e58a31
--- /dev/null
+++ b/core/java/android/view/MotionPredictor.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2023 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.view;
+
+import android.annotation.NonNull;
+import android.content.Context;
+
+import libcore.util.NativeAllocationRegistry;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Calculates motion predictions.
+ *
+ * Add motions here to get predicted events!
+ * @hide
+ */
+// Acts as a pass-through to the native MotionPredictor object.
+// Do not store any state in this Java layer, or add any business logic here. All of the
+// implementation details should go into the native MotionPredictor.
+// The context / resource access must be here rather than in native layer due to the lack of the
+// corresponding native API surface.
+public final class MotionPredictor {
+
+ private static class RegistryHolder {
+ public static final NativeAllocationRegistry REGISTRY =
+ NativeAllocationRegistry.createMalloced(
+ MotionPredictor.class.getClassLoader(),
+ nativeGetNativeMotionPredictorFinalizer());
+ }
+
+ // Pointer to the native object.
+ private final long mPtr;
+ private final Context mContext;
+
+ /**
+ * Create a new MotionPredictor for the provided {@link Context}.
+ * @param context The context for the predictions
+ */
+ public MotionPredictor(@NonNull Context context) {
+ mContext = context;
+ final int offsetNanos = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_motionPredictionOffsetNanos);
+ mPtr = nativeInitialize(offsetNanos);
+ RegistryHolder.REGISTRY.registerNativeAllocation(this, mPtr);
+ }
+
+ /**
+ * Record a movement so that in the future, a prediction for the current gesture can be
+ * generated. Ensure to add all motions from the gesture of interest to generate the correct
+ * prediction.
+ * @param event The received event
+ */
+ public void record(@NonNull MotionEvent event) {
+ nativeRecord(mPtr, event);
+ }
+
+ /**
+ * Get predicted events for all gestures that have been provided to the 'record' function.
+ * If events from multiple devices were sent to 'record', this will produce a separate
+ * {@link MotionEvent} for each device id. The returned list may be empty if no predictions for
+ * any of the added events are available.
+ * Predictions may not reach the requested timestamp if the confidence in the prediction results
+ * is low.
+ *
+ * @param predictionTimeNanos The time that the prediction should target, in the
+ * {@link android.os.SystemClock#uptimeMillis} time base, but in nanoseconds.
+ *
+ * @return the list of predicted motion events, for each device id. Ensure to check the
+ * historical data in addition to the latest ({@link MotionEvent#getX getX()},
+ * {@link MotionEvent#getY getY()}) coordinates for smoothest prediction curves. Empty list is
+ * returned if predictions are not supported, or not possible for the current set of gestures.
+ */
+ @NonNull
+ public List<MotionEvent> predict(long predictionTimeNanos) {
+ return Arrays.asList(nativePredict(mPtr, predictionTimeNanos));
+ }
+
+ /**
+ * Check whether this device supports motion predictions for the given source type.
+ *
+ * @param deviceId The input device id
+ * @param source The source of input events
+ * @return True if the current device supports predictions, false otherwise.
+ */
+ public boolean isPredictionAvailable(int deviceId, int source) {
+ // Device-specific override
+ if (!mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_enableMotionPrediction)) {
+ return false;
+ }
+ return nativeIsPredictionAvailable(mPtr, deviceId, source);
+ }
+
+ private static native long nativeInitialize(int offsetNanos);
+ private static native void nativeRecord(long nativePtr, MotionEvent event);
+ private static native MotionEvent[] nativePredict(long nativePtr, long predictionTimeNanos);
+ private static native boolean nativeIsPredictionAvailable(long nativePtr, int deviceId,
+ int source);
+ private static native long nativeGetNativeMotionPredictorFinalizer();
+}
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index c9eee6a..3efbb75 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -292,7 +292,7 @@
public SurfaceControlViewHost(@NonNull Context c, @NonNull Display d,
@NonNull WindowlessWindowManager wwm) {
mWm = wwm;
- mViewRoot = new ViewRootImpl(c, d, mWm, new WindowlessWindowLayout());
+ mViewRoot = new ViewRootImpl(c, d, mWm);
addConfigCallback(c, d);
WindowManagerGlobal.getInstance().addWindowlessRoot(mViewRoot);
@@ -322,7 +322,7 @@
mWm = new WindowlessWindowManager(context.getResources().getConfiguration(),
mSurfaceControl, hostToken);
- mViewRoot = new ViewRootImpl(context, display, mWm, new WindowlessWindowLayout());
+ mViewRoot = new ViewRootImpl(context, display, mWm);
addConfigCallback(context, display);
WindowManagerGlobal.getInstance().addWindowlessRoot(mViewRoot);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 4f1f569..2114ce7 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -227,6 +227,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
+import java.util.OptionalInt;
import java.util.Queue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
@@ -920,14 +921,13 @@
private String mTag = TAG;
public ViewRootImpl(Context context, Display display) {
- this(context, display, WindowManagerGlobal.getWindowSession(), new WindowLayout());
+ this(context, display, WindowManagerGlobal.getWindowSession());
}
- public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session,
- WindowLayout windowLayout) {
+ public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session) {
mContext = context;
mWindowSession = session;
- mWindowLayout = windowLayout;
+ mWindowLayout = new WindowLayout();
mDisplay = display;
mBasePackageName = context.getBasePackageName();
mThread = Thread.currentThread();
@@ -1110,6 +1110,8 @@
// Update the last resource config in case the resource configuration was changed while
// activity relaunched.
updateLastConfigurationFromResources(getConfiguration());
+ // Make sure to report the completion of draw for relaunch with preserved window.
+ reportNextDraw("rebuilt");
}
private Configuration getConfiguration() {
@@ -1424,7 +1426,7 @@
!= AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
if (registered) {
final AccessibilityWindowAttributes attributes = new AccessibilityWindowAttributes(
- mWindowAttributes);
+ mWindowAttributes, mContext.getResources().getConfiguration().getLocales());
if (!attributes.equals(mAccessibilityWindowAttributes)) {
mAccessibilityWindowAttributes = attributes;
mAccessibilityManager.setAccessibilityWindowAttributes(getDisplayId(),
@@ -10866,6 +10868,12 @@
public View mSource;
public long mLastEventTimeMillis;
/**
+ * Keep track of action that caused the event.
+ * This is empty if there's no performing actions for pending events.
+ * This is zero if there're multiple events performed for pending events.
+ */
+ @NonNull public OptionalInt mAction = OptionalInt.empty();
+ /**
* Override for {@link AccessibilityEvent#originStackTrace} to provide the stack trace
* of the original {@link #runOrPost} call instead of one for sending the delayed event
* from a looper.
@@ -10888,6 +10896,7 @@
AccessibilityEvent event = AccessibilityEvent.obtain();
event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
event.setContentChangeTypes(mChangeTypes);
+ if (mAction.isPresent()) event.setAction(mAction.getAsInt());
if (AccessibilityEvent.DEBUG_ORIGIN) event.originStackTrace = mOrigin;
source.sendAccessibilityEventUnchecked(event);
} else {
@@ -10896,6 +10905,7 @@
// In any case reset to initial state.
source.resetSubtreeAccessibilityStateChanged();
mChangeTypes = 0;
+ mAction = OptionalInt.empty();
if (AccessibilityEvent.DEBUG_ORIGIN) mOrigin = null;
}
@@ -10925,10 +10935,27 @@
}
mSource = (predecessor != null) ? predecessor : source;
mChangeTypes |= changeType;
+
+ final int performingAction = mAccessibilityManager.getPerformingAction();
+ if (performingAction != 0) {
+ if (mAction.isEmpty()) {
+ mAction = OptionalInt.of(performingAction);
+ } else if (mAction.getAsInt() != performingAction) {
+ // Multiple actions are performed for pending events. We cannot decide one
+ // action here.
+ // We're doing best effort to set action value, and it's fine to set
+ // no action this case.
+ mAction = OptionalInt.of(0);
+ }
+ }
+
return;
}
mSource = source;
mChangeTypes = changeType;
+ if (mAccessibilityManager.getPerformingAction() != 0) {
+ mAction = OptionalInt.of(mAccessibilityManager.getPerformingAction());
+ }
if (AccessibilityEvent.DEBUG_ORIGIN) {
mOrigin = Thread.currentThread().getStackTrace();
}
diff --git a/core/java/android/view/WindowInfo.java b/core/java/android/view/WindowInfo.java
index 11d63c8..27dca0af 100644
--- a/core/java/android/view/WindowInfo.java
+++ b/core/java/android/view/WindowInfo.java
@@ -20,6 +20,7 @@
import android.graphics.Matrix;
import android.graphics.Region;
import android.os.IBinder;
+import android.os.LocaleList;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Pools;
@@ -60,6 +61,8 @@
public MagnificationSpec mMagnificationSpec = new MagnificationSpec();
+ public LocaleList locales = LocaleList.getEmptyLocaleList();
+
private WindowInfo() {
/* do nothing - hide constructor */
}
@@ -99,6 +102,7 @@
}
}
window.mMagnificationSpec.setTo(other.mMagnificationSpec);
+ window.locales = other.locales;
return window;
}
@@ -136,6 +140,7 @@
parcel.writeInt(0);
}
mMagnificationSpec.writeToParcel(parcel, flags);
+ parcel.writeParcelable(locales, flags);
}
@Override
@@ -160,6 +165,7 @@
matrix.setValues(mTransformMatrix);
builder.append(", mTransformMatrix=").append(matrix);
builder.append(", mMagnificationSpec=").append(mMagnificationSpec);
+ builder.append(", locales=").append(locales);
builder.append(']');
return builder.toString();
}
@@ -187,6 +193,7 @@
parcel.readBinderList(childTokens);
}
mMagnificationSpec = MagnificationSpec.CREATOR.createFromParcel(parcel);
+ locales = parcel.readParcelable(null, LocaleList.class);
}
private void clear() {
@@ -210,6 +217,7 @@
mMagnificationSpec.clear();
title = null;
accessibilityIdOfAnchor = AccessibilityNodeInfo.UNDEFINED_NODE_ID;
+ locales = LocaleList.getEmptyLocaleList();
}
public static final @android.annotation.NonNull Parcelable.Creator<WindowInfo> CREATOR =
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index d0f0d4a..35f1787 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -853,6 +853,143 @@
"android.window.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION";
/**
+ * Activity level {@link android.content.pm.PackageManager.Property PackageManager
+ * .Property} for an app to inform the system that the activity should be excluded from the
+ * camera compatibility force rotation treatment.
+ *
+ * <p>The camera compatibility treatment aligns orientations of portrait app window and natural
+ * orientation of the device and set opposite to natural orientation for a landscape app
+ * window. Mismatch between them can lead to camera issues like sideways or stretched
+ * viewfinder since this is one of the strongest assumptions that apps make when they implement
+ * camera previews. Since app and natural display orientations aren't guaranteed to match, the
+ * rotation can cause letterboxing. The forced rotation is triggered as soon as app opens to
+ * camera and is removed once camera is closed.
+ *
+ * <p>The camera compatibility can be enabled by device manufacturers on the displays that have
+ * ignoreOrientationRequest display setting enabled (enables compatibility mode for fixed
+ * orientation, see <a href="https://developer.android.com/guide/practices/enhanced-letterboxing">Enhanced letterboxing</a>
+ * for more details).
+ *
+ * <p>With this property set to {@code true} or unset, the system may apply the force rotation
+ * treatment to fixed orientation activities. Device manufacturers can exclude packages from the
+ * treatment using their discretion to improve display compatibility.
+ *
+ * <p>With this property set to {@code false}, the system will not apply the force rotation
+ * treatment.
+ *
+ * <p><b>Syntax:</b>
+ * <pre>
+ * <activity>
+ * <property
+ * android:name="android.window.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION"
+ * android:value="true|false"/>
+ * </activity>
+ * </pre>
+ *
+ * @hide
+ */
+ // TODO(b/263984287): Make this public API.
+ String PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION =
+ "android.window.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION";
+
+ /**
+ * Activity level {@link android.content.pm.PackageManager.Property PackageManager
+ * .Property} for an app to inform the system that the activity should be excluded
+ * from the activity "refresh" after the camera compatibility force rotation treatment.
+ *
+ * <p>The camera compatibility treatment aligns orientations of portrait app window and natural
+ * orientation of the device and set opposite to natural orientation for a landscape app
+ * window. Mismatch between them can lead to camera issues like sideways or stretched
+ * viewfinder since this is one of the strongest assumptions that apps make when they implement
+ * camera previews. Since app and natural display orientations aren't guaranteed to match, the
+ * rotation can cause letterboxing. The forced rotation is triggered as soon as app opens to
+ * camera and is removed once camera is closed.
+ *
+ * <p>Force rotation is followed by the "Refresh" of the activity by going through "resumed ->
+ * ... -> stopped -> ... -> resumed" cycle (by default) or "resumed -> paused -> resumed" cycle
+ * (if overridden, see {@link #PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE} for context).
+ * This allows to clear cached values in apps (e.g. display or camera rotation) that influence
+ * camera preview and can lead to sideways or stretching issues persisting even after force
+ * rotation.
+ *
+ * <p>The camera compatibility can be enabled by device manufacturers on the displays that have
+ * ignoreOrientationRequest display setting enabled (enables compatibility mode for fixed
+ * orientation, see <a href="https://developer.android.com/guide/practices/enhanced-letterboxing">Enhanced letterboxing</a>
+ * for more details).
+ *
+ * <p>With this property set to {@code true} or unset, the system may "refresh" activity after
+ * the force rotation treatment. Device manufacturers can exclude packages from the "refresh"
+ * using their discretion to improve display compatibility.
+ *
+ * <p>With this property set to {@code false}, the system will not "refresh" activity after the
+ * force rotation treatment.
+ *
+ * <p><b>Syntax:</b>
+ * <pre>
+ * <activity>
+ * <property
+ * android:name="android.window.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH"
+ * android:value="true|false"/>
+ * </activity>
+ * </pre>
+ *
+ * @hide
+ */
+ // TODO(b/263984287): Make this public API.
+ String PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH =
+ "android.window.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH";
+
+ /**
+ * Activity level {@link android.content.pm.PackageManager.Property PackageManager
+ * .Property} for an app to inform the system that the activity should be or shouldn't be
+ * "refreshed" after the camera compatibility force rotation treatment using "paused ->
+ * resumed" cycle rather than "stopped -> resumed".
+ *
+ * <p>The camera compatibility treatment aligns orientations of portrait app window and natural
+ * orientation of the device and set opposite to natural orientation for a landscape app
+ * window. Mismatch between them can lead to camera issues like sideways or stretched
+ * viewfinder since this is one of the strongest assumptions that apps make when they implement
+ * camera previews. Since app and natural display orientations aren't guaranteed to match, the
+ * rotation can cause letterboxing. The forced rotation is triggered as soon as app opens to
+ * camera and is removed once camera is closed.
+ *
+ * <p>Force rotation is followed by the "Refresh" of the activity by going through "resumed ->
+ * ... -> stopped -> ... -> resumed" cycle (by default) or "resumed -> paused -> resumed" cycle
+ * (if overridden by device manufacturers or using this property). This allows to clear cached
+ * values in apps (e.g., display or camera rotation) that influence camera preview and can lead
+ * to sideways or stretching issues persisting even after force rotation.
+ *
+ * <p>The camera compatibility can be enabled by device manufacturers on the displays that have
+ * ignoreOrientationRequest display setting enabled (enables compatibility mode for fixed
+ * orientation, see <a href="https://developer.android.com/guide/practices/enhanced-letterboxing">Enhanced letterboxing</a>
+ * for more details).
+ *
+ * <p>Device manufacturers can override packages to "refresh" via "resumed -> paused -> resumed"
+ * cycle using their discretion to improve display compatibility.
+ *
+ * <p>With this property set to {@code true}, the system will "refresh" activity after the
+ * force rotation treatment using "resumed -> paused -> resumed" cycle.
+ *
+ * <p>With this property set to {@code false}, the system will not "refresh" activity after the
+ * force rotation treatment using "resumed -> paused -> resumed" cycle even if the device
+ * manufacturer adds the corresponding override.
+ *
+ * <p><b>Syntax:</b>
+ * <pre>
+ * <activity>
+ * <property
+ * android:name="android.window.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE"
+ * android:value="true|false"/>
+ * </activity>
+ * </pre>
+ *
+ * @hide
+ */
+ // TODO(b/263984287): Make this public API.
+ String PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE =
+ "android.window.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE";
+
+ /**
* @hide
*/
public static final String PARCEL_KEY_SHORTCUTS_ARRAY = "shortcuts_array";
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 4a9dc5b..acc0c0b 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -388,8 +388,7 @@
if (windowlessSession == null) {
root = new ViewRootImpl(view.getContext(), display);
} else {
- root = new ViewRootImpl(view.getContext(), display,
- windowlessSession, new WindowlessWindowLayout());
+ root = new ViewRootImpl(view.getContext(), display, windowlessSession);
}
view.setLayoutParams(wparams);
diff --git a/core/java/android/view/WindowlessWindowLayout.java b/core/java/android/view/WindowlessWindowLayout.java
deleted file mode 100644
index 6fb01f2..0000000
--- a/core/java/android/view/WindowlessWindowLayout.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2022 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.view;
-
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-
-import android.app.WindowConfiguration.WindowingMode;
-import android.graphics.Rect;
-import android.view.WindowInsets.Type.InsetsType;
-import android.window.ClientWindowFrames;
-
-// TODO(b/262891212) use the real WindowLayout and remove WindowlessWindowLayout
-
-/**
- * Computes window frames for the windowless window.
- *
- * @hide
- */
-public class WindowlessWindowLayout extends WindowLayout {
-
- @Override
- public void computeFrames(WindowManager.LayoutParams attrs, InsetsState state,
- Rect displayCutoutSafe, Rect windowBounds, @WindowingMode int windowingMode,
- int requestedWidth, int requestedHeight, @InsetsType int requestedVisibleTypes,
- float compatScale, ClientWindowFrames frames) {
- if (frames.attachedFrame == null) {
- frames.frame.set(0, 0, attrs.width, attrs.height);
- frames.parentFrame.set(frames.frame);
- frames.displayFrame.set(frames.frame);
- return;
- }
-
- final int height = calculateLength(attrs.height, requestedHeight,
- frames.attachedFrame.height());
- final int width = calculateLength(attrs.width, requestedWidth,
- frames.attachedFrame.width());
- Gravity.apply(attrs.gravity, width, height, frames.attachedFrame,
- (int) (attrs.x + attrs.horizontalMargin),
- (int) (attrs.y + attrs.verticalMargin),
- frames.frame);
- frames.displayFrame.set(frames.frame);
- frames.parentFrame.set(frames.attachedFrame);
- }
-
- private static int calculateLength(int attrLength, int requestedLength, int parentLength) {
- if (attrLength == MATCH_PARENT) {
- return parentLength;
- }
- if (attrLength == WRAP_CONTENT) {
- return requestedLength;
- }
- return attrLength;
- }
-}
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 021193e..4ddd485 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -94,7 +94,10 @@
private InsetsState mInsetsState;
private final ClientWindowFrames mTmpFrames = new ClientWindowFrames();
private final MergedConfiguration mTmpConfig = new MergedConfiguration();
- private final WindowlessWindowLayout mLayout = new WindowlessWindowLayout();
+ private final InsetsState mTmpInsetsState = new InsetsState();
+ private final Rect mTmpDisplayCutoutSafe = new Rect();
+ private final Rect mTmpWindowBounds = new Rect();
+ private final WindowLayout mLayout = new WindowLayout();
public WindowlessWindowManager(Configuration c, SurfaceControl rootSurface,
IBinder hostInputToken) {
@@ -346,22 +349,27 @@
}
WindowManager.LayoutParams attrs = state.mParams;
- ClientWindowFrames frames = new ClientWindowFrames();
- frames.attachedFrame = state.mAttachedFrame;
+ mTmpFrames.attachedFrame = state.mAttachedFrame;
- mLayout.computeFrames(attrs, null, null, null, WindowConfiguration.WINDOWING_MODE_UNDEFINED,
- requestedWidth, requestedHeight, 0, 0,
- frames);
-
- state.mFrame.set(frames.frame);
- if (outFrames != null) {
- outFrames.frame.set(frames.frame);
- outFrames.parentFrame.set(frames.parentFrame);
- outFrames.displayFrame.set(frames.displayFrame);
+ if (state.mAttachedFrame == null) {
+ mTmpWindowBounds.set(0, 0, requestedWidth, requestedHeight);
+ } else {
+ mTmpWindowBounds.set(state.mAttachedFrame);
}
- t.setPosition(leash, frames.frame.left, frames.frame.top);
- t.setWindowCrop(leash, frames.frame.width(), frames.frame.height());
+ mLayout.computeFrames(attrs, mTmpInsetsState, mTmpDisplayCutoutSafe, mTmpWindowBounds,
+ WindowConfiguration.WINDOWING_MODE_UNDEFINED, requestedWidth, requestedHeight, 0,
+ 1f, mTmpFrames);
+
+ state.mFrame.set(mTmpFrames.frame);
+ if (outFrames != null) {
+ outFrames.frame.set(mTmpFrames.frame);
+ outFrames.parentFrame.set(mTmpFrames.parentFrame);
+ outFrames.displayFrame.set(mTmpFrames.displayFrame);
+ }
+
+ t.setPosition(leash, mTmpFrames.frame.left, mTmpFrames.frame.top);
+ t.setWindowCrop(leash, mTmpFrames.frame.width(), mTmpFrames.frame.height());
if (viewFlags == View.VISIBLE) {
// TODO(b/262892794) ViewRootImpl modifies the app's rendering SurfaceControl
diff --git a/core/java/android/view/accessibility/AccessibilityDisplayProxy.java b/core/java/android/view/accessibility/AccessibilityDisplayProxy.java
index a757236..dd320e1 100644
--- a/core/java/android/view/accessibility/AccessibilityDisplayProxy.java
+++ b/core/java/android/view/accessibility/AccessibilityDisplayProxy.java
@@ -83,7 +83,7 @@
* @param displayId the id of the display to proxy.
* @param executor the executor used to execute proxy callbacks.
* @param installedAndEnabledServices the list of infos representing the installed and
- * enabled a11y services.
+ * enabled accessibility services.
*/
public AccessibilityDisplayProxy(int displayId, @NonNull Executor executor,
@NonNull List<AccessibilityServiceInfo> installedAndEnabledServices) {
@@ -147,19 +147,27 @@
}
/**
- * Gets the focus of the window specified by {@code windowInfo}.
+ * Gets the node with focus, in this display.
*
- * @param windowInfo the window to search
- * @param focus The focus to find. One of {@link AccessibilityNodeInfo#FOCUS_INPUT} or
+ * <p>For {@link AccessibilityNodeInfo#FOCUS_INPUT}, this returns the input-focused node in the
+ * proxy display if this display can receive unspecified input events (input that does not
+ * specify a target display.)
+ *
+ * <p>For {@link AccessibilityNodeInfo#FOCUS_ACCESSIBILITY}, this returns the
+ * accessibility-focused node in the proxy display if the display has accessibility focus.
+ * @param focusType The focus to find. One of {@link AccessibilityNodeInfo#FOCUS_INPUT} or
* {@link AccessibilityNodeInfo#FOCUS_ACCESSIBILITY}.
* @return The node info of the focused view or null.
- * @hide
- * TODO(254545943): Do not expose until support for accessibility focus and/or input is in place
+
*/
@Nullable
- public AccessibilityNodeInfo findFocus(@NonNull AccessibilityWindowInfo windowInfo, int focus) {
- AccessibilityNodeInfo windowRoot = windowInfo.getRoot();
- return windowRoot != null ? windowRoot.findFocus(focus) : null;
+ public AccessibilityNodeInfo findFocus(int focusType) {
+ // TODO(264423198): Support querying the focused node of the proxy's display even if it is
+ // not the top-focused display and can't receive untargeted input events.
+ // TODO(254545943): Separate accessibility focus between proxy and phone state.
+ return AccessibilityInteractionClient.getInstance().findFocus(mConnectionId,
+ AccessibilityWindowInfo.ANY_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID,
+ focusType);
}
/**
@@ -177,10 +185,10 @@
* Sets the list of {@link AccessibilityServiceInfo}s describing the services interested in the
* {@link AccessibilityDisplayProxy}'s display.
*
- * <p>These represent a11y features and services that are installed and running. These should
- * not include {@link AccessibilityService}s installed on the phone.
+ * <p>These represent accessibility features and services that are installed and running. These
+ * should not include {@link AccessibilityService}s installed on the phone.
*
- * @param installedAndEnabledServices the list of installed and running a11y services.
+ * @param installedAndEnabledServices the list of installed and running accessibility services.
*/
public void setInstalledAndEnabledServices(
@NonNull List<AccessibilityServiceInfo> installedAndEnabledServices) {
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index 52eda0a..83a6c5a 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -921,8 +921,6 @@
*
* @param connectionId The id of a connection for interacting with the system.
* @param accessibilityWindowId A unique window id. Use
- * {@link AccessibilityWindowInfo#ACTIVE_WINDOW_ID}
- * to query the currently active window. Use
* {@link AccessibilityWindowInfo#ANY_WINDOW_ID} to query all
* windows
* @param accessibilityNodeId A unique view id or virtual descendant id from
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 9abbba9..8e335e8 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -1275,6 +1275,15 @@
}
/**
+ * Get the id of {@link AccessibilityNodeInfo.AccessibilityAction} currently being performed.
+ *
+ * @hide
+ */
+ public int getPerformingAction() {
+ return mPerformingAction;
+ }
+
+ /**
* Registers a {@link HighTextContrastChangeListener} for changes in
* the global high text contrast state of the system.
*
diff --git a/core/java/android/view/accessibility/AccessibilityWindowAttributes.java b/core/java/android/view/accessibility/AccessibilityWindowAttributes.java
index 562300c..92ed73b 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowAttributes.java
+++ b/core/java/android/view/accessibility/AccessibilityWindowAttributes.java
@@ -17,11 +17,14 @@
package android.view.accessibility;
import android.annotation.NonNull;
+import android.os.LocaleList;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.view.WindowManager;
+import java.util.Objects;
+
/**
* This class represents the attributes of a window needed for {@link AccessibilityWindowInfo}.
*
@@ -30,13 +33,22 @@
public final class AccessibilityWindowAttributes implements Parcelable {
private final CharSequence mWindowTitle;
+ private final LocaleList mLocales;
- public AccessibilityWindowAttributes(@NonNull WindowManager.LayoutParams layoutParams) {
+ public AccessibilityWindowAttributes(@NonNull WindowManager.LayoutParams layoutParams,
+ @NonNull LocaleList locales) {
mWindowTitle = populateWindowTitle(layoutParams);
+ mLocales = locales;
}
private AccessibilityWindowAttributes(Parcel in) {
mWindowTitle = in.readCharSequence();
+ LocaleList inLocales = in.readParcelable(null, LocaleList.class);
+ if (inLocales != null) {
+ mLocales = inLocales;
+ } else {
+ mLocales = LocaleList.getEmptyLocaleList();
+ }
}
public CharSequence getWindowTitle() {
@@ -63,6 +75,10 @@
return windowTitle;
}
+ public @NonNull LocaleList getLocales() {
+ return mLocales;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -70,12 +86,13 @@
AccessibilityWindowAttributes that = (AccessibilityWindowAttributes) o;
- return TextUtils.equals(mWindowTitle, that.mWindowTitle);
+ return TextUtils.equals(mWindowTitle, that.mWindowTitle) && Objects.equals(
+ mLocales, that.mLocales);
}
@Override
public int hashCode() {
- return mWindowTitle.hashCode();
+ return Objects.hash(mWindowTitle, mLocales);
}
public static final Creator<AccessibilityWindowAttributes> CREATOR =
@@ -99,12 +116,14 @@
@Override
public void writeToParcel(@NonNull Parcel parcel, int flags) {
parcel.writeCharSequence(mWindowTitle);
+ parcel.writeParcelable(mLocales, flags);
}
@Override
public String toString() {
return "AccessibilityWindowAttributes{"
+ "mAccessibilityWindowTitle=" + mWindowTitle
+ + "mLocales=" + mLocales
+ '}';
}
}
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
index 9be9990..d84e0fb 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
@@ -23,6 +23,7 @@
import android.app.ActivityTaskManager;
import android.graphics.Rect;
import android.graphics.Region;
+import android.os.LocaleList;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
@@ -132,6 +133,8 @@
private int mConnectionId = UNDEFINED_CONNECTION_ID;
+ private LocaleList mLocales = LocaleList.getEmptyLocaleList();
+
/**
* Creates a new {@link AccessibilityWindowInfo}.
*/
@@ -555,6 +558,26 @@
}
/**
+ * Sets the locales of the window. Locales are populated by the view root by default.
+ *
+ * @param locales The {@link android.os.LocaleList}.
+ *
+ * @hide
+ */
+ public void setLocales(@NonNull LocaleList locales) {
+ mLocales = locales;
+ }
+
+ /**
+ * Return the {@link android.os.LocaleList} of the window.
+ *
+ * @return the locales of the window.
+ */
+ public @NonNull LocaleList getLocales() {
+ return mLocales;
+ }
+
+ /**
* Returns a cached instance if such is available or a new one is
* created.
*
@@ -676,6 +699,7 @@
}
parcel.writeInt(mConnectionId);
+ parcel.writeParcelable(mLocales, flags);
}
/**
@@ -706,6 +730,7 @@
}
mConnectionId = other.mConnectionId;
+ mLocales = other.mLocales;
}
private void initFromParcel(Parcel parcel) {
@@ -733,6 +758,7 @@
}
mConnectionId = parcel.readInt();
+ mLocales = parcel.readParcelable(null, LocaleList.class);
}
@Override
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index d067d4b..497f066 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -66,8 +66,7 @@
import java.util.function.Consumer;
/**
- * <p>The {@link ContentCaptureManager} provides additional ways for for apps to
- * integrate with the content capture subsystem.
+ * <p>Provides additional ways for apps to integrate with the content capture subsystem.
*
* <p>Content capture provides real-time, continuous capture of application activity, display and
* events to an intelligence service that is provided by the Android system. The intelligence
diff --git a/core/java/android/view/inputmethod/HandwritingGesture.java b/core/java/android/view/inputmethod/HandwritingGesture.java
index 2516269..e0fc426 100644
--- a/core/java/android/view/inputmethod/HandwritingGesture.java
+++ b/core/java/android/view/inputmethod/HandwritingGesture.java
@@ -82,38 +82,60 @@
@IntDef({GRANULARITY_CHARACTER, GRANULARITY_WORD})
@interface Granularity {}
- /** Undefined gesture type. */
+ /**
+ * Undefined gesture type.
+ * @hide
+ */
+ @TestApi
public static final int GESTURE_TYPE_NONE = 0x0000;
/**
* Gesture of type {@link SelectGesture} to select an area of text.
+ * @hide
*/
+ @TestApi
public static final int GESTURE_TYPE_SELECT = 0x0001;
/**
* Gesture of type {@link InsertGesture} to insert text at a designated point.
+ * @hide
*/
+ @TestApi
public static final int GESTURE_TYPE_INSERT = 1 << 1;
/**
* Gesture of type {@link DeleteGesture} to delete an area of text.
+ * @hide
*/
+ @TestApi
public static final int GESTURE_TYPE_DELETE = 1 << 2;
- /** Gesture of type {@link RemoveSpaceGesture} to remove whitespace from text. */
+ /**
+ * Gesture of type {@link RemoveSpaceGesture} to remove whitespace from text.
+ * @hide
+ */
+ @TestApi
public static final int GESTURE_TYPE_REMOVE_SPACE = 1 << 3;
- /** Gesture of type {@link JoinOrSplitGesture} to join or split text. */
+ /**
+ * Gesture of type {@link JoinOrSplitGesture} to join or split text.
+ * @hide
+ */
+ @TestApi
public static final int GESTURE_TYPE_JOIN_OR_SPLIT = 1 << 4;
/**
* Gesture of type {@link SelectRangeGesture} to select range of text.
+ * @hide
*/
+ @TestApi
public static final int GESTURE_TYPE_SELECT_RANGE = 1 << 5;
/**
* Gesture of type {@link DeleteRangeGesture} to delete range of text.
+ * @hide
*/
+ @TestApi
public static final int GESTURE_TYPE_DELETE_RANGE = 1 << 6;
/**
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index 9b519c3..6872536 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -1262,13 +1262,13 @@
/**
* Called by input method to request the {@link TextBoundsInfo} for a range of text which is
- * covered by or in vicinity of the given {@code RectF}. It can be used as a supplementary
+ * covered by or in vicinity of the given {@code bounds}. It can be used as a supplementary
* method to implement the handwriting gesture API -
* {@link #performHandwritingGesture(HandwritingGesture, Executor, IntConsumer)}.
*
* <p><strong>Editor authors</strong>: It's preferred that the editor returns a
* {@link TextBoundsInfo} of all the text lines whose bounds intersect with the given
- * {@code rectF}.
+ * {@code bounds}.
* </p>
*
* <p><strong>IME authors</strong>: This method is expensive when the text is long. Please
@@ -1276,7 +1276,7 @@
* consuming. It's preferable to only request text bounds in smaller areas.
* </p>
*
- * @param rectF the interested area where the text bounds are requested, in the screen
+ * @param bounds the interested area where the text bounds are requested, in the screen
* coordinates.
* @param executor the executor to run the callback.
* @param consumer the callback invoked by editor to return the result. It must return a
@@ -1286,7 +1286,7 @@
* @see android.view.inputmethod.TextBoundsInfoResult
*/
default void requestTextBoundsInfo(
- @NonNull RectF rectF, @NonNull @CallbackExecutor Executor executor,
+ @NonNull RectF bounds, @NonNull @CallbackExecutor Executor executor,
@NonNull Consumer<TextBoundsInfoResult> consumer) {
Objects.requireNonNull(executor);
Objects.requireNonNull(consumer);
diff --git a/core/java/android/view/inputmethod/InputConnectionWrapper.java b/core/java/android/view/inputmethod/InputConnectionWrapper.java
index 4befd6f..5e323fa 100644
--- a/core/java/android/view/inputmethod/InputConnectionWrapper.java
+++ b/core/java/android/view/inputmethod/InputConnectionWrapper.java
@@ -362,9 +362,9 @@
*/
@Override
public void requestTextBoundsInfo(
- @NonNull RectF rectF, @NonNull @CallbackExecutor Executor executor,
+ @NonNull RectF bounds, @NonNull @CallbackExecutor Executor executor,
@NonNull Consumer<TextBoundsInfoResult> consumer) {
- mTarget.requestTextBoundsInfo(rectF, executor, consumer);
+ mTarget.requestTextBoundsInfo(bounds, executor, consumer);
}
/**
diff --git a/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java b/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java
index 7525d72..6f8b422 100644
--- a/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java
+++ b/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java
@@ -1106,7 +1106,7 @@
@Dispatching(cancellable = true)
@Override
public void requestTextBoundsInfo(
- InputConnectionCommandHeader header, RectF rectF,
+ InputConnectionCommandHeader header, RectF bounds,
@NonNull ResultReceiver resultReceiver) {
dispatchWithTracing("requestTextBoundsInfo", () -> {
if (header.mSessionId != mCurrentSessionId.get()) {
@@ -1121,7 +1121,7 @@
}
ic.requestTextBoundsInfo(
- rectF,
+ bounds,
Runnable::run,
(textBoundsInfoResult) -> {
final int resultCode = textBoundsInfoResult.getResultCode();
diff --git a/core/java/android/view/inputmethod/TextBoundsInfo.java b/core/java/android/view/inputmethod/TextBoundsInfo.java
index dd05543..d42d94e 100644
--- a/core/java/android/view/inputmethod/TextBoundsInfo.java
+++ b/core/java/android/view/inputmethod/TextBoundsInfo.java
@@ -43,8 +43,8 @@
* The text bounds information of a slice of text in the editor.
*
* <p> This class provides IME the layout information of the text within the range from
- * {@link #getStart()} to {@link #getEnd()}. It's intended to be used by IME as a supplementary API
- * to support handwriting gestures.
+ * {@link #getStartIndex()} to {@link #getEndIndex()}. It's intended to be used by IME as a
+ * supplementary API to support handwriting gestures.
* </p>
*/
public final class TextBoundsInfo implements Parcelable {
@@ -168,16 +168,13 @@
private final SegmentFinder mGraphemeSegmentFinder;
/**
- * Returns a new instance of {@link android.graphics.Matrix} that indicates the transformation
+ * Set the given {@link android.graphics.Matrix} to be the transformation
* matrix that is to be applied other positional data in this class.
- *
- * @return a new instance (copy) of the transformation matrix.
*/
@NonNull
- public Matrix getMatrix() {
- final Matrix matrix = new Matrix();
+ public void getMatrix(@NonNull Matrix matrix) {
+ Objects.requireNonNull(matrix);
matrix.setValues(mMatrixValues);
- return matrix;
}
/**
@@ -186,7 +183,7 @@
*
* @see Builder#setStartAndEnd(int, int)
*/
- public int getStart() {
+ public int getStartIndex() {
return mStart;
}
@@ -196,28 +193,28 @@
*
* @see Builder#setStartAndEnd(int, int)
*/
- public int getEnd() {
+ public int getEndIndex() {
return mEnd;
}
/**
- * Return the bounds of the character at the given {@code index}, in the coordinates of the
- * editor.
+ * Set the bounds of the character at the given {@code index} to the given {@link RectF}, in
+ * the coordinates of the editor.
*
* @param index the index of the queried character.
- * @return the bounding box of the queried character.
+ * @param bounds the {@link RectF} used to receive the result.
*
* @throws IndexOutOfBoundsException if the given {@code index} is out of the range from
* the {@code start} to the {@code end}.
*/
@NonNull
- public RectF getCharacterBounds(int index) {
+ public void getCharacterBounds(int index, @NonNull RectF bounds) {
if (index < mStart || index >= mEnd) {
throw new IndexOutOfBoundsException("Index is out of the bounds of "
+ "[" + mStart + ", " + mEnd + ").");
}
final int offset = 4 * (index - mStart);
- return new RectF(mCharacterBounds[offset], mCharacterBounds[offset + 1],
+ bounds.set(mCharacterBounds[offset], mCharacterBounds[offset + 1],
mCharacterBounds[offset + 2], mCharacterBounds[offset + 3]);
}
@@ -333,6 +330,16 @@
* won't check the text in the ranges of [5, 7) and [12, 15).
* </p>
*
+ * <p> Under the following conditions, this method will return -1 indicating that no valid
+ * character is found:
+ * <ul>
+ * <li> The given {@code y} coordinate is above the first line or below the last line (the
+ * first line or the last line is identified by the {@link SegmentFinder} returned from
+ * {@link #getLineSegmentFinder()}). </li>
+ * <li> There is no character in this {@link TextBoundsInfo}. </li>
+ * </ul>
+ * </p>
+ *
* @param x the x coordinates of the interested location, in the editor's coordinates.
* @param y the y coordinates of the interested location, in the editor's coordinates.
* @return the index of the character whose position is closest to the given location. It will
@@ -990,8 +997,8 @@
public static final class Builder {
private final float[] mMatrixValues = new float[9];
private boolean mMatrixInitialized;
- private int mStart;
- private int mEnd;
+ private int mStart = -1;
+ private int mEnd = -1;
private float[] mCharacterBounds;
private int[] mCharacterFlags;
private int[] mCharacterBidiLevels;
@@ -999,6 +1006,17 @@
private SegmentFinder mWordSegmentFinder;
private SegmentFinder mGraphemeSegmentFinder;
+ /**
+ * Create a builder for {@link TextBoundsInfo}.
+ * @param start the start index of the {@link TextBoundsInfo}, inclusive.
+ * @param end the end index of the {@link TextBoundsInfo}, exclusive.
+ * @throws IllegalArgumentException if the given {@code start} or {@code end} is negative,
+ * or {@code end} is smaller than the {@code start}.
+ */
+ public Builder(int start, int end) {
+ setStartAndEnd(start, end);
+ }
+
/** Clear all the parameters set on this {@link Builder} to reuse it. */
@NonNull
public Builder clear() {
@@ -1152,7 +1170,7 @@
*
* @see #getGraphemeSegmentFinder()
* @see SegmentFinder
- * @see SegmentFinder.DefaultSegmentFinder
+ * @see SegmentFinder.PrescribedSegmentFinder
*/
@NonNull
public Builder setGraphemeSegmentFinder(@NonNull SegmentFinder graphemeSegmentFinder) {
@@ -1171,7 +1189,7 @@
*
* @see #getWordSegmentFinder()
* @see SegmentFinder
- * @see SegmentFinder.DefaultSegmentFinder
+ * @see SegmentFinder.PrescribedSegmentFinder
*/
@NonNull
public Builder setWordSegmentFinder(@NonNull SegmentFinder wordSegmentFinder) {
@@ -1193,7 +1211,7 @@
*
* @see #getLineSegmentFinder()
* @see SegmentFinder
- * @see SegmentFinder.DefaultSegmentFinder
+ * @see SegmentFinder.PrescribedSegmentFinder
*/
@NonNull
public Builder setLineSegmentFinder(@NonNull SegmentFinder lineSegmentFinder) {
@@ -1360,7 +1378,7 @@
breaks = GrowingArrayUtils.append(breaks, count++, start + offset);
}
}
- return new SegmentFinder.DefaultSegmentFinder(Arrays.copyOf(breaks, count));
+ return new SegmentFinder.PrescribedSegmentFinder(Arrays.copyOf(breaks, count));
}
/**
diff --git a/core/java/android/webkit/TEST_MAPPING b/core/java/android/webkit/TEST_MAPPING
index bd25200..c1bc6d7 100644
--- a/core/java/android/webkit/TEST_MAPPING
+++ b/core/java/android/webkit/TEST_MAPPING
@@ -9,6 +9,14 @@
]
},
{
+ "name": "CtsSdkSandboxWebkitTestCases",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ },
+ {
"name": "CtsHostsideWebViewTests",
"options": [
{
diff --git a/core/java/android/webkit/WebResourceError.java b/core/java/android/webkit/WebResourceError.java
index 11f1b6f1..4c87489 100644
--- a/core/java/android/webkit/WebResourceError.java
+++ b/core/java/android/webkit/WebResourceError.java
@@ -19,7 +19,7 @@
import android.annotation.SystemApi;
/**
- * Encapsulates information about errors occured during loading of web resources. See
+ * Encapsulates information about errors that occurred during loading of web resources. See
* {@link WebViewClient#onReceivedError(WebView, WebResourceRequest, WebResourceError) WebViewClient.onReceivedError(WebView, WebResourceRequest, WebResourceError)}
*/
public abstract class WebResourceError {
diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java
index ff2e175..2bd5c88 100644
--- a/core/java/android/widget/MediaController.java
+++ b/core/java/android/widget/MediaController.java
@@ -218,6 +218,7 @@
p.width = mAnchor.getWidth();
p.x = anchorPos[0] + (mAnchor.getWidth() - p.width) / 2;
p.y = anchorPos[1] + mAnchor.getHeight() - mDecor.getMeasuredHeight();
+ p.token = mAnchor.getWindowToken();
}
// This is called whenever mAnchor's layout bound changes
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index b9b928e..4005bc8 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -13245,7 +13245,7 @@
* Creates the {@link TextBoundsInfo} for the text lines that intersects with the {@code rectF}.
* @hide
*/
- public TextBoundsInfo getTextBoundsInfo(@NonNull RectF rectF) {
+ public TextBoundsInfo getTextBoundsInfo(@NonNull RectF bounds) {
final Layout layout = getLayout();
if (layout == null) {
// No valid text layout, return null.
@@ -13268,19 +13268,18 @@
final float layoutLeft = viewportToContentHorizontalOffset();
final float layoutTop = viewportToContentVerticalOffset();
- final RectF localRectF = new RectF(rectF);
- globalToLocalMatrix.mapRect(localRectF);
- localRectF.offset(-layoutLeft, -layoutTop);
+ final RectF localBounds = new RectF(bounds);
+ globalToLocalMatrix.mapRect(localBounds);
+ localBounds.offset(-layoutLeft, -layoutTop);
// Text length is 0. There is no character bounds, return empty TextBoundsInfo.
// rectF doesn't intersect with the layout, return empty TextBoundsInfo.
- if (!localRectF.intersects(0f, 0f, layout.getWidth(), layout.getHeight())
+ if (!localBounds.intersects(0f, 0f, layout.getWidth(), layout.getHeight())
|| text.length() == 0) {
- final TextBoundsInfo.Builder builder = new TextBoundsInfo.Builder();
+ final TextBoundsInfo.Builder builder = new TextBoundsInfo.Builder(0, 0);
final SegmentFinder emptySegmentFinder =
- new SegmentFinder.DefaultSegmentFinder(new int[0]);
- builder.setStartAndEnd(0, 0)
- .setMatrix(localToGlobalMatrix)
+ new SegmentFinder.PrescribedSegmentFinder(new int[0]);
+ builder.setMatrix(localToGlobalMatrix)
.setCharacterBounds(new float[0])
.setCharacterBidiLevel(new int[0])
.setCharacterFlags(new int[0])
@@ -13290,8 +13289,8 @@
return builder.build();
}
- final int startLine = layout.getLineForVertical((int) Math.floor(localRectF.top));
- final int endLine = layout.getLineForVertical((int) Math.floor(localRectF.bottom));
+ final int startLine = layout.getLineForVertical((int) Math.floor(localBounds.top));
+ final int endLine = layout.getLineForVertical((int) Math.floor(localBounds.bottom));
final int start = layout.getLineStart(startLine);
final int end = layout.getLineEnd(endLine);
@@ -13349,18 +13348,18 @@
lineRanges[2 * offset] = layout.getLineStart(line);
lineRanges[2 * offset + 1] = layout.getLineEnd(line);
}
- final SegmentFinder lineSegmentFinder = new SegmentFinder.DefaultSegmentFinder(lineRanges);
+ final SegmentFinder lineSegmentFinder =
+ new SegmentFinder.PrescribedSegmentFinder(lineRanges);
- final TextBoundsInfo.Builder builder = new TextBoundsInfo.Builder();
- builder.setStartAndEnd(start, end)
+ return new TextBoundsInfo.Builder(start, end)
.setMatrix(localToGlobalMatrix)
.setCharacterBounds(characterBounds)
.setCharacterBidiLevel(characterBidiLevels)
.setCharacterFlags(characterFlags)
.setGraphemeSegmentFinder(graphemeSegmentFinder)
.setLineSegmentFinder(lineSegmentFinder)
- .setWordSegmentFinder(wordSegmentFinder);
- return builder.build();
+ .setWordSegmentFinder(wordSegmentFinder)
+ .build();
}
/**
diff --git a/core/java/android/window/ITaskOrganizerController.aidl b/core/java/android/window/ITaskOrganizerController.aidl
index e6bb1f6..0032b9c 100644
--- a/core/java/android/window/ITaskOrganizerController.aidl
+++ b/core/java/android/window/ITaskOrganizerController.aidl
@@ -40,7 +40,8 @@
void unregisterTaskOrganizer(ITaskOrganizer organizer);
/** Creates a persistent root task in WM for a particular windowing-mode. */
- void createRootTask(int displayId, int windowingMode, IBinder launchCookie);
+ void createRootTask(int displayId, int windowingMode, IBinder launchCookie,
+ boolean removeWithTaskOrganizer);
/** Deletes a persistent root task in WM */
boolean deleteRootTask(in WindowContainerToken task);
diff --git a/core/java/android/window/TaskFragmentAnimationParams.aidl b/core/java/android/window/TaskFragmentAnimationParams.aidl
index 04dee58..8ae84c2 100644
--- a/core/java/android/window/TaskFragmentAnimationParams.aidl
+++ b/core/java/android/window/TaskFragmentAnimationParams.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 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.
diff --git a/core/java/android/window/TaskFragmentAnimationParams.java b/core/java/android/window/TaskFragmentAnimationParams.java
index a600a4d..12ad914 100644
--- a/core/java/android/window/TaskFragmentAnimationParams.java
+++ b/core/java/android/window/TaskFragmentAnimationParams.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 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.
diff --git a/core/java/android/window/TaskFragmentCreationParams.java b/core/java/android/window/TaskFragmentCreationParams.java
index c9ddf92..203d79a 100644
--- a/core/java/android/window/TaskFragmentCreationParams.java
+++ b/core/java/android/window/TaskFragmentCreationParams.java
@@ -71,20 +71,42 @@
*
* This is needed in case we need to launch a placeholder Activity to split below a transparent
* always-expand Activity.
+ *
+ * This should not be used with {@link #mPairedActivityToken}.
*/
@Nullable
private final IBinder mPairedPrimaryFragmentToken;
+ /**
+ * The Activity token to place the new TaskFragment on top of.
+ * When it is set, the new TaskFragment will be positioned right above the target Activity.
+ * Otherwise, the new TaskFragment will be positioned on the top of the Task by default.
+ *
+ * This is needed in case we need to place an Activity into TaskFragment to launch placeholder
+ * below a transparent always-expand Activity, or when there is another Intent being started in
+ * a TaskFragment above.
+ *
+ * This should not be used with {@link #mPairedPrimaryFragmentToken}.
+ */
+ @Nullable
+ private final IBinder mPairedActivityToken;
+
private TaskFragmentCreationParams(
@NonNull TaskFragmentOrganizerToken organizer, @NonNull IBinder fragmentToken,
@NonNull IBinder ownerToken, @NonNull Rect initialBounds,
- @WindowingMode int windowingMode, @Nullable IBinder pairedPrimaryFragmentToken) {
+ @WindowingMode int windowingMode, @Nullable IBinder pairedPrimaryFragmentToken,
+ @Nullable IBinder pairedActivityToken) {
+ if (pairedPrimaryFragmentToken != null && pairedActivityToken != null) {
+ throw new IllegalArgumentException("pairedPrimaryFragmentToken and"
+ + " pairedActivityToken should not be set at the same time.");
+ }
mOrganizer = organizer;
mFragmentToken = fragmentToken;
mOwnerToken = ownerToken;
mInitialBounds.set(initialBounds);
mWindowingMode = windowingMode;
mPairedPrimaryFragmentToken = pairedPrimaryFragmentToken;
+ mPairedActivityToken = pairedActivityToken;
}
@NonNull
@@ -121,6 +143,15 @@
return mPairedPrimaryFragmentToken;
}
+ /**
+ * TODO(b/232476698): remove the hide with adding CTS for this in next release.
+ * @hide
+ */
+ @Nullable
+ public IBinder getPairedActivityToken() {
+ return mPairedActivityToken;
+ }
+
private TaskFragmentCreationParams(Parcel in) {
mOrganizer = TaskFragmentOrganizerToken.CREATOR.createFromParcel(in);
mFragmentToken = in.readStrongBinder();
@@ -128,6 +159,7 @@
mInitialBounds.readFromParcel(in);
mWindowingMode = in.readInt();
mPairedPrimaryFragmentToken = in.readStrongBinder();
+ mPairedActivityToken = in.readStrongBinder();
}
/** @hide */
@@ -139,6 +171,7 @@
mInitialBounds.writeToParcel(dest, flags);
dest.writeInt(mWindowingMode);
dest.writeStrongBinder(mPairedPrimaryFragmentToken);
+ dest.writeStrongBinder(mPairedActivityToken);
}
@NonNull
@@ -164,6 +197,7 @@
+ " initialBounds=" + mInitialBounds
+ " windowingMode=" + mWindowingMode
+ " pairedFragmentToken=" + mPairedPrimaryFragmentToken
+ + " pairedActivityToken=" + mPairedActivityToken
+ "}";
}
@@ -194,6 +228,9 @@
@Nullable
private IBinder mPairedPrimaryFragmentToken;
+ @Nullable
+ private IBinder mPairedActivityToken;
+
public Builder(@NonNull TaskFragmentOrganizerToken organizer,
@NonNull IBinder fragmentToken, @NonNull IBinder ownerToken) {
mOrganizer = organizer;
@@ -224,6 +261,8 @@
* This is needed in case we need to launch a placeholder Activity to split below a
* transparent always-expand Activity.
*
+ * This should not be used with {@link #setPairedActivityToken}.
+ *
* TODO(b/232476698): remove the hide with adding CTS for this in next release.
* @hide
*/
@@ -233,11 +272,32 @@
return this;
}
+ /**
+ * Sets the Activity token to place the new TaskFragment on top of.
+ * When it is set, the new TaskFragment will be positioned right above the target Activity.
+ * Otherwise, the new TaskFragment will be positioned on the top of the Task by default.
+ *
+ * This is needed in case we need to place an Activity into TaskFragment to launch
+ * placeholder below a transparent always-expand Activity, or when there is another Intent
+ * being started in a TaskFragment above.
+ *
+ * This should not be used with {@link #setPairedPrimaryFragmentToken}.
+ *
+ * TODO(b/232476698): remove the hide with adding CTS for this in next release.
+ * @hide
+ */
+ @NonNull
+ public Builder setPairedActivityToken(@Nullable IBinder activityToken) {
+ mPairedActivityToken = activityToken;
+ return this;
+ }
+
/** Constructs the options to create TaskFragment with. */
@NonNull
public TaskFragmentCreationParams build() {
return new TaskFragmentCreationParams(mOrganizer, mFragmentToken, mOwnerToken,
- mInitialBounds, mWindowingMode, mPairedPrimaryFragmentToken);
+ mInitialBounds, mWindowingMode, mPairedPrimaryFragmentToken,
+ mPairedActivityToken);
}
}
}
diff --git a/core/java/android/window/TaskFragmentOperation.aidl b/core/java/android/window/TaskFragmentOperation.aidl
index c21700c..c1ed0c7 100644
--- a/core/java/android/window/TaskFragmentOperation.aidl
+++ b/core/java/android/window/TaskFragmentOperation.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 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.
diff --git a/core/java/android/window/TaskFragmentOperation.java b/core/java/android/window/TaskFragmentOperation.java
index bec6c58..3272c3b 100644
--- a/core/java/android/window/TaskFragmentOperation.java
+++ b/core/java/android/window/TaskFragmentOperation.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 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.
@@ -19,6 +19,8 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.Intent;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -30,41 +32,108 @@
/**
* Data object of params for TaskFragment related {@link WindowContainerTransaction} operation.
*
- * @see WindowContainerTransaction#setTaskFragmentOperation(IBinder, TaskFragmentOperation).
+ * @see WindowContainerTransaction#addTaskFragmentOperation(IBinder, TaskFragmentOperation).
* @hide
*/
-// TODO(b/263436063): move other TaskFragment related operation here.
public final class TaskFragmentOperation implements Parcelable {
+ /**
+ * Type for tracking other {@link WindowContainerTransaction} to TaskFragment that is not set
+ * through {@link TaskFragmentOperation}, such as {@link WindowContainerTransaction#setBounds}.
+ */
+ public static final int OP_TYPE_UNKNOWN = -1;
+
+ /** Creates a new TaskFragment. */
+ public static final int OP_TYPE_CREATE_TASK_FRAGMENT = 0;
+
+ /** Deletes the given TaskFragment. */
+ public static final int OP_TYPE_DELETE_TASK_FRAGMENT = 1;
+
+ /** Starts an Activity in the given TaskFragment. */
+ public static final int OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT = 2;
+
+ /** Reparents the given Activity to the given TaskFragment. */
+ public static final int OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT = 3;
+
+ /** Sets two TaskFragments adjacent to each other. */
+ public static final int OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS = 4;
+
+ /** Requests focus on the top running Activity in the given TaskFragment. */
+ public static final int OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT = 5;
+
+ /** Sets a given TaskFragment to have a companion TaskFragment. */
+ public static final int OP_TYPE_SET_COMPANION_TASK_FRAGMENT = 6;
+
/** Sets the {@link TaskFragmentAnimationParams} for the given TaskFragment. */
- public static final int OP_TYPE_SET_ANIMATION_PARAMS = 0;
+ public static final int OP_TYPE_SET_ANIMATION_PARAMS = 7;
@IntDef(prefix = { "OP_TYPE_" }, value = {
+ OP_TYPE_UNKNOWN,
+ OP_TYPE_CREATE_TASK_FRAGMENT,
+ OP_TYPE_DELETE_TASK_FRAGMENT,
+ OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT,
+ OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT,
+ OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS,
+ OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT,
+ OP_TYPE_SET_COMPANION_TASK_FRAGMENT,
OP_TYPE_SET_ANIMATION_PARAMS
})
@Retention(RetentionPolicy.SOURCE)
- @interface OperationType {}
+ public @interface OperationType {}
@OperationType
private final int mOpType;
@Nullable
+ private final TaskFragmentCreationParams mTaskFragmentCreationParams;
+
+ @Nullable
+ private final IBinder mActivityToken;
+
+ @Nullable
+ private final Intent mActivityIntent;
+
+ @Nullable
+ private final Bundle mBundle;
+
+ @Nullable
+ private final IBinder mSecondaryFragmentToken;
+
+ @Nullable
private final TaskFragmentAnimationParams mAnimationParams;
private TaskFragmentOperation(@OperationType int opType,
+ @Nullable TaskFragmentCreationParams taskFragmentCreationParams,
+ @Nullable IBinder activityToken, @Nullable Intent activityIntent,
+ @Nullable Bundle bundle, @Nullable IBinder secondaryFragmentToken,
@Nullable TaskFragmentAnimationParams animationParams) {
mOpType = opType;
+ mTaskFragmentCreationParams = taskFragmentCreationParams;
+ mActivityToken = activityToken;
+ mActivityIntent = activityIntent;
+ mBundle = bundle;
+ mSecondaryFragmentToken = secondaryFragmentToken;
mAnimationParams = animationParams;
}
private TaskFragmentOperation(Parcel in) {
mOpType = in.readInt();
+ mTaskFragmentCreationParams = in.readTypedObject(TaskFragmentCreationParams.CREATOR);
+ mActivityToken = in.readStrongBinder();
+ mActivityIntent = in.readTypedObject(Intent.CREATOR);
+ mBundle = in.readBundle(getClass().getClassLoader());
+ mSecondaryFragmentToken = in.readStrongBinder();
mAnimationParams = in.readTypedObject(TaskFragmentAnimationParams.CREATOR);
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mOpType);
+ dest.writeTypedObject(mTaskFragmentCreationParams, flags);
+ dest.writeStrongBinder(mActivityToken);
+ dest.writeTypedObject(mActivityIntent, flags);
+ dest.writeBundle(mBundle);
+ dest.writeStrongBinder(mSecondaryFragmentToken);
dest.writeTypedObject(mAnimationParams, flags);
}
@@ -91,6 +160,46 @@
}
/**
+ * Gets the options to create a new TaskFragment.
+ */
+ @Nullable
+ public TaskFragmentCreationParams getTaskFragmentCreationParams() {
+ return mTaskFragmentCreationParams;
+ }
+
+ /**
+ * Gets the Activity token set in this operation.
+ */
+ @Nullable
+ public IBinder getActivityToken() {
+ return mActivityToken;
+ }
+
+ /**
+ * Gets the Intent to start a new Activity.
+ */
+ @Nullable
+ public Intent getActivityIntent() {
+ return mActivityIntent;
+ }
+
+ /**
+ * Gets the Bundle set in this operation.
+ */
+ @Nullable
+ public Bundle getBundle() {
+ return mBundle;
+ }
+
+ /**
+ * Gets the fragment token of the secondary TaskFragment set in this operation.
+ */
+ @Nullable
+ public IBinder getSecondaryFragmentToken() {
+ return mSecondaryFragmentToken;
+ }
+
+ /**
* Gets the animation related override of TaskFragment.
*/
@Nullable
@@ -102,6 +211,21 @@
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("TaskFragmentOperation{ opType=").append(mOpType);
+ if (mTaskFragmentCreationParams != null) {
+ sb.append(", taskFragmentCreationParams=").append(mTaskFragmentCreationParams);
+ }
+ if (mActivityToken != null) {
+ sb.append(", activityToken=").append(mActivityToken);
+ }
+ if (mActivityIntent != null) {
+ sb.append(", activityIntent=").append(mActivityIntent);
+ }
+ if (mBundle != null) {
+ sb.append(", bundle=").append(mBundle);
+ }
+ if (mSecondaryFragmentToken != null) {
+ sb.append(", secondaryFragmentToken=").append(mSecondaryFragmentToken);
+ }
if (mAnimationParams != null) {
sb.append(", animationParams=").append(mAnimationParams);
}
@@ -112,9 +236,8 @@
@Override
public int hashCode() {
- int result = mOpType;
- result = result * 31 + mAnimationParams.hashCode();
- return result;
+ return Objects.hash(mOpType, mTaskFragmentCreationParams, mActivityToken, mActivityIntent,
+ mBundle, mSecondaryFragmentToken, mAnimationParams);
}
@Override
@@ -124,6 +247,11 @@
}
final TaskFragmentOperation other = (TaskFragmentOperation) obj;
return mOpType == other.mOpType
+ && Objects.equals(mTaskFragmentCreationParams, other.mTaskFragmentCreationParams)
+ && Objects.equals(mActivityToken, other.mActivityToken)
+ && Objects.equals(mActivityIntent, other.mActivityIntent)
+ && Objects.equals(mBundle, other.mBundle)
+ && Objects.equals(mSecondaryFragmentToken, other.mSecondaryFragmentToken)
&& Objects.equals(mAnimationParams, other.mAnimationParams);
}
@@ -139,6 +267,21 @@
private final int mOpType;
@Nullable
+ private TaskFragmentCreationParams mTaskFragmentCreationParams;
+
+ @Nullable
+ private IBinder mActivityToken;
+
+ @Nullable
+ private Intent mActivityIntent;
+
+ @Nullable
+ private Bundle mBundle;
+
+ @Nullable
+ private IBinder mSecondaryFragmentToken;
+
+ @Nullable
private TaskFragmentAnimationParams mAnimationParams;
/**
@@ -149,6 +292,52 @@
}
/**
+ * Sets the {@link TaskFragmentCreationParams} for creating a new TaskFragment.
+ */
+ @NonNull
+ public Builder setTaskFragmentCreationParams(
+ @Nullable TaskFragmentCreationParams taskFragmentCreationParams) {
+ mTaskFragmentCreationParams = taskFragmentCreationParams;
+ return this;
+ }
+
+ /**
+ * Sets an Activity token to this operation.
+ */
+ @NonNull
+ public Builder setActivityToken(@Nullable IBinder activityToken) {
+ mActivityToken = activityToken;
+ return this;
+ }
+
+ /**
+ * Sets the Intent to start a new Activity.
+ */
+ @NonNull
+ public Builder setActivityIntent(@Nullable Intent activityIntent) {
+ mActivityIntent = activityIntent;
+ return this;
+ }
+
+ /**
+ * Sets a Bundle to this operation.
+ */
+ @NonNull
+ public Builder setBundle(@Nullable Bundle bundle) {
+ mBundle = bundle;
+ return this;
+ }
+
+ /**
+ * Sets the secondary fragment token to this operation.
+ */
+ @NonNull
+ public Builder setSecondaryFragmentToken(@Nullable IBinder secondaryFragmentToken) {
+ mSecondaryFragmentToken = secondaryFragmentToken;
+ return this;
+ }
+
+ /**
* Sets the {@link TaskFragmentAnimationParams} for the given TaskFragment.
*/
@NonNull
@@ -162,7 +351,8 @@
*/
@NonNull
public TaskFragmentOperation build() {
- return new TaskFragmentOperation(mOpType, mAnimationParams);
+ return new TaskFragmentOperation(mOpType, mTaskFragmentCreationParams, mActivityToken,
+ mActivityIntent, mBundle, mSecondaryFragmentToken, mAnimationParams);
}
}
}
diff --git a/core/java/android/window/TaskFragmentOrganizer.java b/core/java/android/window/TaskFragmentOrganizer.java
index 283df76..f785a3d 100644
--- a/core/java/android/window/TaskFragmentOrganizer.java
+++ b/core/java/android/window/TaskFragmentOrganizer.java
@@ -55,7 +55,7 @@
public static final String KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO = "task_fragment_info";
/**
- * Key to the {@link WindowContainerTransaction.HierarchyOp} in
+ * Key to the {@link TaskFragmentOperation.OperationType} in
* {@link TaskFragmentTransaction.Change#getErrorBundle()}.
*/
public static final String KEY_ERROR_CALLBACK_OP_TYPE = "operation_type";
@@ -112,7 +112,7 @@
* @hide
*/
public static @NonNull Bundle putErrorInfoInBundle(@NonNull Throwable exception,
- @Nullable TaskFragmentInfo info, int opType) {
+ @Nullable TaskFragmentInfo info, @TaskFragmentOperation.OperationType int opType) {
final Bundle errorBundle = new Bundle();
errorBundle.putSerializable(KEY_ERROR_CALLBACK_THROWABLE, exception);
if (info != null) {
diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java
index bffd4e4..02878f8 100644
--- a/core/java/android/window/TaskOrganizer.java
+++ b/core/java/android/window/TaskOrganizer.java
@@ -152,15 +152,31 @@
* @param windowingMode Windowing mode to put the root task in.
* @param launchCookie Launch cookie to associate with the task so that is can be identified
* when the {@link ITaskOrganizer#onTaskAppeared} callback is called.
+ * @param removeWithTaskOrganizer True if this task should be removed when organizer destroyed.
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
+ public void createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie,
+ boolean removeWithTaskOrganizer) {
+ try {
+ mTaskOrganizerController.createRootTask(displayId, windowingMode, launchCookie,
+ removeWithTaskOrganizer);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Creates a persistent root task in WM for a particular windowing-mode.
+ * @param displayId The display to create the root task on.
+ * @param windowingMode Windowing mode to put the root task in.
+ * @param launchCookie Launch cookie to associate with the task so that is can be identified
+ * when the {@link ITaskOrganizer#onTaskAppeared} callback is called.
*/
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
@Nullable
public void createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie) {
- try {
- mTaskOrganizerController.createRootTask(displayId, windowingMode, launchCookie);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ createRootTask(displayId, windowingMode, launchCookie, false /* removeWithTaskOrganizer */);
}
/** Deletes a persistent root task in WM */
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index 647ccf5..80b2161 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -16,6 +16,14 @@
package android.window;
+import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_DELETE_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS;
+import static android.window.TaskFragmentOperation.OP_TYPE_SET_COMPANION_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
@@ -505,32 +513,29 @@
/**
* Creates a new TaskFragment with the given options.
- * @param taskFragmentOptions the options used to create the TaskFragment.
+ * @param taskFragmentCreationParams the options used to create the TaskFragment.
*/
@NonNull
public WindowContainerTransaction createTaskFragment(
- @NonNull TaskFragmentCreationParams taskFragmentOptions) {
- final HierarchyOp hierarchyOp =
- new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT)
- .setTaskFragmentCreationOptions(taskFragmentOptions)
- .build();
- mHierarchyOps.add(hierarchyOp);
- return this;
+ @NonNull TaskFragmentCreationParams taskFragmentCreationParams) {
+ final TaskFragmentOperation operation = new TaskFragmentOperation.Builder(
+ OP_TYPE_CREATE_TASK_FRAGMENT)
+ .setTaskFragmentCreationParams(taskFragmentCreationParams)
+ .build();
+ return addTaskFragmentOperation(taskFragmentCreationParams.getFragmentToken(), operation);
}
/**
* Deletes an existing TaskFragment. Any remaining activities below it will be destroyed.
- * @param taskFragment the TaskFragment to be removed.
+ * @param fragmentToken client assigned unique token to create TaskFragment with specified in
+ * {@link TaskFragmentCreationParams#getFragmentToken()}.
*/
@NonNull
- public WindowContainerTransaction deleteTaskFragment(
- @NonNull WindowContainerToken taskFragment) {
- final HierarchyOp hierarchyOp =
- new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT)
- .setContainer(taskFragment.asBinder())
- .build();
- mHierarchyOps.add(hierarchyOp);
- return this;
+ public WindowContainerTransaction deleteTaskFragment(@NonNull IBinder fragmentToken) {
+ final TaskFragmentOperation operation = new TaskFragmentOperation.Builder(
+ OP_TYPE_DELETE_TASK_FRAGMENT)
+ .build();
+ return addTaskFragmentOperation(fragmentToken, operation);
}
/**
@@ -546,16 +551,13 @@
public WindowContainerTransaction startActivityInTaskFragment(
@NonNull IBinder fragmentToken, @NonNull IBinder callerToken,
@NonNull Intent activityIntent, @Nullable Bundle activityOptions) {
- final HierarchyOp hierarchyOp =
- new HierarchyOp.Builder(
- HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT)
- .setContainer(fragmentToken)
- .setReparentContainer(callerToken)
- .setActivityIntent(activityIntent)
- .setLaunchOptions(activityOptions)
- .build();
- mHierarchyOps.add(hierarchyOp);
- return this;
+ final TaskFragmentOperation operation = new TaskFragmentOperation.Builder(
+ OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT)
+ .setActivityToken(callerToken)
+ .setActivityIntent(activityIntent)
+ .setBundle(activityOptions)
+ .build();
+ return addTaskFragmentOperation(fragmentToken, operation);
}
/**
@@ -567,33 +569,11 @@
@NonNull
public WindowContainerTransaction reparentActivityToTaskFragment(
@NonNull IBinder fragmentToken, @NonNull IBinder activityToken) {
- final HierarchyOp hierarchyOp =
- new HierarchyOp.Builder(
- HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT)
- .setReparentContainer(fragmentToken)
- .setContainer(activityToken)
- .build();
- mHierarchyOps.add(hierarchyOp);
- return this;
- }
-
- /**
- * Reparents all children of one TaskFragment to another.
- * @param oldParent children of this TaskFragment will be reparented.
- * @param newParent the new parent TaskFragment to move the children to. If {@code null}, the
- * children will be moved to the leaf Task.
- */
- @NonNull
- public WindowContainerTransaction reparentChildren(
- @NonNull WindowContainerToken oldParent,
- @Nullable WindowContainerToken newParent) {
- final HierarchyOp hierarchyOp =
- new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_CHILDREN)
- .setContainer(oldParent.asBinder())
- .setReparentContainer(newParent != null ? newParent.asBinder() : null)
- .build();
- mHierarchyOps.add(hierarchyOp);
- return this;
+ final TaskFragmentOperation operation = new TaskFragmentOperation.Builder(
+ OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT)
+ .setActivityToken(activityToken)
+ .build();
+ return addTaskFragmentOperation(fragmentToken, operation);
}
/**
@@ -613,14 +593,12 @@
public WindowContainerTransaction setAdjacentTaskFragments(
@NonNull IBinder fragmentToken1, @Nullable IBinder fragmentToken2,
@Nullable TaskFragmentAdjacentParams params) {
- final HierarchyOp hierarchyOp =
- new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS)
- .setContainer(fragmentToken1)
- .setReparentContainer(fragmentToken2)
- .setLaunchOptions(params != null ? params.toBundle() : null)
- .build();
- mHierarchyOps.add(hierarchyOp);
- return this;
+ final TaskFragmentOperation operation = new TaskFragmentOperation.Builder(
+ OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS)
+ .setSecondaryFragmentToken(fragmentToken2)
+ .setBundle(params != null ? params.toBundle() : null)
+ .build();
+ return addTaskFragmentOperation(fragmentToken1, operation);
}
/**
@@ -700,14 +678,10 @@
*/
@NonNull
public WindowContainerTransaction requestFocusOnTaskFragment(@NonNull IBinder fragmentToken) {
- final HierarchyOp hierarchyOp =
- new HierarchyOp.Builder(
- HierarchyOp.HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT)
- .setContainer(fragmentToken)
- .build();
- mHierarchyOps.add(hierarchyOp);
- return this;
-
+ final TaskFragmentOperation operation = new TaskFragmentOperation.Builder(
+ OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT)
+ .build();
+ return addTaskFragmentOperation(fragmentToken, operation);
}
/**
@@ -728,30 +702,32 @@
}
/**
- * Sets the TaskFragment {@code container} to have a companion TaskFragment {@code companion}.
+ * Sets the TaskFragment {@code fragmentToken} to have a companion TaskFragment
+ * {@code companionFragmentToken}.
* This indicates that the organizer will remove the TaskFragment when the companion
* TaskFragment is removed.
*
- * @param container the TaskFragment container
- * @param companion the companion TaskFragment. If it is {@code null}, the transaction will
- * reset the companion TaskFragment.
+ * @param fragmentToken client assigned unique token to create TaskFragment with specified
+ * in {@link TaskFragmentCreationParams#getFragmentToken()}.
+ * @param companionFragmentToken client assigned unique token to create TaskFragment with
+ * specified in
+ * {@link TaskFragmentCreationParams#getFragmentToken()}.
+ * If it is {@code null}, the transaction will reset the companion
+ * TaskFragment.
* @hide
*/
@NonNull
- public WindowContainerTransaction setCompanionTaskFragment(@NonNull IBinder container,
- @Nullable IBinder companion) {
- final HierarchyOp hierarchyOp =
- new HierarchyOp.Builder(
- HierarchyOp.HIERARCHY_OP_TYPE_SET_COMPANION_TASK_FRAGMENT)
- .setContainer(container)
- .setReparentContainer(companion)
- .build();
- mHierarchyOps.add(hierarchyOp);
- return this;
+ public WindowContainerTransaction setCompanionTaskFragment(@NonNull IBinder fragmentToken,
+ @Nullable IBinder companionFragmentToken) {
+ final TaskFragmentOperation operation = new TaskFragmentOperation.Builder(
+ OP_TYPE_SET_COMPANION_TASK_FRAGMENT)
+ .setSecondaryFragmentToken(companionFragmentToken)
+ .build();
+ return addTaskFragmentOperation(fragmentToken, operation);
}
/**
- * Sets the {@link TaskFragmentOperation} to apply to the given TaskFragment.
+ * Adds a {@link TaskFragmentOperation} to apply to the given TaskFragment.
*
* @param fragmentToken client assigned unique token to create TaskFragment with specified in
* {@link TaskFragmentCreationParams#getFragmentToken()}.
@@ -760,13 +736,13 @@
* @hide
*/
@NonNull
- public WindowContainerTransaction setTaskFragmentOperation(@NonNull IBinder fragmentToken,
+ public WindowContainerTransaction addTaskFragmentOperation(@NonNull IBinder fragmentToken,
@NonNull TaskFragmentOperation taskFragmentOperation) {
Objects.requireNonNull(fragmentToken);
Objects.requireNonNull(taskFragmentOperation);
final HierarchyOp hierarchyOp =
new HierarchyOp.Builder(
- HierarchyOp.HIERARCHY_OP_TYPE_SET_TASK_FRAGMENT_OPERATION)
+ HierarchyOp.HIERARCHY_OP_TYPE_ADD_TASK_FRAGMENT_OPERATION)
.setContainer(fragmentToken)
.setTaskFragmentOperation(taskFragmentOperation)
.build();
@@ -1267,25 +1243,17 @@
public static final int HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS = 4;
public static final int HIERARCHY_OP_TYPE_LAUNCH_TASK = 5;
public static final int HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT = 6;
- public static final int HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT = 7;
- public static final int HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT = 8;
- public static final int HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT = 9;
- public static final int HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT = 10;
- public static final int HIERARCHY_OP_TYPE_REPARENT_CHILDREN = 11;
- public static final int HIERARCHY_OP_TYPE_PENDING_INTENT = 12;
- public static final int HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS = 13;
- public static final int HIERARCHY_OP_TYPE_START_SHORTCUT = 14;
- public static final int HIERARCHY_OP_TYPE_RESTORE_TRANSIENT_ORDER = 15;
- public static final int HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER = 16;
- public static final int HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER = 17;
- public static final int HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT = 18;
- public static final int HIERARCHY_OP_TYPE_SET_ALWAYS_ON_TOP = 19;
- public static final int HIERARCHY_OP_TYPE_REMOVE_TASK = 20;
- public static final int HIERARCHY_OP_TYPE_FINISH_ACTIVITY = 21;
- public static final int HIERARCHY_OP_TYPE_SET_COMPANION_TASK_FRAGMENT = 22;
- public static final int HIERARCHY_OP_TYPE_CLEAR_ADJACENT_ROOTS = 23;
- public static final int HIERARCHY_OP_TYPE_SET_REPARENT_LEAF_TASK_IF_RELAUNCH = 24;
- public static final int HIERARCHY_OP_TYPE_SET_TASK_FRAGMENT_OPERATION = 25;
+ public static final int HIERARCHY_OP_TYPE_PENDING_INTENT = 7;
+ public static final int HIERARCHY_OP_TYPE_START_SHORTCUT = 8;
+ public static final int HIERARCHY_OP_TYPE_RESTORE_TRANSIENT_ORDER = 9;
+ public static final int HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER = 10;
+ public static final int HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER = 11;
+ public static final int HIERARCHY_OP_TYPE_SET_ALWAYS_ON_TOP = 12;
+ public static final int HIERARCHY_OP_TYPE_REMOVE_TASK = 13;
+ public static final int HIERARCHY_OP_TYPE_FINISH_ACTIVITY = 14;
+ public static final int HIERARCHY_OP_TYPE_CLEAR_ADJACENT_ROOTS = 15;
+ public static final int HIERARCHY_OP_TYPE_SET_REPARENT_LEAF_TASK_IF_RELAUNCH = 16;
+ public static final int HIERARCHY_OP_TYPE_ADD_TASK_FRAGMENT_OPERATION = 17;
// The following key(s) are for use with mLaunchOptions:
// When launching a task (eg. from recents), this is the taskId to be launched.
@@ -1326,11 +1294,7 @@
@Nullable
private Intent mActivityIntent;
- /** Used as options for {@link #createTaskFragment}. */
- @Nullable
- private TaskFragmentCreationParams mTaskFragmentCreationOptions;
-
- /** Used as options for {@link #setTaskFragmentOperation}. */
+ /** Used as options for {@link #addTaskFragmentOperation}. */
@Nullable
private TaskFragmentOperation mTaskFragmentOperation;
@@ -1452,7 +1416,6 @@
mActivityTypes = copy.mActivityTypes;
mLaunchOptions = copy.mLaunchOptions;
mActivityIntent = copy.mActivityIntent;
- mTaskFragmentCreationOptions = copy.mTaskFragmentCreationOptions;
mTaskFragmentOperation = copy.mTaskFragmentOperation;
mPendingIntent = copy.mPendingIntent;
mShortcutInfo = copy.mShortcutInfo;
@@ -1476,7 +1439,6 @@
mActivityTypes = in.createIntArray();
mLaunchOptions = in.readBundle();
mActivityIntent = in.readTypedObject(Intent.CREATOR);
- mTaskFragmentCreationOptions = in.readTypedObject(TaskFragmentCreationParams.CREATOR);
mTaskFragmentOperation = in.readTypedObject(TaskFragmentOperation.CREATOR);
mPendingIntent = in.readTypedObject(PendingIntent.CREATOR);
mShortcutInfo = in.readTypedObject(ShortcutInfo.CREATOR);
@@ -1516,16 +1478,6 @@
return mReparent;
}
- @NonNull
- public IBinder getCompanionContainer() {
- return mReparent;
- }
-
- @NonNull
- public IBinder getCallingActivity() {
- return mReparent;
- }
-
public boolean getToTop() {
return mToTop;
}
@@ -1561,11 +1513,6 @@
}
@Nullable
- public TaskFragmentCreationParams getTaskFragmentCreationOptions() {
- return mTaskFragmentCreationOptions;
- }
-
- @Nullable
public TaskFragmentOperation getTaskFragmentOperation() {
return mTaskFragmentOperation;
}
@@ -1605,22 +1552,6 @@
case HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT:
return "{SetAdjacentFlagRoot: container=" + mContainer + " clearRoot=" + mToTop
+ "}";
- case HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT:
- return "{CreateTaskFragment: options=" + mTaskFragmentCreationOptions + "}";
- case HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT:
- return "{DeleteTaskFragment: taskFragment=" + mContainer + "}";
- case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT:
- return "{StartActivityInTaskFragment: fragmentToken=" + mContainer + " intent="
- + mActivityIntent + " options=" + mLaunchOptions + "}";
- case HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT:
- return "{ReparentActivityToTaskFragment: fragmentToken=" + mReparent
- + " activity=" + mContainer + "}";
- case HIERARCHY_OP_TYPE_REPARENT_CHILDREN:
- return "{ReparentChildren: oldParent=" + mContainer + " newParent=" + mReparent
- + "}";
- case HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS:
- return "{SetAdjacentTaskFragments: container=" + mContainer
- + " adjacentContainer=" + mReparent + "}";
case HIERARCHY_OP_TYPE_START_SHORTCUT:
return "{StartShortcut: options=" + mLaunchOptions + " info=" + mShortcutInfo
+ "}";
@@ -1631,8 +1562,6 @@
case HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER:
return "{removeLocalInsetsProvider: container=" + mContainer
+ " insetsType=" + Arrays.toString(mInsetsTypes) + "}";
- case HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT:
- return "{requestFocusOnTaskFragment: container=" + mContainer + "}";
case HIERARCHY_OP_TYPE_SET_ALWAYS_ON_TOP:
return "{setAlwaysOnTop: container=" + mContainer
+ " alwaysOnTop=" + mAlwaysOnTop + "}";
@@ -1640,16 +1569,13 @@
return "{RemoveTask: task=" + mContainer + "}";
case HIERARCHY_OP_TYPE_FINISH_ACTIVITY:
return "{finishActivity: activity=" + mContainer + "}";
- case HIERARCHY_OP_TYPE_SET_COMPANION_TASK_FRAGMENT:
- return "{setCompanionTaskFragment: container = " + mContainer + " companion = "
- + mReparent + "}";
case HIERARCHY_OP_TYPE_CLEAR_ADJACENT_ROOTS:
return "{ClearAdjacentRoot: container=" + mContainer + "}";
case HIERARCHY_OP_TYPE_SET_REPARENT_LEAF_TASK_IF_RELAUNCH:
return "{setReparentLeafTaskIfRelaunch: container= " + mContainer
+ " reparentLeafTaskIfRelaunch= " + mReparentLeafTaskIfRelaunch + "}";
- case HIERARCHY_OP_TYPE_SET_TASK_FRAGMENT_OPERATION:
- return "{setTaskFragmentOperation: fragmentToken= " + mContainer
+ case HIERARCHY_OP_TYPE_ADD_TASK_FRAGMENT_OPERATION:
+ return "{addTaskFragmentOperation: fragmentToken= " + mContainer
+ " operation= " + mTaskFragmentOperation + "}";
default:
return "{mType=" + mType + " container=" + mContainer + " reparent=" + mReparent
@@ -1677,7 +1603,6 @@
dest.writeIntArray(mActivityTypes);
dest.writeBundle(mLaunchOptions);
dest.writeTypedObject(mActivityIntent, flags);
- dest.writeTypedObject(mTaskFragmentCreationOptions, flags);
dest.writeTypedObject(mTaskFragmentOperation, flags);
dest.writeTypedObject(mPendingIntent, flags);
dest.writeTypedObject(mShortcutInfo, flags);
@@ -1733,9 +1658,6 @@
private Intent mActivityIntent;
@Nullable
- private TaskFragmentCreationParams mTaskFragmentCreationOptions;
-
- @Nullable
private TaskFragmentOperation mTaskFragmentOperation;
@Nullable
@@ -1812,12 +1734,6 @@
return this;
}
- Builder setTaskFragmentCreationOptions(
- @Nullable TaskFragmentCreationParams taskFragmentCreationOptions) {
- mTaskFragmentCreationOptions = taskFragmentCreationOptions;
- return this;
- }
-
Builder setTaskFragmentOperation(
@Nullable TaskFragmentOperation taskFragmentOperation) {
mTaskFragmentOperation = taskFragmentOperation;
@@ -1852,7 +1768,6 @@
hierarchyOp.mActivityIntent = mActivityIntent;
hierarchyOp.mPendingIntent = mPendingIntent;
hierarchyOp.mAlwaysOnTop = mAlwaysOnTop;
- hierarchyOp.mTaskFragmentCreationOptions = mTaskFragmentCreationOptions;
hierarchyOp.mTaskFragmentOperation = mTaskFragmentOperation;
hierarchyOp.mShortcutInfo = mShortcutInfo;
hierarchyOp.mReparentLeafTaskIfRelaunch = mReparentLeafTaskIfRelaunch;
diff --git a/core/java/com/android/internal/inputmethod/EditableInputConnection.java b/core/java/com/android/internal/inputmethod/EditableInputConnection.java
index 52e7471..8690e8d 100644
--- a/core/java/com/android/internal/inputmethod/EditableInputConnection.java
+++ b/core/java/com/android/internal/inputmethod/EditableInputConnection.java
@@ -271,9 +271,9 @@
@Override
public void requestTextBoundsInfo(
- @NonNull RectF rectF, @Nullable @CallbackExecutor Executor executor,
+ @NonNull RectF bounds, @Nullable @CallbackExecutor Executor executor,
@NonNull Consumer<TextBoundsInfoResult> consumer) {
- final TextBoundsInfo textBoundsInfo = mTextView.getTextBoundsInfo(rectF);
+ final TextBoundsInfo textBoundsInfo = mTextView.getTextBoundsInfo(bounds);
final int resultCode;
if (textBoundsInfo != null) {
resultCode = TextBoundsInfoResult.CODE_SUCCESS;
diff --git a/core/java/com/android/internal/inputmethod/IRemoteInputConnection.aidl b/core/java/com/android/internal/inputmethod/IRemoteInputConnection.aidl
index 65016c2..b375936 100644
--- a/core/java/com/android/internal/inputmethod/IRemoteInputConnection.aidl
+++ b/core/java/com/android/internal/inputmethod/IRemoteInputConnection.aidl
@@ -111,7 +111,7 @@
int cursorUpdateMode, int cursorUpdateFilter, int imeDisplayId,
in AndroidFuture future /* T=Boolean */);
- void requestTextBoundsInfo(in InputConnectionCommandHeader header, in RectF rect,
+ void requestTextBoundsInfo(in InputConnectionCommandHeader header, in RectF bounds,
in ResultReceiver resultReceiver /* T=TextBoundsInfoResult */);
void commitContent(in InputConnectionCommandHeader header, in InputContentInfo inputContentInfo,
diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java
index 3d8982b..04b7239cb 100644
--- a/core/java/com/android/internal/os/BatteryStatsHistory.java
+++ b/core/java/com/android/internal/os/BatteryStatsHistory.java
@@ -187,8 +187,6 @@
private int mNextHistoryTagIdx = 0;
private int mNumHistoryTagChars = 0;
private int mHistoryBufferLastPos = -1;
- private int mActiveHistoryStates = 0xffffffff;
- private int mActiveHistoryStates2 = 0xffffffff;
private long mLastHistoryElapsedRealtimeMs = 0;
private long mTrackRunningHistoryElapsedRealtimeMs = 0;
private long mTrackRunningHistoryUptimeMs = 0;
@@ -362,8 +360,6 @@
mNextHistoryTagIdx = 0;
mNumHistoryTagChars = 0;
mHistoryBufferLastPos = -1;
- mActiveHistoryStates = 0xffffffff;
- mActiveHistoryStates2 = 0xffffffff;
if (mStepDetailsCalculator != null) {
mStepDetailsCalculator.clear();
}
@@ -1098,8 +1094,9 @@
*/
public void recordScreenBrightnessEvent(long elapsedRealtimeMs, long uptimeMs,
int brightnessBin) {
- mHistoryCur.states = (mHistoryCur.states & ~HistoryItem.STATE_BRIGHTNESS_MASK)
- | (brightnessBin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
+ mHistoryCur.states = setBitField(mHistoryCur.states, brightnessBin,
+ HistoryItem.STATE_BRIGHTNESS_SHIFT,
+ HistoryItem.STATE_BRIGHTNESS_MASK);
writeHistoryItem(elapsedRealtimeMs, uptimeMs);
}
@@ -1108,8 +1105,9 @@
*/
public void recordGpsSignalQualityEvent(long elapsedRealtimeMs, long uptimeMs,
int signalLevel) {
- mHistoryCur.states2 = (mHistoryCur.states2 & ~HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK)
- | (signalLevel << HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT);
+ mHistoryCur.states2 = setBitField(mHistoryCur.states2, signalLevel,
+ HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT,
+ HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK);
writeHistoryItem(elapsedRealtimeMs, uptimeMs);
}
@@ -1117,8 +1115,9 @@
* Records a device idle mode change event.
*/
public void recordDeviceIdleEvent(long elapsedRealtimeMs, long uptimeMs, int mode) {
- mHistoryCur.states2 = (mHistoryCur.states2 & ~HistoryItem.STATE2_DEVICE_IDLE_MASK)
- | (mode << HistoryItem.STATE2_DEVICE_IDLE_SHIFT);
+ mHistoryCur.states2 = setBitField(mHistoryCur.states2, mode,
+ HistoryItem.STATE2_DEVICE_IDLE_SHIFT,
+ HistoryItem.STATE2_DEVICE_IDLE_MASK);
writeHistoryItem(elapsedRealtimeMs, uptimeMs);
}
@@ -1130,13 +1129,15 @@
mHistoryCur.states = (mHistoryCur.states | addStateFlag) & ~removeStateFlag;
if (state != -1) {
mHistoryCur.states =
- (mHistoryCur.states & ~HistoryItem.STATE_PHONE_STATE_MASK)
- | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
+ setBitField(mHistoryCur.states, state,
+ HistoryItem.STATE_PHONE_STATE_SHIFT,
+ HistoryItem.STATE_PHONE_STATE_MASK);
}
if (signalStrength != -1) {
mHistoryCur.states =
- (mHistoryCur.states & ~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK)
- | (signalStrength << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT);
+ setBitField(mHistoryCur.states, signalStrength,
+ HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT,
+ HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK);
}
writeHistoryItem(elapsedRealtimeMs, uptimeMs);
}
@@ -1146,8 +1147,9 @@
*/
public void recordDataConnectionTypeChangeEvent(long elapsedRealtimeMs, long uptimeMs,
int dataConnectionType) {
- mHistoryCur.states = (mHistoryCur.states & ~HistoryItem.STATE_DATA_CONNECTION_MASK)
- | (dataConnectionType << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
+ mHistoryCur.states = setBitField(mHistoryCur.states, dataConnectionType,
+ HistoryItem.STATE_DATA_CONNECTION_SHIFT,
+ HistoryItem.STATE_DATA_CONNECTION_MASK);
writeHistoryItem(elapsedRealtimeMs, uptimeMs);
}
@@ -1157,8 +1159,9 @@
public void recordWifiSupplicantStateChangeEvent(long elapsedRealtimeMs, long uptimeMs,
int supplState) {
mHistoryCur.states2 =
- (mHistoryCur.states2 & ~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK)
- | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT);
+ setBitField(mHistoryCur.states2, supplState,
+ HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT,
+ HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK);
writeHistoryItem(elapsedRealtimeMs, uptimeMs);
}
@@ -1168,8 +1171,9 @@
public void recordWifiSignalStrengthChangeEvent(long elapsedRealtimeMs, long uptimeMs,
int strengthBin) {
mHistoryCur.states2 =
- (mHistoryCur.states2 & ~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK)
- | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT);
+ setBitField(mHistoryCur.states2, strengthBin,
+ HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT,
+ HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK);
writeHistoryItem(elapsedRealtimeMs, uptimeMs);
}
@@ -1227,6 +1231,16 @@
}
}
+ private int setBitField(int bits, int value, int shift, int mask) {
+ int shiftedValue = value << shift;
+ if ((shiftedValue & ~mask) != 0) {
+ Slog.wtfStack(TAG, "Value " + Integer.toHexString(value)
+ + " does not fit in the bit field: " + Integer.toHexString(mask));
+ shiftedValue &= mask;
+ }
+ return (bits & ~mask) | shiftedValue;
+ }
+
/**
* Writes the current history item to history.
*/
@@ -1260,8 +1274,8 @@
}
final long timeDiffMs = (mHistoryBaseTimeMs + elapsedRealtimeMs) - mHistoryLastWritten.time;
- final int diffStates = mHistoryLastWritten.states ^ (cur.states & mActiveHistoryStates);
- final int diffStates2 = mHistoryLastWritten.states2 ^ (cur.states2 & mActiveHistoryStates2);
+ final int diffStates = mHistoryLastWritten.states ^ cur.states;
+ final int diffStates2 = mHistoryLastWritten.states2 ^ cur.states2;
final int lastDiffStates = mHistoryLastWritten.states ^ mHistoryLastLastWritten.states;
final int lastDiffStates2 = mHistoryLastWritten.states2 ^ mHistoryLastLastWritten.states2;
if (DEBUG) {
@@ -1274,9 +1288,9 @@
recordTraceEvents(cur.eventCode, cur.eventTag);
recordTraceCounters(mHistoryLastWritten.states,
- cur.states & mActiveHistoryStates, BatteryStats.HISTORY_STATE_DESCRIPTIONS);
+ cur.states, BatteryStats.HISTORY_STATE_DESCRIPTIONS);
recordTraceCounters(mHistoryLastWritten.states2,
- cur.states2 & mActiveHistoryStates2, BatteryStats.HISTORY_STATE2_DESCRIPTIONS);
+ cur.states2, BatteryStats.HISTORY_STATE2_DESCRIPTIONS);
if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
&& timeDiffMs < 1000 && (diffStates & lastDiffStates) == 0
@@ -1387,8 +1401,6 @@
final boolean hasTags = mHistoryLastWritten.tagsFirstOccurrence || cur.tagsFirstOccurrence;
mHistoryLastWritten.setTo(mHistoryBaseTimeMs + elapsedRealtimeMs, cmd, cur);
mHistoryLastWritten.tagsFirstOccurrence = hasTags;
- mHistoryLastWritten.states &= mActiveHistoryStates;
- mHistoryLastWritten.states2 &= mActiveHistoryStates2;
writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten);
mLastHistoryElapsedRealtimeMs = elapsedRealtimeMs;
cur.wakelockTag = null;
@@ -1627,7 +1639,7 @@
}
if (cur.eventCode != HistoryItem.EVENT_NONE) {
final int index = writeHistoryTag(cur.eventTag);
- final int codeAndIndex = (cur.eventCode & 0xffff) | (index << 16);
+ final int codeAndIndex = setBitField(cur.eventCode & 0xffff, index, 16, 0xFFFF0000);
dest.writeInt(codeAndIndex);
if ((index & BatteryStatsHistory.TAG_FIRST_OCCURRENCE_FLAG) != 0) {
cur.eventTag.writeToParcel(dest, 0);
@@ -1689,9 +1701,11 @@
}
private int buildBatteryLevelInt(HistoryItem h) {
- return ((((int) h.batteryLevel) << 25) & 0xfe000000)
- | ((((int) h.batteryTemperature) << 15) & 0x01ff8000)
- | ((((int) h.batteryVoltage) << 1) & 0x00007ffe);
+ int bits = 0;
+ bits = setBitField(bits, h.batteryLevel, 25, 0xfe000000 /* 7F << 25 */);
+ bits = setBitField(bits, h.batteryTemperature, 15, 0x01ff8000 /* 3FF << 15 */);
+ bits = setBitField(bits, h.batteryVoltage, 1, 0x00007ffe /* 3FFF << 1 */);
+ return bits;
}
private int buildStateInt(HistoryItem h) {
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index a43f0b3..21f1d6d 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -129,6 +129,7 @@
"android_view_KeyCharacterMap.cpp",
"android_view_KeyEvent.cpp",
"android_view_MotionEvent.cpp",
+ "android_view_MotionPredictor.cpp",
"android_view_PointerIcon.cpp",
"android_view_Surface.cpp",
"android_view_SurfaceControl.cpp",
@@ -283,6 +284,7 @@
"libhwui",
"libmediandk",
"libpermission",
+ "libPlatformProperties",
"libsensor",
"libinput",
"libcamera_client",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 6ceffde..578cf24 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -187,6 +187,7 @@
extern int register_android_view_KeyCharacterMap(JNIEnv *env);
extern int register_android_view_KeyEvent(JNIEnv* env);
extern int register_android_view_MotionEvent(JNIEnv* env);
+extern int register_android_view_MotionPredictor(JNIEnv* env);
extern int register_android_view_PointerIcon(JNIEnv* env);
extern int register_android_view_VelocityTracker(JNIEnv* env);
extern int register_android_view_VerifiedKeyEvent(JNIEnv* env);
@@ -1643,6 +1644,7 @@
REG_JNI(register_android_view_InputQueue),
REG_JNI(register_android_view_KeyEvent),
REG_JNI(register_android_view_MotionEvent),
+ REG_JNI(register_android_view_MotionPredictor),
REG_JNI(register_android_view_PointerIcon),
REG_JNI(register_android_view_VelocityTracker),
REG_JNI(register_android_view_VerifiedKeyEvent),
diff --git a/core/jni/android_hardware_OverlayProperties.cpp b/core/jni/android_hardware_OverlayProperties.cpp
index a96af86..9941ca4 100644
--- a/core/jni/android_hardware_OverlayProperties.cpp
+++ b/core/jni/android_hardware_OverlayProperties.cpp
@@ -69,6 +69,16 @@
return false;
}
+static jboolean android_hardware_OverlayProperties_supportMixedColorSpaces(JNIEnv* env,
+ jobject thiz,
+ jlong nativeObject) {
+ gui::OverlayProperties* properties = reinterpret_cast<gui::OverlayProperties*>(nativeObject);
+ if (properties != nullptr && properties->supportMixedColorSpaces) {
+ return true;
+ }
+ return false;
+}
+
// ----------------------------------------------------------------------------
// Serialization
// ----------------------------------------------------------------------------
@@ -128,6 +138,8 @@
{ "nGetDestructor", "()J", (void*) android_hardware_OverlayProperties_getDestructor },
{ "nSupportFp16ForHdr", "(J)Z",
(void*) android_hardware_OverlayProperties_supportFp16ForHdr },
+ { "nSupportMixedColorSpaces", "(J)Z",
+ (void*) android_hardware_OverlayProperties_supportMixedColorSpaces },
{ "nWriteOverlayPropertiesToParcel", "(JLandroid/os/Parcel;)V",
(void*) android_hardware_OverlayProperties_write },
{ "nReadOverlayPropertiesFromParcel", "(Landroid/os/Parcel;)J",
diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp
index 7002d9b..7d379e5 100644
--- a/core/jni/android_view_InputDevice.cpp
+++ b/core/jni/android_view_InputDevice.cpp
@@ -97,7 +97,6 @@
return env->NewLocalRef(inputDeviceObj.get());
}
-
int register_android_view_InputDevice(JNIEnv* env)
{
gInputDeviceClassInfo.clazz = FindClassOrDie(env, "android/view/InputDevice");
@@ -108,9 +107,8 @@
"String;ZIILandroid/view/KeyCharacterMap;Ljava/"
"lang/String;Ljava/lang/String;ZZZZZZ)V");
- gInputDeviceClassInfo.addMotionRange = GetMethodIDOrDie(env, gInputDeviceClassInfo.clazz,
- "addMotionRange", "(IIFFFFF)V");
-
+ gInputDeviceClassInfo.addMotionRange =
+ GetMethodIDOrDie(env, gInputDeviceClassInfo.clazz, "addMotionRange", "(IIFFFFF)V");
return 0;
}
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp
index bc0f9fb..88444cb 100644
--- a/core/jni/android_view_MotionEvent.cpp
+++ b/core/jni/android_view_MotionEvent.cpp
@@ -103,6 +103,20 @@
return eventObj;
}
+jobject android_view_MotionEvent_obtainFromNative(JNIEnv* env, std::unique_ptr<MotionEvent> event) {
+ if (event == nullptr) {
+ return nullptr;
+ }
+ jobject eventObj =
+ env->CallStaticObjectMethod(gMotionEventClassInfo.clazz, gMotionEventClassInfo.obtain);
+ if (env->ExceptionCheck() || !eventObj) {
+ LOGE_EX(env);
+ LOG_ALWAYS_FATAL("An exception occurred while obtaining a Java motion event.");
+ }
+ android_view_MotionEvent_setNativePtr(env, eventObj, event.release());
+ return eventObj;
+}
+
status_t android_view_MotionEvent_recycle(JNIEnv* env, jobject eventObj) {
env->CallVoidMethod(eventObj, gMotionEventClassInfo.recycle);
if (env->ExceptionCheck()) {
diff --git a/core/jni/android_view_MotionEvent.h b/core/jni/android_view_MotionEvent.h
index 32a280e..e812136 100644
--- a/core/jni/android_view_MotionEvent.h
+++ b/core/jni/android_view_MotionEvent.h
@@ -28,6 +28,11 @@
* Returns NULL on error. */
extern jobject android_view_MotionEvent_obtainAsCopy(JNIEnv* env, const MotionEvent& event);
+/* Obtains an instance of a Java MotionEvent object, taking over the ownership of the provided
+ * native MotionEvent instance. Crashes on error. */
+extern jobject android_view_MotionEvent_obtainFromNative(JNIEnv* env,
+ std::unique_ptr<MotionEvent> event);
+
/* Gets the underlying native MotionEvent instance within a DVM MotionEvent object.
* Returns NULL if the event is NULL or if it is uninitialized. */
extern MotionEvent* android_view_MotionEvent_getNativePtr(JNIEnv* env, jobject eventObj);
diff --git a/core/jni/android_view_MotionPredictor.cpp b/core/jni/android_view_MotionPredictor.cpp
new file mode 100644
index 0000000..2c232fa
--- /dev/null
+++ b/core/jni/android_view_MotionPredictor.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#define LOG_TAG "MotionPredictor-JNI"
+
+#include <input/Input.h>
+#include <input/MotionPredictor.h>
+
+#include "android_view_MotionEvent.h"
+#include "core_jni_converters.h"
+#include "core_jni_helpers.h"
+
+/**
+ * This file is a bridge from Java to native for MotionPredictor class.
+ * It should be pass-through only. Do not store any state or put any business logic into this file.
+ */
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static struct {
+ jclass clazz;
+} gMotionEventClassInfo;
+
+// ----------------------------------------------------------------------------
+
+static void release(void* ptr) {
+ delete reinterpret_cast<MotionPredictor*>(ptr);
+}
+
+static jlong android_view_MotionPredictor_nativeGetNativeMotionPredictorFinalizer(JNIEnv* env,
+ jclass clazz) {
+ return reinterpret_cast<jlong>(release);
+}
+
+static jlong android_view_MotionPredictor_nativeInitialize(JNIEnv* env, jclass clazz,
+ jint offsetNanos) {
+ const nsecs_t offset = static_cast<nsecs_t>(offsetNanos);
+ return reinterpret_cast<jlong>(new MotionPredictor(offset));
+}
+
+static void android_view_MotionPredictor_nativeRecord(JNIEnv* env, jclass clazz, jlong ptr,
+ jobject event) {
+ MotionPredictor* predictor = reinterpret_cast<MotionPredictor*>(ptr);
+ MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, event);
+ predictor->record(*motionEvent);
+}
+
+static jobject android_view_MotionPredictor_nativePredict(JNIEnv* env, jclass clazz, jlong ptr,
+ jlong predictionTimeNanos) {
+ MotionPredictor* predictor = reinterpret_cast<MotionPredictor*>(ptr);
+ return toJavaArray(env, predictor->predict(static_cast<nsecs_t>(predictionTimeNanos)),
+ gMotionEventClassInfo.clazz, &android_view_MotionEvent_obtainFromNative);
+}
+
+static jboolean android_view_MotionPredictor_nativeIsPredictionAvailable(JNIEnv* env, jclass clazz,
+ jlong ptr, jint deviceId,
+ jint source) {
+ MotionPredictor* predictor = reinterpret_cast<MotionPredictor*>(ptr);
+ return predictor->isPredictionAvailable(static_cast<int32_t>(deviceId),
+ static_cast<int32_t>(source));
+}
+
+// ----------------------------------------------------------------------------
+
+static const std::array<JNINativeMethod, 5> gMotionPredictorMethods{{
+ /* name, signature, funcPtr */
+ {"nativeInitialize", "(I)J", (void*)android_view_MotionPredictor_nativeInitialize},
+ {"nativeGetNativeMotionPredictorFinalizer", "()J",
+ (void*)android_view_MotionPredictor_nativeGetNativeMotionPredictorFinalizer},
+ {"nativeRecord", "(JLandroid/view/MotionEvent;)V",
+ (void*)android_view_MotionPredictor_nativeRecord},
+ {"nativePredict", "(JJ)[Landroid/view/MotionEvent;",
+ (void*)android_view_MotionPredictor_nativePredict},
+ {"nativeIsPredictionAvailable", "(JII)Z",
+ (void*)android_view_MotionPredictor_nativeIsPredictionAvailable},
+}};
+
+int register_android_view_MotionPredictor(JNIEnv* env) {
+ jclass motionEventClazz = FindClassOrDie(env, "android/view/MotionEvent");
+ gMotionEventClassInfo.clazz = MakeGlobalRefOrDie(env, motionEventClazz);
+ return RegisterMethodsOrDie(env, "android/view/MotionPredictor", gMotionPredictorMethods.data(),
+ gMotionPredictorMethods.size());
+}
+
+} // namespace android
diff --git a/core/jni/core_jni_converters.h b/core/jni/core_jni_converters.h
new file mode 100644
index 0000000..cb9bdf7
--- /dev/null
+++ b/core/jni/core_jni_converters.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#pragma once
+
+#include <nativehelper/scoped_local_ref.h>
+
+template <class T>
+static jobject toJavaArray(JNIEnv* env, std::vector<T>&& list, jclass clazz,
+ jobject (*convert)(JNIEnv* env, T)) {
+ jobjectArray arr = env->NewObjectArray(list.size(), clazz, nullptr);
+ LOG_ALWAYS_FATAL_IF(arr == nullptr);
+ for (size_t i = 0; i < list.size(); i++) {
+ T& t = list[i];
+ ScopedLocalRef<jobject> javaObj(env, convert(env, std::move(t)));
+ env->SetObjectArrayElement(arr, i, javaObj.get());
+ }
+ return arr;
+}
\ No newline at end of file
diff --git a/core/proto/android/service/package.proto b/core/proto/android/service/package.proto
index 1dedbb9..0fe2a6b 100644
--- a/core/proto/android/service/package.proto
+++ b/core/proto/android/service/package.proto
@@ -124,6 +124,9 @@
// The package on behalf of which the initiiating package requested the install.
optional string originating_package_name = 2;
+
+ // The package that is the update owner.
+ optional string update_owner_package_name = 3;
}
message StatesProto {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 31ae0aa..81b3af0 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3993,6 +3993,18 @@
<permission android:name="android.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS"
android:protectionLevel="signature|privileged" />
+ <!-- Allows a system application to be registered with credential manager without
+ having to be enabled by the user.
+ @hide -->
+ <permission android:name="android.permission.SYSTEM_CREDENTIAL_PROVIDER"
+ android:protectionLevel="signature|privileged" />
+
+ <!-- Allows an application to be able to store and retrieve credentials from a remote
+ device.
+ @hide -->
+ <permission android:name="android.permission.HYBRID_CREDENTIAL_PROVIDER"
+ android:protectionLevel="signature|privileged" />
+
<!-- ========================================= -->
<!-- Permissions for special development tools -->
<!-- ========================================= -->
@@ -6815,6 +6827,16 @@
android:protectionLevel="normal" />
<uses-permission android:name="android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION"/>
+ <!-- Allows an application to indicate via {@link
+ android.content.pm.PackageInstaller.SessionParams#setRequestUpdateOwnership}
+ that it has the intention of becoming the update owner.
+ <p>Protection level: normal
+ -->
+ <permission android:name="android.permission.ENFORCE_UPDATE_OWNERSHIP"
+ android:protectionLevel="normal" />
+ <uses-permission android:name="android.permission.ENFORCE_UPDATE_OWNERSHIP" />
+
+
<!-- Allows an application to take screenshots of layers that normally would be blacked out when
a screenshot is taken. Specifically, layers that have the flag
{@link android.view.SurfaceControl#SECURE} will be screenshot if the caller requests to
@@ -6885,7 +6907,7 @@
@hide
-->
<permission android:name="android.permission.ACCESS_AMBIENT_CONTEXT_EVENT"
- android:protectionLevel="internal|role"/>
+ android:protectionLevel="signature|privileged|role"/>
<!-- @SystemApi Required by a AmbientContextEventDetectionService
to ensure that only the service with this permission can bind to it.
@@ -6986,7 +7008,7 @@
@hide
-->
<permission android:name="android.permission.GET_APP_METADATA"
- android:protectionLevel="signature" />
+ android:protectionLevel="signature|installer" />
<!-- @SystemApi Allows the holder to call health connect migration APIs.
@hide -->
diff --git a/core/res/res/values-television/themes_device_defaults.xml b/core/res/res/values-television/themes_device_defaults.xml
index 9d0e522..7cda99a 100644
--- a/core/res/res/values-television/themes_device_defaults.xml
+++ b/core/res/res/values-television/themes_device_defaults.xml
@@ -14,6 +14,7 @@
limitations under the License.
-->
<resources>
+ <style name="Theme.DeviceDefault.Dialog" parent="Theme.Leanback.Dialog" />
<style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
<style name="Theme.DeviceDefault.Dialog.AppError" parent="Theme.Leanback.Dialog.AppError" />
<style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 8ac13ef..ef94484 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1783,6 +1783,14 @@
-->
<attr name="attributionTags" format="string" />
+ <!-- Default value <code>true</code> allows an installer to enable update
+ ownership enforcement for this package via {@link
+ android.content.pm.PackageInstaller.SessionParams#setRequestUpdateOwnership}
+ during initial installation. This overrides the installer's use of {@link
+ android.content.pm.PackageInstaller.SessionParams#setRequestUpdateOwnership}.
+ -->
+ <attr name="allowUpdateOwnership" format="boolean" />
+
<!-- The <code>manifest</code> tag is the root of an
<code>AndroidManifest.xml</code> file,
describing the contents of an Android package (.apk) file. One
@@ -1820,6 +1828,7 @@
<attr name="isSplitRequired" />
<attr name="requiredSplitTypes" />
<attr name="splitTypes" />
+ <attr name="allowUpdateOwnership" />
</declare-styleable>
<!-- The <code>application</code> tag describes application-level components
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index a4d6fdd..6d21fb6 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2344,6 +2344,24 @@
display, this value should be true. -->
<bool name="config_perDisplayFocusEnabled">false</bool>
+ <!-- Whether the system enables motion prediction. Only enable this after confirming that the
+ model works well on your device. To enable system-based prediction, set this value to true.
+ -->
+ <bool name="config_enableMotionPrediction">true</bool>
+
+ <!-- Additional offset to use for motion prediction, in nanoseconds. A positive number indicates
+ that the prediction will take place further in the future. For example, suppose a
+ MotionEvent arrives with timestamp t=1, and the current expected presentation time is t=2.
+ Typically, the prediction will target the presentation time, t=2. If you'd like to make
+ prediction more aggressive, you could set the offset to a positive number.
+ Setting the offset to 1 here would mean that the prediction will be done for time t=3.
+ A negative number may also be provided, to make the prediction less aggressive. In general,
+ the offset here should represent some built-in hardware delays that may not be accounted
+ for by the "expected present time". See also:
+ https://developer.android.com/reference/android/view/
+ Choreographer.FrameTimeline#getExpectedPresentationTimeNanos() -->
+ <integer name="config_motionPredictionOffsetNanos">0</integer>
+
<!-- Whether a software navigation bar should be shown. NOTE: in the future this may be
autodetected from the Configuration. -->
<bool name="config_showNavigationBar">false</bool>
@@ -2704,6 +2722,10 @@
frameworks/base/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java -->
<integer name="config_userTypePackageWhitelistMode">13</integer> <!-- 1+4+8 -->
+ <!-- Whether the main user is a permanent admin user. If the main user is a permanent admin user
+ it can't be deleted or downgraded to non-admin status. -->
+ <bool name="config_isMainUserPermanentAdmin">false</bool>
+
<!-- Whether UI for multi user should be shown -->
<bool name="config_enableMultiUserUI">false</bool>
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index dfd4d9a..a9c56f0 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -124,6 +124,7 @@
<public name="allowSharedIsolatedProcess" />
<public name="keyboardLocale" />
<public name="keyboardLayoutType" />
+ <public name="allowUpdateOwnership" />
</staging-public-group>
<staging-public-group type="id" first-id="0x01cd0000">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 23f45ea..4131887 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -352,6 +352,7 @@
<java-symbol type="bool" name="config_restartRadioAfterProvisioning" />
<java-symbol type="bool" name="config_speed_up_audio_on_mt_calls" />
<java-symbol type="bool" name="config_useFixedVolume" />
+ <java-symbol type="bool" name="config_isMainUserPermanentAdmin"/>
<java-symbol type="bool" name="config_enableMultiUserUI"/>
<java-symbol type="bool" name="config_enableMultipleAdmins"/>
<java-symbol type="bool" name="config_enableNewAutoSelectNetworkUI"/>
@@ -1684,6 +1685,8 @@
<java-symbol type="bool" name="config_lockUiMode" />
<java-symbol type="bool" name="config_reverseDefaultRotation" />
<java-symbol type="bool" name="config_perDisplayFocusEnabled" />
+ <java-symbol type="bool" name="config_enableMotionPrediction" />
+ <java-symbol type="integer" name="config_motionPredictionOffsetNanos" />
<java-symbol type="bool" name="config_showNavigationBar" />
<java-symbol type="bool" name="config_supportAutoRotation" />
<java-symbol type="bool" name="config_dockedStackDividerFreeSnapMode" />
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java
index 82db716..cce1b2b 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java
@@ -21,10 +21,15 @@
import android.hardware.broadcastradio.ProgramInfo;
import android.hardware.broadcastradio.ProgramListChunk;
import android.hardware.broadcastradio.VendorKeyValue;
+import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioMetadata;
+import android.os.RemoteException;
import android.util.ArrayMap;
+import android.util.ArraySet;
+
+import java.util.List;
final class AidlTestUtils {
@@ -94,6 +99,14 @@
return makeHalProgramInfo(hwSel, hwSel.primaryId, hwSel.primaryId, hwSignalQuality);
}
+ static ProgramInfo programInfoToHalProgramInfo(RadioManager.ProgramInfo info) {
+ return makeHalProgramInfo(
+ ConversionUtils.programSelectorToHalProgramSelector(info.getSelector()),
+ ConversionUtils.identifierToHalProgramIdentifier(info.getLogicallyTunedTo()),
+ ConversionUtils.identifierToHalProgramIdentifier(info.getPhysicallyTunedTo()),
+ info.getSignalStrength());
+ }
+
static ProgramInfo makeHalProgramInfo(
android.hardware.broadcastradio.ProgramSelector hwSel,
ProgramIdentifier logicallyTunedTo, ProgramIdentifier physicallyTunedTo,
@@ -108,7 +121,23 @@
return hwInfo;
}
- static ProgramListChunk makeProgramListChunk(boolean purge, boolean complete,
+ static ProgramListChunk makeHalChunk(boolean purge, boolean complete,
+ List<RadioManager.ProgramInfo> modified, List<ProgramSelector.Identifier> removed) {
+ ProgramInfo[] halModified =
+ new android.hardware.broadcastradio.ProgramInfo[modified.size()];
+ for (int i = 0; i < modified.size(); i++) {
+ halModified[i] = programInfoToHalProgramInfo(modified.get(i));
+ }
+
+ ProgramIdentifier[] halRemoved =
+ new android.hardware.broadcastradio.ProgramIdentifier[removed.size()];
+ for (int i = 0; i < removed.size(); i++) {
+ halRemoved[i] = ConversionUtils.identifierToHalProgramIdentifier(removed.get(i));
+ }
+ return makeHalChunk(purge, complete, halModified, halRemoved);
+ }
+
+ static ProgramListChunk makeHalChunk(boolean purge, boolean complete,
ProgramInfo[] modified, ProgramIdentifier[] removed) {
ProgramListChunk halChunk = new ProgramListChunk();
halChunk.purge = purge;
@@ -118,6 +147,21 @@
return halChunk;
}
+ static ProgramList.Chunk makeChunk(boolean purge, boolean complete,
+ List<RadioManager.ProgramInfo> modified,
+ List<ProgramSelector.Identifier> removed) throws RemoteException {
+ ArraySet<RadioManager.ProgramInfo> modifiedSet = new ArraySet<>();
+ if (modified != null) {
+ modifiedSet.addAll(modified);
+ }
+ ArraySet<ProgramSelector.Identifier> removedSet = new ArraySet<>();
+ if (removed != null) {
+ removedSet.addAll(removed);
+ }
+ ProgramList.Chunk chunk = new ProgramList.Chunk(purge, complete, modifiedSet, removedSet);
+ return chunk;
+ }
+
static VendorKeyValue makeVendorKeyValue(String vendorKey, String vendorValue) {
VendorKeyValue vendorKeyValue = new VendorKeyValue();
vendorKeyValue.key = vendorKey;
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
index 710c150..5d0e076 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
@@ -328,7 +328,7 @@
TEST_HAL_DAB_SID_EXT_ID, TEST_HAL_DAB_FREQUENCY_ID, TEST_SIGNAL_QUALITY);
RadioManager.ProgramInfo dabInfo =
ConversionUtils.programInfoFromHalProgramInfo(halDabInfo);
- ProgramListChunk halChunk = AidlTestUtils.makeProgramListChunk(purge, complete,
+ ProgramListChunk halChunk = AidlTestUtils.makeHalChunk(purge, complete,
new ProgramInfo[]{halDabInfo},
new ProgramIdentifier[]{TEST_HAL_VENDOR_ID, TEST_HAL_FM_FREQUENCY_ID});
@@ -353,7 +353,7 @@
TEST_HAL_DAB_ENSEMBLE_ID, TEST_HAL_DAB_FREQUENCY_ID});
ProgramInfo halDabInfo = AidlTestUtils.makeHalProgramInfo(halDabSelector,
TEST_HAL_DAB_SID_EXT_ID, TEST_HAL_DAB_ENSEMBLE_ID, TEST_SIGNAL_QUALITY);
- ProgramListChunk halChunk = AidlTestUtils.makeProgramListChunk(purge, complete,
+ ProgramListChunk halChunk = AidlTestUtils.makeHalChunk(purge, complete,
new ProgramInfo[]{halDabInfo}, new ProgramIdentifier[]{TEST_HAL_FM_FREQUENCY_ID});
ProgramList.Chunk chunk = ConversionUtils.chunkFromHalProgramListChunk(halChunk);
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ProgramInfoCacheTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ProgramInfoCacheTest.java
new file mode 100644
index 0000000..d54397e
--- /dev/null
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ProgramInfoCacheTest.java
@@ -0,0 +1,409 @@
+/*
+ * Copyright (C) 2022 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.server.broadcastradio.aidl;
+
+import android.hardware.broadcastradio.ProgramIdentifier;
+import android.hardware.broadcastradio.ProgramInfo;
+import android.hardware.broadcastradio.ProgramListChunk;
+import android.hardware.radio.ProgramList;
+import android.hardware.radio.ProgramSelector;
+import android.hardware.radio.RadioManager;
+import android.os.RemoteException;
+import android.util.ArraySet;
+
+import com.google.common.truth.Expect;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Unit tests for AIDL ProgramInfoCache
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class ProgramInfoCacheTest {
+
+ private static final int TEST_SIGNAL_QUALITY = 90;
+
+ private static final ProgramSelector.Identifier TEST_FM_FREQUENCY_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY,
+ /* value= */ 88_500);
+ private static final RadioManager.ProgramInfo TEST_FM_INFO = AidlTestUtils.makeProgramInfo(
+ AidlTestUtils.makeProgramSelector(ProgramSelector.PROGRAM_TYPE_FM,
+ TEST_FM_FREQUENCY_ID), TEST_FM_FREQUENCY_ID, TEST_FM_FREQUENCY_ID,
+ TEST_SIGNAL_QUALITY);
+ private static final RadioManager.ProgramInfo TEST_FM_INFO_MODIFIED =
+ AidlTestUtils.makeProgramInfo(AidlTestUtils.makeProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_FM, TEST_FM_FREQUENCY_ID), TEST_FM_FREQUENCY_ID,
+ TEST_FM_FREQUENCY_ID, /* signalQuality= */ 99);
+
+ private static final ProgramSelector.Identifier TEST_AM_FREQUENCY_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY,
+ /* value= */ 1_700);
+ private static final RadioManager.ProgramInfo TEST_AM_INFO = AidlTestUtils.makeProgramInfo(
+ AidlTestUtils.makeProgramSelector(ProgramSelector.PROGRAM_TYPE_FM,
+ TEST_AM_FREQUENCY_ID), TEST_AM_FREQUENCY_ID, TEST_AM_FREQUENCY_ID,
+ TEST_SIGNAL_QUALITY);
+
+ private static final ProgramSelector.Identifier TEST_RDS_PI_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_RDS_PI,
+ /* value= */ 15_019);
+ private static final RadioManager.ProgramInfo TEST_RDS_INFO = AidlTestUtils.makeProgramInfo(
+ AidlTestUtils.makeProgramSelector(ProgramSelector.PROGRAM_TYPE_FM, TEST_RDS_PI_ID),
+ TEST_RDS_PI_ID, new ProgramSelector.Identifier(
+ ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY, /* value= */ 89_500),
+ TEST_SIGNAL_QUALITY);
+
+ private static final ProgramSelector.Identifier TEST_DAB_DMB_SID_EXT_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT,
+ /* value= */ 0xA000000111L);
+ private static final ProgramSelector.Identifier TEST_DAB_ENSEMBLE_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE,
+ /* value= */ 0x1001);
+ private static final ProgramSelector.Identifier TEST_DAB_FREQUENCY_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY,
+ /* value= */ 220_352);
+ private static final RadioManager.ProgramInfo TEST_DAB_INFO = AidlTestUtils.makeProgramInfo(
+ new ProgramSelector(ProgramSelector.PROGRAM_TYPE_DAB, TEST_DAB_DMB_SID_EXT_ID,
+ new ProgramSelector.Identifier[]{TEST_DAB_FREQUENCY_ID, TEST_DAB_ENSEMBLE_ID},
+ /* vendorIds= */ null), TEST_DAB_DMB_SID_EXT_ID, TEST_DAB_FREQUENCY_ID,
+ TEST_SIGNAL_QUALITY);
+
+ private static final ProgramSelector.Identifier TEST_VENDOR_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_VENDOR_START,
+ /* value= */ 9_001);
+ private static final RadioManager.ProgramInfo TEST_VENDOR_INFO = AidlTestUtils.makeProgramInfo(
+ AidlTestUtils.makeProgramSelector(ProgramSelector.PROGRAM_TYPE_VENDOR_START,
+ TEST_VENDOR_ID), TEST_VENDOR_ID, TEST_VENDOR_ID, TEST_SIGNAL_QUALITY);
+
+ private static final ProgramInfoCache FULL_PROGRAM_INFO_CACHE = new ProgramInfoCache(
+ /* filter= */ null, /* complete= */ true,
+ TEST_FM_INFO, TEST_AM_INFO, TEST_RDS_INFO, TEST_DAB_INFO, TEST_VENDOR_INFO);
+
+ @Rule
+ public final Expect expect = Expect.create();
+
+ @Test
+ public void isComplete_forCompleteProgramInfoCache_returnsTrue() {
+ expect.withMessage("Complete program info cache")
+ .that(FULL_PROGRAM_INFO_CACHE.isComplete()).isTrue();
+ }
+
+ @Test
+ public void isComplete_forIncompleteProgramInfoCache_returnsFalse() {
+ ProgramInfoCache programInfoCache = new ProgramInfoCache(/* filter= */ null,
+ /* complete= */ false);
+ expect.withMessage("Incomplete program info cache")
+ .that(programInfoCache.isComplete()).isFalse();
+ }
+
+ @Test
+ public void getFilter_forProgramInfoCache() {
+ ProgramList.Filter fmFilter = new ProgramList.Filter(
+ Set.of(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY), new ArraySet<>(),
+ /* includeCategories= */ true, /* excludeModifications= */ false);
+ ProgramInfoCache fmProgramInfoCache = new ProgramInfoCache(fmFilter);
+
+ expect.withMessage("Program info cache filter")
+ .that(fmProgramInfoCache.getFilter()).isEqualTo(fmFilter);
+ }
+
+ @Test
+ public void updateFromHalProgramListChunk_withPurgingCompleteChunk() {
+ ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null,
+ /* complete= */ false, TEST_FM_INFO);
+ ProgramListChunk chunk = AidlTestUtils.makeHalChunk(/* purge= */ true, /* complete= */ true,
+ new ProgramInfo[]{AidlTestUtils.programInfoToHalProgramInfo(TEST_RDS_INFO),
+ AidlTestUtils.programInfoToHalProgramInfo(TEST_VENDOR_INFO)},
+ new ProgramIdentifier[]{});
+
+ cache.updateFromHalProgramListChunk(chunk);
+
+ expect.withMessage("Program cache updated with purge-enabled and complete chunk")
+ .that(cache.toProgramInfoList())
+ .containsExactly(TEST_RDS_INFO, TEST_VENDOR_INFO);
+ expect.withMessage("Complete program cache").that(cache.isComplete()).isTrue();
+ }
+
+ @Test
+ public void updateFromHalProgramListChunk_withNonPurgingIncompleteChunk() {
+ ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null,
+ /* complete= */ false, TEST_FM_INFO, TEST_RDS_INFO, TEST_AM_INFO);
+ ProgramListChunk chunk = AidlTestUtils.makeHalChunk(/* purge= */ false,
+ /* complete= */ false,
+ new ProgramInfo[]{AidlTestUtils.programInfoToHalProgramInfo(TEST_FM_INFO_MODIFIED),
+ AidlTestUtils.programInfoToHalProgramInfo(TEST_VENDOR_INFO)},
+ new ProgramIdentifier[]{ConversionUtils.identifierToHalProgramIdentifier(
+ TEST_RDS_PI_ID)});
+
+ cache.updateFromHalProgramListChunk(chunk);
+
+ expect.withMessage("Program cache updated with non-purging and incomplete chunk")
+ .that(cache.toProgramInfoList())
+ .containsExactly(TEST_FM_INFO_MODIFIED, TEST_VENDOR_INFO, TEST_AM_INFO);
+ expect.withMessage("Incomplete program cache").that(cache.isComplete()).isFalse();
+ }
+
+ @Test
+ public void filterAndUpdateFromInternal_withNullFilter() {
+ ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null,
+ /* complete= */ true);
+
+ cache.filterAndUpdateFromInternal(FULL_PROGRAM_INFO_CACHE, /* purge= */ false);
+
+ expect.withMessage("Program cache filtered by null filter")
+ .that(cache.toProgramInfoList())
+ .containsExactly(TEST_FM_INFO, TEST_AM_INFO, TEST_RDS_INFO, TEST_DAB_INFO,
+ TEST_VENDOR_INFO);
+ }
+
+ @Test
+ public void filterAndUpdateFromInternal_withEmptyFilter() {
+ ProgramInfoCache cache = new ProgramInfoCache(new ProgramList.Filter(new ArraySet<>(),
+ new ArraySet<>(),
+ /* includeCategories= */ true, /* excludeModifications= */ false));
+
+ cache.filterAndUpdateFromInternal(FULL_PROGRAM_INFO_CACHE, /* purge= */ false);
+
+ expect.withMessage("Program cache filtered by empty filter")
+ .that(cache.toProgramInfoList())
+ .containsExactly(TEST_FM_INFO, TEST_AM_INFO, TEST_RDS_INFO, TEST_DAB_INFO,
+ TEST_VENDOR_INFO);
+ }
+
+ @Test
+ public void filterAndUpdateFromInternal_withFilterByIdentifierType() {
+ ProgramInfoCache cache = new ProgramInfoCache(
+ new ProgramList.Filter(Set.of(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY,
+ ProgramSelector.IDENTIFIER_TYPE_RDS_PI), new ArraySet<>(),
+ /* includeCategories= */ true, /* excludeModifications= */ false));
+
+ cache.filterAndUpdateFromInternal(FULL_PROGRAM_INFO_CACHE, /* purge= */ false);
+
+ expect.withMessage("Program cache filtered by identifier type")
+ .that(cache.toProgramInfoList())
+ .containsExactly(TEST_FM_INFO, TEST_AM_INFO, TEST_RDS_INFO);
+ }
+
+ @Test
+ public void filterAndUpdateFromInternal_withFilterByIdentifier() {
+ ProgramInfoCache cache = new ProgramInfoCache(new ProgramList.Filter(
+ new ArraySet<>(), Set.of(TEST_FM_FREQUENCY_ID, TEST_DAB_DMB_SID_EXT_ID),
+ /* includeCategories= */ true, /* excludeModifications= */ false));
+ int maxNumModifiedPerChunk = 2;
+ int maxNumRemovedPerChunk = 2;
+
+ List<ProgramList.Chunk> programListChunks = cache.filterAndUpdateFromInternal(
+ FULL_PROGRAM_INFO_CACHE, /* purge= */ true, maxNumModifiedPerChunk,
+ maxNumRemovedPerChunk);
+
+ expect.withMessage("Program cache filtered by identifier")
+ .that(cache.toProgramInfoList()).containsExactly(TEST_FM_INFO, TEST_DAB_INFO);
+ verifyChunkListPurge(programListChunks, /* purge= */ true);
+ verifyChunkListComplete(programListChunks, FULL_PROGRAM_INFO_CACHE.isComplete());
+ verifyChunkListModified(programListChunks, maxNumModifiedPerChunk, TEST_FM_INFO,
+ TEST_DAB_INFO);
+ verifyChunkListRemoved(programListChunks, maxNumRemovedPerChunk);
+ }
+
+ @Test
+ public void filterAndUpdateFromInternal_withFilterExcludingCategories() {
+ ProgramInfoCache cache = new ProgramInfoCache(new ProgramList.Filter(new ArraySet<>(),
+ new ArraySet<>(), /* includeCategories= */ false,
+ /* excludeModifications= */ false));
+ int maxNumModifiedPerChunk = 3;
+ int maxNumRemovedPerChunk = 2;
+
+ List<ProgramList.Chunk> programListChunks = cache.filterAndUpdateFromInternal(
+ FULL_PROGRAM_INFO_CACHE, /* purge= */ false, maxNumModifiedPerChunk,
+ maxNumRemovedPerChunk);
+
+ expect.withMessage("Program cache filtered by excluding categories")
+ .that(cache.toProgramInfoList())
+ .containsExactly(TEST_FM_INFO, TEST_AM_INFO, TEST_RDS_INFO, TEST_DAB_INFO);
+ verifyChunkListPurge(programListChunks, /* purge= */ true);
+ verifyChunkListComplete(programListChunks, FULL_PROGRAM_INFO_CACHE.isComplete());
+ verifyChunkListModified(programListChunks, maxNumModifiedPerChunk, TEST_FM_INFO,
+ TEST_AM_INFO, TEST_RDS_INFO, TEST_DAB_INFO);
+ verifyChunkListRemoved(programListChunks, maxNumRemovedPerChunk);
+ }
+
+ @Test
+ public void filterAndUpdateFromInternal_withFilterExcludingModifications() {
+ ProgramList.Filter filterExcludingModifications = new ProgramList.Filter(new ArraySet<>(),
+ new ArraySet<>(), /* includeCategories= */ true,
+ /* excludeModifications= */ true);
+ ProgramInfoCache cache = new ProgramInfoCache(filterExcludingModifications,
+ /* complete= */ true, TEST_FM_INFO, TEST_RDS_INFO, TEST_AM_INFO, TEST_DAB_INFO);
+ ProgramInfoCache halCache = new ProgramInfoCache(/* filter= */ null, /* complete= */ false,
+ TEST_FM_INFO_MODIFIED, TEST_VENDOR_INFO);
+ int maxNumModifiedPerChunk = 2;
+ int maxNumRemovedPerChunk = 2;
+
+ List<ProgramList.Chunk> programListChunks = cache.filterAndUpdateFromInternal(halCache,
+ /* purge= */ false, maxNumModifiedPerChunk, maxNumRemovedPerChunk);
+
+ expect.withMessage("Program cache filtered by excluding modifications")
+ .that(cache.toProgramInfoList())
+ .containsExactly(TEST_FM_INFO, TEST_VENDOR_INFO);
+ verifyChunkListPurge(programListChunks, /* purge= */ false);
+ verifyChunkListComplete(programListChunks, halCache.isComplete());
+ verifyChunkListModified(programListChunks, maxNumModifiedPerChunk, TEST_VENDOR_INFO);
+ verifyChunkListRemoved(programListChunks, maxNumRemovedPerChunk, TEST_RDS_PI_ID,
+ TEST_AM_FREQUENCY_ID, TEST_DAB_DMB_SID_EXT_ID);
+ }
+
+ @Test
+ public void filterAndUpdateFromInternal_withPurge() {
+ ProgramInfoCache cache = new ProgramInfoCache(new ProgramList.Filter(new ArraySet<>(),
+ new ArraySet<>(), /* includeCategories= */ true,
+ /* excludeModifications= */ false),
+ /* complete= */ true, TEST_FM_INFO, TEST_RDS_INFO);
+ ProgramInfoCache halCache = new ProgramInfoCache(/* filter= */ null, /* complete= */ false,
+ TEST_FM_INFO_MODIFIED, TEST_DAB_INFO, TEST_VENDOR_INFO);
+ int maxNumModifiedPerChunk = 2;
+ int maxNumRemovedPerChunk = 2;
+
+ List<ProgramList.Chunk> programListChunks = cache.filterAndUpdateFromInternal(halCache,
+ /* purge= */ true, maxNumModifiedPerChunk, maxNumRemovedPerChunk);
+
+ expect.withMessage("Purged program cache").that(cache.toProgramInfoList())
+ .containsExactly(TEST_FM_INFO_MODIFIED, TEST_DAB_INFO, TEST_VENDOR_INFO);
+ verifyChunkListPurge(programListChunks, /* purge= */ true);
+ verifyChunkListComplete(programListChunks, halCache.isComplete());
+ verifyChunkListModified(programListChunks, maxNumModifiedPerChunk, TEST_FM_INFO_MODIFIED,
+ TEST_DAB_INFO, TEST_VENDOR_INFO);
+ verifyChunkListRemoved(programListChunks, maxNumRemovedPerChunk);
+ }
+
+ @Test
+ public void filterAndApplyChunkInternal_withPurgingIncompleteChunk() throws RemoteException {
+ ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null,
+ /* complete= */ false, TEST_FM_INFO, TEST_DAB_INFO);
+ ProgramList.Chunk chunk = AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ false,
+ List.of(TEST_FM_INFO_MODIFIED, TEST_RDS_INFO, TEST_VENDOR_INFO),
+ List.of(TEST_DAB_DMB_SID_EXT_ID));
+ int maxNumModifiedPerChunk = 2;
+ int maxNumRemovedPerChunk = 2;
+
+ List<ProgramList.Chunk> programListChunks = cache.filterAndApplyChunkInternal(chunk,
+ maxNumModifiedPerChunk, maxNumRemovedPerChunk);
+
+ expect.withMessage("Program cache applied with non-purging and complete chunk")
+ .that(cache.toProgramInfoList())
+ .containsExactly(TEST_FM_INFO_MODIFIED, TEST_RDS_INFO, TEST_VENDOR_INFO);
+ verifyChunkListPurge(programListChunks, /* purge= */ true);
+ verifyChunkListComplete(programListChunks, /* complete= */ false);
+ verifyChunkListModified(programListChunks, maxNumModifiedPerChunk, TEST_FM_INFO_MODIFIED,
+ TEST_RDS_INFO, TEST_VENDOR_INFO);
+ verifyChunkListRemoved(programListChunks, maxNumRemovedPerChunk);
+ }
+
+ @Test
+ public void filterAndApplyChunk_withNonPurgingCompleteChunk() throws RemoteException {
+ ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null,
+ /* complete= */ false, TEST_FM_INFO, TEST_RDS_INFO, TEST_AM_INFO, TEST_DAB_INFO);
+ ProgramList.Chunk chunk = AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
+ List.of(TEST_FM_INFO_MODIFIED, TEST_VENDOR_INFO),
+ List.of(TEST_RDS_PI_ID, TEST_AM_FREQUENCY_ID, TEST_DAB_DMB_SID_EXT_ID));
+ int maxNumModifiedPerChunk = 2;
+ int maxNumRemovedPerChunk = 2;
+
+ List<ProgramList.Chunk> programListChunks = cache.filterAndApplyChunkInternal(chunk,
+ maxNumModifiedPerChunk, maxNumRemovedPerChunk);
+
+ expect.withMessage("Program cache applied with purge-enabled complete chunk")
+ .that(cache.toProgramInfoList())
+ .containsExactly(TEST_FM_INFO_MODIFIED, TEST_VENDOR_INFO);
+ verifyChunkListPurge(programListChunks, /* purge= */ false);
+ verifyChunkListComplete(programListChunks, /* complete= */ true);
+ verifyChunkListModified(programListChunks, maxNumModifiedPerChunk, TEST_FM_INFO_MODIFIED,
+ TEST_VENDOR_INFO);
+ verifyChunkListRemoved(programListChunks, maxNumRemovedPerChunk, TEST_RDS_PI_ID,
+ TEST_AM_FREQUENCY_ID, TEST_DAB_DMB_SID_EXT_ID);
+ }
+
+ private void verifyChunkListPurge(List<ProgramList.Chunk> chunks, boolean purge) {
+ if (chunks.isEmpty()) {
+ return;
+ }
+ for (int i = 0; i < chunks.size(); i++) {
+ ProgramList.Chunk chunk = chunks.get(i);
+ boolean expectedPurge = (i == 0 && purge);
+
+ expect.withMessage("Purge for chunk %s", i)
+ .that(chunk.isPurge()).isEqualTo(expectedPurge);
+ }
+ }
+
+ private void verifyChunkListComplete(List<ProgramList.Chunk> chunks, boolean complete) {
+ if (chunks.isEmpty()) {
+ return;
+ }
+ for (int i = 0; i < chunks.size(); i++) {
+ ProgramList.Chunk chunk = chunks.get(i);
+ boolean expectedComplete = (i == chunks.size() - 1 && complete);
+
+ expect.withMessage("Purge for chunk %s", i)
+ .that(chunk.isComplete()).isEqualTo(expectedComplete);
+ }
+ }
+
+ private void verifyChunkListModified(List<ProgramList.Chunk> chunks,
+ int maxModifiedPerChunk, RadioManager.ProgramInfo... expectedProgramInfos) {
+ if (chunks.isEmpty()) {
+ expect.withMessage("Empty program info list")
+ .that(expectedProgramInfos.length).isEqualTo(0);
+ return;
+ }
+
+ ArraySet<RadioManager.ProgramInfo> actualSet = new ArraySet<>();
+ for (int i = 0; i < chunks.size(); i++) {
+ Set<RadioManager.ProgramInfo> chunkModified = chunks.get(i).getModified();
+ actualSet.addAll(chunkModified);
+
+ expect.withMessage("Chunk %s modified program info array size", i)
+ .that(chunkModified.size()).isAtMost(maxModifiedPerChunk);
+ }
+ expect.withMessage("Program info items")
+ .that(actualSet).containsExactlyElementsIn(expectedProgramInfos);
+ }
+
+ private void verifyChunkListRemoved(List<ProgramList.Chunk> chunks,
+ int maxRemovedPerChunk, ProgramSelector.Identifier... expectedIdentifiers) {
+ if (chunks.isEmpty()) {
+ expect.withMessage("Empty program info list")
+ .that(expectedIdentifiers.length).isEqualTo(0);
+ return;
+ }
+
+ ArraySet<ProgramSelector.Identifier> actualSet = new ArraySet<>();
+ for (int i = 0; i < chunks.size(); i++) {
+ Set<ProgramSelector.Identifier> chunkRemoved = chunks.get(i).getRemoved();
+ actualSet.addAll(chunkRemoved);
+
+ expect.withMessage("Chunk %s removed identifier array size ", i)
+ .that(chunkRemoved.size()).isAtMost(maxRemovedPerChunk);
+ }
+ expect.withMessage("Removed identifier items")
+ .that(actualSet).containsExactlyElementsIn(expectedIdentifiers);
+ }
+}
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
index d7723ac..464ecb2 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
@@ -37,7 +37,9 @@
import android.hardware.broadcastradio.IBroadcastRadio;
import android.hardware.broadcastradio.ITunerCallback;
import android.hardware.broadcastradio.IdentifierType;
+import android.hardware.broadcastradio.ProgramFilter;
import android.hardware.broadcastradio.ProgramInfo;
+import android.hardware.broadcastradio.ProgramListChunk;
import android.hardware.broadcastradio.Result;
import android.hardware.broadcastradio.VendorKeyValue;
import android.hardware.radio.ProgramList;
@@ -61,8 +63,10 @@
import org.mockito.Mock;
import org.mockito.verification.VerificationWithTimeout;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Tests for AIDL HAL TunerSession.
@@ -72,7 +76,7 @@
private static final int TARGET_SDK_VERSION = Build.VERSION_CODES.CUR_DEVELOPMENT;
private static final VerificationWithTimeout CALLBACK_TIMEOUT =
timeout(/* millis= */ 200);
- private static final int SIGNAL_QUALITY = 1;
+ private static final int SIGNAL_QUALITY = 90;
private static final long AM_FM_FREQUENCY_SPACING = 500;
private static final long[] AM_FM_FREQUENCY_LIST = {97_500, 98_100, 99_100};
private static final RadioManager.FmBandDescriptor FM_BAND_DESCRIPTOR =
@@ -84,6 +88,27 @@
new RadioManager.FmBandConfig(FM_BAND_DESCRIPTOR);
private static final int UNSUPPORTED_CONFIG_FLAG = 0;
+ private static final ProgramSelector.Identifier TEST_FM_FREQUENCY_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY,
+ /* value= */ 88_500);
+ private static final ProgramSelector.Identifier TEST_RDS_PI_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_RDS_PI,
+ /* value= */ 15_019);
+
+ private static final RadioManager.ProgramInfo TEST_FM_INFO = AidlTestUtils.makeProgramInfo(
+ AidlTestUtils.makeProgramSelector(ProgramSelector.PROGRAM_TYPE_FM,
+ TEST_FM_FREQUENCY_ID), TEST_FM_FREQUENCY_ID, TEST_FM_FREQUENCY_ID,
+ SIGNAL_QUALITY);
+ private static final RadioManager.ProgramInfo TEST_FM_INFO_MODIFIED =
+ AidlTestUtils.makeProgramInfo(AidlTestUtils.makeProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_FM, TEST_FM_FREQUENCY_ID), TEST_FM_FREQUENCY_ID,
+ TEST_FM_FREQUENCY_ID, /* signalQuality= */ 100);
+ private static final RadioManager.ProgramInfo TEST_RDS_INFO = AidlTestUtils.makeProgramInfo(
+ AidlTestUtils.makeProgramSelector(ProgramSelector.PROGRAM_TYPE_FM, TEST_RDS_PI_ID),
+ TEST_RDS_PI_ID, new ProgramSelector.Identifier(
+ ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY, /* value= */ 89_500),
+ SIGNAL_QUALITY);
+
// Mocks
@Mock private IBroadcastRadio mBroadcastRadioMock;
private android.hardware.radio.ITunerCallback[] mAidlTunerCallbackMocks;
@@ -393,7 +418,7 @@
}
@Test
- public void tune_withHalHasUnknownError_fails() throws Exception {
+ public void tune_withUnknownErrorFromHal_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
ProgramSelector sel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
doThrow(new ServiceSpecificException(Result.UNKNOWN_ERROR))
@@ -403,7 +428,7 @@
mTunerSessions[0].tune(sel);
});
- assertWithMessage("Exception for tuning when HAL has unknown error")
+ assertWithMessage("Unknown error HAL exception when tuning")
.that(thrown).hasMessageThat().contains("UNKNOWN_ERROR");
}
@@ -536,7 +561,7 @@
}
@Test
- public void seek_withHalHasInternalError_fails() throws Exception {
+ public void seek_withInternalErrorFromHal_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
doThrow(new ServiceSpecificException(Result.INTERNAL_ERROR))
.when(mBroadcastRadioMock).seek(anyBoolean(), anyBoolean());
@@ -545,7 +570,7 @@
mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false);
});
- assertWithMessage("Exception for seeking when HAL has internal error")
+ assertWithMessage("Internal error HAL exception when seeking")
.that(thrown).hasMessageThat().contains("INTERNAL_ERROR");
}
@@ -644,11 +669,276 @@
}
@Test
+ public void startProgramListUpdates_withEmptyFilter() throws Exception {
+ openAidlClients(/* numClients= */ 1);
+ ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
+ /* includeCategories= */ true, /* excludeModifications= */ false);
+ ProgramFilter halFilter = ConversionUtils.filterToHalProgramFilter(filter);
+ List<RadioManager.ProgramInfo> modified = List.of(TEST_FM_INFO, TEST_RDS_INFO);
+ List<ProgramSelector.Identifier> removed = new ArrayList<>();
+ ProgramListChunk halProgramList = AidlTestUtils.makeHalChunk(/* purge= */ true,
+ /* complete= */ true, modified, removed);
+ ProgramList.Chunk expectedProgramList =
+ AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ true, modified, removed);
+
+ mTunerSessions[0].startProgramListUpdates(filter);
+ mHalTunerCallback.onProgramListUpdated(halProgramList);
+
+ verify(mBroadcastRadioMock).startProgramListUpdates(halFilter);
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT)
+ .onProgramListUpdated(expectedProgramList);
+ }
+
+ @Test
+ public void startProgramListUpdates_withCallbackCalledForMultipleTimes() throws Exception {
+ openAidlClients(/* numClients= */ 1);
+ ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
+ /* includeCategories= */ true, /* excludeModifications= */ false);
+ mTunerSessions[0].startProgramListUpdates(filter);
+ mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ true,
+ /* complete= */ true, List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
+ AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ true,
+ List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
+
+ mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
+ /* complete= */ true, List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
+
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
+ AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
+ List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
+ }
+
+ @Test
+ public void startProgramListUpdates_withTheSameFilterForMultipleTimes() throws Exception {
+ openAidlClients(/* numClients= */ 1);
+ ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
+ /* includeCategories= */ true, /* excludeModifications= */ false);
+ mTunerSessions[0].startProgramListUpdates(filter);
+ mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ true,
+ /* complete= */ true, List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
+ AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ true,
+ List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
+ mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
+ /* complete= */ true, List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
+ AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
+ List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
+
+ mTunerSessions[0].startProgramListUpdates(filter);
+
+ verify(mBroadcastRadioMock).startProgramListUpdates(any());
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
+ AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ true,
+ List.of(TEST_FM_INFO_MODIFIED), new ArrayList<>()));
+ }
+
+ @Test
+ public void startProgramListUpdates_withNullFilter() throws Exception {
+ openAidlClients(/* numClients= */ 1);
+
+ mTunerSessions[0].startProgramListUpdates(/* filter= */ null);
+ mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ true,
+ /* complete= */ true, List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
+
+ verify(mBroadcastRadioMock).startProgramListUpdates(any());
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
+ AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ true,
+ List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
+
+ mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
+ /* complete= */ true, List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
+
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
+ AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
+ List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
+ }
+
+ @Test
+ public void startProgramListUpdates_withIdFilter() throws Exception {
+ openAidlClients(/* numClients= */ 1);
+ ProgramList.Filter idFilter = new ProgramList.Filter(new ArraySet<>(),
+ Set.of(TEST_RDS_PI_ID), /* includeCategories= */ true,
+ /* excludeModifications= */ true);
+ ProgramFilter halFilter = ConversionUtils.filterToHalProgramFilter(idFilter);
+
+ mTunerSessions[0].startProgramListUpdates(idFilter);
+ mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
+ /* complete= */ true, List.of(TEST_RDS_INFO), new ArrayList<>()));
+
+ verify(mBroadcastRadioMock).startProgramListUpdates(halFilter);
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
+ AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
+ List.of(TEST_RDS_INFO), new ArrayList<>()));
+
+ mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
+ /* complete= */ true, List.of(TEST_FM_INFO), new ArrayList<>()));
+
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(any());
+ }
+
+ @Test
+ public void startProgramListUpdates_withFilterExcludingModifications() throws Exception {
+ openAidlClients(/* numClients= */ 1);
+ ProgramList.Filter filterExcludingModifications = new ProgramList.Filter(
+ Set.of(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY), new ArraySet<>(),
+ /* includeCategories= */ true, /* excludeModifications= */ true);
+ ProgramFilter halFilter =
+ ConversionUtils.filterToHalProgramFilter(filterExcludingModifications);
+
+ mTunerSessions[0].startProgramListUpdates(filterExcludingModifications);
+ mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
+ /* complete= */ true, List.of(TEST_FM_INFO), new ArrayList<>()));
+
+ verify(mBroadcastRadioMock).startProgramListUpdates(halFilter);
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
+ AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
+ List.of(TEST_FM_INFO), new ArrayList<>()));
+
+ mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
+ /* complete= */ true, List.of(TEST_FM_INFO_MODIFIED), new ArrayList<>()));
+
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(any());
+ }
+
+ @Test
+ public void startProgramListUpdates_withFilterIncludingModifications() throws Exception {
+ openAidlClients(/* numClients= */ 1);
+ ProgramList.Filter filterIncludingModifications = new ProgramList.Filter(
+ Set.of(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY), new ArraySet<>(),
+ /* includeCategories= */ true, /* excludeModifications= */ false);
+ ProgramFilter halFilter =
+ ConversionUtils.filterToHalProgramFilter(filterIncludingModifications);
+
+ mTunerSessions[0].startProgramListUpdates(filterIncludingModifications);
+ mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
+ /* complete= */ true, List.of(TEST_FM_INFO), new ArrayList<>()));
+
+ verify(mBroadcastRadioMock).startProgramListUpdates(halFilter);
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
+ AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
+ List.of(TEST_FM_INFO), new ArrayList<>()));
+
+ mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
+ /* complete= */ true, List.of(TEST_FM_INFO_MODIFIED), new ArrayList<>()));
+
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
+ AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
+ List.of(TEST_FM_INFO_MODIFIED), new ArrayList<>()));
+ }
+
+ @Test
+ public void onProgramListUpdated_afterSessionClosed_doesNotUpdates() throws Exception {
+ openAidlClients(/* numClients= */ 1);
+ ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
+ /* includeCategories= */ true, /* excludeModifications= */ false);
+ mTunerSessions[0].startProgramListUpdates(filter);
+
+ mTunerSessions[0].close();
+
+ verify(mBroadcastRadioMock).stopProgramListUpdates();
+
+ mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
+ /* complete= */ true, List.of(TEST_FM_INFO), new ArrayList<>()));
+
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)).onProgramListUpdated(any());
+ }
+
+ @Test
+ public void startProgramListUpdates_forMultipleSessions() throws Exception {
+ int numSessions = 3;
+ openAidlClients(numSessions);
+ ProgramList.Filter fmIdFilter = new ProgramList.Filter(new ArraySet<>(),
+ Set.of(TEST_FM_FREQUENCY_ID), /* includeCategories= */ false,
+ /* excludeModifications= */ true);
+ ProgramList.Filter filterExcludingCategories = new ProgramList.Filter(new ArraySet<>(),
+ new ArraySet<>(), /* includeCategories= */ true,
+ /* excludeModifications= */ true);
+ ProgramList.Filter rdsTypeFilter = new ProgramList.Filter(
+ Set.of(ProgramSelector.IDENTIFIER_TYPE_RDS_PI), new ArraySet<>(),
+ /* includeCategories= */ true, /* excludeModifications= */ false);
+
+ mTunerSessions[0].startProgramListUpdates(fmIdFilter);
+
+ ProgramFilter halFilter = ConversionUtils.filterToHalProgramFilter(fmIdFilter);
+ verify(mBroadcastRadioMock).startProgramListUpdates(halFilter);
+
+ mTunerSessions[1].startProgramListUpdates(filterExcludingCategories);
+
+ halFilter.identifiers = new android.hardware.broadcastradio.ProgramIdentifier[]{};
+ halFilter.includeCategories = true;
+ verify(mBroadcastRadioMock).startProgramListUpdates(halFilter);
+
+ mTunerSessions[2].startProgramListUpdates(rdsTypeFilter);
+
+ halFilter.excludeModifications = false;
+ verify(mBroadcastRadioMock).startProgramListUpdates(halFilter);
+ }
+
+ @Test
+ public void onProgramListUpdated_forMultipleSessions() throws Exception {
+ int numSessions = 3;
+ openAidlClients(numSessions);
+ List<ProgramList.Filter> filters = List.of(new ProgramList.Filter(
+ Set.of(ProgramSelector.IDENTIFIER_TYPE_RDS_PI), new ArraySet<>(),
+ /* includeCategories= */ true, /* excludeModifications= */ false),
+ new ProgramList.Filter(new ArraySet<>(), Set.of(TEST_FM_FREQUENCY_ID),
+ /* includeCategories= */ false, /* excludeModifications= */ true),
+ new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
+ /* includeCategories= */ true, /* excludeModifications= */ true));
+
+ for (int index = 0; index < numSessions; index++) {
+ mTunerSessions[index].startProgramListUpdates(filters.get(index));
+ }
+
+ mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
+ /* complete= */ true, List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
+
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT)
+ .onProgramListUpdated(AidlTestUtils.makeChunk(/* purge= */ false,
+ /* complete= */ true, List.of(TEST_RDS_INFO), new ArrayList<>()));
+ verify(mAidlTunerCallbackMocks[1], CALLBACK_TIMEOUT)
+ .onProgramListUpdated(AidlTestUtils.makeChunk(/* purge= */ false,
+ /* complete= */ true, List.of(TEST_FM_INFO), new ArrayList<>()));
+ verify(mAidlTunerCallbackMocks[2], CALLBACK_TIMEOUT)
+ .onProgramListUpdated(AidlTestUtils.makeChunk(/* purge= */ false,
+ /* complete= */ true, List.of(TEST_RDS_INFO, TEST_FM_INFO),
+ new ArrayList<>()));
+ }
+
+ @Test
+ public void startProgramListUpdates_forNonCurrentUser_doesNotStartUpdates() throws Exception {
+ openAidlClients(/* numClients= */ 1);
+ ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
+ /* includeCategories= */ true, /* excludeModifications= */ false);
+ doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+
+ mTunerSessions[0].startProgramListUpdates(filter);
+
+ verify(mBroadcastRadioMock, never()).startProgramListUpdates(any());
+ }
+
+ @Test
+ public void startProgramListUpdates_withUnknownErrorFromHal_fails() throws Exception {
+ openAidlClients(/* numClients= */ 1);
+ doThrow(new ServiceSpecificException(Result.UNKNOWN_ERROR))
+ .when(mBroadcastRadioMock).startProgramListUpdates(any());
+
+ ParcelableException thrown = assertThrows(ParcelableException.class, () -> {
+ mTunerSessions[0].startProgramListUpdates(/* filter= */ null);
+ });
+
+ assertWithMessage("Unknown error HAL exception when updating program list")
+ .that(thrown).hasMessageThat().contains("UNKNOWN_ERROR");
+ }
+
+ @Test
public void stopProgramListUpdates() throws Exception {
openAidlClients(/* numClients= */ 1);
- ProgramList.Filter aidlFilter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
+ ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
/* includeCategories= */ true, /* excludeModifications= */ false);
- mTunerSessions[0].startProgramListUpdates(aidlFilter);
+ mTunerSessions[0].startProgramListUpdates(filter);
mTunerSessions[0].stopProgramListUpdates();
@@ -658,9 +948,9 @@
@Test
public void stopProgramListUpdates_forNonCurrentUser_doesNotStopUpdates() throws Exception {
openAidlClients(/* numClients= */ 1);
- ProgramList.Filter aidlFilter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
+ ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
/* includeCategories= */ true, /* excludeModifications= */ false);
- mTunerSessions[0].startProgramListUpdates(aidlFilter);
+ mTunerSessions[0].startProgramListUpdates(filter);
doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
mTunerSessions[0].stopProgramListUpdates();
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
index ea9a846..3815008 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
@@ -373,7 +373,7 @@
}
@Test
- public void tune_withHalHasUnknownError_fails() throws Exception {
+ public void tune_withUnknownErrorFromHal_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
ProgramSelector sel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
doAnswer(invocation -> Result.UNKNOWN_ERROR).when(mHalTunerSessionMock).tune(any());
@@ -382,7 +382,7 @@
mTunerSessions[0].tune(sel);
});
- assertWithMessage("Exception for tuning when HAL has unknown error")
+ assertWithMessage("Unknown error HAL exception when tuning")
.that(thrown).hasMessageThat().contains(Result.toString(Result.UNKNOWN_ERROR));
}
@@ -513,7 +513,7 @@
}
@Test
- public void seek_withHalHasInternalError_fails() throws Exception {
+ public void seek_withInternalErrorFromHal_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
doAnswer(invocation -> Result.INTERNAL_ERROR).when(mHalTunerSessionMock)
.scan(anyBoolean(), anyBoolean());
@@ -522,7 +522,7 @@
mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false);
});
- assertWithMessage("Exception for seeking when HAL has internal error")
+ assertWithMessage("Internal error HAL exception when seeking")
.that(thrown).hasMessageThat().contains(Result.toString(Result.INTERNAL_ERROR));
}
@@ -633,6 +633,32 @@
}
@Test
+ public void startProgramListUpdates_forNonCurrentUser_doesNotStartUpdates() throws Exception {
+ openAidlClients(/* numClients= */ 1);
+ ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
+ /* includeCategories= */ true, /* excludeModifications= */ false);
+ doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
+
+ mTunerSessions[0].startProgramListUpdates(filter);
+
+ verify(mHalTunerSessionMock, never()).startProgramListUpdates(any());
+ }
+
+ @Test
+ public void startProgramListUpdates_withUnknownErrorFromHal_fails() throws Exception {
+ openAidlClients(/* numClients= */ 1);
+ doAnswer(invocation -> Result.UNKNOWN_ERROR).when(mHalTunerSessionMock)
+ .startProgramListUpdates(any());
+
+ ParcelableException thrown = assertThrows(ParcelableException.class, () -> {
+ mTunerSessions[0].startProgramListUpdates(/* filter= */ null);
+ });
+
+ assertWithMessage("Unknown error HAL exception when updating program list")
+ .that(thrown).hasMessageThat().contains(Result.toString(Result.UNKNOWN_ERROR));
+ }
+
+ @Test
public void stopProgramListUpdates() throws Exception {
openAidlClients(/* numClients= */ 1);
ProgramList.Filter aidlFilter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
diff --git a/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt b/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt
index 625c318..249e246 100644
--- a/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt
+++ b/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt
@@ -16,6 +16,8 @@
package android.content.res
+
+import android.platform.test.annotations.Presubmit
import androidx.core.util.forEach
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
@@ -27,6 +29,7 @@
import org.junit.Test
import org.junit.runner.RunWith
+@Presubmit
@RunWith(AndroidJUnit4::class)
class FontScaleConverterFactoryTest {
@@ -79,10 +82,10 @@
@LargeTest
@Test
fun allFeasibleScalesAndConversionsDoNotCrash() {
- generateSequenceOfFractions(-10000f..10000f, step = 0.01f)
+ generateSequenceOfFractions(-10f..10f, step = 0.01f)
.mapNotNull{ FontScaleConverterFactory.forScale(it) }
.flatMap{ table ->
- generateSequenceOfFractions(-10000f..10000f, step = 0.01f)
+ generateSequenceOfFractions(-2000f..2000f, step = 0.01f)
.map{ Pair(table, it) }
}
.forEach { (table, sp) ->
diff --git a/core/tests/coretests/src/android/content/res/FontScaleConverterTest.kt b/core/tests/coretests/src/android/content/res/FontScaleConverterTest.kt
index e9f850e..bfa8c9a 100644
--- a/core/tests/coretests/src/android/content/res/FontScaleConverterTest.kt
+++ b/core/tests/coretests/src/android/content/res/FontScaleConverterTest.kt
@@ -16,11 +16,13 @@
package android.content.res
+import android.platform.test.annotations.Presubmit
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertWithMessage
import org.junit.Test
import org.junit.runner.RunWith
+@Presubmit
@RunWith(AndroidJUnit4::class)
class FontScaleConverterTest {
diff --git a/core/tests/coretests/src/android/hardware/camera2/OWNERS b/core/tests/coretests/src/android/hardware/camera2/OWNERS
new file mode 100644
index 0000000..f48a95c
--- /dev/null
+++ b/core/tests/coretests/src/android/hardware/camera2/OWNERS
@@ -0,0 +1 @@
+include platform/frameworks/av:/camera/OWNERS
diff --git a/core/tests/coretests/src/android/hardware/camera2/impl/CaptureMetadataNativeTest.java b/core/tests/coretests/src/android/hardware/camera2/impl/CaptureMetadataNativeTest.java
new file mode 100644
index 0000000..a38c040
--- /dev/null
+++ b/core/tests/coretests/src/android/hardware/camera2/impl/CaptureMetadataNativeTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 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.hardware.camera2.impl;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.params.LensShadingMap;
+import android.util.Size;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.Arrays;
+
+@SmallTest
+@RunWith(JUnit4.class)
+/** Tests for {@link CameraMetadataNative} class. */
+public class CaptureMetadataNativeTest {
+
+ @Test
+ public void setLensShadingMap() {
+ final Size s = new Size(10, 10);
+ // 4 x rows x columns
+ final float[] elements = new float[400];
+ Arrays.fill(elements, 42);
+
+ final LensShadingMap lensShadingMap =
+ new LensShadingMap(elements, s.getHeight(), s.getWidth());
+ CameraMetadataNative captureResults = new CameraMetadataNative();
+ captureResults.set(CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP, lensShadingMap);
+
+ final LensShadingMap output =
+ captureResults.get(CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP);
+
+ assertThat(output).isEqualTo(lensShadingMap);
+ }
+}
diff --git a/core/tests/coretests/src/android/util/TypedValueTest.kt b/core/tests/coretests/src/android/util/TypedValueTest.kt
index b020c38..af01447 100644
--- a/core/tests/coretests/src/android/util/TypedValueTest.kt
+++ b/core/tests/coretests/src/android/util/TypedValueTest.kt
@@ -17,6 +17,7 @@
package android.util
import android.content.res.FontScaleConverterFactory
+import android.platform.test.annotations.Presubmit
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.filters.SmallTest
@@ -30,6 +31,7 @@
import kotlin.math.min
import kotlin.math.roundToInt
+@Presubmit
@RunWith(AndroidJUnit4::class)
class TypedValueTest {
@LargeTest
@@ -223,7 +225,6 @@
metrics.scaledDensity = 0f
listOf(
- TypedValue.COMPLEX_UNIT_PX,
TypedValue.COMPLEX_UNIT_DIP,
TypedValue.COMPLEX_UNIT_SP,
TypedValue.COMPLEX_UNIT_PT,
@@ -257,8 +258,7 @@
TypedValue.COMPLEX_UNIT_MM
)
.forEach { dimenType ->
- // Test for every integer value in the range...
- for (i: Int in -(1 shl 23) until (1 shl 23)) {
+ for (i: Int in -10000 until 10000) {
assertRoundTripIsEqual(i.toFloat(), dimenType, metrics)
assertRoundTripIsEqual(i - .1f, dimenType, metrics)
assertRoundTripIsEqual(i + .5f, dimenType, metrics)
diff --git a/core/tests/coretests/src/android/view/WindowInfoTest.java b/core/tests/coretests/src/android/view/WindowInfoTest.java
index f9e3f43..d927f06 100644
--- a/core/tests/coretests/src/android/view/WindowInfoTest.java
+++ b/core/tests/coretests/src/android/view/WindowInfoTest.java
@@ -28,6 +28,7 @@
import android.app.ActivityTaskManager;
import android.graphics.Matrix;
import android.os.IBinder;
+import android.os.LocaleList;
import android.os.Parcel;
import android.platform.test.annotations.Presubmit;
import android.text.TextUtils;
@@ -41,6 +42,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Locale;
/**
* Class for testing {@link WindowInfo}.
@@ -48,6 +50,7 @@
@Presubmit
@RunWith(AndroidJUnit4.class)
public class WindowInfoTest {
+ private static final LocaleList TEST_LOCALES = new LocaleList(Locale.ROOT);
@SmallTest
@Test
@@ -129,6 +132,7 @@
assertTrue(windowinfo.regionInScreen.isEmpty());
assertEquals(windowinfo.mTransformMatrix.length, 9);
assertTrue(windowinfo.mMagnificationSpec.isNop());
+ assertEquals(windowinfo.locales, LocaleList.getEmptyLocaleList());
}
private boolean areWindowsEqual(WindowInfo w1, WindowInfo w2) {
@@ -141,6 +145,7 @@
equality &= w1.mMagnificationSpec.equals(w2.mMagnificationSpec);
equality &= Arrays.equals(w1.mTransformMatrix, w2.mTransformMatrix);
equality &= TextUtils.equals(w1.title, w2.title);
+ equality &= w1.locales.equals(w2.locales);
return equality;
}
@@ -164,5 +169,6 @@
windowInfo.mMagnificationSpec.offsetX = 100f;
windowInfo.mMagnificationSpec.offsetY = 200f;
Matrix.IDENTITY_MATRIX.getValues(windowInfo.mTransformMatrix);
+ windowInfo.locales = TEST_LOCALES;
}
}
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityWindowAttributesTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityWindowAttributesTest.java
index a6abee5..8d1c2e3 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityWindowAttributesTest.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityWindowAttributesTest.java
@@ -20,6 +20,7 @@
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotSame;
+import android.os.LocaleList;
import android.os.Parcel;
import android.platform.test.annotations.Presubmit;
import android.view.WindowManager;
@@ -30,6 +31,8 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Locale;
+
/**
* Class for testing {@link AccessibilityWindowAttributes}.
*/
@@ -37,11 +40,13 @@
@RunWith(AndroidJUnit4.class)
public class AccessibilityWindowAttributesTest {
private static final String TEST_WINDOW_TITLE = "test window title";
+ private static final LocaleList TEST_LOCALES = new LocaleList(Locale.ROOT);
@SmallTest
@Test
public void testParceling() {
- final AccessibilityWindowAttributes windowAttributes = createInstance(TEST_WINDOW_TITLE);
+ final AccessibilityWindowAttributes windowAttributes = createInstance(
+ TEST_WINDOW_TITLE, TEST_LOCALES);
Parcel parcel = Parcel.obtain();
windowAttributes.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
@@ -56,14 +61,21 @@
@SmallTest
@Test
public void testNonequality() {
- final AccessibilityWindowAttributes windowAttributes = createInstance(null);
- final AccessibilityWindowAttributes windowAttributes2 = createInstance(TEST_WINDOW_TITLE);
+ final AccessibilityWindowAttributes windowAttributes = createInstance(
+ null, TEST_LOCALES);
+ final AccessibilityWindowAttributes windowAttributes1 = createInstance(
+ TEST_WINDOW_TITLE, TEST_LOCALES);
+ final AccessibilityWindowAttributes windowAttributes2 = createInstance(
+ TEST_WINDOW_TITLE, null);
+ assertNotEquals(windowAttributes, windowAttributes1);
assertNotEquals(windowAttributes, windowAttributes2);
+ assertNotEquals(windowAttributes1, windowAttributes2);
}
- private static AccessibilityWindowAttributes createInstance(String windowTitle) {
+ private static AccessibilityWindowAttributes createInstance(
+ String windowTitle, LocaleList locales) {
final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
layoutParams.accessibilityTitle = windowTitle;
- return new AccessibilityWindowAttributes(layoutParams);
+ return new AccessibilityWindowAttributes(layoutParams, locales);
}
}
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index fc19944..0aad0a8 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -83,5 +83,6 @@
<permission name="android.permission.READ_SAFETY_CENTER_STATUS" />
<permission name="android.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS" />
<permission name="android.permission.READ_SEARCH_INDEXABLES" />
+ <permission name="android.permission.ACCESS_AMBIENT_CONTEXT_EVENT"/>
</privapp-permissions>
</permissions>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 1070841..5040a86 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -500,6 +500,8 @@
<permission name="android.permission.MODIFY_CELL_BROADCASTS" />
<!-- Permission required for CTS test - CtsBroadcastRadioTestCases -->
<permission name="android.permission.ACCESS_BROADCAST_RADIO"/>
+ <!-- Permission required for CTS test - CtsAmbientContextServiceTestCases -->
+ <permission name="android.permission.ACCESS_AMBIENT_CONTEXT_EVENT"/>
</privapp-permissions>
<privapp-permissions package="com.android.statementservice">
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index c7c97e0..89d6304 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -1334,6 +1334,8 @@
final OverlayProperties overlayProperties = defaultDisplay.getOverlaySupport();
boolean supportFp16ForHdr = overlayProperties != null
? overlayProperties.supportFp16ForHdr() : false;
+ boolean supportMixedColorSpaces = overlayProperties != null
+ ? overlayProperties.supportMixedColorSpaces() : false;
for (int i = 0; i < allDisplays.length; i++) {
final Display display = allDisplays[i];
@@ -1361,7 +1363,7 @@
nInitDisplayInfo(largestWidth, largestHeight, defaultDisplay.getRefreshRate(),
wideColorDataspace, defaultDisplay.getAppVsyncOffsetNanos(),
defaultDisplay.getPresentationDeadlineNanos(),
- supportFp16ForHdr);
+ supportFp16ForHdr, supportMixedColorSpaces);
mDisplayInitialized = true;
}
@@ -1542,7 +1544,7 @@
private static native void nInitDisplayInfo(int width, int height, float refreshRate,
int wideColorDataspace, long appVsyncOffsetNanos, long presentationDeadlineNanos,
- boolean supportsFp16ForHdr);
+ boolean supportsFp16ForHdr, boolean nInitDisplayInfo);
private static native void nSetDrawingEnabled(boolean drawingEnabled);
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index f0e496f..d35dcab 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -3151,10 +3151,10 @@
* @see #getRunAdvance(char[], int, int, int, int, boolean, int) for more details.
*
* @param text the text to measure. Cannot be null.
- * @param start the index of the start of the range to measure
- * @param end the index + 1 of the end of the range to measure
- * @param contextStart the index of the start of the shaping context
- * @param contextEnd the index + 1 of the end of the shaping context
+ * @param start the start index of the range to measure, inclusive
+ * @param end the end index of the range to measure, exclusive
+ * @param contextStart the start index of the shaping context, inclusive
+ * @param contextEnd the end index of the shaping context, exclusive
* @param isRtl whether the run is in RTL direction
* @param offset index of caret position
* @param advances the array that receives the computed character advances
diff --git a/graphics/java/android/graphics/drawable/LottieDrawable.java b/graphics/java/android/graphics/drawable/LottieDrawable.java
new file mode 100644
index 0000000..c1f1b50
--- /dev/null
+++ b/graphics/java/android/graphics/drawable/LottieDrawable.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2022 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.graphics.drawable;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.PixelFormat;
+
+import dalvik.annotation.optimization.FastNative;
+
+import libcore.util.NativeAllocationRegistry;
+
+import java.io.IOException;
+
+/**
+ * {@link Drawable} for drawing Lottie files.
+ *
+ * <p>The framework handles decoding subsequent frames in another thread and
+ * updating when necessary. The drawable will only animate while it is being
+ * displayed.</p>
+ *
+ * @hide
+ */
+@SuppressLint("NotCloseable")
+public class LottieDrawable extends Drawable implements Animatable {
+ private long mNativePtr;
+
+ /**
+ * Create an animation from the provided JSON string
+ * @hide
+ */
+ private LottieDrawable(@NonNull String animationJson) throws IOException {
+ mNativePtr = nCreate(animationJson);
+ if (mNativePtr == 0) {
+ throw new IOException("could not make LottieDrawable from json");
+ }
+
+ final long nativeSize = nNativeByteSize(mNativePtr);
+ NativeAllocationRegistry registry = new NativeAllocationRegistry(
+ LottieDrawable.class.getClassLoader(), nGetNativeFinalizer(), nativeSize);
+ registry.registerNativeAllocation(this, mNativePtr);
+ }
+
+ /**
+ * Factory for LottieDrawable, throws IOException if native Skottie Builder fails to parse
+ */
+ public static LottieDrawable makeLottieDrawable(@NonNull String animationJson)
+ throws IOException {
+ return new LottieDrawable(animationJson);
+ }
+
+
+
+ /**
+ * Draw the current frame to the Canvas.
+ * @hide
+ */
+ @Override
+ public void draw(@NonNull Canvas canvas) {
+ if (mNativePtr == 0) {
+ throw new IllegalStateException("called draw on empty LottieDrawable");
+ }
+
+ nDraw(mNativePtr, canvas.getNativeCanvasWrapper());
+ }
+
+ /**
+ * Start the animation. Needs to be called before draw calls.
+ * @hide
+ */
+ @Override
+ public void start() {
+ if (mNativePtr == 0) {
+ throw new IllegalStateException("called start on empty LottieDrawable");
+ }
+
+ if (nStart(mNativePtr)) {
+ invalidateSelf();
+ }
+ }
+
+ /**
+ * Stops the animation playback. Does not release anything.
+ * @hide
+ */
+ @Override
+ public void stop() {
+ if (mNativePtr == 0) {
+ throw new IllegalStateException("called stop on empty LottieDrawable");
+ }
+ nStop(mNativePtr);
+ }
+
+ /**
+ * Return whether the animation is currently running.
+ */
+ @Override
+ public boolean isRunning() {
+ if (mNativePtr == 0) {
+ throw new IllegalStateException("called isRunning on empty LottieDrawable");
+ }
+ return nIsRunning(mNativePtr);
+ }
+
+ @Override
+ public int getOpacity() {
+ // We assume translucency to avoid checking each pixel.
+ return PixelFormat.TRANSLUCENT;
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ //TODO
+ }
+
+ @Override
+ public void setColorFilter(@Nullable ColorFilter colorFilter) {
+ //TODO
+ }
+
+ private static native long nCreate(String json);
+ private static native void nDraw(long nativeInstance, long nativeCanvas);
+ @FastNative
+ private static native long nGetNativeFinalizer();
+ @FastNative
+ private static native long nNativeByteSize(long nativeInstance);
+ @FastNative
+ private static native boolean nIsRunning(long nativeInstance);
+ @FastNative
+ private static native boolean nStart(long nativeInstance);
+ @FastNative
+ private static native boolean nStop(long nativeInstance);
+
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
index 87fa63d..07d0d96 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
@@ -191,10 +191,25 @@
*/
void createTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken,
@NonNull IBinder ownerToken, @NonNull Rect bounds, @WindowingMode int windowingMode) {
+ createTaskFragment(wct, fragmentToken, ownerToken, bounds, windowingMode,
+ null /* pairedActivityToken */);
+ }
+
+ /**
+ * @param ownerToken The token of the activity that creates this task fragment. It does not
+ * have to be a child of this task fragment, but must belong to the same task.
+ * @param pairedActivityToken The token of the activity that will be reparented to this task
+ * fragment. When it is not {@code null}, the task fragment will be
+ * positioned right above it.
+ */
+ void createTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken,
+ @NonNull IBinder ownerToken, @NonNull Rect bounds, @WindowingMode int windowingMode,
+ @Nullable IBinder pairedActivityToken) {
final TaskFragmentCreationParams fragmentOptions = new TaskFragmentCreationParams.Builder(
getOrganizerToken(), fragmentToken, ownerToken)
.setInitialBounds(bounds)
.setWindowingMode(windowingMode)
+ .setPairedActivityToken(pairedActivityToken)
.build();
createTaskFragment(wct, fragmentOptions);
}
@@ -216,8 +231,10 @@
private void createTaskFragmentAndReparentActivity(@NonNull WindowContainerTransaction wct,
@NonNull IBinder fragmentToken, @NonNull IBinder ownerToken, @NonNull Rect bounds,
@WindowingMode int windowingMode, @NonNull Activity activity) {
- createTaskFragment(wct, fragmentToken, ownerToken, bounds, windowingMode);
- wct.reparentActivityToTaskFragment(fragmentToken, activity.getActivityToken());
+ final IBinder reparentActivityToken = activity.getActivityToken();
+ createTaskFragment(wct, fragmentToken, ownerToken, bounds, windowingMode,
+ reparentActivityToken);
+ wct.reparentActivityToTaskFragment(fragmentToken, reparentActivityToken);
}
void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
@@ -293,16 +310,12 @@
OP_TYPE_SET_ANIMATION_PARAMS)
.setAnimationParams(animationParams)
.build();
- wct.setTaskFragmentOperation(fragmentToken, operation);
+ wct.addTaskFragmentOperation(fragmentToken, operation);
}
void deleteTaskFragment(@NonNull WindowContainerTransaction wct,
@NonNull IBinder fragmentToken) {
- if (!mFragmentInfos.containsKey(fragmentToken)) {
- throw new IllegalArgumentException(
- "Can't find an existing TaskFragment with fragmentToken=" + fragmentToken);
- }
- wct.deleteTaskFragment(mFragmentInfos.get(fragmentToken).getToken());
+ wct.deleteTaskFragment(fragmentToken);
}
void updateTaskFragmentInfo(@NonNull TaskFragmentInfo taskFragmentInfo) {
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 8c4de70..b13c672 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -20,6 +20,8 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.window.TaskFragmentOperation.OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
import static android.window.TaskFragmentOrganizer.KEY_ERROR_CALLBACK_OP_TYPE;
import static android.window.TaskFragmentOrganizer.KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO;
import static android.window.TaskFragmentOrganizer.KEY_ERROR_CALLBACK_THROWABLE;
@@ -31,8 +33,6 @@
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_INFO_CHANGED;
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED;
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_VANISHED;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
import static androidx.window.extensions.embedding.SplitContainer.getFinishPrimaryWithSecondaryBehavior;
import static androidx.window.extensions.embedding.SplitContainer.getFinishSecondaryWithPrimaryBehavior;
@@ -67,6 +67,7 @@
import android.view.WindowMetrics;
import android.window.TaskFragmentAnimationParams;
import android.window.TaskFragmentInfo;
+import android.window.TaskFragmentOperation;
import android.window.TaskFragmentParentInfo;
import android.window.TaskFragmentTransaction;
import android.window.WindowContainerTransaction;
@@ -592,11 +593,11 @@
@GuardedBy("mLock")
void onTaskFragmentError(@NonNull WindowContainerTransaction wct,
@Nullable IBinder errorCallbackToken, @Nullable TaskFragmentInfo taskFragmentInfo,
- int opType, @NonNull Throwable exception) {
+ @TaskFragmentOperation.OperationType int opType, @NonNull Throwable exception) {
Log.e(TAG, "onTaskFragmentError=" + exception.getMessage());
switch (opType) {
- case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT:
- case HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT: {
+ case OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT:
+ case OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT: {
final TaskFragmentContainer container;
if (taskFragmentInfo != null) {
container = getContainer(taskFragmentInfo.getFragmentToken());
@@ -1507,7 +1508,7 @@
* Returns the active split that has the provided containers as primary and secondary or as
* secondary and primary, if available.
*/
- @VisibleForTesting
+ @GuardedBy("mLock")
@Nullable
SplitContainer getActiveSplitForContainers(
@NonNull TaskFragmentContainer firstContainer,
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index 6f2fe80..85a00df 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -30,6 +30,7 @@
import android.graphics.Rect;
import android.os.Bundle;
import android.os.IBinder;
+import android.util.DisplayMetrics;
import android.util.LayoutDirection;
import android.util.Pair;
import android.util.Size;
@@ -268,10 +269,11 @@
container = mController.newContainer(activity, taskId);
final int windowingMode = mController.getTaskContainer(taskId)
.getWindowingModeForSplitTaskFragment(bounds);
- createTaskFragment(wct, container.getTaskFragmentToken(), activity.getActivityToken(),
- bounds, windowingMode);
+ final IBinder reparentActivityToken = activity.getActivityToken();
+ createTaskFragment(wct, container.getTaskFragmentToken(), reparentActivityToken,
+ bounds, windowingMode, reparentActivityToken);
wct.reparentActivityToTaskFragment(container.getTaskFragmentToken(),
- activity.getActivityToken());
+ reparentActivityToken);
} else {
resizeTaskFragmentIfRegistered(wct, container, bounds);
final int windowingMode = mController.getTaskContainer(taskId)
@@ -554,9 +556,9 @@
final Function<SplitAttributesCalculatorParams, SplitAttributes> calculator =
mController.getSplitAttributesCalculator();
final SplitAttributes defaultSplitAttributes = rule.getDefaultSplitAttributes();
- final boolean isDefaultMinSizeSatisfied = rule.checkParentMetrics(taskWindowMetrics);
+ final boolean areDefaultConstraintsSatisfied = rule.checkParentMetrics(taskWindowMetrics);
if (calculator == null) {
- if (!isDefaultMinSizeSatisfied) {
+ if (!areDefaultConstraintsSatisfied) {
return EXPAND_CONTAINERS_ATTRIBUTES;
}
return sanitizeSplitAttributes(taskProperties, defaultSplitAttributes,
@@ -566,8 +568,8 @@
.getCurrentWindowLayoutInfo(taskProperties.getDisplayId(),
taskConfiguration.windowConfiguration);
final SplitAttributesCalculatorParams params = new SplitAttributesCalculatorParams(
- taskWindowMetrics, taskConfiguration, defaultSplitAttributes,
- isDefaultMinSizeSatisfied, windowLayoutInfo, rule.getTag());
+ taskWindowMetrics, taskConfiguration, windowLayoutInfo, defaultSplitAttributes,
+ areDefaultConstraintsSatisfied, rule.getTag());
final SplitAttributes splitAttributes = calculator.apply(params);
return sanitizeSplitAttributes(taskProperties, splitAttributes, minDimensionsPair);
}
@@ -971,6 +973,7 @@
private static WindowMetrics getTaskWindowMetrics(@NonNull Configuration taskConfiguration) {
final Rect taskBounds = taskConfiguration.windowConfiguration.getBounds();
// TODO(b/190433398): Supply correct insets.
- return new WindowMetrics(taskBounds, WindowInsets.CONSUMED);
+ final float density = taskConfiguration.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
+ return new WindowMetrics(taskBounds, WindowInsets.CONSUMED, density);
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
index 076856c..17814c6 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -141,12 +141,26 @@
mToken = new Binder("TaskFragmentContainer");
mTaskContainer = taskContainer;
if (pairedPrimaryContainer != null) {
+ // The TaskFragment will be positioned right above the paired container.
if (pairedPrimaryContainer.getTaskContainer() != taskContainer) {
throw new IllegalArgumentException(
"pairedPrimaryContainer must be in the same Task");
}
final int primaryIndex = taskContainer.mContainers.indexOf(pairedPrimaryContainer);
taskContainer.mContainers.add(primaryIndex + 1, this);
+ } else if (pendingAppearedActivity != null) {
+ // The TaskFragment will be positioned right above the pending appeared Activity. If any
+ // existing TaskFragment is empty with pending Intent, it is likely that the Activity of
+ // the pending Intent hasn't been created yet, so the new Activity should be below the
+ // empty TaskFragment.
+ int i = taskContainer.mContainers.size() - 1;
+ for (; i >= 0; i--) {
+ final TaskFragmentContainer container = taskContainer.mContainers.get(i);
+ if (!container.isEmpty() || container.getPendingAppearedIntent() == null) {
+ break;
+ }
+ }
+ taskContainer.mContainers.add(i + 1, this);
} else {
taskContainer.mContainers.add(this);
}
@@ -500,6 +514,8 @@
}
if (!shouldFinishDependent) {
+ // Always finish the placeholder when the primary is finished.
+ finishPlaceholderIfAny(wct, presenter);
return;
}
@@ -526,6 +542,28 @@
mActivitiesToFinishOnExit.clear();
}
+ @GuardedBy("mController.mLock")
+ private void finishPlaceholderIfAny(@NonNull WindowContainerTransaction wct,
+ @NonNull SplitPresenter presenter) {
+ final List<TaskFragmentContainer> containersToRemove = new ArrayList<>();
+ for (TaskFragmentContainer container : mContainersToFinishOnExit) {
+ if (container.mIsFinished) {
+ continue;
+ }
+ final SplitContainer splitContainer = mController.getActiveSplitForContainers(
+ this, container);
+ if (splitContainer != null && splitContainer.isPlaceholderContainer()
+ && splitContainer.getSecondaryContainer() == container) {
+ // Remove the placeholder secondary TaskFragment.
+ containersToRemove.add(container);
+ }
+ }
+ mContainersToFinishOnExit.removeAll(containersToRemove);
+ for (TaskFragmentContainer container : containersToRemove) {
+ container.finish(false /* shouldFinishDependent */, presenter, wct, mController);
+ }
+ }
+
boolean isFinished() {
return mIsFinished;
}
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
index 0bf0bc8..a26311e 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
@@ -20,13 +20,13 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT;
import static android.window.TaskFragmentTransaction.TYPE_ACTIVITY_REPARENTED_TO_TASK;
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_APPEARED;
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_ERROR;
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_INFO_CHANGED;
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED;
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_VANISHED;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.DEFAULT_FINISH_PRIMARY_WITH_SECONDARY;
import static androidx.window.extensions.embedding.EmbeddingTestUtils.DEFAULT_FINISH_SECONDARY_WITH_PRIMARY;
@@ -1139,7 +1139,7 @@
final TaskFragmentTransaction transaction = new TaskFragmentTransaction();
final IBinder errorToken = new Binder();
final TaskFragmentInfo info = mock(TaskFragmentInfo.class);
- final int opType = HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT;
+ final int opType = OP_TYPE_CREATE_TASK_FRAGMENT;
final Exception exception = new SecurityException("test");
final Bundle errorBundle = TaskFragmentOrganizer.putErrorInfoInBundle(exception, info,
opType);
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java
index ff1256b..07d0158 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java
@@ -66,8 +66,10 @@
import android.graphics.Rect;
import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
+import android.util.DisplayMetrics;
import android.util.Pair;
import android.util.Size;
+import android.view.WindowMetrics;
import android.window.TaskFragmentAnimationParams;
import android.window.TaskFragmentInfo;
import android.window.TaskFragmentOperation;
@@ -101,7 +103,6 @@
@RunWith(AndroidJUnit4.class)
public class SplitPresenterTest {
- @Mock
private Activity mActivity;
@Mock
private Resources mActivityResources;
@@ -193,7 +194,7 @@
OP_TYPE_SET_ANIMATION_PARAMS)
.setAnimationParams(animationParams)
.build();
- verify(mTransaction).setTaskFragmentOperation(container.getTaskFragmentToken(),
+ verify(mTransaction).addTaskFragmentOperation(container.getTaskFragmentToken(),
expectedOperation);
assertTrue(container.areLastRequestedAnimationParamsEqual(animationParams));
@@ -202,7 +203,7 @@
mPresenter.updateAnimationParams(mTransaction, container.getTaskFragmentToken(),
animationParams);
- verify(mTransaction, never()).setTaskFragmentOperation(any(), any());
+ verify(mTransaction, never()).addTaskFragmentOperation(any(), any());
}
@Test
@@ -571,6 +572,21 @@
splitPairRule, null /* minDimensionsPair */));
}
+ @Test
+ public void testGetTaskWindowMetrics() {
+ final Configuration taskConfig = new Configuration();
+ taskConfig.windowConfiguration.setBounds(TASK_BOUNDS);
+ taskConfig.densityDpi = 123;
+ final TaskContainer.TaskProperties taskProperties = new TaskContainer.TaskProperties(
+ DEFAULT_DISPLAY, taskConfig);
+ doReturn(taskProperties).when(mPresenter).getTaskProperties(mActivity);
+
+ final WindowMetrics windowMetrics = mPresenter.getTaskWindowMetrics(mActivity);
+ assertEquals(TASK_BOUNDS, windowMetrics.getBounds());
+ assertEquals(123 * DisplayMetrics.DENSITY_DEFAULT_SCALE,
+ windowMetrics.getDensity(), 0f);
+ }
+
private Activity createMockActivity() {
final Activity activity = mock(Activity.class);
final Configuration activityConfig = new Configuration();
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java
index 7d9d8b0..78b85e6 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java
@@ -154,17 +154,52 @@
null /* pendingAppearedIntent */, taskContainer, mController,
null /* pairedPrimaryContainer */);
doReturn(container1).when(mController).getContainerWithActivity(mActivity);
- final WindowContainerTransaction wct = new WindowContainerTransaction();
// The activity is requested to be reparented, so don't finish it.
- container0.finish(true /* shouldFinishDependent */, mPresenter, wct, mController);
+ container0.finish(true /* shouldFinishDependent */, mPresenter, mTransaction, mController);
verify(mTransaction, never()).finishActivity(any());
- verify(mPresenter).deleteTaskFragment(wct, container0.getTaskFragmentToken());
+ verify(mPresenter).deleteTaskFragment(mTransaction, container0.getTaskFragmentToken());
verify(mController).removeContainer(container0);
}
@Test
+ public void testFinish_alwaysFinishPlaceholder() {
+ // Register container1 as a placeholder
+ final TaskContainer taskContainer = createTestTaskContainer();
+ final TaskFragmentContainer container0 = new TaskFragmentContainer(mActivity,
+ null /* pendingAppearedIntent */, taskContainer, mController,
+ null /* pairedPrimaryContainer */);
+ final TaskFragmentInfo info0 = createMockTaskFragmentInfo(container0, mActivity);
+ container0.setInfo(mTransaction, info0);
+ final Activity placeholderActivity = createMockActivity();
+ final TaskFragmentContainer container1 = new TaskFragmentContainer(placeholderActivity,
+ null /* pendingAppearedIntent */, taskContainer, mController,
+ null /* pairedPrimaryContainer */);
+ final TaskFragmentInfo info1 = createMockTaskFragmentInfo(container1, placeholderActivity);
+ container1.setInfo(mTransaction, info1);
+ final SplitAttributes splitAttributes = new SplitAttributes.Builder().build();
+ final SplitPlaceholderRule rule = new SplitPlaceholderRule.Builder(new Intent(),
+ mActivity::equals, (java.util.function.Predicate) i -> false,
+ (java.util.function.Predicate) w -> true)
+ .setDefaultSplitAttributes(splitAttributes)
+ .build();
+ mController.registerSplit(mTransaction, container0, mActivity, container1, rule,
+ splitAttributes);
+
+ // The placeholder TaskFragment should be finished even if the primary is finished with
+ // shouldFinishDependent = false.
+ container0.finish(false /* shouldFinishDependent */, mPresenter, mTransaction, mController);
+
+ assertTrue(container0.isFinished());
+ assertTrue(container1.isFinished());
+ verify(mPresenter).deleteTaskFragment(mTransaction, container0.getTaskFragmentToken());
+ verify(mPresenter).deleteTaskFragment(mTransaction, container1.getTaskFragmentToken());
+ verify(mController).removeContainer(container0);
+ verify(mController).removeContainer(container1);
+ }
+
+ @Test
public void testSetInfo() {
final TaskContainer taskContainer = createTestTaskContainer();
// Pending activity should be cleared when it has appeared on server side.
@@ -493,8 +528,6 @@
final TaskFragmentContainer tf1 = new TaskFragmentContainer(
null /* pendingAppearedActivity */, new Intent(), taskContainer, mController,
null /* pairedPrimaryTaskFragment */);
- taskContainer.mContainers.add(tf0);
- taskContainer.mContainers.add(tf1);
// When tf2 is created with using tf0 as pairedPrimaryContainer, tf2 should be inserted
// right above tf0.
@@ -506,6 +539,26 @@
}
@Test
+ public void testNewContainerWithPairedPendingAppearedActivity() {
+ final TaskContainer taskContainer = createTestTaskContainer();
+ final TaskFragmentContainer tf0 = new TaskFragmentContainer(
+ createMockActivity(), null /* pendingAppearedIntent */, taskContainer, mController,
+ null /* pairedPrimaryTaskFragment */);
+ final TaskFragmentContainer tf1 = new TaskFragmentContainer(
+ null /* pendingAppearedActivity */, new Intent(), taskContainer, mController,
+ null /* pairedPrimaryTaskFragment */);
+
+ // When tf2 is created with pendingAppearedActivity, tf2 should be inserted below any
+ // TaskFragment without any Activity.
+ final TaskFragmentContainer tf2 = new TaskFragmentContainer(
+ createMockActivity(), null /* pendingAppearedIntent */, taskContainer, mController,
+ null /* pairedPrimaryTaskFragment */);
+ assertEquals(0, taskContainer.indexOf(tf0));
+ assertEquals(1, taskContainer.indexOf(tf2));
+ assertEquals(2, taskContainer.indexOf(tf1));
+ }
+
+ @Test
public void testIsVisible() {
final TaskContainer taskContainer = createTestTaskContainer();
final TaskFragmentContainer container = new TaskFragmentContainer(
diff --git a/libs/WindowManager/Jetpack/window-extensions-release.aar b/libs/WindowManager/Jetpack/window-extensions-release.aar
index a939cd8..5de5365 100644
--- a/libs/WindowManager/Jetpack/window-extensions-release.aar
+++ b/libs/WindowManager/Jetpack/window-extensions-release.aar
Binary files differ
diff --git a/libs/WindowManager/Shell/res/drawable/decor_minimize_button_dark.xml b/libs/WindowManager/Shell/res/drawable/decor_minimize_button_dark.xml
index 0bcaa53..b7ff96e 100644
--- a/libs/WindowManager/Shell/res/drawable/decor_minimize_button_dark.xml
+++ b/libs/WindowManager/Shell/res/drawable/decor_minimize_button_dark.xml
@@ -18,7 +18,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?attr/colorControlNormal">
+ android:tint="@color/decor_button_dark_color">
<path
android:fillColor="@android:color/white" android:pathData="M6,21V19H18V21Z"/>
</vector>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index 065fd95..b5ef72a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -257,12 +257,30 @@
}
}
+ /**
+ * Creates a persistent root task in WM for a particular windowing-mode.
+ * @param displayId The display to create the root task on.
+ * @param windowingMode Windowing mode to put the root task in.
+ * @param listener The listener to get the created task callback.
+ */
public void createRootTask(int displayId, int windowingMode, TaskListener listener) {
- ProtoLog.v(WM_SHELL_TASK_ORG, "createRootTask() displayId=%d winMode=%d listener=%s",
+ createRootTask(displayId, windowingMode, listener, false /* removeWithTaskOrganizer */);
+ }
+
+ /**
+ * Creates a persistent root task in WM for a particular windowing-mode.
+ * @param displayId The display to create the root task on.
+ * @param windowingMode Windowing mode to put the root task in.
+ * @param listener The listener to get the created task callback.
+ * @param removeWithTaskOrganizer True if this task should be removed when organizer destroyed.
+ */
+ public void createRootTask(int displayId, int windowingMode, TaskListener listener,
+ boolean removeWithTaskOrganizer) {
+ ProtoLog.v(WM_SHELL_TASK_ORG, "createRootTask() displayId=%d winMode=%d listener=%s" ,
displayId, windowingMode, listener.toString());
final IBinder cookie = new Binder();
setPendingLaunchCookieListener(cookie, listener);
- super.createRootTask(displayId, windowingMode, cookie);
+ super.createRootTask(displayId, windowingMode, cookie, removeWithTaskOrganizer);
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 9674b69..360bfe7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -981,21 +981,59 @@
}
/**
- * Adds and expands bubble for a specific intent. These bubbles are <b>not</b> backed by a n
- * otification and remain until the user dismisses the bubble or bubble stack. Only one intent
- * bubble is supported at a time.
+ * This method has different behavior depending on:
+ * - if an app bubble exists
+ * - if an app bubble is expanded
+ *
+ * If no app bubble exists, this will add and expand a bubble with the provided intent. The
+ * intent must be explicit (i.e. include a package name or fully qualified component class name)
+ * and the activity for it should be resizable.
+ *
+ * If an app bubble exists, this will toggle the visibility of it, i.e. if the app bubble is
+ * expanded, calling this method will collapse it. If the app bubble is not expanded, calling
+ * this method will expand it.
+ *
+ * These bubbles are <b>not</b> backed by a notification and remain until the user dismisses
+ * the bubble or bubble stack.
+ *
+ * Some notes:
+ * - Only one app bubble is supported at a time
+ * - Calling this method with a different intent than the existing app bubble will do nothing
*
* @param intent the intent to display in the bubble expanded view.
*/
- public void showAppBubble(Intent intent) {
- if (intent == null || intent.getPackage() == null) return;
+ public void showOrHideAppBubble(Intent intent) {
+ if (intent == null || intent.getPackage() == null) {
+ Log.w(TAG, "App bubble failed to show, invalid intent: " + intent
+ + ((intent != null) ? " with package: " + intent.getPackage() : " "));
+ return;
+ }
PackageManager packageManager = getPackageManagerForUser(mContext, mCurrentUserId);
if (!isResizableActivity(intent, packageManager, KEY_APP_BUBBLE)) return;
- Bubble b = new Bubble(intent, UserHandle.of(mCurrentUserId), mMainExecutor);
- b.setShouldAutoExpand(true);
- inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false);
+ Bubble existingAppBubble = mBubbleData.getBubbleInStackWithKey(KEY_APP_BUBBLE);
+ if (existingAppBubble != null) {
+ BubbleViewProvider selectedBubble = mBubbleData.getSelectedBubble();
+ if (isStackExpanded()) {
+ if (selectedBubble != null && KEY_APP_BUBBLE.equals(selectedBubble.getKey())) {
+ // App bubble is expanded, lets collapse
+ collapseStack();
+ } else {
+ // App bubble is not selected, select it
+ mBubbleData.setSelectedBubble(existingAppBubble);
+ }
+ } else {
+ // App bubble is not selected, select it & expand
+ mBubbleData.setSelectedBubble(existingAppBubble);
+ mBubbleData.setExpanded(true);
+ }
+ } else {
+ // App bubble does not exist, lets add and expand it
+ Bubble b = new Bubble(intent, UserHandle.of(mCurrentUserId), mMainExecutor);
+ b.setShouldAutoExpand(true);
+ inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false);
+ }
}
/**
@@ -1705,9 +1743,9 @@
}
@Override
- public void showAppBubble(Intent intent) {
+ public void showOrHideAppBubble(Intent intent) {
mMainExecutor.execute(() -> {
- BubbleController.this.showAppBubble(intent);
+ BubbleController.this.showOrHideAppBubble(intent);
});
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index af31391..6230d22 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -17,6 +17,7 @@
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
+import static com.android.wm.shell.bubbles.Bubble.KEY_APP_BUBBLE;
import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_DATA;
import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
@@ -684,7 +685,8 @@
if (bubble.getPendingIntentCanceled()
|| !(reason == Bubbles.DISMISS_AGED
|| reason == Bubbles.DISMISS_USER_GESTURE
- || reason == Bubbles.DISMISS_RELOAD_FROM_DISK)) {
+ || reason == Bubbles.DISMISS_RELOAD_FROM_DISK)
+ || KEY_APP_BUBBLE.equals(bubble.getKey())) {
return;
}
if (DEBUG_BUBBLE_DATA) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
index 465d1ab..df43257 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
@@ -109,13 +109,28 @@
void expandStackAndSelectBubble(Bubble bubble);
/**
- * Adds and expands bubble that is not notification based, but instead based on an intent from
- * the app. The intent must be explicit (i.e. include a package name or fully qualified
- * component class name) and the activity for it should be resizable.
+ * This method has different behavior depending on:
+ * - if an app bubble exists
+ * - if an app bubble is expanded
*
- * @param intent the intent to populate the bubble.
+ * If no app bubble exists, this will add and expand a bubble with the provided intent. The
+ * intent must be explicit (i.e. include a package name or fully qualified component class name)
+ * and the activity for it should be resizable.
+ *
+ * If an app bubble exists, this will toggle the visibility of it, i.e. if the app bubble is
+ * expanded, calling this method will collapse it. If the app bubble is not expanded, calling
+ * this method will expand it.
+ *
+ * These bubbles are <b>not</b> backed by a notification and remain until the user dismisses
+ * the bubble or bubble stack.
+ *
+ * Some notes:
+ * - Only one app bubble is supported at a time
+ * - Calling this method with a different intent than the existing app bubble will do nothing
+ *
+ * @param intent the intent to display in the bubble expanded view.
*/
- void showAppBubble(Intent intent);
+ void showOrHideAppBubble(Intent intent);
/**
* @return a bubble that matches the provided shortcutId, if one exists.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
index f5f3573..63b03ab 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
@@ -251,7 +251,8 @@
* Show apps on desktop
*/
void showDesktopApps() {
- WindowContainerTransaction wct = bringDesktopAppsToFront();
+ // Bring apps to front, ignoring their visibility status to always ensure they are on top.
+ WindowContainerTransaction wct = bringDesktopAppsToFront(true /* ignoreVisibility */);
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
mTransitions.startTransition(TRANSIT_TO_FRONT, wct, null /* handler */);
@@ -261,7 +262,7 @@
}
@NonNull
- private WindowContainerTransaction bringDesktopAppsToFront() {
+ private WindowContainerTransaction bringDesktopAppsToFront(boolean force) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
final ArraySet<Integer> activeTasks = mDesktopModeTaskRepository.getActiveTasks();
ProtoLog.d(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: tasks=%s", activeTasks.size());
@@ -278,12 +279,14 @@
return wct;
}
- final boolean allActiveTasksAreVisible = taskInfos.stream()
- .allMatch(info -> mDesktopModeTaskRepository.isVisibleTask(info.taskId));
- if (allActiveTasksAreVisible) {
- ProtoLog.d(WM_SHELL_DESKTOP_MODE,
- "bringDesktopAppsToFront: active tasks are already in front, skipping.");
- return wct;
+ if (!force) {
+ final boolean allActiveTasksAreVisible = taskInfos.stream()
+ .allMatch(info -> mDesktopModeTaskRepository.isVisibleTask(info.taskId));
+ if (allActiveTasksAreVisible) {
+ ProtoLog.d(WM_SHELL_DESKTOP_MODE,
+ "bringDesktopAppsToFront: active tasks are already in front, skipping.");
+ return wct;
+ }
}
ProtoLog.d(WM_SHELL_DESKTOP_MODE,
"bringDesktopAppsToFront: reordering all active tasks to the front");
@@ -354,7 +357,7 @@
if (wct == null) {
wct = new WindowContainerTransaction();
}
- wct.merge(bringDesktopAppsToFront(), true /* transfer */);
+ wct.merge(bringDesktopAppsToFront(false /* ignoreVisibility */), true /* transfer */);
wct.reorder(request.getTriggerTask().token, true /* onTop */);
return wct;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 3341470..9165f70 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -84,8 +84,7 @@
fun showDesktopApps() {
ProtoLog.v(WM_SHELL_DESKTOP_MODE, "showDesktopApps")
val wct = WindowContainerTransaction()
-
- bringDesktopAppsToFront(wct)
+ bringDesktopAppsToFront(wct, force = true)
// Execute transaction if there are pending operations
if (!wct.isEmpty) {
@@ -150,11 +149,11 @@
?: WINDOWING_MODE_UNDEFINED
}
- private fun bringDesktopAppsToFront(wct: WindowContainerTransaction) {
+ private fun bringDesktopAppsToFront(wct: WindowContainerTransaction, force: Boolean = false) {
val activeTasks = desktopModeTaskRepository.getActiveTasks()
// Skip if all tasks are already visible
- if (activeTasks.isNotEmpty() && activeTasks.all(desktopModeTaskRepository::isVisibleTask)) {
+ if (!force && activeTasks.all(desktopModeTaskRepository::isVisibleTask)) {
ProtoLog.d(
WM_SHELL_DESKTOP_MODE,
"bringDesktopAppsToFront: active tasks are already in front, skipping."
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index e6c7e10..83158ff 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -662,8 +662,8 @@
}
// Please file a bug to handle the unexpected transition type.
- throw new IllegalStateException("Entering PIP with unexpected transition type="
- + transitTypeToString(transitType));
+ android.util.Slog.e(TAG, "Found new PIP in transition with mis-matched type="
+ + transitTypeToString(transitType), new Throwable());
}
return false;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
index a0a8f9f..94e593b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
@@ -333,6 +333,9 @@
mTmpDestinationRectF.set(destinationBounds);
mMoveTransform.setRectToRect(mTmpSourceRectF, mTmpDestinationRectF, Matrix.ScaleToFit.FILL);
final SurfaceControl surfaceControl = getSurfaceControl();
+ if (surfaceControl == null) {
+ return;
+ }
final SurfaceControl.Transaction menuTx =
mSurfaceControlTransactionFactory.getTransaction();
menuTx.setMatrix(surfaceControl, mMoveTransform, mTmpTransform);
@@ -359,6 +362,9 @@
}
final SurfaceControl surfaceControl = getSurfaceControl();
+ if (surfaceControl == null) {
+ return;
+ }
final SurfaceControl.Transaction menuTx =
mSurfaceControlTransactionFactory.getTransaction();
menuTx.setCrop(surfaceControl, destinationBounds);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 8ddc3c04..1488469 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -605,9 +605,19 @@
float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
if (options1 == null) options1 = new Bundle();
+ if (taskId2 == INVALID_TASK_ID) {
+ // Launching a solo task.
+ ActivityOptions activityOptions = ActivityOptions.fromBundle(options1);
+ activityOptions.update(ActivityOptions.makeRemoteAnimation(adapter));
+ options1 = activityOptions.toBundle();
+ addActivityOptions(options1, null /* launchTarget */);
+ wct.startTask(taskId1, options1);
+ mSyncQueue.queue(wct);
+ return;
+ }
+
addActivityOptions(options1, mSideStage);
wct.startTask(taskId1, options1);
-
startWithLegacyTransition(wct, taskId2, options2, splitPosition, splitRatio, adapter,
instanceId);
}
@@ -632,9 +642,19 @@
InstanceId instanceId) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
if (options1 == null) options1 = new Bundle();
+ if (taskId == INVALID_TASK_ID) {
+ // Launching a solo task.
+ ActivityOptions activityOptions = ActivityOptions.fromBundle(options1);
+ activityOptions.update(ActivityOptions.makeRemoteAnimation(adapter));
+ options1 = activityOptions.toBundle();
+ addActivityOptions(options1, null /* launchTarget */);
+ wct.sendPendingIntent(pendingIntent, fillInIntent, options1);
+ mSyncQueue.queue(wct);
+ return;
+ }
+
addActivityOptions(options1, mSideStage);
wct.sendPendingIntent(pendingIntent, fillInIntent, options1);
-
startWithLegacyTransition(wct, taskId, options2, splitPosition, splitRatio, adapter,
instanceId);
}
@@ -696,6 +716,34 @@
mShouldUpdateRecents = false;
mIsSplitEntering = true;
+ setSideStagePosition(sidePosition, wct);
+ if (!mMainStage.isActive()) {
+ mMainStage.activate(wct, false /* reparent */);
+ }
+
+ if (mainOptions == null) mainOptions = new Bundle();
+ addActivityOptions(mainOptions, mMainStage);
+ mainOptions = wrapAsSplitRemoteAnimation(adapter, mainOptions);
+
+ updateWindowBounds(mSplitLayout, wct);
+ if (mainTaskId == INVALID_TASK_ID) {
+ wct.sendPendingIntent(mainPendingIntent, mainFillInIntent, mainOptions);
+ } else {
+ wct.startTask(mainTaskId, mainOptions);
+ }
+
+ wct.reorder(mRootTaskInfo.token, true);
+ wct.setForceTranslucent(mRootTaskInfo.token, false);
+
+ mSyncQueue.queue(wct);
+ mSyncQueue.runInSync(t -> {
+ setDividerVisibility(true, t);
+ });
+
+ setEnterInstanceId(instanceId);
+ }
+
+ private Bundle wrapAsSplitRemoteAnimation(RemoteAnimationAdapter adapter, Bundle options) {
final WindowContainerTransaction evictWct = new WindowContainerTransaction();
if (isSplitScreenVisible()) {
mMainStage.evictAllChildren(evictWct);
@@ -739,37 +787,9 @@
};
RemoteAnimationAdapter wrappedAdapter = new RemoteAnimationAdapter(
wrapper, adapter.getDuration(), adapter.getStatusBarTransitionDelay());
-
- if (mainOptions == null) {
- mainOptions = ActivityOptions.makeRemoteAnimation(wrappedAdapter).toBundle();
- } else {
- ActivityOptions mainActivityOptions = ActivityOptions.fromBundle(mainOptions);
- mainActivityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter));
- mainOptions = mainActivityOptions.toBundle();
- }
-
- setSideStagePosition(sidePosition, wct);
- if (!mMainStage.isActive()) {
- mMainStage.activate(wct, false /* reparent */);
- }
-
- if (mainOptions == null) mainOptions = new Bundle();
- addActivityOptions(mainOptions, mMainStage);
- updateWindowBounds(mSplitLayout, wct);
- if (mainTaskId == INVALID_TASK_ID) {
- wct.sendPendingIntent(mainPendingIntent, mainFillInIntent, mainOptions);
- } else {
- wct.startTask(mainTaskId, mainOptions);
- }
- wct.reorder(mRootTaskInfo.token, true);
- wct.setForceTranslucent(mRootTaskInfo.token, false);
-
- mSyncQueue.queue(wct);
- mSyncQueue.runInSync(t -> {
- setDividerVisibility(true, t);
- });
-
- setEnterInstanceId(instanceId);
+ ActivityOptions activityOptions = ActivityOptions.fromBundle(options);
+ activityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter));
+ return activityOptions.toBundle();
}
private void setEnterInstanceId(InstanceId instanceId) {
@@ -1228,8 +1248,10 @@
return SPLIT_POSITION_UNDEFINED;
}
- private void addActivityOptions(Bundle opts, StageTaskListener stage) {
- opts.putParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, stage.mRootTaskInfo.token);
+ private void addActivityOptions(Bundle opts, @Nullable StageTaskListener launchTarget) {
+ if (launchTarget != null) {
+ opts.putParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, launchTarget.mRootTaskInfo.token);
+ }
// Put BAL flags to avoid activity start aborted. Otherwise, flows like shortcut to split
// will be canceled.
opts.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, true);
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DismissBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DismissBubbleScreen.kt
index 7fc12f0..7a86c25 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DismissBubbleScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DismissBubbleScreen.kt
@@ -18,7 +18,6 @@
import android.content.Context
import android.graphics.Point
-import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.util.DisplayMetrics
import android.view.WindowManager
@@ -74,20 +73,4 @@
open fun testAppIsAlwaysVisible() {
flicker.assertLayers { this.isVisible(testApp) }
}
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
- super.visibleLayersShownMoreThanOneConsecutiveEntry()
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
index 08ed91b..379d5e9 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
@@ -94,9 +94,19 @@
flicker.assertLayersEnd { this.isVisible(testApp) }
}
- @Postsubmit @Test fun navBarLayerIsVisibleAtEnd() = flicker.navBarLayerIsVisibleAtEnd()
+ @Postsubmit
+ @Test
+ fun navBarLayerIsVisibleAtEnd() {
+ Assume.assumeFalse(flicker.scenario.isTablet)
+ flicker.navBarLayerIsVisibleAtEnd()
+ }
- @Postsubmit @Test fun navBarLayerPositionAtEnd() = flicker.navBarLayerPositionAtEnd()
+ @Postsubmit
+ @Test
+ fun navBarLayerPositionAtEnd() {
+ Assume.assumeFalse(flicker.scenario.isTablet)
+ flicker.navBarLayerPositionAtEnd()
+ }
/** {@inheritDoc} */
@FlakyTest
@@ -127,42 +137,4 @@
Assume.assumeTrue(flicker.scenario.isGesturalNavigation)
super.navBarWindowIsAlwaysVisible()
}
-
- /** {@inheritDoc} */
- @FlakyTest(bugId = 242088970)
- @Test
- override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
-
- /** {@inheritDoc} */
- @FlakyTest(bugId = 242088970)
- @Test
- override fun statusBarLayerIsVisibleAtStartAndEnd() =
- super.statusBarLayerIsVisibleAtStartAndEnd()
-
- /** {@inheritDoc} */
- @FlakyTest(bugId = 242088970)
- @Test
- override fun statusBarLayerPositionAtStartAndEnd() = super.statusBarLayerPositionAtStartAndEnd()
-
- /** {@inheritDoc} */
- @FlakyTest(bugId = 242088970)
- @Test
- override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
-
- /** {@inheritDoc} */
- @FlakyTest(bugId = 242088970)
- @Test
- override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
- super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
- @FlakyTest(bugId = 251217773)
- @Test
- override fun entireScreenCovered() {
- super.entireScreenCovered()
- }
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt
index b69ff64..5c0f854 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt
@@ -16,6 +16,7 @@
package com.android.wm.shell.flicker.bubble
+import android.platform.test.annotations.Presubmit
import androidx.test.filters.RequiresDevice
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
@@ -57,6 +58,7 @@
}
}
+ @Presubmit
@Test
open fun testAppIsAlwaysVisible() {
flicker.assertLayers { this.isVisible(testApp) }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
index 5e898e8..4f3facb 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
@@ -21,12 +21,7 @@
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerBuilder
import com.android.server.wm.flicker.FlickerTest
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule
-import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
-import com.android.server.wm.traces.common.service.PlatformConsts
import org.junit.Assume
import org.junit.FixMethodOrder
import org.junit.Test
@@ -64,17 +59,12 @@
override val transition: FlickerBuilder.() -> Unit
get() = {
setup {
- removeAllTasksButHome()
- device.wakeUpAndGoToHomeScreen()
pipApp.launchViaIntent(wmHelper)
pipApp.enableAutoEnterForPipActivity()
}
teardown {
// close gracefully so that onActivityUnpinned() can be called before force exit
pipApp.closePipWindow(wmHelper)
-
- setRotation(PlatformConsts.Rotation.ROTATION_0)
- RemoveAllTasksButHomeRule.removeAllTasksButHome()
pipApp.exit(wmHelper)
}
transitions { tapl.goHome() }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
index 79feeaa..8a694f7 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
@@ -20,11 +20,7 @@
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerBuilder
import com.android.server.wm.flicker.FlickerTest
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule
-import com.android.server.wm.traces.common.service.PlatformConsts
import org.junit.Assume
import org.junit.FixMethodOrder
import org.junit.Test
@@ -56,20 +52,17 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class EnterPipOnUserLeaveHintTest(flicker: FlickerTest) : EnterPipTest(flicker) {
+open class EnterPipOnUserLeaveHintTest(flicker: FlickerTest) : EnterPipTest(flicker) {
/** Defines the transition used to run the test */
override val transition: FlickerBuilder.() -> Unit
get() = {
setup {
- RemoveAllTasksButHomeRule.removeAllTasksButHome()
- device.wakeUpAndGoToHomeScreen()
- device.wakeUpAndGoToHomeScreen()
pipApp.launchViaIntent(wmHelper)
pipApp.enableEnterPipOnUserLeaveHint()
}
teardown {
- setRotation(PlatformConsts.Rotation.ROTATION_0)
- RemoveAllTasksButHomeRule.removeAllTasksButHome()
+ // close gracefully so that onActivityUnpinned() can be called before force exit
+ pipApp.closePipWindow(wmHelper)
pipApp.exit(wmHelper)
}
transitions { tapl.goHome() }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTestCfArm.kt
new file mode 100644
index 0000000..e478050
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTestCfArm.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 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.wm.shell.flicker.pip
+
+import com.android.server.wm.flicker.FlickerTest
+import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/** This test will fail because of b/264261596 */
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class EnterPipOnUserLeaveHintTestCfArm(flicker: FlickerTest) : EnterPipOnUserLeaveHintTest(flicker)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
index 1a76142..1524b16 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
@@ -21,10 +21,7 @@
import com.android.server.wm.flicker.FlickerBuilder
import com.android.server.wm.flicker.FlickerTest
import com.android.server.wm.flicker.FlickerTestFactory
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule
import com.android.server.wm.traces.common.ComponentNameMatcher
import com.android.server.wm.traces.common.service.PlatformConsts
import org.junit.FixMethodOrder
@@ -63,13 +60,9 @@
override val transition: FlickerBuilder.() -> Unit
get() = {
setup {
- RemoveAllTasksButHomeRule.removeAllTasksButHome()
- device.wakeUpAndGoToHomeScreen()
pipApp.launchViaIntent(wmHelper)
}
teardown {
- setRotation(PlatformConsts.Rotation.ROTATION_0)
- RemoveAllTasksButHomeRule.removeAllTasksButHome()
pipApp.exit(wmHelper)
}
transitions { pipApp.clickEnterPipButton(wmHelper) }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTestCfArm.kt
new file mode 100644
index 0000000..d2e8645
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTestCfArm.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 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.wm.shell.flicker.pip
+
+import com.android.server.wm.flicker.FlickerTest
+import com.android.server.wm.flicker.FlickerTestFactory
+import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
+import com.android.server.wm.traces.common.service.PlatformConsts
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class EnterPipTestCfArm(flicker: FlickerTest) : EnterPipTest(flicker) {
+ companion object {
+ /**
+ * Creates the test configurations.
+ *
+ * See [FlickerTestFactory.nonRotationTests] for configuring repetitions, screen orientation
+ * and navigation modes.
+ */
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): List<FlickerTest> {
+ return FlickerTestFactory.nonRotationTests(
+ supportedRotations = listOf(PlatformConsts.Rotation.ROTATION_0)
+ )
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
index a4c8d6f..ea6c14d7 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
@@ -26,11 +26,8 @@
import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.helpers.FixedOrientationAppHelper
import com.android.server.wm.flicker.helpers.WindowUtils
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.navBarLayerPositionAtStartAndEnd
-import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule
import com.android.server.wm.flicker.testapp.ActivityOptions.Pip.ACTION_ENTER_PIP
import com.android.server.wm.flicker.testapp.ActivityOptions.PortraitOnlyActivity.EXTRA_FIXED_ORIENTATION
import com.android.server.wm.traces.common.ComponentNameMatcher
@@ -70,7 +67,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class EnterPipToOtherOrientationTest(flicker: FlickerTest) : PipTransition(flicker) {
+open class EnterPipToOtherOrientationTest(flicker: FlickerTest) : PipTransition(flicker) {
private val testApp = FixedOrientationAppHelper(instrumentation)
private val startingBounds = WindowUtils.getDisplayBounds(PlatformConsts.Rotation.ROTATION_90)
private val endingBounds = WindowUtils.getDisplayBounds(PlatformConsts.Rotation.ROTATION_0)
@@ -79,9 +76,6 @@
override val transition: FlickerBuilder.() -> Unit
get() = {
setup {
- RemoveAllTasksButHomeRule.removeAllTasksButHome()
- device.wakeUpAndGoToHomeScreen()
-
// Launch a portrait only app on the fullscreen stack
testApp.launchViaIntent(
wmHelper,
@@ -95,8 +89,6 @@
)
}
teardown {
- setRotation(PlatformConsts.Rotation.ROTATION_0)
- RemoveAllTasksButHomeRule.removeAllTasksButHome()
pipApp.exit(wmHelper)
testApp.exit(wmHelper)
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTestCfArm.kt
new file mode 100644
index 0000000..39aab6e
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTestCfArm.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 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.wm.shell.flicker.pip
+
+import com.android.server.wm.flicker.FlickerTest
+import com.android.server.wm.flicker.FlickerTestFactory
+import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
+import com.android.server.wm.traces.common.service.PlatformConsts
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/** This test fails because of b/264261596 */
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class EnterPipToOtherOrientationTestCfArm(flicker: FlickerTest) :
+ EnterPipToOtherOrientationTest(flicker) {
+ companion object {
+ /**
+ * Creates the test configurations.
+ *
+ * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * navigation modes.
+ */
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<FlickerTest> {
+ return FlickerTestFactory.nonRotationTests(
+ supportedRotations = listOf(PlatformConsts.Rotation.ROTATION_0)
+ )
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
index 1420f8ce..b5a5004 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
@@ -56,7 +56,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ExitPipViaExpandButtonClickTest(flicker: FlickerTest) : ExitPipToAppTransition(flicker) {
+open class ExitPipViaExpandButtonClickTest(flicker: FlickerTest) : ExitPipToAppTransition(flicker) {
/** Defines the transition used to run the test */
override val transition: FlickerBuilder.() -> Unit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTestCfArm.kt
new file mode 100644
index 0000000..f77e335
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTestCfArm.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 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.wm.shell.flicker.pip
+
+import com.android.server.wm.flicker.FlickerTest
+import com.android.server.wm.flicker.FlickerTestFactory
+import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
+import com.android.server.wm.traces.common.service.PlatformConsts
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class ExitPipViaExpandButtonClickTestCfArm(flicker: FlickerTest) :
+ ExitPipViaExpandButtonClickTest(flicker) {
+ companion object {
+ /**
+ * Creates the test configurations.
+ *
+ * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * navigation modes.
+ */
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): List<FlickerTest> {
+ return FlickerTestFactory.nonRotationTests(
+ supportedRotations = listOf(PlatformConsts.Rotation.ROTATION_0)
+ )
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
index 12d6362..737e65c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
@@ -58,7 +58,6 @@
}
teardown {
imeApp.exit(wmHelper)
- setRotation(PlatformConsts.Rotation.ROTATION_0)
}
transitions {
// open the soft keyboard
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
index 0e0be79..1bf1354 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
@@ -18,6 +18,7 @@
import android.app.Instrumentation
import android.content.Intent
+import android.platform.test.annotations.Postsubmit
import com.android.server.wm.flicker.FlickerBuilder
import com.android.server.wm.flicker.FlickerTest
import com.android.server.wm.flicker.helpers.PipAppHelper
@@ -25,8 +26,11 @@
import com.android.server.wm.flicker.helpers.setRotation
import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
import com.android.server.wm.flicker.testapp.ActivityOptions
+import com.android.server.wm.traces.common.ComponentNameMatcher
import com.android.server.wm.traces.common.service.PlatformConsts
import com.android.wm.shell.flicker.BaseTest
+import com.google.common.truth.Truth
+import org.junit.Test
abstract class PipTransition(flicker: FlickerTest) : BaseTest(flicker) {
protected val pipApp = PipAppHelper(instrumentation)
@@ -56,7 +60,6 @@
* Gets a configuration that handles basic setup and teardown of pip tests and that launches the
* Pip app for test
*
- * @param eachRun If the pip app should be launched in each run (otherwise only 1x per test)
* @param stringExtras Arguments to pass to the PIP launch intent
* @param extraSpec Additional segment of flicker specification
*/
@@ -72,12 +75,27 @@
pipApp.launchViaIntentAndWaitForPip(wmHelper, stringExtras = stringExtras)
}
teardown {
- setRotation(PlatformConsts.Rotation.ROTATION_0)
- removeAllTasksButHome()
pipApp.exit(wmHelper)
}
extraSpec(this)
}
}
+
+ @Postsubmit
+ @Test
+ fun hasAtMostOnePipDismissOverlayWindow() {
+ val matcher = ComponentNameMatcher("", "pip-dismiss-overlay")
+ flicker.assertWm {
+ val overlaysPerState = trace.entries.map { entry ->
+ entry.windowStates.count { window ->
+ matcher.windowMatchesAnyOf(window)
+ } <= 1
+ }
+
+ Truth.assertWithMessage("Number of dismiss overlays per state")
+ .that(overlaysPerState)
+ .doesNotContain(false)
+ }
+ }
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
index 7d5dd89..d7107db 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
@@ -26,10 +26,7 @@
import com.android.server.wm.flicker.FlickerTestFactory
import com.android.server.wm.flicker.helpers.WindowUtils
import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
import com.android.server.wm.flicker.testapp.ActivityOptions
import com.android.server.wm.flicker.testapp.ActivityOptions.PortraitOnlyActivity.EXTRA_FIXED_ORIENTATION
import com.android.server.wm.traces.common.service.PlatformConsts
@@ -58,9 +55,6 @@
override val transition: FlickerBuilder.() -> Unit
get() = {
setup {
- removeAllTasksButHome()
- device.wakeUpAndGoToHomeScreen()
-
// Launch the PiP activity fixed as landscape.
pipApp.launchViaIntent(
wmHelper,
@@ -80,8 +74,6 @@
}
teardown {
pipApp.exit(wmHelper)
- setRotation(PlatformConsts.Rotation.ROTATION_0)
- removeAllTasksButHome()
}
transitions {
// Launch the activity back into fullscreen and ensure that it is now in landscape
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt
index 7403aab..0432a84 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt
@@ -31,22 +31,26 @@
@RequiresDevice
class TvPipMenuTests : TvPipTestBase() {
- private val systemUiResources =
+ private val systemUiResources by lazy {
packageManager.getResourcesForApplication(SYSTEM_UI_PACKAGE_NAME)
- private val pipBoundsWhileInMenu: Rect =
+ }
+ private val pipBoundsWhileInMenu: Rect by lazy {
systemUiResources.run {
val bounds =
getString(getIdentifier("pip_menu_bounds", "string", SYSTEM_UI_PACKAGE_NAME))
Rect.unflattenFromString(bounds) ?: error("Could not retrieve PiP menu bounds")
}
- private val playButtonDescription =
+ }
+ private val playButtonDescription by lazy {
systemUiResources.run {
getString(getIdentifier("pip_play", "string", SYSTEM_UI_PACKAGE_NAME))
}
- private val pauseButtonDescription =
+ }
+ private val pauseButtonDescription by lazy {
systemUiResources.run {
getString(getIdentifier("pip_pause", "string", SYSTEM_UI_PACKAGE_NAME))
}
+ }
@Before
fun tvPipMenuTestsTestUp() {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
index e6711ac..8b025cd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
@@ -16,6 +16,8 @@
package com.android.wm.shell.bubbles;
+import static com.android.wm.shell.bubbles.Bubble.KEY_APP_BUBBLE;
+
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -32,6 +34,7 @@
import android.app.Notification;
import android.app.PendingIntent;
+import android.content.Intent;
import android.content.LocusId;
import android.graphics.drawable.Icon;
import android.os.Bundle;
@@ -94,6 +97,7 @@
private Bubble mBubbleInterruptive;
private Bubble mBubbleDismissed;
private Bubble mBubbleLocusId;
+ private Bubble mAppBubble;
private BubbleData mBubbleData;
private TestableBubblePositioner mPositioner;
@@ -178,6 +182,11 @@
mBubbleMetadataFlagListener,
mPendingIntentCanceledListener,
mMainExecutor);
+
+ Intent appBubbleIntent = new Intent(mContext, BubblesTestActivity.class);
+ appBubbleIntent.setPackage(mContext.getPackageName());
+ mAppBubble = new Bubble(appBubbleIntent, new UserHandle(1), mMainExecutor);
+
mPositioner = new TestableBubblePositioner(mContext,
mock(WindowManager.class));
mBubbleData = new BubbleData(getContext(), mBubbleLogger, mPositioner,
@@ -1089,6 +1098,18 @@
assertOverflowChangedTo(ImmutableList.of());
}
+ @Test
+ public void test_removeAppBubble_skipsOverflow() {
+ mBubbleData.notificationEntryUpdated(mAppBubble, true /* suppressFlyout*/,
+ false /* showInShade */);
+ assertThat(mBubbleData.getBubbleInStackWithKey(KEY_APP_BUBBLE)).isEqualTo(mAppBubble);
+
+ mBubbleData.dismissBubbleWithKey(KEY_APP_BUBBLE, Bubbles.DISMISS_USER_GESTURE);
+
+ assertThat(mBubbleData.getOverflowBubbleWithKey(KEY_APP_BUBBLE)).isNull();
+ assertThat(mBubbleData.getBubbleInStackWithKey(KEY_APP_BUBBLE)).isNull();
+ }
+
private void verifyUpdateReceived() {
verify(mListener).applyUpdate(mUpdateCaptor.capture());
reset(mListener);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
index 08af3d3..35cc168 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
@@ -279,7 +279,7 @@
}
@Test
- public void testShowDesktopApps_appsAlreadyVisible_doesNothing() {
+ public void testShowDesktopApps_appsAlreadyVisible_bringsToFront() {
final RunningTaskInfo task1 = createFreeformTask();
mDesktopModeTaskRepository.addActiveTask(task1.taskId);
mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task1.taskId);
@@ -294,8 +294,17 @@
mController.showDesktopApps();
final WindowContainerTransaction wct = getBringAppsToFrontTransaction();
- // No reordering needed.
- assertThat(wct.getHierarchyOps()).isEmpty();
+ // Check wct has reorder calls
+ assertThat(wct.getHierarchyOps()).hasSize(2);
+ // Task 1 appeared first, must be first reorder to top.
+ HierarchyOp op1 = wct.getHierarchyOps().get(0);
+ assertThat(op1.getType()).isEqualTo(HIERARCHY_OP_TYPE_REORDER);
+ assertThat(op1.getContainer()).isEqualTo(task1.token.asBinder());
+
+ // Task 2 appeared last, must be last reorder to top.
+ HierarchyOp op2 = wct.getHierarchyOps().get(1);
+ assertThat(op2.getType()).isEqualTo(HIERARCHY_OP_TYPE_REORDER);
+ assertThat(op2.getContainer()).isEqualTo(task2.token.asBinder());
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 9a92879..4011d08 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -150,8 +150,8 @@
}
@Test
- fun showDesktopApps_appsAlreadyVisible_doesNothing() {
- setUpHomeTask()
+ fun showDesktopApps_appsAlreadyVisible_bringsToFront() {
+ val homeTask = setUpHomeTask()
val task1 = setUpFreeformTask()
val task2 = setUpFreeformTask()
markTaskVisible(task1)
@@ -159,7 +159,12 @@
controller.showDesktopApps()
- verifyWCTNotExecuted()
+ val wct = getLatestWct()
+ assertThat(wct.hierarchyOps).hasSize(3)
+ // Expect order to be from bottom: home, task1, task2
+ wct.assertReorderAt(index = 0, homeTask)
+ wct.assertReorderAt(index = 1, task1)
+ wct.assertReorderAt(index = 2, task2)
}
@Test
@@ -207,6 +212,23 @@
}
@Test
+ fun moveToDesktop_otherFreeformTasksBroughtToFront() {
+ val homeTask = setUpHomeTask()
+ val freeformTask = setUpFreeformTask()
+ val fullscreenTask = setUpFullscreenTask()
+ markTaskHidden(freeformTask)
+
+ controller.moveToDesktop(fullscreenTask)
+
+ with(getLatestWct()) {
+ assertThat(hierarchyOps).hasSize(3)
+ assertReorderSequence(homeTask, freeformTask, fullscreenTask)
+ assertThat(changes[fullscreenTask.token.asBinder()]?.windowingMode)
+ .isEqualTo(WINDOWING_MODE_FREEFORM)
+ }
+ }
+
+ @Test
fun moveToFullscreen() {
val task = setUpFreeformTask()
controller.moveToFullscreen(task)
@@ -406,3 +428,9 @@
assertThat(op.type).isEqualTo(HIERARCHY_OP_TYPE_REORDER)
assertThat(op.container).isEqualTo(task.token.asBinder())
}
+
+private fun WindowContainerTransaction.assertReorderSequence(vararg tasks: RunningTaskInfo) {
+ for (i in tasks.indices) {
+ assertReorderAt(i, tasks[i])
+ }
+}
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 59e4b7a..aeead5e 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -78,6 +78,7 @@
"external/skia/src/utils",
"external/skia/src/gpu",
"external/skia/src/shaders",
+ "external/skia/modules/skottie",
],
},
host: {
@@ -214,6 +215,15 @@
path: "apex/java",
}
+java_api_contribution {
+ name: "framework-graphics-public-stubs",
+ api_surface: "public",
+ api_file: "api/current.txt",
+ visibility: [
+ "//build/orchestrator/apis",
+ ],
+}
+
// ------------------------
// APEX
// ------------------------
@@ -375,6 +385,7 @@
"external/skia/src/effects",
"external/skia/src/image",
"external/skia/src/images",
+ "external/skia/modules/skottie",
],
shared_libs: [
@@ -402,6 +413,7 @@
"jni/BitmapRegionDecoder.cpp",
"jni/GIFMovie.cpp",
"jni/GraphicsStatsService.cpp",
+ "jni/LottieDrawable.cpp",
"jni/Movie.cpp",
"jni/MovieImpl.cpp",
"jni/pdf/PdfDocument.cpp",
@@ -509,6 +521,7 @@
"hwui/BlurDrawLooper.cpp",
"hwui/Canvas.cpp",
"hwui/ImageDecoder.cpp",
+ "hwui/LottieDrawable.cpp",
"hwui/MinikinSkia.cpp",
"hwui/MinikinUtils.cpp",
"hwui/PaintImpl.cpp",
diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp
index 0240c86..32bc122 100644
--- a/libs/hwui/DeviceInfo.cpp
+++ b/libs/hwui/DeviceInfo.cpp
@@ -108,6 +108,10 @@
get()->mSupportFp16ForHdr = supportFp16ForHdr;
}
+void DeviceInfo::setSupportMixedColorSpaces(bool supportMixedColorSpaces) {
+ get()->mSupportMixedColorSpaces = supportMixedColorSpaces;
+}
+
void DeviceInfo::onRefreshRateChanged(int64_t vsyncPeriod) {
mVsyncPeriod = vsyncPeriod;
}
diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h
index 577780b..d4af087 100644
--- a/libs/hwui/DeviceInfo.h
+++ b/libs/hwui/DeviceInfo.h
@@ -62,6 +62,9 @@
static void setSupportFp16ForHdr(bool supportFp16ForHdr);
static bool isSupportFp16ForHdr() { return get()->mSupportFp16ForHdr; };
+ static void setSupportMixedColorSpaces(bool supportMixedColorSpaces);
+ static bool isSupportMixedColorSpaces() { return get()->mSupportMixedColorSpaces; };
+
// this value is only valid after the GPU has been initialized and there is a valid graphics
// context or if you are using the HWUI_NULL_GPU
int maxTextureSize() const;
@@ -92,6 +95,7 @@
int mMaxTextureSize;
sk_sp<SkColorSpace> mWideColorSpace = SkColorSpace::MakeSRGB();
bool mSupportFp16ForHdr = false;
+ bool mSupportMixedColorSpaces = false;
SkColorType mWideColorType = SkColorType::kN32_SkColorType;
int mDisplaysSize = 0;
int mPhysicalDisplayIndex = -1;
diff --git a/libs/hwui/MemoryPolicy.h b/libs/hwui/MemoryPolicy.h
index 41ced8c..2f0f7f5 100644
--- a/libs/hwui/MemoryPolicy.h
+++ b/libs/hwui/MemoryPolicy.h
@@ -53,8 +53,8 @@
// Whether or not to only purge scratch resources when triggering UI Hidden or background
// collection
bool purgeScratchOnly = true;
- // EXPERIMENTAL: Whether or not to trigger releasing GPU context when all contexts are stopped
- bool releaseContextOnStoppedOnly = false;
+ // Whether or not to trigger releasing GPU context when all contexts are stopped
+ bool releaseContextOnStoppedOnly = true;
};
const MemoryPolicy& loadMemoryPolicy();
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index 8dcd6db..045de35 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -28,6 +28,7 @@
#include <SkRefCnt.h>
#include <SkSamplingOptions.h>
#include <SkSurface.h>
+#include "include/gpu/GpuTypes.h" // from Skia
#include <gui/TraceUtils.h>
#include <private/android/AHardwareBufferHelpers.h>
#include <shaders/shaders.h>
@@ -170,14 +171,15 @@
SkBitmap skBitmap = request->getDestinationBitmap(srcRect.width(), srcRect.height());
SkBitmap* bitmap = &skBitmap;
sk_sp<SkSurface> tmpSurface =
- SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), SkBudgeted::kYes,
+ SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), skgpu::Budgeted::kYes,
bitmap->info(), 0, kTopLeft_GrSurfaceOrigin, nullptr);
// if we can't generate a GPU surface that matches the destination bitmap (e.g. 565) then we
// attempt to do the intermediate rendering step in 8888
if (!tmpSurface.get()) {
SkImageInfo tmpInfo = bitmap->info().makeColorType(SkColorType::kN32_SkColorType);
- tmpSurface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), SkBudgeted::kYes,
+ tmpSurface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(),
+ skgpu::Budgeted::kYes,
tmpInfo, 0, kTopLeft_GrSurfaceOrigin, nullptr);
if (!tmpSurface.get()) {
ALOGW("Unable to generate GPU buffer in a format compatible with the provided bitmap");
@@ -345,14 +347,17 @@
* software buffer.
*/
sk_sp<SkSurface> tmpSurface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(),
- SkBudgeted::kYes, bitmap->info(), 0,
+ skgpu::Budgeted::kYes,
+ bitmap->info(),
+ 0,
kTopLeft_GrSurfaceOrigin, nullptr);
// if we can't generate a GPU surface that matches the destination bitmap (e.g. 565) then we
// attempt to do the intermediate rendering step in 8888
if (!tmpSurface.get()) {
SkImageInfo tmpInfo = bitmap->info().makeColorType(SkColorType::kN32_SkColorType);
- tmpSurface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), SkBudgeted::kYes,
+ tmpSurface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(),
+ skgpu::Budgeted::kYes,
tmpInfo, 0, kTopLeft_GrSurfaceOrigin, nullptr);
if (!tmpSurface.get()) {
ALOGW("Unable to generate GPU buffer in a format compatible with the provided bitmap");
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 3f21940..e1030b0 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -44,6 +44,7 @@
#include "SkTextBlob.h"
#include "SkVertices.h"
#include "VectorDrawable.h"
+#include "include/gpu/GpuTypes.h" // from Skia
#include "pipeline/skia/AnimatedDrawables.h"
#include "pipeline/skia/FunctorDrawable.h"
@@ -570,7 +571,7 @@
GrRecordingContext* directContext = c->recordingContext();
mLayerImageInfo =
c->imageInfo().makeWH(deviceBounds.width(), deviceBounds.height());
- mLayerSurface = SkSurface::MakeRenderTarget(directContext, SkBudgeted::kYes,
+ mLayerSurface = SkSurface::MakeRenderTarget(directContext, skgpu::Budgeted::kYes,
mLayerImageInfo, 0,
kTopLeft_GrSurfaceOrigin, nullptr);
}
@@ -605,12 +606,17 @@
};
}
+static constexpr inline bool is_power_of_two(int value) {
+ return (value & (value - 1)) == 0;
+}
+
template <typename T, typename... Args>
void* DisplayListData::push(size_t pod, Args&&... args) {
size_t skip = SkAlignPtr(sizeof(T) + pod);
SkASSERT(skip < (1 << 24));
if (fUsed + skip > fReserved) {
- static_assert(SkIsPow2(SKLITEDL_PAGE), "This math needs updating for non-pow2.");
+ static_assert(is_power_of_two(SKLITEDL_PAGE),
+ "This math needs updating for non-pow2.");
// Next greater multiple of SKLITEDL_PAGE.
fReserved = (fUsed + skip + SKLITEDL_PAGE) & ~(SKLITEDL_PAGE - 1);
fBytes.realloc(fReserved);
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 2539694..b7d4dc9 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -16,11 +16,13 @@
#pragma once
-#include "CanvasTransform.h"
-#include "hwui/Bitmap.h"
-#include "utils/Macros.h"
-#include "utils/TypeLogic.h"
+#include <SkRuntimeEffect.h>
+#include <log/log.h>
+#include <cstdlib>
+#include <vector>
+
+#include "CanvasTransform.h"
#include "SkCanvas.h"
#include "SkCanvasVirtualEnforcer.h"
#include "SkDrawable.h"
@@ -28,11 +30,11 @@
#include "SkPaint.h"
#include "SkPath.h"
#include "SkRect.h"
-
+#include "hwui/Bitmap.h"
#include "pipeline/skia/AnimatedDrawables.h"
-
-#include <SkRuntimeEffect.h>
-#include <vector>
+#include "utils/AutoMalloc.h"
+#include "utils/Macros.h"
+#include "utils/TypeLogic.h"
enum class SkBlendMode;
class SkRRect;
@@ -145,7 +147,7 @@
template <typename Fn, typename... Args>
void map(const Fn[], Args...) const;
- SkAutoTMalloc<uint8_t> fBytes;
+ AutoTMalloc<uint8_t> fBytes;
size_t fUsed = 0;
size_t fReserved = 0;
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index d83d78f..af8bd26 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -16,23 +16,12 @@
#include "SkiaCanvas.h"
-#include "CanvasProperty.h"
-#include "NinePatchUtils.h"
-#include "SkBlendMode.h"
-#include "VectorDrawable.h"
-#include "hwui/Bitmap.h"
-#include "hwui/MinikinUtils.h"
-#include "hwui/PaintFilter.h"
-#include "pipeline/skia/AnimatedDrawables.h"
-#include "pipeline/skia/HolePunch.h"
-
#include <SkAndroidFrameworkUtils.h>
#include <SkAnimatedImage.h>
#include <SkBitmap.h>
#include <SkCanvasPriv.h>
#include <SkCanvasStateUtils.h>
#include <SkColorFilter.h>
-#include <SkDeque.h>
#include <SkDrawable.h>
#include <SkFont.h>
#include <SkGraphics.h>
@@ -41,8 +30,8 @@
#include <SkMatrix.h>
#include <SkPaint.h>
#include <SkPicture.h>
-#include <SkRSXform.h>
#include <SkRRect.h>
+#include <SkRSXform.h>
#include <SkRect.h>
#include <SkRefCnt.h>
#include <SkShader.h>
@@ -54,6 +43,16 @@
#include <optional>
#include <utility>
+#include "CanvasProperty.h"
+#include "NinePatchUtils.h"
+#include "SkBlendMode.h"
+#include "VectorDrawable.h"
+#include "hwui/Bitmap.h"
+#include "hwui/MinikinUtils.h"
+#include "hwui/PaintFilter.h"
+#include "pipeline/skia/AnimatedDrawables.h"
+#include "pipeline/skia/HolePunch.h"
+
namespace android {
using uirenderer::PaintUtils;
@@ -176,7 +175,7 @@
// operation. It does this by explicitly saving off the clip & matrix state
// when requested and playing it back after the SkCanvas::restore.
void SkiaCanvas::restore() {
- const auto* rec = this->currentSaveRec();
+ const SaveRec* rec = this->currentSaveRec();
if (!rec) {
// Fast path - no record for this frame.
mCanvas->restore();
@@ -245,7 +244,9 @@
}
const SkiaCanvas::SaveRec* SkiaCanvas::currentSaveRec() const {
- const SaveRec* rec = mSaveStack ? static_cast<const SaveRec*>(mSaveStack->back()) : nullptr;
+ const SaveRec* rec = (mSaveStack && !mSaveStack->empty())
+ ? static_cast<const SaveRec*>(&mSaveStack->back())
+ : nullptr;
int currentSaveCount = mCanvas->getSaveCount();
SkASSERT(!rec || currentSaveCount >= rec->saveCount);
@@ -277,13 +278,12 @@
}
if (!mSaveStack) {
- mSaveStack.reset(new SkDeque(sizeof(struct SaveRec), 8));
+ mSaveStack.reset(new std::deque<SaveRec>());
}
- SaveRec* rec = static_cast<SaveRec*>(mSaveStack->push_back());
- rec->saveCount = mCanvas->getSaveCount();
- rec->saveFlags = flags;
- rec->clipIndex = mClipStack.size();
+ mSaveStack->emplace_back(mCanvas->getSaveCount(), // saveCount
+ flags, // saveFlags
+ mClipStack.size()); // clipIndex
}
template <typename T>
@@ -314,7 +314,7 @@
// If the current/post-restore save rec is also persisting clips, we
// leave them on the stack to be reapplied part of the next restore().
// Otherwise we're done and just pop them.
- const auto* rec = this->currentSaveRec();
+ const SaveRec* rec = this->currentSaveRec();
if (!rec || (rec->saveFlags & SaveFlags::Clip)) {
mClipStack.erase(begin, end);
}
@@ -736,6 +736,10 @@
return imgDrawable->drawStaging(mCanvas);
}
+void SkiaCanvas::drawLottie(LottieDrawable* lottieDrawable) {
+ lottieDrawable->drawStaging(mCanvas);
+}
+
void SkiaCanvas::drawVectorDrawable(VectorDrawableRoot* vectorDrawable) {
vectorDrawable->drawStaging(this);
}
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index 31e3b4c..533106d 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -19,20 +19,20 @@
#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
#include "DeferredLayerUpdater.h"
#endif
-#include "RenderNode.h"
-#include "VectorDrawable.h"
-#include "hwui/Canvas.h"
-#include "hwui/Paint.h"
-#include "hwui/BlurDrawLooper.h"
-
#include <SkCanvas.h>
-#include <SkDeque.h>
-#include "pipeline/skia/AnimatedDrawables.h"
-#include "src/core/SkArenaAlloc.h"
#include <cassert>
+#include <deque>
#include <optional>
+#include "RenderNode.h"
+#include "VectorDrawable.h"
+#include "hwui/BlurDrawLooper.h"
+#include "hwui/Canvas.h"
+#include "hwui/Paint.h"
+#include "pipeline/skia/AnimatedDrawables.h"
+#include "src/core/SkArenaAlloc.h"
+
enum class SkBlendMode;
class SkRRect;
@@ -145,6 +145,7 @@
float dstTop, float dstRight, float dstBottom,
const Paint* paint) override;
virtual double drawAnimatedImage(AnimatedImageDrawable* imgDrawable) override;
+ virtual void drawLottie(LottieDrawable* lottieDrawable) override;
virtual void drawVectorDrawable(VectorDrawableRoot* vectorDrawable) override;
@@ -211,6 +212,9 @@
int saveCount;
SaveFlags::Flags saveFlags;
size_t clipIndex;
+
+ SaveRec(int saveCount, SaveFlags::Flags saveFlags, size_t clipIndex)
+ : saveCount(saveCount), saveFlags(saveFlags), clipIndex(clipIndex) {}
};
const SaveRec* currentSaveRec() const;
@@ -224,11 +228,11 @@
class Clip;
- std::unique_ptr<SkCanvas> mCanvasOwned; // might own a canvas we allocated
- SkCanvas* mCanvas; // we do NOT own this canvas, it must survive us
- // unless it is the same as mCanvasOwned.get()
- std::unique_ptr<SkDeque> mSaveStack; // lazily allocated, tracks partial saves.
- std::vector<Clip> mClipStack; // tracks persistent clips.
+ std::unique_ptr<SkCanvas> mCanvasOwned; // Might own a canvas we allocated.
+ SkCanvas* mCanvas; // We do NOT own this canvas, it must survive us
+ // unless it is the same as mCanvasOwned.get().
+ std::unique_ptr<std::deque<SaveRec>> mSaveStack; // Lazily allocated, tracks partial saves.
+ std::vector<Clip> mClipStack; // Tracks persistent clips.
sk_sp<PaintFilter> mPaintFilter;
};
diff --git a/libs/hwui/SkiaInterpolator.cpp b/libs/hwui/SkiaInterpolator.cpp
index b28b15a..47bd0b9 100644
--- a/libs/hwui/SkiaInterpolator.cpp
+++ b/libs/hwui/SkiaInterpolator.cpp
@@ -20,9 +20,10 @@
#include "include/core/SkScalar.h"
#include "include/core/SkTypes.h"
#include "include/private/SkFixed.h"
-#include "include/private/SkMalloc.h"
#include "src/core/SkTSearch.h"
+#include <log/log.h>
+
typedef int Dot14;
#define Dot14_ONE (1 << 14)
#define Dot14_HALF (1 << 13)
@@ -96,7 +97,7 @@
SkiaInterpolatorBase::~SkiaInterpolatorBase() {
if (fStorage) {
- sk_free(fStorage);
+ free(fStorage);
}
}
@@ -106,7 +107,7 @@
fFrameCount = static_cast<int16_t>(frameCount);
fRepeat = SK_Scalar1;
if (fStorage) {
- sk_free(fStorage);
+ free(fStorage);
fStorage = nullptr;
fTimes = nullptr;
}
@@ -213,7 +214,10 @@
void SkiaInterpolator::reset(int elemCount, int frameCount) {
INHERITED::reset(elemCount, frameCount);
- fStorage = sk_malloc_throw((sizeof(float) * elemCount + sizeof(SkTimeCode)) * frameCount);
+ size_t numBytes = (sizeof(float) * elemCount + sizeof(SkTimeCode)) * frameCount;
+ fStorage = malloc(numBytes);
+ LOG_ALWAYS_FATAL_IF(!fStorage, "Failed to allocate %zu bytes in %s",
+ numBytes, __func__);
fTimes = (SkTimeCode*)fStorage;
fValues = (float*)((char*)fStorage + sizeof(SkTimeCode) * frameCount);
}
diff --git a/libs/hwui/apex/jni_runtime.cpp b/libs/hwui/apex/jni_runtime.cpp
index f57d80c..b1aa1947 100644
--- a/libs/hwui/apex/jni_runtime.cpp
+++ b/libs/hwui/apex/jni_runtime.cpp
@@ -37,6 +37,7 @@
extern int register_android_graphics_Graphics(JNIEnv* env);
extern int register_android_graphics_ImageDecoder(JNIEnv*);
extern int register_android_graphics_drawable_AnimatedImageDrawable(JNIEnv*);
+extern int register_android_graphics_drawable_LottieDrawable(JNIEnv*);
extern int register_android_graphics_Interpolator(JNIEnv* env);
extern int register_android_graphics_MaskFilter(JNIEnv* env);
extern int register_android_graphics_Movie(JNIEnv* env);
@@ -117,6 +118,7 @@
REG_JNI(register_android_graphics_HardwareRendererObserver),
REG_JNI(register_android_graphics_ImageDecoder),
REG_JNI(register_android_graphics_drawable_AnimatedImageDrawable),
+ REG_JNI(register_android_graphics_drawable_LottieDrawable),
REG_JNI(register_android_graphics_Interpolator),
REG_JNI(register_android_graphics_MaskFilter),
REG_JNI(register_android_graphics_Matrix),
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index 2a20191..07e2fe2 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -60,6 +60,7 @@
typedef std::function<void(uint16_t* text, float* positions)> ReadGlyphFunc;
class AnimatedImageDrawable;
+class LottieDrawable;
class Bitmap;
class Paint;
struct Typeface;
@@ -242,6 +243,7 @@
const Paint* paint) = 0;
virtual double drawAnimatedImage(AnimatedImageDrawable* imgDrawable) = 0;
+ virtual void drawLottie(LottieDrawable* lottieDrawable) = 0;
virtual void drawPicture(const SkPicture& picture) = 0;
/**
diff --git a/libs/hwui/hwui/LottieDrawable.cpp b/libs/hwui/hwui/LottieDrawable.cpp
new file mode 100644
index 0000000..92dc51e
--- /dev/null
+++ b/libs/hwui/hwui/LottieDrawable.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#include "LottieDrawable.h"
+
+#include <SkTime.h>
+#include <log/log.h>
+#include <pipeline/skia/SkiaUtils.h>
+
+namespace android {
+
+sk_sp<LottieDrawable> LottieDrawable::Make(sk_sp<skottie::Animation> animation, size_t bytesUsed) {
+ if (animation) {
+ return sk_sp<LottieDrawable>(new LottieDrawable(std::move(animation), bytesUsed));
+ }
+ return nullptr;
+}
+LottieDrawable::LottieDrawable(sk_sp<skottie::Animation> animation, size_t bytesUsed)
+ : mAnimation(std::move(animation)), mBytesUsed(bytesUsed) {}
+
+bool LottieDrawable::start() {
+ if (mRunning) {
+ return false;
+ }
+
+ mRunning = true;
+ return true;
+}
+
+bool LottieDrawable::stop() {
+ bool wasRunning = mRunning;
+ mRunning = false;
+ return wasRunning;
+}
+
+bool LottieDrawable::isRunning() {
+ return mRunning;
+}
+
+// TODO: Check to see if drawable is actually dirty
+bool LottieDrawable::isDirty() {
+ return true;
+}
+
+void LottieDrawable::onDraw(SkCanvas* canvas) {
+ if (mRunning) {
+ const nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
+
+ nsecs_t t = 0;
+ if (mStartTime == 0) {
+ mStartTime = currentTime;
+ } else {
+ t = currentTime - mStartTime;
+ }
+ double seekTime = std::fmod((double)t * 1e-9, mAnimation->duration());
+ mAnimation->seekFrameTime(seekTime);
+ mAnimation->render(canvas);
+ }
+}
+
+void LottieDrawable::drawStaging(SkCanvas* canvas) {
+ onDraw(canvas);
+}
+
+SkRect LottieDrawable::onGetBounds() {
+ // We do not actually know the bounds, so give a conservative answer.
+ return SkRectMakeLargest();
+}
+
+} // namespace android
diff --git a/libs/hwui/hwui/LottieDrawable.h b/libs/hwui/hwui/LottieDrawable.h
new file mode 100644
index 0000000..9cc34bf
--- /dev/null
+++ b/libs/hwui/hwui/LottieDrawable.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#pragma once
+
+#include <SkDrawable.h>
+#include <Skottie.h>
+#include <utils/Timers.h>
+
+class SkCanvas;
+
+namespace android {
+
+/**
+ * Native component of android.graphics.drawable.LottieDrawable.java.
+ * This class can be drawn into Canvas.h and maintains the state needed to drive
+ * the animation from the RenderThread.
+ */
+class LottieDrawable : public SkDrawable {
+public:
+ static sk_sp<LottieDrawable> Make(sk_sp<skottie::Animation> animation, size_t bytes);
+
+ // Draw to software canvas
+ void drawStaging(SkCanvas* canvas);
+
+ // Returns true if the animation was started; false otherwise (e.g. it was
+ // already running)
+ bool start();
+ // Returns true if the animation was stopped; false otherwise (e.g. it was
+ // already stopped)
+ bool stop();
+ bool isRunning();
+
+ // TODO: Is dirty should take in a time til next frame to determine if it is dirty
+ bool isDirty();
+
+ SkRect onGetBounds() override;
+
+ size_t byteSize() const { return sizeof(*this) + mBytesUsed; }
+
+protected:
+ void onDraw(SkCanvas* canvas) override;
+
+private:
+ LottieDrawable(sk_sp<skottie::Animation> animation, size_t bytes_used);
+
+ sk_sp<skottie::Animation> mAnimation;
+ bool mRunning = false;
+ // The start time for the drawable itself.
+ nsecs_t mStartTime = 0;
+ const size_t mBytesUsed = 0;
+};
+
+} // namespace android
diff --git a/libs/hwui/jni/LottieDrawable.cpp b/libs/hwui/jni/LottieDrawable.cpp
new file mode 100644
index 0000000..fb6eede
--- /dev/null
+++ b/libs/hwui/jni/LottieDrawable.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#include <SkRect.h>
+#include <Skottie.h>
+#include <hwui/Canvas.h>
+#include <hwui/LottieDrawable.h>
+
+#include "GraphicsJNI.h"
+#include "Utils.h"
+
+using namespace android;
+
+static jclass gLottieDrawableClass;
+
+static jlong LottieDrawable_nCreate(JNIEnv* env, jobject, jstring jjson) {
+ const ScopedUtfChars cstr(env, jjson);
+ // TODO(b/259267150) provide more accurate byteSize
+ size_t bytes = strlen(cstr.c_str());
+ auto animation = skottie::Animation::Builder().make(cstr.c_str(), bytes);
+ sk_sp<LottieDrawable> drawable(LottieDrawable::Make(std::move(animation), bytes));
+ if (!drawable) {
+ return 0;
+ }
+ return reinterpret_cast<jlong>(drawable.release());
+}
+
+static void LottieDrawable_destruct(LottieDrawable* drawable) {
+ SkSafeUnref(drawable);
+}
+
+static jlong LottieDrawable_nGetNativeFinalizer(JNIEnv* /*env*/, jobject /*clazz*/) {
+ return static_cast<jlong>(reinterpret_cast<uintptr_t>(&LottieDrawable_destruct));
+}
+
+static void LottieDrawable_nDraw(JNIEnv* env, jobject /*clazz*/, jlong nativePtr, jlong canvasPtr) {
+ auto* drawable = reinterpret_cast<LottieDrawable*>(nativePtr);
+ auto* canvas = reinterpret_cast<Canvas*>(canvasPtr);
+ canvas->drawLottie(drawable);
+}
+
+static jboolean LottieDrawable_nIsRunning(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
+ auto* drawable = reinterpret_cast<LottieDrawable*>(nativePtr);
+ return drawable->isRunning();
+}
+
+static jboolean LottieDrawable_nStart(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
+ auto* drawable = reinterpret_cast<LottieDrawable*>(nativePtr);
+ return drawable->start();
+}
+
+static jboolean LottieDrawable_nStop(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
+ auto* drawable = reinterpret_cast<LottieDrawable*>(nativePtr);
+ return drawable->stop();
+}
+
+static jlong LottieDrawable_nNativeByteSize(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
+ auto* drawable = reinterpret_cast<LottieDrawable*>(nativePtr);
+ return drawable->byteSize();
+}
+
+static const JNINativeMethod gLottieDrawableMethods[] = {
+ {"nCreate", "(Ljava/lang/String;)J", (void*)LottieDrawable_nCreate},
+ {"nNativeByteSize", "(J)J", (void*)LottieDrawable_nNativeByteSize},
+ {"nGetNativeFinalizer", "()J", (void*)LottieDrawable_nGetNativeFinalizer},
+ {"nDraw", "(JJ)V", (void*)LottieDrawable_nDraw},
+ {"nIsRunning", "(J)Z", (void*)LottieDrawable_nIsRunning},
+ {"nStart", "(J)Z", (void*)LottieDrawable_nStart},
+ {"nStop", "(J)Z", (void*)LottieDrawable_nStop},
+};
+
+int register_android_graphics_drawable_LottieDrawable(JNIEnv* env) {
+ gLottieDrawableClass = reinterpret_cast<jclass>(
+ env->NewGlobalRef(FindClassOrDie(env, "android/graphics/drawable/LottieDrawable")));
+
+ return android::RegisterMethodsOrDie(env, "android/graphics/drawable/LottieDrawable",
+ gLottieDrawableMethods, NELEM(gLottieDrawableMethods));
+}
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index 47e2edb..3f4d004 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -829,12 +829,10 @@
DeviceInfo::setDensity(density);
}
-static void android_view_ThreadedRenderer_initDisplayInfo(JNIEnv* env, jclass, jint physicalWidth,
- jint physicalHeight, jfloat refreshRate,
- jint wideColorDataspace,
- jlong appVsyncOffsetNanos,
- jlong presentationDeadlineNanos,
- jboolean supportFp16ForHdr) {
+static void android_view_ThreadedRenderer_initDisplayInfo(
+ JNIEnv* env, jclass, jint physicalWidth, jint physicalHeight, jfloat refreshRate,
+ jint wideColorDataspace, jlong appVsyncOffsetNanos, jlong presentationDeadlineNanos,
+ jboolean supportFp16ForHdr, jboolean supportMixedColorSpaces) {
DeviceInfo::setWidth(physicalWidth);
DeviceInfo::setHeight(physicalHeight);
DeviceInfo::setRefreshRate(refreshRate);
@@ -842,6 +840,7 @@
DeviceInfo::setAppVsyncOffsetNanos(appVsyncOffsetNanos);
DeviceInfo::setPresentationDeadlineNanos(presentationDeadlineNanos);
DeviceInfo::setSupportFp16ForHdr(supportFp16ForHdr);
+ DeviceInfo::setSupportMixedColorSpaces(supportMixedColorSpaces);
}
static void android_view_ThreadedRenderer_setDrawingEnabled(JNIEnv*, jclass, jboolean enabled) {
@@ -991,7 +990,7 @@
{"nSetForceDark", "(JZ)V", (void*)android_view_ThreadedRenderer_setForceDark},
{"nSetDisplayDensityDpi", "(I)V",
(void*)android_view_ThreadedRenderer_setDisplayDensityDpi},
- {"nInitDisplayInfo", "(IIFIJJZ)V", (void*)android_view_ThreadedRenderer_initDisplayInfo},
+ {"nInitDisplayInfo", "(IIFIJJZZ)V", (void*)android_view_ThreadedRenderer_initDisplayInfo},
{"preload", "()V", (void*)android_view_ThreadedRenderer_preload},
{"isWebViewOverlaysEnabled", "()Z",
(void*)android_view_ThreadedRenderer_isWebViewOverlaysEnabled},
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
index dc72aea..a4960ea 100644
--- a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
@@ -24,6 +24,7 @@
#include "SkClipStack.h"
#include "SkRect.h"
#include "SkM44.h"
+#include "include/gpu/GpuTypes.h" // from Skia
#include "utils/GLUtils.h"
namespace android {
@@ -92,7 +93,7 @@
SkImageInfo surfaceInfo =
canvas->imageInfo().makeWH(clipBounds.width(), clipBounds.height());
tmpSurface =
- SkSurface::MakeRenderTarget(directContext, SkBudgeted::kYes, surfaceInfo);
+ SkSurface::MakeRenderTarget(directContext, skgpu::Budgeted::kYes, surfaceInfo);
tmpSurface->getCanvas()->clear(SK_ColorTRANSPARENT);
GrGLFramebufferInfo fboInfo;
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
index fcfc4f8..f0dc5eb 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -146,6 +146,16 @@
}
}
+ for (auto& lottie : mLotties) {
+ // If any animated image in the display list needs updated, then damage the node.
+ if (lottie->isDirty()) {
+ isDirty = true;
+ }
+ if (lottie->isRunning()) {
+ info.out.hasAnimations = true;
+ }
+ }
+
for (auto& [vectorDrawable, cachedMatrix] : mVectorDrawables) {
// If any vector drawable in the display list needs update, damage the node.
if (vectorDrawable->isDirty()) {
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h
index 2a67734..39217fc 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.h
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h
@@ -22,6 +22,7 @@
#include "RenderNodeDrawable.h"
#include "TreeInfo.h"
#include "hwui/AnimatedImageDrawable.h"
+#include "hwui/LottieDrawable.h"
#include "utils/LinearAllocator.h"
#include "utils/Pair.h"
@@ -186,6 +187,8 @@
return mHasHolePunches;
}
+ // TODO(b/257304231): create common base class for Lotties and AnimatedImages
+ std::vector<LottieDrawable*> mLotties;
std::vector<AnimatedImageDrawable*> mAnimatedImages;
DisplayListData mDisplayList;
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 1a336c5..3692f09 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -36,6 +36,7 @@
#include <SkStream.h>
#include <SkString.h>
#include <SkTypeface.h>
+#include "include/gpu/GpuTypes.h" // from Skia
#include <android-base/properties.h>
#include <unistd.h>
@@ -187,7 +188,7 @@
SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
SkASSERT(mRenderThread.getGrContext() != nullptr);
node->setLayerSurface(SkSurface::MakeRenderTarget(mRenderThread.getGrContext(),
- SkBudgeted::kYes, info, 0,
+ skgpu::Budgeted::kYes, info, 0,
this->getSurfaceOrigin(), &props));
if (node->getLayerSurface()) {
// update the transform in window of the layer to reset its origin wrt light source
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 1f87865..db449d6 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -188,6 +188,11 @@
#endif
}
+void SkiaRecordingCanvas::drawLottie(LottieDrawable* lottie) {
+ drawDrawable(lottie);
+ mDisplayList->mLotties.push_back(lottie);
+}
+
void SkiaRecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) {
mRecorder.drawVectorDrawable(tree);
SkMatrix mat;
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
index 7844e2c..c823d8d 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
@@ -78,6 +78,7 @@
uirenderer::CanvasPropertyPaint* paint) override;
virtual void drawRipple(const RippleDrawableParams& params) override;
+ virtual void drawLottie(LottieDrawable* lottieDrawable) override;
virtual void drawVectorDrawable(VectorDrawableRoot* vectorDrawable) override;
virtual void enableZ(bool enableZ) override;
diff --git a/libs/hwui/pipeline/skia/StretchMask.cpp b/libs/hwui/pipeline/skia/StretchMask.cpp
index b169c92..cad3703 100644
--- a/libs/hwui/pipeline/skia/StretchMask.cpp
+++ b/libs/hwui/pipeline/skia/StretchMask.cpp
@@ -18,6 +18,8 @@
#include "SkBlendMode.h"
#include "SkCanvas.h"
#include "SkSurface.h"
+#include "include/gpu/GpuTypes.h" // from Skia
+
#include "TransformCanvas.h"
#include "SkiaDisplayList.h"
@@ -36,7 +38,7 @@
// not match.
mMaskSurface = SkSurface::MakeRenderTarget(
context,
- SkBudgeted::kYes,
+ skgpu::Budgeted::kYes,
SkImageInfo::Make(
width,
height,
diff --git a/libs/hwui/tests/unit/CacheManagerTests.cpp b/libs/hwui/tests/unit/CacheManagerTests.cpp
index 508e198..2b90bda 100644
--- a/libs/hwui/tests/unit/CacheManagerTests.cpp
+++ b/libs/hwui/tests/unit/CacheManagerTests.cpp
@@ -21,6 +21,7 @@
#include "tests/common/TestUtils.h"
#include <SkImagePriv.h>
+#include "include/gpu/GpuTypes.h" // from Skia
using namespace android;
using namespace android::uirenderer;
@@ -45,7 +46,8 @@
while (getCacheUsage(grContext) <= renderThread.cacheManager().getBackgroundCacheSize()) {
SkImageInfo info = SkImageInfo::MakeA8(width, height);
- sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(grContext, SkBudgeted::kYes, info);
+ sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(grContext, skgpu::Budgeted::kYes,
+ info);
surface->getCanvas()->drawColor(SK_AlphaTRANSPARENT);
grContext->flushAndSubmit();
diff --git a/libs/hwui/tests/unit/GraphicsStatsServiceTests.cpp b/libs/hwui/tests/unit/GraphicsStatsServiceTests.cpp
index 92fd829..c2d23e6 100644
--- a/libs/hwui/tests/unit/GraphicsStatsServiceTests.cpp
+++ b/libs/hwui/tests/unit/GraphicsStatsServiceTests.cpp
@@ -15,6 +15,7 @@
*/
#include <android-base/macros.h>
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <stdio.h>
#include <stdlib.h>
@@ -49,8 +50,14 @@
// No code left untested
TEST(GraphicsStats, findRootPath) {
- std::string expected = "/data/local/tmp/nativetest/hwui_unit_tests/" ABI_STRING;
- EXPECT_EQ(expected, findRootPath());
+ // Different tools/infrastructure seem to push this to different locations. It shouldn't really
+ // matter where the binary is, so add new locations here as needed. This test still seems good
+ // as it's nice to understand the possibility space, and ensure findRootPath continues working
+ // as expected.
+ std::string acceptableLocations[] = {"/data/nativetest/hwui_unit_tests",
+ "/data/nativetest64/hwui_unit_tests",
+ "/data/local/tmp/nativetest/hwui_unit_tests/" ABI_STRING};
+ EXPECT_THAT(acceptableLocations, ::testing::Contains(findRootPath()));
}
TEST(GraphicsStats, saveLoad) {
diff --git a/libs/hwui/utils/AutoMalloc.h b/libs/hwui/utils/AutoMalloc.h
new file mode 100644
index 0000000..05f5e9f
--- /dev/null
+++ b/libs/hwui/utils/AutoMalloc.h
@@ -0,0 +1,94 @@
+/**
+ * Copyright (C) 2023 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.
+ */
+
+#pragma once
+
+#include <cstdlib>
+#include <memory>
+#include <type_traits>
+
+namespace android {
+namespace uirenderer {
+
+/** Manages an array of T elements, freeing the array in the destructor.
+ * Does NOT call any constructors/destructors on T (T must be POD).
+ */
+template <typename T,
+ typename = std::enable_if_t<std::is_trivially_default_constructible<T>::value &&
+ std::is_trivially_destructible<T>::value>>
+class AutoTMalloc {
+public:
+ /** Takes ownership of the ptr. The ptr must be a value which can be passed to std::free. */
+ explicit AutoTMalloc(T* ptr = nullptr) : fPtr(ptr) {}
+
+ /** Allocates space for 'count' Ts. */
+ explicit AutoTMalloc(size_t count) : fPtr(mallocIfCountThrowOnFail(count)) {}
+
+ AutoTMalloc(AutoTMalloc&&) = default;
+ AutoTMalloc& operator=(AutoTMalloc&&) = default;
+
+ /** Resize the memory area pointed to by the current ptr preserving contents. */
+ void realloc(size_t count) { fPtr.reset(reallocIfCountThrowOnFail(count)); }
+
+ /** Resize the memory area pointed to by the current ptr without preserving contents. */
+ T* reset(size_t count = 0) {
+ fPtr.reset(mallocIfCountThrowOnFail(count));
+ return this->get();
+ }
+
+ T* get() const { return fPtr.get(); }
+
+ operator T*() { return fPtr.get(); }
+
+ operator const T*() const { return fPtr.get(); }
+
+ T& operator[](int index) { return fPtr.get()[index]; }
+
+ const T& operator[](int index) const { return fPtr.get()[index]; }
+
+ /**
+ * Transfer ownership of the ptr to the caller, setting the internal
+ * pointer to NULL. Note that this differs from get(), which also returns
+ * the pointer, but it does not transfer ownership.
+ */
+ T* release() { return fPtr.release(); }
+
+private:
+ struct FreeDeleter {
+ void operator()(uint8_t* p) { std::free(p); }
+ };
+ std::unique_ptr<T, FreeDeleter> fPtr;
+
+ T* mallocIfCountThrowOnFail(size_t count) {
+ T* newPtr = nullptr;
+ if (count) {
+ newPtr = (T*)std::malloc(count * sizeof(T));
+ LOG_ALWAYS_FATAL_IF(!newPtr, "failed to malloc %zu bytes", count * sizeof(T));
+ }
+ return newPtr;
+ }
+ T* reallocIfCountThrowOnFail(size_t count) {
+ T* newPtr = nullptr;
+ if (count) {
+ newPtr = (T*)std::realloc(fPtr.release(), count * sizeof(T));
+ LOG_ALWAYS_FATAL_IF(!newPtr, "failed to realloc %zu bytes", count * sizeof(T));
+ }
+ return newPtr;
+ }
+};
+
+} // namespace uirenderer
+} // namespace android
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 761edf6..24c5b41 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3500,6 +3500,19 @@
}
/**
+ * Suspends the use of LE Audio.
+ *
+ * @param enable {@code true} to suspend le audio, {@code false} to unsuspend
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_STACK)
+ public void setLeAudioSuspended(boolean enable) {
+ AudioSystem.setParameters("LeAudioSuspended=" + enable);
+ }
+
+ /**
* Gets a variable number of parameter values from audio hardware.
*
* @param keys list of parameters
@@ -7009,6 +7022,10 @@
* Returns an array of {@link AudioDeviceInfo} objects corresponding to the audio devices
* currently connected to the system and meeting the criteria specified in the
* <code>flags</code> parameter.
+ * Notes that Android audio framework only support one device per device type. In that case,
+ * if there are multiple audio device with the same device type connected to the Android device,
+ * only the last reported device will be known by Android audio framework and returned by this
+ * API.
* @param flags A set of bitflags specifying the criteria to test.
* @see #GET_DEVICES_OUTPUTS
* @see #GET_DEVICES_INPUTS
diff --git a/media/java/android/media/MediaCas.java b/media/java/android/media/MediaCas.java
index 582a28e..015602e 100644
--- a/media/java/android/media/MediaCas.java
+++ b/media/java/android/media/MediaCas.java
@@ -21,11 +21,12 @@
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.content.Context;
+import android.hardware.cas.AidlCasPluginDescriptor;
+import android.hardware.cas.ICas;
+import android.hardware.cas.ICasListener;
+import android.hardware.cas.IMediaCasService;
+import android.hardware.cas.Status;
import android.hardware.cas.V1_0.HidlCasPluginDescriptor;
-import android.hardware.cas.V1_0.ICas;
-import android.hardware.cas.V1_0.IMediaCasService;
-import android.hardware.cas.V1_2.ICasListener;
-import android.hardware.cas.V1_2.Status;
import android.media.MediaCasException.*;
import android.media.tv.TvInputService.PriorityHintUseCaseType;
import android.media.tv.tunerresourcemanager.CasSessionRequest;
@@ -39,6 +40,7 @@
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.util.Log;
import android.util.Singleton;
@@ -47,6 +49,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -114,9 +117,10 @@
*/
public final class MediaCas implements AutoCloseable {
private static final String TAG = "MediaCas";
- private ICas mICas;
- private android.hardware.cas.V1_1.ICas mICasV11;
- private android.hardware.cas.V1_2.ICas mICasV12;
+ private ICas mICas = null;
+ private android.hardware.cas.V1_0.ICas mICasHidl = null;
+ private android.hardware.cas.V1_1.ICas mICasHidl11 = null;
+ private android.hardware.cas.V1_2.ICas mICasHidl12 = null;
private EventListener mListener;
private HandlerThread mHandlerThread;
private EventHandler mEventHandler;
@@ -133,88 +137,84 @@
*
* @hide
*/
- @IntDef(prefix = "SCRAMBLING_MODE_",
- value = {SCRAMBLING_MODE_RESERVED, SCRAMBLING_MODE_DVB_CSA1, SCRAMBLING_MODE_DVB_CSA2,
- SCRAMBLING_MODE_DVB_CSA3_STANDARD,
- SCRAMBLING_MODE_DVB_CSA3_MINIMAL, SCRAMBLING_MODE_DVB_CSA3_ENHANCE,
- SCRAMBLING_MODE_DVB_CISSA_V1, SCRAMBLING_MODE_DVB_IDSA,
- SCRAMBLING_MODE_MULTI2, SCRAMBLING_MODE_AES128, SCRAMBLING_MODE_AES_ECB,
- SCRAMBLING_MODE_AES_SCTE52, SCRAMBLING_MODE_TDES_ECB, SCRAMBLING_MODE_TDES_SCTE52})
+ @IntDef(
+ prefix = "SCRAMBLING_MODE_",
+ value = {
+ SCRAMBLING_MODE_RESERVED,
+ SCRAMBLING_MODE_DVB_CSA1,
+ SCRAMBLING_MODE_DVB_CSA2,
+ SCRAMBLING_MODE_DVB_CSA3_STANDARD,
+ SCRAMBLING_MODE_DVB_CSA3_MINIMAL,
+ SCRAMBLING_MODE_DVB_CSA3_ENHANCE,
+ SCRAMBLING_MODE_DVB_CISSA_V1,
+ SCRAMBLING_MODE_DVB_IDSA,
+ SCRAMBLING_MODE_MULTI2,
+ SCRAMBLING_MODE_AES128,
+ SCRAMBLING_MODE_AES_CBC,
+ SCRAMBLING_MODE_AES_ECB,
+ SCRAMBLING_MODE_AES_SCTE52,
+ SCRAMBLING_MODE_TDES_ECB,
+ SCRAMBLING_MODE_TDES_SCTE52
+ })
@Retention(RetentionPolicy.SOURCE)
public @interface ScramblingMode {}
- /**
- * DVB (Digital Video Broadcasting) reserved mode.
- */
- public static final int SCRAMBLING_MODE_RESERVED =
- android.hardware.cas.V1_2.ScramblingMode.RESERVED;
- /**
- * DVB (Digital Video Broadcasting) Common Scrambling Algorithm (CSA) 1.
- */
- public static final int SCRAMBLING_MODE_DVB_CSA1 =
- android.hardware.cas.V1_2.ScramblingMode.DVB_CSA1;
- /**
- * DVB CSA 2.
- */
- public static final int SCRAMBLING_MODE_DVB_CSA2 =
- android.hardware.cas.V1_2.ScramblingMode.DVB_CSA2;
- /**
- * DVB CSA 3 in standard mode.
- */
+ /** DVB (Digital Video Broadcasting) reserved mode. */
+ public static final int SCRAMBLING_MODE_RESERVED = android.hardware.cas.ScramblingMode.RESERVED;
+
+ /** DVB (Digital Video Broadcasting) Common Scrambling Algorithm (CSA) 1. */
+ public static final int SCRAMBLING_MODE_DVB_CSA1 = android.hardware.cas.ScramblingMode.DVB_CSA1;
+
+ /** DVB CSA 2. */
+ public static final int SCRAMBLING_MODE_DVB_CSA2 = android.hardware.cas.ScramblingMode.DVB_CSA2;
+
+ /** DVB CSA 3 in standard mode. */
public static final int SCRAMBLING_MODE_DVB_CSA3_STANDARD =
- android.hardware.cas.V1_2.ScramblingMode.DVB_CSA3_STANDARD;
- /**
- * DVB CSA 3 in minimally enhanced mode.
- */
+ android.hardware.cas.ScramblingMode.DVB_CSA3_STANDARD;
+
+ /** DVB CSA 3 in minimally enhanced mode. */
public static final int SCRAMBLING_MODE_DVB_CSA3_MINIMAL =
- android.hardware.cas.V1_2.ScramblingMode.DVB_CSA3_MINIMAL;
- /**
- * DVB CSA 3 in fully enhanced mode.
- */
+ android.hardware.cas.ScramblingMode.DVB_CSA3_MINIMAL;
+
+ /** DVB CSA 3 in fully enhanced mode. */
public static final int SCRAMBLING_MODE_DVB_CSA3_ENHANCE =
- android.hardware.cas.V1_2.ScramblingMode.DVB_CSA3_ENHANCE;
- /**
- * DVB Common IPTV Software-oriented Scrambling Algorithm (CISSA) Version 1.
- */
+ android.hardware.cas.ScramblingMode.DVB_CSA3_ENHANCE;
+
+ /** DVB Common IPTV Software-oriented Scrambling Algorithm (CISSA) Version 1. */
public static final int SCRAMBLING_MODE_DVB_CISSA_V1 =
- android.hardware.cas.V1_2.ScramblingMode.DVB_CISSA_V1;
- /**
- * ATIS-0800006 IIF Default Scrambling Algorithm (IDSA).
- */
- public static final int SCRAMBLING_MODE_DVB_IDSA =
- android.hardware.cas.V1_2.ScramblingMode.DVB_IDSA;
- /**
- * A symmetric key algorithm.
- */
- public static final int SCRAMBLING_MODE_MULTI2 =
- android.hardware.cas.V1_2.ScramblingMode.MULTI2;
- /**
- * Advanced Encryption System (AES) 128-bit Encryption mode.
- */
- public static final int SCRAMBLING_MODE_AES128 =
- android.hardware.cas.V1_2.ScramblingMode.AES128;
- /**
- * Advanced Encryption System (AES) Electronic Code Book (ECB) mode.
- */
- public static final int SCRAMBLING_MODE_AES_ECB =
- android.hardware.cas.V1_2.ScramblingMode.AES_ECB;
+ android.hardware.cas.ScramblingMode.DVB_CISSA_V1;
+
+ /** ATIS-0800006 IIF Default Scrambling Algorithm (IDSA). */
+ public static final int SCRAMBLING_MODE_DVB_IDSA = android.hardware.cas.ScramblingMode.DVB_IDSA;
+
+ /** A symmetric key algorithm. */
+ public static final int SCRAMBLING_MODE_MULTI2 = android.hardware.cas.ScramblingMode.MULTI2;
+
+ /** Advanced Encryption System (AES) 128-bit Encryption mode. */
+ public static final int SCRAMBLING_MODE_AES128 = android.hardware.cas.ScramblingMode.AES128;
+
+ /** Advanced Encryption System (AES) Cipher Block Chaining (CBC) mode. */
+ public static final int SCRAMBLING_MODE_AES_CBC = android.hardware.cas.ScramblingMode.AES_CBC;
+
+ /** Advanced Encryption System (AES) Electronic Code Book (ECB) mode. */
+ public static final int SCRAMBLING_MODE_AES_ECB = android.hardware.cas.ScramblingMode.AES_ECB;
+
/**
* Advanced Encryption System (AES) Society of Cable Telecommunications Engineers (SCTE) 52
* mode.
*/
public static final int SCRAMBLING_MODE_AES_SCTE52 =
- android.hardware.cas.V1_2.ScramblingMode.AES_SCTE52;
- /**
- * Triple Data Encryption Algorithm (TDES) Electronic Code Book (ECB) mode.
- */
- public static final int SCRAMBLING_MODE_TDES_ECB =
- android.hardware.cas.V1_2.ScramblingMode.TDES_ECB;
+ android.hardware.cas.ScramblingMode.AES_SCTE52;
+
+ /** Triple Data Encryption Algorithm (TDES) Electronic Code Book (ECB) mode. */
+ public static final int SCRAMBLING_MODE_TDES_ECB = android.hardware.cas.ScramblingMode.TDES_ECB;
+
/**
* Triple Data Encryption Algorithm (TDES) Society of Cable Telecommunications Engineers (SCTE)
* 52 mode.
*/
public static final int SCRAMBLING_MODE_TDES_SCTE52 =
- android.hardware.cas.V1_2.ScramblingMode.TDES_SCTE52;
+ android.hardware.cas.ScramblingMode.TDES_SCTE52;
/**
* Usages used to open cas sessions.
@@ -226,25 +226,21 @@
SESSION_USAGE_TIMESHIFT})
@Retention(RetentionPolicy.SOURCE)
public @interface SessionUsage {}
- /**
- * Cas session is used to descramble live streams.
- */
- public static final int SESSION_USAGE_LIVE = android.hardware.cas.V1_2.SessionIntent.LIVE;
- /**
- * Cas session is used to descramble recoreded streams.
- */
- public static final int SESSION_USAGE_PLAYBACK =
- android.hardware.cas.V1_2.SessionIntent.PLAYBACK;
- /**
- * Cas session is used to descramble live streams and encrypt local recorded content
- */
- public static final int SESSION_USAGE_RECORD = android.hardware.cas.V1_2.SessionIntent.RECORD;
+
+ /** Cas session is used to descramble live streams. */
+ public static final int SESSION_USAGE_LIVE = android.hardware.cas.SessionIntent.LIVE;
+
+ /** Cas session is used to descramble recoreded streams. */
+ public static final int SESSION_USAGE_PLAYBACK = android.hardware.cas.SessionIntent.PLAYBACK;
+
+ /** Cas session is used to descramble live streams and encrypt local recorded content */
+ public static final int SESSION_USAGE_RECORD = android.hardware.cas.SessionIntent.RECORD;
+
/**
* Cas session is used to descramble live streams , encrypt local recorded content and playback
* local encrypted content.
*/
- public static final int SESSION_USAGE_TIMESHIFT =
- android.hardware.cas.V1_2.SessionIntent.TIMESHIFT;
+ public static final int SESSION_USAGE_TIMESHIFT = android.hardware.cas.SessionIntent.TIMESHIFT;
/**
* Plugin status events sent from cas system.
@@ -261,63 +257,90 @@
* physical CAS modules.
*/
public static final int PLUGIN_STATUS_PHYSICAL_MODULE_CHANGED =
- android.hardware.cas.V1_2.StatusEvent.PLUGIN_PHYSICAL_MODULE_CHANGED;
- /**
- * The event to indicate that the number of CAS system's session is changed.
- */
+ android.hardware.cas.StatusEvent.PLUGIN_PHYSICAL_MODULE_CHANGED;
+
+ /** The event to indicate that the number of CAS system's session is changed. */
public static final int PLUGIN_STATUS_SESSION_NUMBER_CHANGED =
- android.hardware.cas.V1_2.StatusEvent.PLUGIN_SESSION_NUMBER_CHANGED;
+ android.hardware.cas.StatusEvent.PLUGIN_SESSION_NUMBER_CHANGED;
- private static final Singleton<IMediaCasService> sService = new Singleton<IMediaCasService>() {
- @Override
- protected IMediaCasService create() {
- try {
- Log.d(TAG, "Trying to get cas@1.2 service");
- android.hardware.cas.V1_2.IMediaCasService serviceV12 =
- android.hardware.cas.V1_2.IMediaCasService.getService(true /*wait*/);
- if (serviceV12 != null) {
- return serviceV12;
- }
- } catch (Exception eV1_2) {
- Log.d(TAG, "Failed to get cas@1.2 service");
- }
-
- try {
- Log.d(TAG, "Trying to get cas@1.1 service");
- android.hardware.cas.V1_1.IMediaCasService serviceV11 =
- android.hardware.cas.V1_1.IMediaCasService.getService(true /*wait*/);
- if (serviceV11 != null) {
- return serviceV11;
+ private static final Singleton<IMediaCasService> sService =
+ new Singleton<IMediaCasService>() {
+ @Override
+ protected IMediaCasService create() {
+ try {
+ Log.d(TAG, "Trying to get AIDL service");
+ IMediaCasService serviceAidl =
+ IMediaCasService.Stub.asInterface(
+ ServiceManager.getService(
+ IMediaCasService.DESCRIPTOR + "/default"));
+ if (serviceAidl != null) {
+ return serviceAidl;
+ }
+ } catch (Exception eAidl) {
+ Log.d(TAG, "Failed to get cas AIDL service");
}
- } catch (Exception eV1_1) {
- Log.d(TAG, "Failed to get cas@1.1 service");
- }
+ return null;
+ }
+ };
- try {
- Log.d(TAG, "Trying to get cas@1.0 service");
- return IMediaCasService.getService(true /*wait*/);
- } catch (Exception eV1_0) {
- Log.d(TAG, "Failed to get cas@1.0 service");
- }
+ private static final Singleton<android.hardware.cas.V1_0.IMediaCasService> sServiceHidl =
+ new Singleton<android.hardware.cas.V1_0.IMediaCasService>() {
+ @Override
+ protected android.hardware.cas.V1_0.IMediaCasService create() {
+ try {
+ Log.d(TAG, "Trying to get cas@1.2 service");
+ android.hardware.cas.V1_2.IMediaCasService serviceV12 =
+ android.hardware.cas.V1_2.IMediaCasService.getService(
+ true /*wait*/);
+ if (serviceV12 != null) {
+ return serviceV12;
+ }
+ } catch (Exception eV1_2) {
+ Log.d(TAG, "Failed to get cas@1.2 service");
+ }
- return null;
- }
- };
+ try {
+ Log.d(TAG, "Trying to get cas@1.1 service");
+ android.hardware.cas.V1_1.IMediaCasService serviceV11 =
+ android.hardware.cas.V1_1.IMediaCasService.getService(
+ true /*wait*/);
+ if (serviceV11 != null) {
+ return serviceV11;
+ }
+ } catch (Exception eV1_1) {
+ Log.d(TAG, "Failed to get cas@1.1 service");
+ }
+
+ try {
+ Log.d(TAG, "Trying to get cas@1.0 service");
+ return android.hardware.cas.V1_0.IMediaCasService.getService(true /*wait*/);
+ } catch (Exception eV1_0) {
+ Log.d(TAG, "Failed to get cas@1.0 service");
+ }
+
+ return null;
+ }
+ };
static IMediaCasService getService() {
return sService.get();
}
+ static android.hardware.cas.V1_0.IMediaCasService getServiceHidl() {
+ return sServiceHidl.get();
+ }
+
private void validateInternalStates() {
- if (mICas == null) {
+ if (mICas == null && mICasHidl == null) {
throw new IllegalStateException();
}
}
private void cleanupAndRethrowIllegalState() {
mICas = null;
- mICasV11 = null;
- mICasV12 = null;
+ mICasHidl = null;
+ mICasHidl11 = null;
+ mICasHidl12 = null;
throw new IllegalStateException();
}
@@ -341,7 +364,7 @@
toBytes((ArrayList<Byte>) msg.obj));
} else if (msg.what == MSG_CAS_SESSION_EVENT) {
Bundle bundle = msg.getData();
- ArrayList<Byte> sessionId = toByteArray(bundle.getByteArray(SESSION_KEY));
+ byte[] sessionId = bundle.getByteArray(SESSION_KEY);
mListener.onSessionEvent(MediaCas.this,
createFromSessionId(sessionId), msg.arg1, msg.arg2,
bundle.getByteArray(DATA_KEY));
@@ -357,40 +380,94 @@
}
}
- private final ICasListener.Stub mBinder = new ICasListener.Stub() {
- @Override
- public void onEvent(int event, int arg, @Nullable ArrayList<Byte> data)
- throws RemoteException {
- if (mEventHandler != null) {
- mEventHandler.sendMessage(mEventHandler.obtainMessage(
- EventHandler.MSG_CAS_EVENT, event, arg, data));
- }
- }
- @Override
- public void onSessionEvent(@NonNull ArrayList<Byte> sessionId,
- int event, int arg, @Nullable ArrayList<Byte> data)
- throws RemoteException {
- if (mEventHandler != null) {
- Message msg = mEventHandler.obtainMessage();
- msg.what = EventHandler.MSG_CAS_SESSION_EVENT;
- msg.arg1 = event;
- msg.arg2 = arg;
- Bundle bundle = new Bundle();
- bundle.putByteArray(EventHandler.SESSION_KEY, toBytes(sessionId));
- bundle.putByteArray(EventHandler.DATA_KEY, toBytes(data));
- msg.setData(bundle);
- mEventHandler.sendMessage(msg);
- }
- }
- @Override
- public void onStatusUpdate(byte status, int arg)
- throws RemoteException {
- if (mEventHandler != null) {
- mEventHandler.sendMessage(mEventHandler.obtainMessage(
- EventHandler.MSG_CAS_STATUS_EVENT, status, arg));
- }
- }
- };
+ private final ICasListener.Stub mBinder =
+ new ICasListener.Stub() {
+ @Override
+ public void onEvent(int event, int arg, byte[] data) throws RemoteException {
+ if (mEventHandler != null) {
+ mEventHandler.sendMessage(
+ mEventHandler.obtainMessage(
+ EventHandler.MSG_CAS_EVENT, event, arg, data));
+ }
+ }
+
+ @Override
+ public void onSessionEvent(byte[] sessionId, int event, int arg, byte[] data)
+ throws RemoteException {
+ if (mEventHandler != null) {
+ Message msg = mEventHandler.obtainMessage();
+ msg.what = EventHandler.MSG_CAS_SESSION_EVENT;
+ msg.arg1 = event;
+ msg.arg2 = arg;
+ Bundle bundle = new Bundle();
+ bundle.putByteArray(EventHandler.SESSION_KEY, sessionId);
+ bundle.putByteArray(EventHandler.DATA_KEY, data);
+ msg.setData(bundle);
+ mEventHandler.sendMessage(msg);
+ }
+ }
+
+ @Override
+ public void onStatusUpdate(byte status, int arg) throws RemoteException {
+ if (mEventHandler != null) {
+ mEventHandler.sendMessage(
+ mEventHandler.obtainMessage(
+ EventHandler.MSG_CAS_STATUS_EVENT, status, arg));
+ }
+ }
+
+ @Override
+ public synchronized String getInterfaceHash() throws android.os.RemoteException {
+ return ICasListener.Stub.HASH;
+ }
+
+ @Override
+ public int getInterfaceVersion() throws android.os.RemoteException {
+ return ICasListener.Stub.VERSION;
+ }
+ };
+
+ private final android.hardware.cas.V1_2.ICasListener.Stub mBinderHidl =
+ new android.hardware.cas.V1_2.ICasListener.Stub() {
+ @Override
+ public void onEvent(int event, int arg, @Nullable ArrayList<Byte> data)
+ throws RemoteException {
+ if (mEventHandler != null) {
+ mEventHandler.sendMessage(
+ mEventHandler.obtainMessage(
+ EventHandler.MSG_CAS_EVENT, event, arg, data));
+ }
+ }
+
+ @Override
+ public void onSessionEvent(
+ @NonNull ArrayList<Byte> sessionId,
+ int event,
+ int arg,
+ @Nullable ArrayList<Byte> data)
+ throws RemoteException {
+ if (mEventHandler != null) {
+ Message msg = mEventHandler.obtainMessage();
+ msg.what = EventHandler.MSG_CAS_SESSION_EVENT;
+ msg.arg1 = event;
+ msg.arg2 = arg;
+ Bundle bundle = new Bundle();
+ bundle.putByteArray(EventHandler.SESSION_KEY, toBytes(sessionId));
+ bundle.putByteArray(EventHandler.DATA_KEY, toBytes(data));
+ msg.setData(bundle);
+ mEventHandler.sendMessage(msg);
+ }
+ }
+
+ @Override
+ public void onStatusUpdate(byte status, int arg) throws RemoteException {
+ if (mEventHandler != null) {
+ mEventHandler.sendMessage(
+ mEventHandler.obtainMessage(
+ EventHandler.MSG_CAS_STATUS_EVENT, status, arg));
+ }
+ }
+ };
private final TunerResourceManager.ResourcesReclaimListener mResourceListener =
new TunerResourceManager.ResourcesReclaimListener() {
@@ -422,6 +499,11 @@
mName = null;
}
+ PluginDescriptor(@NonNull AidlCasPluginDescriptor descriptor) {
+ mCASystemId = descriptor.caSystemId;
+ mName = descriptor.name;
+ }
+
PluginDescriptor(@NonNull HidlCasPluginDescriptor descriptor) {
mCASystemId = descriptor.caSystemId;
mName = descriptor.name;
@@ -467,19 +549,20 @@
}
return data;
}
+
/**
* Class for an open session with the CA system.
*/
public final class Session implements AutoCloseable {
- final ArrayList<Byte> mSessionId;
+ final byte[] mSessionId;
boolean mIsClosed = false;
- Session(@NonNull ArrayList<Byte> sessionId) {
- mSessionId = new ArrayList<Byte>(sessionId);
+ Session(@NonNull byte[] sessionId) {
+ mSessionId = sessionId;
}
private void validateSessionInternalStates() {
- if (mICas == null) {
+ if (mICas == null && mICasHidl == null) {
throw new IllegalStateException();
}
if (mIsClosed) {
@@ -496,7 +579,7 @@
*/
public boolean equals(Object obj) {
if (obj instanceof Session) {
- return mSessionId.equals(((Session) obj).mSessionId);
+ return Arrays.equals(mSessionId, ((Session) obj).mSessionId);
}
return false;
}
@@ -515,8 +598,13 @@
validateSessionInternalStates();
try {
- MediaCasException.throwExceptionIfNeeded(
- mICas.setSessionPrivateData(mSessionId, toByteArray(data, 0, data.length)));
+ if (mICas != null) {
+ mICas.setSessionPrivateData(mSessionId, data);
+ } else {
+ MediaCasException.throwExceptionIfNeeded(
+ mICasHidl.setSessionPrivateData(
+ toByteArray(mSessionId), toByteArray(data, 0, data.length)));
+ }
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -539,8 +627,13 @@
validateSessionInternalStates();
try {
- MediaCasException.throwExceptionIfNeeded(
- mICas.processEcm(mSessionId, toByteArray(data, offset, length)));
+ if (mICas != null) {
+ mICas.processEcm(mSessionId, data);
+ } else {
+ MediaCasException.throwExceptionIfNeeded(
+ mICasHidl.processEcm(
+ toByteArray(mSessionId), toByteArray(data, offset, length)));
+ }
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -576,15 +669,23 @@
public void sendSessionEvent(int event, int arg, @Nullable byte[] data)
throws MediaCasException {
validateSessionInternalStates();
+ if (mICas != null) {
+ try {
+ mICas.sendSessionEvent(mSessionId, event, arg, data);
+ } catch (RemoteException e) {
+ cleanupAndRethrowIllegalState();
+ }
+ }
- if (mICasV11 == null) {
+ if (mICasHidl11 == null) {
Log.d(TAG, "Send Session Event isn't supported by cas@1.0 interface");
throw new UnsupportedCasException("Send Session Event is not supported");
}
try {
MediaCasException.throwExceptionIfNeeded(
- mICasV11.sendSessionEvent(mSessionId, event, arg, toByteArray(data)));
+ mICasHidl11.sendSessionEvent(
+ toByteArray(mSessionId), event, arg, toByteArray(data)));
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -600,7 +701,7 @@
@NonNull
public byte[] getSessionId() {
validateSessionInternalStates();
- return toBytes(mSessionId);
+ return mSessionId;
}
/**
@@ -613,8 +714,12 @@
public void close() {
validateSessionInternalStates();
try {
- MediaCasStateException.throwExceptionIfNeeded(
- mICas.closeSession(mSessionId));
+ if (mICas != null) {
+ mICas.closeSession(mSessionId);
+ } else {
+ MediaCasStateException.throwExceptionIfNeeded(
+ mICasHidl.closeSession(toByteArray(mSessionId)));
+ }
mIsClosed = true;
removeSessionFromResourceMap(this);
} catch (RemoteException e) {
@@ -623,8 +728,8 @@
}
}
- Session createFromSessionId(@NonNull ArrayList<Byte> sessionId) {
- if (sessionId == null || sessionId.size() == 0) {
+ Session createFromSessionId(byte[] sessionId) {
+ if (sessionId == null || sessionId.length == 0) {
return null;
}
return new Session(sessionId);
@@ -638,12 +743,20 @@
* @return Whether the specified CA system is supported on this device.
*/
public static boolean isSystemIdSupported(int CA_system_id) {
- IMediaCasService service = getService();
-
+ IMediaCasService service = sService.get();
if (service != null) {
try {
return service.isSystemIdSupported(CA_system_id);
} catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ android.hardware.cas.V1_0.IMediaCasService serviceHidl = sServiceHidl.get();
+ if (serviceHidl != null) {
+ try {
+ return serviceHidl.isSystemIdSupported(CA_system_id);
+ } catch (RemoteException e) {
}
}
return false;
@@ -655,12 +768,26 @@
* @return an array of descriptors for the available CA plugins.
*/
public static PluginDescriptor[] enumeratePlugins() {
- IMediaCasService service = getService();
-
+ IMediaCasService service = sService.get();
if (service != null) {
try {
- ArrayList<HidlCasPluginDescriptor> descriptors =
- service.enumeratePlugins();
+ AidlCasPluginDescriptor[] descriptors = service.enumeratePlugins();
+ if (descriptors.length == 0) {
+ return null;
+ }
+ PluginDescriptor[] results = new PluginDescriptor[descriptors.length];
+ for (int i = 0; i < results.length; i++) {
+ results[i] = new PluginDescriptor(descriptors[i]);
+ }
+ return results;
+ } catch (RemoteException e) {
+ }
+ }
+
+ android.hardware.cas.V1_0.IMediaCasService serviceHidl = sServiceHidl.get();
+ if (serviceHidl != null) {
+ try {
+ ArrayList<HidlCasPluginDescriptor> descriptors = serviceHidl.enumeratePlugins();
if (descriptors.size() == 0) {
return null;
}
@@ -680,29 +807,40 @@
mCasSystemId = casSystemId;
mUserId = Process.myUid();
IMediaCasService service = getService();
- android.hardware.cas.V1_2.IMediaCasService serviceV12 =
- android.hardware.cas.V1_2.IMediaCasService.castFrom(service);
- if (serviceV12 == null) {
- android.hardware.cas.V1_1.IMediaCasService serviceV11 =
- android.hardware.cas.V1_1.IMediaCasService.castFrom(service);
- if (serviceV11 == null) {
- Log.d(TAG, "Used cas@1_0 interface to create plugin");
- mICas = service.createPlugin(casSystemId, mBinder);
- } else {
- Log.d(TAG, "Used cas@1.1 interface to create plugin");
- mICas = mICasV11 = serviceV11.createPluginExt(casSystemId, mBinder);
- }
+ if (service != null) {
+ Log.d(TAG, "Use CAS AIDL interface to create plugin");
+ mICas = service.createPlugin(casSystemId, mBinder);
} else {
- Log.d(TAG, "Used cas@1.2 interface to create plugin");
- mICas = mICasV11 = mICasV12 =
- android.hardware.cas.V1_2.ICas
- .castFrom(serviceV12.createPluginExt(casSystemId, mBinder));
+ android.hardware.cas.V1_0.IMediaCasService serviceV10 = getServiceHidl();
+ android.hardware.cas.V1_2.IMediaCasService serviceV12 =
+ android.hardware.cas.V1_2.IMediaCasService.castFrom(serviceV10);
+ if (serviceV12 == null) {
+ android.hardware.cas.V1_1.IMediaCasService serviceV11 =
+ android.hardware.cas.V1_1.IMediaCasService.castFrom(serviceV10);
+ if (serviceV11 == null) {
+ Log.d(TAG, "Used cas@1_0 interface to create plugin");
+ mICasHidl = serviceV10.createPlugin(casSystemId, mBinderHidl);
+ } else {
+ Log.d(TAG, "Used cas@1.1 interface to create plugin");
+ mICasHidl =
+ mICasHidl11 = serviceV11.createPluginExt(casSystemId, mBinderHidl);
+ }
+ } else {
+ Log.d(TAG, "Used cas@1.2 interface to create plugin");
+ mICasHidl =
+ mICasHidl11 =
+ mICasHidl12 =
+ android.hardware.cas.V1_2.ICas.castFrom(
+ serviceV12.createPluginExt(
+ casSystemId, mBinderHidl));
+ }
}
} catch(Exception e) {
Log.e(TAG, "Failed to create plugin: " + e);
mICas = null;
+ mICasHidl = null;
} finally {
- if (mICas == null) {
+ if (mICas == null && mICasHidl == null) {
throw new UnsupportedCasException(
"Unsupported casSystemId " + casSystemId);
}
@@ -783,9 +921,22 @@
}
IHwBinder getBinder() {
+ if (mICas != null) {
+ return null; // Return IHwBinder only for HIDL
+ }
+
validateInternalStates();
- return mICas.asBinder();
+ return mICasHidl.asBinder();
+ }
+
+ /**
+ * Check if the HAL is an AIDL implementation
+ *
+ * @hide
+ */
+ public boolean isAidlHal() {
+ return mICas != null;
}
/**
@@ -886,8 +1037,12 @@
validateInternalStates();
try {
- MediaCasException.throwExceptionIfNeeded(
- mICas.setPrivateData(toByteArray(data, 0, data.length)));
+ if (mICas != null) {
+ mICas.setPrivateData(data);
+ } else {
+ MediaCasException.throwExceptionIfNeeded(
+ mICasHidl.setPrivateData(toByteArray(data, 0, data.length)));
+ }
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -899,7 +1054,7 @@
@Override
public void onValues(int status, ArrayList<Byte> sessionId) {
mStatus = status;
- mSession = createFromSessionId(sessionId);
+ mSession = createFromSessionId(toBytes(sessionId));
}
}
@@ -912,7 +1067,7 @@
@Override
public void onValues(int status, ArrayList<Byte> sessionId) {
mStatus = status;
- mSession = createFromSessionId(sessionId);
+ mSession = createFromSessionId(toBytes(sessionId));
}
}
@@ -971,15 +1126,19 @@
int sessionResourceHandle = getSessionResourceHandle();
try {
- OpenSessionCallback cb = new OpenSessionCallback();
- mICas.openSession(cb);
- MediaCasException.throwExceptionIfNeeded(cb.mStatus);
- addSessionToResourceMap(cb.mSession, sessionResourceHandle);
- Log.d(TAG, "Write Stats Log for succeed to Open Session.");
- FrameworkStatsLog
- .write(FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS, mUserId, mCasSystemId,
+ if (mICasHidl != null) {
+ OpenSessionCallback cb = new OpenSessionCallback();
+ mICasHidl.openSession(cb);
+ MediaCasException.throwExceptionIfNeeded(cb.mStatus);
+ addSessionToResourceMap(cb.mSession, sessionResourceHandle);
+ Log.d(TAG, "Write Stats Log for succeed to Open Session.");
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS,
+ mUserId,
+ mCasSystemId,
FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS__STATE__SUCCEEDED);
- return cb.mSession;
+ return cb.mSession;
+ }
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -1012,14 +1171,30 @@
throws MediaCasException {
int sessionResourceHandle = getSessionResourceHandle();
- if (mICasV12 == null) {
+ if (mICas != null) {
+ try {
+ byte[] sessionId = mICas.openSession(sessionUsage, scramblingMode);
+ Session session = createFromSessionId(sessionId);
+ addSessionToResourceMap(session, sessionResourceHandle);
+ Log.d(TAG, "Write Stats Log for succeed to Open Session.");
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS,
+ mUserId,
+ mCasSystemId,
+ FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS__STATE__SUCCEEDED);
+ return session;
+ } catch (RemoteException e) {
+ cleanupAndRethrowIllegalState();
+ }
+ }
+ if (mICasHidl12 == null) {
Log.d(TAG, "Open Session with scrambling mode is only supported by cas@1.2+ interface");
throw new UnsupportedCasException("Open Session with scrambling mode is not supported");
}
try {
OpenSession_1_2_Callback cb = new OpenSession_1_2_Callback();
- mICasV12.openSession_1_2(sessionUsage, scramblingMode, cb);
+ mICasHidl12.openSession_1_2(sessionUsage, scramblingMode, cb);
MediaCasException.throwExceptionIfNeeded(cb.mStatus);
addSessionToResourceMap(cb.mSession, sessionResourceHandle);
Log.d(TAG, "Write Stats Log for succeed to Open Session.");
@@ -1053,8 +1228,12 @@
validateInternalStates();
try {
- MediaCasException.throwExceptionIfNeeded(
- mICas.processEmm(toByteArray(data, offset, length)));
+ if (mICas != null) {
+ mICas.processEmm(Arrays.copyOfRange(data, offset, length));
+ } else {
+ MediaCasException.throwExceptionIfNeeded(
+ mICasHidl.processEmm(toByteArray(data, offset, length)));
+ }
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -1092,8 +1271,12 @@
validateInternalStates();
try {
- MediaCasException.throwExceptionIfNeeded(
- mICas.sendEvent(event, arg, toByteArray(data)));
+ if (mICas != null) {
+ mICas.sendEvent(event, arg, data);
+ } else {
+ MediaCasException.throwExceptionIfNeeded(
+ mICasHidl.sendEvent(event, arg, toByteArray(data)));
+ }
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -1114,8 +1297,11 @@
validateInternalStates();
try {
- MediaCasException.throwExceptionIfNeeded(
- mICas.provision(provisionString));
+ if (mICas != null) {
+ mICas.provision(provisionString);
+ } else {
+ MediaCasException.throwExceptionIfNeeded(mICasHidl.provision(provisionString));
+ }
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -1136,8 +1322,12 @@
validateInternalStates();
try {
- MediaCasException.throwExceptionIfNeeded(
- mICas.refreshEntitlements(refreshType, toByteArray(refreshData)));
+ if (mICas != null) {
+ mICas.refreshEntitlements(refreshType, refreshData);
+ } else {
+ MediaCasException.throwExceptionIfNeeded(
+ mICasHidl.refreshEntitlements(refreshType, toByteArray(refreshData)));
+ }
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -1163,6 +1353,13 @@
} finally {
mICas = null;
}
+ } else if (mICasHidl != null) {
+ try {
+ mICasHidl.release();
+ } catch (RemoteException e) {
+ } finally {
+ mICasHidl = mICasHidl11 = mICasHidl12 = null;
+ }
}
if (mTunerResourceManager != null) {
diff --git a/media/java/android/media/MediaDescrambler.java b/media/java/android/media/MediaDescrambler.java
index 99bd254..b4bdf93d 100644
--- a/media/java/android/media/MediaDescrambler.java
+++ b/media/java/android/media/MediaDescrambler.java
@@ -17,14 +17,26 @@
package android.media;
import android.annotation.NonNull;
-import android.hardware.cas.V1_0.*;
+import android.hardware.cas.DestinationBuffer;
+import android.hardware.cas.IDescrambler;
+import android.hardware.cas.ScramblingControl;
+import android.hardware.cas.SharedBuffer;
+import android.hardware.cas.SubSample;
+import android.hardware.cas.V1_0.IDescramblerBase;
+import android.hardware.common.Ashmem;
+import android.hardware.common.NativeHandle;
import android.media.MediaCasException.UnsupportedCasException;
import android.os.IHwBinder;
+import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
+import android.os.SharedMemory;
+import android.system.ErrnoException;
import android.util.Log;
+import java.io.IOException;
import java.nio.ByteBuffer;
+import java.util.ArrayList;
/**
* MediaDescrambler class can be used in conjunction with {@link android.media.MediaCodec}
@@ -39,7 +51,198 @@
*/
public final class MediaDescrambler implements AutoCloseable {
private static final String TAG = "MediaDescrambler";
- private IDescramblerBase mIDescrambler;
+ private DescramblerWrapper mIDescrambler;
+
+ private interface DescramblerWrapper {
+
+ IHwBinder asBinder();
+
+ int descramble(
+ @NonNull ByteBuffer srcBuf,
+ @NonNull ByteBuffer dstBuf,
+ @NonNull MediaCodec.CryptoInfo cryptoInfo)
+ throws RemoteException;
+
+ boolean requiresSecureDecoderComponent(@NonNull String mime) throws RemoteException;
+
+ void setMediaCasSession(byte[] sessionId) throws RemoteException;
+
+ void release() throws RemoteException;
+ }
+ ;
+
+ private long getSubsampleInfo(
+ int numSubSamples,
+ int[] numBytesOfClearData,
+ int[] numBytesOfEncryptedData,
+ SubSample[] subSamples) {
+ long totalSize = 0;
+
+ for (int i = 0; i < numSubSamples; i++) {
+ totalSize += numBytesOfClearData[i];
+ subSamples[i].numBytesOfClearData = numBytesOfClearData[i];
+ totalSize += numBytesOfEncryptedData[i];
+ subSamples[i].numBytesOfEncryptedData = numBytesOfEncryptedData[i];
+ }
+ return totalSize;
+ }
+
+ private ParcelFileDescriptor createSharedMemory(ByteBuffer buffer, String name)
+ throws RemoteException {
+ byte[] source = buffer.array();
+ if (source.length == 0) {
+ return null;
+ }
+ ParcelFileDescriptor fd = null;
+ try {
+ SharedMemory ashmem = SharedMemory.create(name == null ? "" : name, source.length);
+ ByteBuffer ptr = ashmem.mapReadWrite();
+ ptr.put(buffer);
+ ashmem.unmap(ptr);
+ fd = ashmem.getFdDup();
+ return fd;
+ } catch (ErrnoException | IOException e) {
+ throw new RemoteException(e);
+ }
+ }
+
+ private class AidlDescrambler implements DescramblerWrapper {
+
+ IDescrambler mAidlDescrambler;
+
+ AidlDescrambler(IDescrambler aidlDescrambler) {
+ mAidlDescrambler = aidlDescrambler;
+ }
+
+ @Override
+ public IHwBinder asBinder() {
+ return null;
+ }
+
+ @Override
+ public int descramble(
+ @NonNull ByteBuffer src,
+ @NonNull ByteBuffer dst,
+ @NonNull MediaCodec.CryptoInfo cryptoInfo)
+ throws RemoteException {
+ SubSample[] subSamples = new SubSample[cryptoInfo.numSubSamples];
+ long totalLength =
+ getSubsampleInfo(
+ cryptoInfo.numSubSamples,
+ cryptoInfo.numBytesOfClearData,
+ cryptoInfo.numBytesOfEncryptedData,
+ subSamples);
+ SharedBuffer srcBuffer = new SharedBuffer();
+ DestinationBuffer dstBuffer;
+ srcBuffer.heapBase = new Ashmem();
+ srcBuffer.heapBase.fd = createSharedMemory(src, "Descrambler Source Buffer");
+ srcBuffer.heapBase.size = src.array().length;
+ if (dst == null) {
+ dstBuffer = DestinationBuffer.nonsecureMemory(srcBuffer);
+ } else {
+ ParcelFileDescriptor pfd =
+ createSharedMemory(dst, "Descrambler Destination Buffer");
+ NativeHandle nh = new NativeHandle();
+ nh.fds = new ParcelFileDescriptor[] {pfd};
+ nh.ints = new int[] {1}; // Mark 1 since source buffer also uses it?
+ dstBuffer = DestinationBuffer.secureMemory(nh);
+ }
+ @ScramblingControl int control = cryptoInfo.key[0];
+
+ return mAidlDescrambler.descramble(
+ (byte) control,
+ subSamples,
+ srcBuffer,
+ src.position(),
+ dstBuffer,
+ dst.position());
+ }
+
+ @Override
+ public boolean requiresSecureDecoderComponent(@NonNull String mime) throws RemoteException {
+ return mAidlDescrambler.requiresSecureDecoderComponent(mime);
+ }
+
+ @Override
+ public void setMediaCasSession(byte[] sessionId) throws RemoteException {
+ mAidlDescrambler.setMediaCasSession(sessionId);
+ }
+
+ @Override
+ public void release() throws RemoteException {
+ mAidlDescrambler.release();
+ }
+ }
+
+ private class HidlDescrambler implements DescramblerWrapper {
+
+ IDescramblerBase mHidlDescrambler;
+
+ HidlDescrambler(IDescramblerBase hidlDescrambler) {
+ mHidlDescrambler = hidlDescrambler;
+ native_setup(hidlDescrambler.asBinder());
+ }
+
+ @Override
+ public IHwBinder asBinder() {
+ return mHidlDescrambler.asBinder();
+ }
+
+ @Override
+ public int descramble(
+ @NonNull ByteBuffer srcBuf,
+ @NonNull ByteBuffer dstBuf,
+ @NonNull MediaCodec.CryptoInfo cryptoInfo)
+ throws RemoteException {
+
+ try {
+ return native_descramble(
+ cryptoInfo.key[0],
+ cryptoInfo.key[1],
+ cryptoInfo.numSubSamples,
+ cryptoInfo.numBytesOfClearData,
+ cryptoInfo.numBytesOfEncryptedData,
+ srcBuf,
+ srcBuf.position(),
+ srcBuf.limit(),
+ dstBuf,
+ dstBuf.position(),
+ dstBuf.limit());
+ } catch (ServiceSpecificException e) {
+ MediaCasStateException.throwExceptionIfNeeded(e.errorCode, e.getMessage());
+ } catch (RemoteException e) {
+ cleanupAndRethrowIllegalState();
+ }
+ return -1;
+ }
+
+ @Override
+ public boolean requiresSecureDecoderComponent(@NonNull String mime) throws RemoteException {
+ return mHidlDescrambler.requiresSecureDecoderComponent(mime);
+ }
+
+ @Override
+ public void setMediaCasSession(byte[] sessionId) throws RemoteException {
+ ArrayList<Byte> byteArray = new ArrayList<>();
+
+ if (sessionId != null) {
+ int length = sessionId.length;
+ byteArray = new ArrayList<Byte>(length);
+ for (int i = 0; i < length; i++) {
+ byteArray.add(Byte.valueOf(sessionId[i]));
+ }
+ }
+
+ MediaCasStateException.throwExceptionIfNeeded(
+ mHidlDescrambler.setMediaCasSession(byteArray));
+ }
+
+ @Override
+ public void release() throws RemoteException {
+ mHidlDescrambler.release();
+ native_release();
+ }
+ }
private final void validateInternalStates() {
if (mIDescrambler == null) {
@@ -61,7 +264,14 @@
*/
public MediaDescrambler(int CA_system_id) throws UnsupportedCasException {
try {
- mIDescrambler = MediaCas.getService().createDescrambler(CA_system_id);
+ if (MediaCas.getService() != null) {
+ mIDescrambler =
+ new AidlDescrambler(MediaCas.getService().createDescrambler(CA_system_id));
+ } else if (MediaCas.getServiceHidl() != null) {
+ mIDescrambler =
+ new HidlDescrambler(
+ MediaCas.getServiceHidl().createDescrambler(CA_system_id));
+ }
} catch(Exception e) {
Log.e(TAG, "Failed to create descrambler: " + e);
mIDescrambler = null;
@@ -70,7 +280,6 @@
throw new UnsupportedCasException("Unsupported CA_system_id " + CA_system_id);
}
}
- native_setup(mIDescrambler.asBinder());
}
IHwBinder getBinder() {
@@ -117,8 +326,7 @@
validateInternalStates();
try {
- MediaCasStateException.throwExceptionIfNeeded(
- mIDescrambler.setMediaCasSession(session.mSessionId));
+ mIDescrambler.setMediaCasSession(session.mSessionId);
} catch (RemoteException e) {
cleanupAndRethrowIllegalState();
}
@@ -126,27 +334,31 @@
/**
* Scramble control value indicating that the samples are not scrambled.
+ *
* @see #descramble(ByteBuffer, ByteBuffer, android.media.MediaCodec.CryptoInfo)
*/
- public static final byte SCRAMBLE_CONTROL_UNSCRAMBLED = 0;
+ public static final byte SCRAMBLE_CONTROL_UNSCRAMBLED = (byte) ScramblingControl.UNSCRAMBLED;
/**
* Scramble control value reserved and shouldn't be used currently.
+ *
* @see #descramble(ByteBuffer, ByteBuffer, android.media.MediaCodec.CryptoInfo)
*/
- public static final byte SCRAMBLE_CONTROL_RESERVED = 1;
+ public static final byte SCRAMBLE_CONTROL_RESERVED = (byte) ScramblingControl.RESERVED;
/**
* Scramble control value indicating that the even key is used.
+ *
* @see #descramble(ByteBuffer, ByteBuffer, android.media.MediaCodec.CryptoInfo)
*/
- public static final byte SCRAMBLE_CONTROL_EVEN_KEY = 2;
+ public static final byte SCRAMBLE_CONTROL_EVEN_KEY = (byte) ScramblingControl.EVENKEY;
/**
* Scramble control value indicating that the odd key is used.
+ *
* @see #descramble(ByteBuffer, ByteBuffer, android.media.MediaCodec.CryptoInfo)
*/
- public static final byte SCRAMBLE_CONTROL_ODD_KEY = 3;
+ public static final byte SCRAMBLE_CONTROL_ODD_KEY = (byte) ScramblingControl.ODDKEY;
/**
* Scramble flag for a hint indicating that the descrambling request is for
@@ -207,14 +419,7 @@
}
try {
- return native_descramble(
- cryptoInfo.key[0],
- cryptoInfo.key[1],
- cryptoInfo.numSubSamples,
- cryptoInfo.numBytesOfClearData,
- cryptoInfo.numBytesOfEncryptedData,
- srcBuf, srcBuf.position(), srcBuf.limit(),
- dstBuf, dstBuf.position(), dstBuf.limit());
+ return mIDescrambler.descramble(srcBuf, dstBuf, cryptoInfo);
} catch (ServiceSpecificException e) {
MediaCasStateException.throwExceptionIfNeeded(e.errorCode, e.getMessage());
} catch (RemoteException e) {
@@ -233,7 +438,6 @@
mIDescrambler = null;
}
}
- native_release();
}
@Override
@@ -256,4 +460,4 @@
}
private long mNativeContext;
-}
\ No newline at end of file
+}
diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java
index dab188e..b11a810 100644
--- a/media/java/android/media/MediaExtractor.java
+++ b/media/java/android/media/MediaExtractor.java
@@ -36,7 +36,6 @@
import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -325,14 +324,6 @@
}
}
- private ArrayList<Byte> toByteArray(@NonNull byte[] data) {
- ArrayList<Byte> byteArray = new ArrayList<Byte>(data.length);
- for (int i = 0; i < data.length; i++) {
- byteArray.add(i, Byte.valueOf(data[i]));
- }
- return byteArray;
- }
-
/**
* Retrieves the information about the conditional access system used to scramble
* a track.
@@ -357,7 +348,7 @@
buf.rewind();
final byte[] sessionId = new byte[buf.remaining()];
buf.get(sessionId);
- session = mMediaCas.createFromSessionId(toByteArray(sessionId));
+ session = mMediaCas.createFromSessionId(sessionId);
}
return new CasInfo(systemId, session, privateData);
}
diff --git a/media/tests/AudioPolicyTest/res/values/strings.xml b/media/tests/AudioPolicyTest/res/values/strings.xml
index 0365927..128c3c5 100644
--- a/media/tests/AudioPolicyTest/res/values/strings.xml
+++ b/media/tests/AudioPolicyTest/res/values/strings.xml
@@ -2,4 +2,7 @@
<resources>
<!-- name of the app [CHAR LIMIT=25]-->
<string name="app_name">Audio Policy APIs Tests</string>
+ <string name="capture_duration_key">captureDurationMs</string>
+ <string name="callback_key">callback</string>
+ <string name="status_key">result</string>
</resources>
diff --git a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyDeathTest.java b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyDeathTest.java
index 841804b..48c51af 100644
--- a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyDeathTest.java
+++ b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyDeathTest.java
@@ -20,6 +20,8 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -30,6 +32,8 @@
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
+import android.os.Bundle;
+import android.os.RemoteCallback;
import android.platform.test.annotations.Presubmit;
import android.util.Log;
@@ -39,33 +43,62 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
@Presubmit
@RunWith(AndroidJUnit4.class)
public class AudioPolicyDeathTest {
private static final String TAG = "AudioPolicyDeathTest";
private static final int SAMPLE_RATE = 48000;
- private static final int PLAYBACK_TIME_MS = 2000;
+ private static final int PLAYBACK_TIME_MS = 4000;
+ private static final int RECORD_TIME_MS = 1000;
+ private static final int ACTIVITY_TIMEOUT_SEC = 5;
+ private static final int BROADCAST_TIMEOUT_SEC = 10;
+ private static final int MAX_ATTEMPTS = 5;
+ private static final int DELAY_BETWEEN_ATTEMPTS_MS = 2000;
private static final IntentFilter AUDIO_NOISY_INTENT_FILTER =
new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
private class MyBroadcastReceiver extends BroadcastReceiver {
- private boolean mReceived = false;
+ private CountDownLatch mLatch = new CountDownLatch(1);
+
@Override
public void onReceive(Context context, Intent intent) {
if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
- synchronized (this) {
- mReceived = true;
- notify();
- }
+ mLatch.countDown();
}
}
- public synchronized boolean received() {
- return mReceived;
+ public void reset() {
+ mLatch = new CountDownLatch(1);
+ }
+
+ public boolean waitForBroadcast() {
+ boolean received = false;
+ long startTimeMs = System.currentTimeMillis();
+ long elapsedTimeMs = 0;
+
+ Log.i(TAG, "waiting for broadcast");
+
+ while (elapsedTimeMs < BROADCAST_TIMEOUT_SEC && !received) {
+ try {
+ received = mLatch.await(BROADCAST_TIMEOUT_SEC, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ Log.w(TAG, "wait interrupted");
+ }
+ elapsedTimeMs = System.currentTimeMillis() - startTimeMs;
+ }
+ Log.i(TAG, "broadcast " + (received ? "" : "NOT ") + "received");
+ return received;
}
}
+
private final MyBroadcastReceiver mReceiver = new MyBroadcastReceiver();
private Context mContext;
@@ -85,31 +118,55 @@
public void testPolicyClientDeathSendBecomingNoisyIntent() {
mContext.registerReceiver(mReceiver, AUDIO_NOISY_INTENT_FILTER);
- // Launch process registering a dynamic auido policy and dying after PLAYBACK_TIME_MS/2 ms
- Intent intent = new Intent(mContext, AudioPolicyDeathTestActivity.class);
- intent.putExtra("captureDurationMs", PLAYBACK_TIME_MS / 2);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- mContext.startActivity(intent);
+ boolean result = false;
+ for (int numAttempts = 1; numAttempts <= MAX_ATTEMPTS && !result; numAttempts++) {
+ mReceiver.reset();
- AudioTrack track = createAudioTrack();
- track.play();
- synchronized (mReceiver) {
- long startTimeMs = System.currentTimeMillis();
- long elapsedTimeMs = 0;
- while (elapsedTimeMs < PLAYBACK_TIME_MS && !mReceiver.received()) {
- try {
- mReceiver.wait(PLAYBACK_TIME_MS - elapsedTimeMs);
- } catch (InterruptedException e) {
- Log.w(TAG, "wait interrupted");
+ CompletableFuture<Integer> callbackReturn = new CompletableFuture<>();
+ RemoteCallback cb = new RemoteCallback((Bundle res) -> {
+ callbackReturn.complete(
+ res.getInt(mContext.getResources().getString(R.string.status_key)));
+ });
+
+ // Launch process registering a dynamic auido policy and dying after RECORD_TIME_MS ms
+ // RECORD_TIME_MS must be shorter than PLAYBACK_TIME_MS
+ Intent intent = new Intent(mContext, AudioPolicyDeathTestActivity.class);
+ intent.putExtra(mContext.getResources().getString(R.string.capture_duration_key),
+ RECORD_TIME_MS);
+ intent.putExtra(mContext.getResources().getString(R.string.callback_key), cb);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+
+ mContext.startActivity(intent);
+
+ Integer status = AudioManager.ERROR;
+ try {
+ status = callbackReturn.get(ACTIVITY_TIMEOUT_SEC, TimeUnit.SECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ assumeNoException(e);
+ }
+ assumeTrue(status != null && status == AudioManager.SUCCESS);
+
+ Log.i(TAG, "Activity started");
+ AudioTrack track = null;
+ try {
+ track = createAudioTrack();
+ track.play();
+ result = mReceiver.waitForBroadcast();
+ } finally {
+ if (track != null) {
+ track.stop();
+ track.release();
}
- elapsedTimeMs = System.currentTimeMillis() - startTimeMs;
+ }
+ if (!result) {
+ try {
+ Log.i(TAG, "Retrying after attempt: " + numAttempts);
+ Thread.sleep(DELAY_BETWEEN_ATTEMPTS_MS);
+ } catch (InterruptedException e) {
+ }
}
}
-
- track.stop();
- track.release();
-
- assertTrue(mReceiver.received());
+ assertTrue(result);
}
private AudioTrack createAudioTrack() {
diff --git a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyDeathTestActivity.java b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyDeathTestActivity.java
index 957e719..ce5f56c 100644
--- a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyDeathTestActivity.java
+++ b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyDeathTestActivity.java
@@ -26,6 +26,7 @@
import android.media.audiopolicy.AudioPolicy;
import android.os.Bundle;
import android.os.Looper;
+import android.os.RemoteCallback;
import android.util.Log;
// This activity will register a dynamic audio policy to intercept media playback and launch
@@ -71,19 +72,29 @@
mAudioPolicy = audioPolicyBuilder.build();
int result = mAudioManager.registerAudioPolicy(mAudioPolicy);
- if (result != AudioManager.SUCCESS) {
+ if (result == AudioManager.SUCCESS) {
+ AudioRecord audioRecord = mAudioPolicy.createAudioRecordSink(audioMix);
+ if (audioRecord != null && audioRecord.getState() != AudioRecord.STATE_UNINITIALIZED) {
+ int captureDurationMs = getIntent().getIntExtra(
+ getString(R.string.capture_duration_key), RECORD_TIME_MS);
+ AudioCapturingThread thread =
+ new AudioCapturingThread(audioRecord, captureDurationMs);
+ thread.start();
+ } else {
+ Log.w(TAG, "AudioRecord creation failed");
+ result = AudioManager.ERROR_NO_INIT;
+ }
+ } else {
Log.w(TAG, "registerAudioPolicy failed, status: " + result);
- return;
- }
- AudioRecord audioRecord = mAudioPolicy.createAudioRecordSink(audioMix);
- if (audioRecord == null) {
- Log.w(TAG, "AudioRecord creation failed");
- return;
}
- int captureDurationMs = getIntent().getIntExtra("captureDurationMs", RECORD_TIME_MS);
- AudioCapturingThread thread = new AudioCapturingThread(audioRecord, captureDurationMs);
- thread.start();
+ RemoteCallback cb =
+ (RemoteCallback) getIntent().getExtras().get(getString(R.string.callback_key));
+ Bundle res = new Bundle();
+ res.putInt(getString(R.string.status_key), result);
+ Log.i(TAG, "policy " + (result == AudioManager.SUCCESS ? "" : "un")
+ + "successfully registered");
+ cb.sendResult(res);
}
@Override
diff --git a/native/webview/TEST_MAPPING b/native/webview/TEST_MAPPING
index bd25200..c1bc6d7 100644
--- a/native/webview/TEST_MAPPING
+++ b/native/webview/TEST_MAPPING
@@ -9,6 +9,14 @@
]
},
{
+ "name": "CtsSdkSandboxWebkitTestCases",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ },
+ {
"name": "CtsHostsideWebViewTests",
"options": [
{
diff --git a/packages/CredentialManager/Android.bp b/packages/CredentialManager/Android.bp
index d8577c3..90bb2d1 100644
--- a/packages/CredentialManager/Android.bp
+++ b/packages/CredentialManager/Android.bp
@@ -14,6 +14,11 @@
srcs: ["src/**/*.kt"],
resource_dirs: ["res"],
+ dex_preopt: {
+ profile_guided: true,
+ profile: "profile.txt.prof",
+ },
+
static_libs: [
"androidx.activity_activity-compose",
"androidx.appcompat_appcompat",
diff --git a/packages/CredentialManager/profile.txt.prof b/packages/CredentialManager/profile.txt.prof
new file mode 100644
index 0000000..16f8798
--- /dev/null
+++ b/packages/CredentialManager/profile.txt.prof
@@ -0,0 +1,14627 @@
+HPLandroidx/compose/animation/core/FloatSpringSpec;->getValueFromNanos(JFFF)F
+HPLandroidx/compose/animation/core/FloatSpringSpec;->getVelocityFromNanos(JFFF)F
+HPLandroidx/compose/animation/core/SpringSimulation;->updateValues-IJZedt4$animation_core_release(FFJ)J
+HPLandroidx/compose/animation/core/VectorConvertersKt$FloatToVector$2;->invoke(Landroidx/compose/animation/core/AnimationVector1D;)Ljava/lang/Float;
+HPLandroidx/compose/animation/core/VectorizedSpringSpec;->getValueFromNanos(JLandroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;)Landroidx/compose/animation/core/AnimationVector;
+HPLandroidx/compose/animation/core/VectorizedSpringSpec;->getVelocityFromNanos(JLandroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;)Landroidx/compose/animation/core/AnimationVector;
+HPLandroidx/compose/foundation/ImageKt;->Image(Landroidx/compose/ui/graphics/painter/Painter;Ljava/lang/String;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/Alignment;Landroidx/compose/ui/layout/ContentScale;FLandroidx/compose/ui/graphics/ColorFilter;Landroidx/compose/runtime/Composer;II)V
+HPLandroidx/compose/foundation/gestures/TapGestureDetectorKt;->waitForUpOrCancellation(Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;Landroidx/compose/ui/input/pointer/PointerEventPass;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HPLandroidx/compose/foundation/lazy/LazyListKt$rememberLazyListMeasurePolicy$1$1$measuredItemProvider$1;->createItem-HK0c1C0(ILjava/lang/Object;Ljava/util/List;)Landroidx/compose/foundation/lazy/LazyMeasuredItem;
+HPLandroidx/compose/foundation/lazy/LazyListKt$rememberLazyListMeasurePolicy$1$1;->invoke-0kLqBqw(Landroidx/compose/foundation/lazy/layout/LazyLayoutMeasureScope;J)Landroidx/compose/foundation/lazy/LazyListMeasureResult;
+HPLandroidx/compose/foundation/lazy/LazyListMeasureKt;->measureLazyList-jIHJTys(ILandroidx/compose/foundation/lazy/LazyMeasuredItemProvider;IIIIIIFJZLjava/util/List;Landroidx/compose/foundation/layout/Arrangement$Vertical;Landroidx/compose/foundation/layout/Arrangement$Horizontal;ZLandroidx/compose/ui/unit/Density;Landroidx/compose/foundation/lazy/LazyListItemPlacementAnimator;Landroidx/compose/foundation/lazy/LazyListBeyondBoundsInfo;ILkotlin/jvm/functions/Function3;)Landroidx/compose/foundation/lazy/LazyListMeasureResult;
+HPLandroidx/compose/foundation/lazy/LazyListPositionedItem;->place(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+HPLandroidx/compose/foundation/lazy/LazyMeasuredItem;-><init>(ILjava/util/List;ZLandroidx/compose/ui/Alignment$Horizontal;Landroidx/compose/ui/Alignment$Vertical;Landroidx/compose/ui/unit/LayoutDirection;ZIILandroidx/compose/foundation/lazy/LazyListItemPlacementAnimator;IJLjava/lang/Object;)V
+HPLandroidx/compose/foundation/lazy/layout/DefaultLazyLayoutItemsProvider;->getKey(I)Ljava/lang/Object;
+HPLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory;->getContent(ILjava/lang/Object;)Lkotlin/jvm/functions/Function2;
+HPLandroidx/compose/foundation/lazy/layout/LazyLayoutMeasureScopeImpl;->measure-0kLqBqw(IJ)Ljava/util/List;
+HPLandroidx/compose/runtime/ComposerKt;->removeCurrentGroup(Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+HPLandroidx/compose/runtime/DerivedSnapshotState$ResultRecord;->isValid(Landroidx/compose/runtime/DerivedState;Landroidx/compose/runtime/snapshots/Snapshot;)Z
+HPLandroidx/compose/runtime/DerivedSnapshotState$ResultRecord;->readableHash(Landroidx/compose/runtime/DerivedState;Landroidx/compose/runtime/snapshots/Snapshot;)I
+HPLandroidx/compose/runtime/DerivedSnapshotState;->currentRecord(Landroidx/compose/runtime/DerivedSnapshotState$ResultRecord;Landroidx/compose/runtime/snapshots/Snapshot;ZLkotlin/jvm/functions/Function0;)Landroidx/compose/runtime/DerivedSnapshotState$ResultRecord;
+HPLandroidx/compose/runtime/DerivedSnapshotState;->getValue()Ljava/lang/Object;
+HPLandroidx/compose/runtime/SlotWriter$groupSlots$1;->hasNext()Z
+HPLandroidx/compose/runtime/SlotWriter$groupSlots$1;->next()Ljava/lang/Object;
+HPLandroidx/compose/runtime/SlotWriter;->access$dataIndexToDataAddress(Landroidx/compose/runtime/SlotWriter;I)I
+HPLandroidx/compose/runtime/SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1$unregisterApplyObserver$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HPLandroidx/compose/runtime/SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1$unregisterApplyObserver$1;->invoke(Ljava/util/Set;Landroidx/compose/runtime/snapshots/Snapshot;)V
+HPLandroidx/compose/runtime/SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HPLandroidx/compose/runtime/SnapshotStateKt__SnapshotFlowKt;->intersects$SnapshotStateKt__SnapshotFlowKt(Ljava/util/Set;Ljava/util/Set;)Z
+HPLandroidx/compose/runtime/snapshots/SnapshotKt;->current(Landroidx/compose/runtime/snapshots/StateRecord;Landroidx/compose/runtime/snapshots/Snapshot;)Landroidx/compose/runtime/snapshots/StateRecord;
+HPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap$derivedStateEnterObserver$1;->invoke(Landroidx/compose/runtime/State;)V
+HPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap$derivedStateExitObserver$1;->invoke(Landroidx/compose/runtime/State;)V
+HPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap$derivedStateExitObserver$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->access$getDeriveStateScopeCount$p(Landroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;)I
+HPLandroidx/compose/ui/Modifier$Node;->detach$ui_release()V
+HPLandroidx/compose/ui/geometry/OffsetKt;->isFinite-k-4lQ0M(J)Z
+HPLandroidx/compose/ui/graphics/Matrix;->map-MK-Hz9U([FJ)J
+HPLandroidx/compose/ui/input/pointer/InternalPointerEvent;->issuesEnterExitEvent-0FcD4WY(J)Z
+HPLandroidx/compose/ui/input/pointer/MotionEventAdapter;->convertToPointerInputEvent$ui_release(Landroid/view/MotionEvent;Landroidx/compose/ui/input/pointer/PositionCalculator;)Landroidx/compose/ui/input/pointer/PointerInputEvent;
+HPLandroidx/compose/ui/input/pointer/MotionEventAdapter;->createPointerInputEventData(Landroidx/compose/ui/input/pointer/PositionCalculator;Landroid/view/MotionEvent;IZ)Landroidx/compose/ui/input/pointer/PointerInputEventData;
+HPLandroidx/compose/ui/input/pointer/Node;->buildCache(Ljava/util/Map;Landroidx/compose/ui/layout/LayoutCoordinates;Landroidx/compose/ui/input/pointer/InternalPointerEvent;Z)Z
+HPLandroidx/compose/ui/input/pointer/Node;->cleanUpHits(Landroidx/compose/ui/input/pointer/InternalPointerEvent;)V
+HPLandroidx/compose/ui/input/pointer/Node;->dispatchFinalEventPass(Landroidx/compose/ui/input/pointer/InternalPointerEvent;)Z
+HPLandroidx/compose/ui/input/pointer/Node;->dispatchMainEventPass(Ljava/util/Map;Landroidx/compose/ui/layout/LayoutCoordinates;Landroidx/compose/ui/input/pointer/InternalPointerEvent;Z)Z
+HPLandroidx/compose/ui/input/pointer/PointerId;-><init>(J)V
+HPLandroidx/compose/ui/input/pointer/PointerId;->equals-impl(JLjava/lang/Object;)Z
+HPLandroidx/compose/ui/input/pointer/PointerInputChange;-><init>(JJJZJJZZIJ)V
+HPLandroidx/compose/ui/input/pointer/PointerInputChange;->copy-OHpmEuE$default(Landroidx/compose/ui/input/pointer/PointerInputChange;JJJZJJZILjava/util/List;JILjava/lang/Object;)Landroidx/compose/ui/input/pointer/PointerInputChange;
+HPLandroidx/compose/ui/input/pointer/PointerInputChange;->copy-OHpmEuE(JJJZJJZILjava/util/List;J)Landroidx/compose/ui/input/pointer/PointerInputChange;
+HPLandroidx/compose/ui/input/pointer/PointerInputChangeEventProducer;->produce(Landroidx/compose/ui/input/pointer/PointerInputEvent;Landroidx/compose/ui/input/pointer/PositionCalculator;)Landroidx/compose/ui/input/pointer/InternalPointerEvent;
+HPLandroidx/compose/ui/input/pointer/PointerInputEventProcessor;->process-BIzXfog(Landroidx/compose/ui/input/pointer/PointerInputEvent;Landroidx/compose/ui/input/pointer/PositionCalculator;Z)I
+HPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;->offerPointerEvent(Landroidx/compose/ui/input/pointer/PointerEvent;Landroidx/compose/ui/input/pointer/PointerEventPass;)V
+HPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;->dispatchPointerEvent(Landroidx/compose/ui/input/pointer/PointerEvent;Landroidx/compose/ui/input/pointer/PointerEventPass;)V
+HPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;->onPointerEvent-H0pRuoY(Landroidx/compose/ui/input/pointer/PointerEvent;Landroidx/compose/ui/input/pointer/PointerEventPass;J)V
+HPLandroidx/compose/ui/node/AlignmentLines;->reset$ui_release()V
+HPLandroidx/compose/ui/node/BackwardsCompatNode;->onPointerEvent-H0pRuoY(Landroidx/compose/ui/input/pointer/PointerEvent;Landroidx/compose/ui/input/pointer/PointerEventPass;J)V
+HPLandroidx/compose/ui/node/InnerNodeCoordinator;->hitTestChild-YqVAtuI(Landroidx/compose/ui/node/NodeCoordinator$HitTestSource;JLandroidx/compose/ui/node/HitTestResult;ZZ)V
+HPLandroidx/compose/ui/node/LayoutNode;->detach$ui_release()V
+HPLandroidx/compose/ui/node/NodeChain;->detach$ui_release()V
+HPLandroidx/compose/ui/node/NodeCoordinator;->ancestorToLocal-R5De75A(Landroidx/compose/ui/node/NodeCoordinator;J)J
+HPLandroidx/compose/ui/node/NodeCoordinator;->detach()V
+HPLandroidx/compose/ui/node/NodeCoordinator;->findCommonAncestor$ui_release(Landroidx/compose/ui/node/NodeCoordinator;)Landroidx/compose/ui/node/NodeCoordinator;
+HPLandroidx/compose/ui/node/NodeCoordinator;->fromParentPosition-MK-Hz9U(J)J
+HPLandroidx/compose/ui/node/NodeCoordinator;->hitTestChild-YqVAtuI(Landroidx/compose/ui/node/NodeCoordinator$HitTestSource;JLandroidx/compose/ui/node/HitTestResult;ZZ)V
+HPLandroidx/compose/ui/node/NodeCoordinator;->localPositionOf-R5De75A(Landroidx/compose/ui/layout/LayoutCoordinates;J)J
+HPLandroidx/compose/ui/node/PointerInputModifierNodeKt;->isAttached(Landroidx/compose/ui/node/PointerInputModifierNode;)Z
+HPLandroidx/compose/ui/platform/AndroidComposeView;->handleMotionEvent-8iAsVTc(Landroid/view/MotionEvent;)I
+HPLandroidx/compose/ui/platform/AndroidComposeView;->screenToLocal-MK-Hz9U(J)J
+HPLandroidx/compose/ui/platform/AndroidComposeView;->sendMotionEvent-8iAsVTc(Landroid/view/MotionEvent;)I
+HPLandroidx/compose/ui/platform/CalculateMatrixToWindowApi29;->calculateMatrixToWindow-EL8BTi8(Landroid/view/View;[F)V
+HPLandroidx/compose/ui/platform/LayerMatrixCache;->calculateInverseMatrix-bWbORWo(Ljava/lang/Object;)[F
+HPLandroidx/compose/ui/platform/LayerMatrixCache;->calculateMatrix-GrdbGEg(Ljava/lang/Object;)[F
+HPLandroidx/compose/ui/platform/RenderNodeLayer;->mapOffset-8S9VItk(JZ)J
+HPLandroidx/compose/ui/platform/ShapeContainingUtilKt;->cornersFit(Landroidx/compose/ui/geometry/RoundRect;)Z
+HPLandroidx/compose/ui/platform/ShapeContainingUtilKt;->isInRoundedRect(Landroidx/compose/ui/graphics/Outline$Rounded;FFLandroidx/compose/ui/graphics/Path;Landroidx/compose/ui/graphics/Path;)Z
+HPLandroidx/compose/ui/unit/IntOffsetKt;->minus-Nv-tHpc(JJ)J
+HPLcom/android/credentialmanager/common/material/SwipeableState$animateInternalToOffset$2$1;->invoke(Landroidx/compose/animation/core/Animatable;)V
+HPLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$CredentialEntryRow$2;->invoke(Landroidx/compose/runtime/Composer;I)V
+HPLkotlinx/coroutines/JobSupport;->cancelMakeCompleting(Ljava/lang/Object;)Ljava/lang/Object;
+HPLkotlinx/coroutines/channels/AbstractSendChannel;->offerInternal(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/activity/ComponentActivity$$ExternalSyntheticLambda0;-><init>(Landroidx/activity/ComponentActivity;)V
+HSPLandroidx/activity/ComponentActivity$$ExternalSyntheticLambda1;-><init>(Landroidx/activity/ComponentActivity;)V
+HSPLandroidx/activity/ComponentActivity$$ExternalSyntheticLambda2;-><init>(Landroidx/activity/ComponentActivity;)V
+HSPLandroidx/activity/ComponentActivity$$ExternalSyntheticLambda3;-><init>(Landroidx/activity/ComponentActivity;)V
+HSPLandroidx/activity/ComponentActivity$$ExternalSyntheticLambda3;->onContextAvailable(Landroid/content/Context;)V
+HSPLandroidx/activity/ComponentActivity$1;-><init>(Landroidx/activity/ComponentActivity;)V
+HSPLandroidx/activity/ComponentActivity$2;-><init>(Landroidx/activity/ComponentActivity;)V
+HSPLandroidx/activity/ComponentActivity$3;-><init>(Landroidx/activity/ComponentActivity;)V
+HSPLandroidx/activity/ComponentActivity$3;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
+HSPLandroidx/activity/ComponentActivity$4;-><init>(Landroidx/activity/ComponentActivity;)V
+HSPLandroidx/activity/ComponentActivity$4;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
+HSPLandroidx/activity/ComponentActivity$5;-><init>(Landroidx/activity/ComponentActivity;)V
+HSPLandroidx/activity/ComponentActivity$5;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
+HSPLandroidx/activity/ComponentActivity$Api33Impl;->getOnBackInvokedDispatcher(Landroid/app/Activity;)Landroid/window/OnBackInvokedDispatcher;
+HSPLandroidx/activity/ComponentActivity$ReportFullyDrawnExecutorApi16Impl;-><init>(Landroidx/activity/ComponentActivity;)V
+HSPLandroidx/activity/ComponentActivity$ReportFullyDrawnExecutorApi16Impl;->onDraw()V
+HSPLandroidx/activity/ComponentActivity$ReportFullyDrawnExecutorApi16Impl;->viewCreated(Landroid/view/View;)V
+HSPLandroidx/activity/ComponentActivity;->$r8$lambda$h2i_RK2mddCIbAsGubaI4eL8_cU(Landroidx/activity/ComponentActivity;Landroid/content/Context;)V
+HSPLandroidx/activity/ComponentActivity;-><init>()V
+HSPLandroidx/activity/ComponentActivity;->addOnContextAvailableListener(Landroidx/activity/contextaware/OnContextAvailableListener;)V
+HSPLandroidx/activity/ComponentActivity;->createFullyDrawnExecutor()Landroidx/activity/ComponentActivity$ReportFullyDrawnExecutor;
+HSPLandroidx/activity/ComponentActivity;->ensureViewModelStore()V
+HSPLandroidx/activity/ComponentActivity;->getActivityResultRegistry()Landroidx/activity/result/ActivityResultRegistry;
+HSPLandroidx/activity/ComponentActivity;->getDefaultViewModelCreationExtras()Landroidx/lifecycle/viewmodel/CreationExtras;
+HSPLandroidx/activity/ComponentActivity;->getDefaultViewModelProviderFactory()Landroidx/lifecycle/ViewModelProvider$Factory;
+HSPLandroidx/activity/ComponentActivity;->getLifecycle()Landroidx/lifecycle/Lifecycle;
+HSPLandroidx/activity/ComponentActivity;->getSavedStateRegistry()Landroidx/savedstate/SavedStateRegistry;
+HSPLandroidx/activity/ComponentActivity;->getViewModelStore()Landroidx/lifecycle/ViewModelStore;
+HSPLandroidx/activity/ComponentActivity;->initViewTreeOwners()V
+HSPLandroidx/activity/ComponentActivity;->lambda$new$2(Landroid/content/Context;)V
+HSPLandroidx/activity/ComponentActivity;->onCreate(Landroid/os/Bundle;)V
+HSPLandroidx/activity/ComponentActivity;->setContentView(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
+HSPLandroidx/activity/FullyDrawnReporter$$ExternalSyntheticLambda0;-><init>(Landroidx/activity/FullyDrawnReporter;)V
+HSPLandroidx/activity/FullyDrawnReporter;-><init>(Ljava/util/concurrent/Executor;Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/activity/OnBackPressedDispatcher$$ExternalSyntheticLambda1;-><init>(Landroidx/activity/OnBackPressedDispatcher;)V
+HSPLandroidx/activity/OnBackPressedDispatcher$$ExternalSyntheticLambda2;-><init>(Landroidx/activity/OnBackPressedDispatcher;)V
+HSPLandroidx/activity/OnBackPressedDispatcher$$ExternalSyntheticThrowCCEIfNotNull0;->m(Ljava/lang/Object;)V
+HSPLandroidx/activity/OnBackPressedDispatcher$Api33Impl$$ExternalSyntheticLambda0;-><init>(Ljava/lang/Runnable;)V
+HSPLandroidx/activity/OnBackPressedDispatcher$Api33Impl;->createOnBackInvokedCallback(Ljava/lang/Runnable;)Landroid/window/OnBackInvokedCallback;
+HSPLandroidx/activity/OnBackPressedDispatcher;-><init>(Ljava/lang/Runnable;)V
+HSPLandroidx/activity/OnBackPressedDispatcher;->hasEnabledCallbacks()Z
+HSPLandroidx/activity/OnBackPressedDispatcher;->setOnBackInvokedDispatcher(Landroid/window/OnBackInvokedDispatcher;)V
+HSPLandroidx/activity/OnBackPressedDispatcher;->updateBackInvokedCallbackState()V
+HSPLandroidx/activity/ViewTreeFullyDrawnReporterOwner;->set(Landroid/view/View;Landroidx/activity/FullyDrawnReporterOwner;)V
+HSPLandroidx/activity/ViewTreeOnBackPressedDispatcherOwner;->set(Landroid/view/View;Landroidx/activity/OnBackPressedDispatcherOwner;)V
+HSPLandroidx/activity/compose/ActivityResultLauncherHolder;-><init>()V
+HSPLandroidx/activity/compose/ActivityResultLauncherHolder;->setLauncher(Landroidx/activity/result/ActivityResultLauncher;)V
+HSPLandroidx/activity/compose/ActivityResultLauncherHolder;->unregister()V
+HSPLandroidx/activity/compose/ActivityResultRegistryKt$rememberLauncherForActivityResult$1$1;-><init>(Landroidx/compose/runtime/State;)V
+HSPLandroidx/activity/compose/ActivityResultRegistryKt$rememberLauncherForActivityResult$1$invoke$$inlined$onDispose$1;-><init>(Landroidx/activity/compose/ActivityResultLauncherHolder;)V
+HSPLandroidx/activity/compose/ActivityResultRegistryKt$rememberLauncherForActivityResult$1$invoke$$inlined$onDispose$1;->dispose()V
+HSPLandroidx/activity/compose/ActivityResultRegistryKt$rememberLauncherForActivityResult$1;-><init>(Landroidx/activity/compose/ActivityResultLauncherHolder;Landroidx/activity/result/ActivityResultRegistry;Ljava/lang/String;Landroidx/activity/result/contract/ActivityResultContract;Landroidx/compose/runtime/State;)V
+HSPLandroidx/activity/compose/ActivityResultRegistryKt$rememberLauncherForActivityResult$1;->invoke(Landroidx/compose/runtime/DisposableEffectScope;)Landroidx/compose/runtime/DisposableEffectResult;
+HSPLandroidx/activity/compose/ActivityResultRegistryKt$rememberLauncherForActivityResult$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/activity/compose/ActivityResultRegistryKt$rememberLauncherForActivityResult$key$1;-><clinit>()V
+HSPLandroidx/activity/compose/ActivityResultRegistryKt$rememberLauncherForActivityResult$key$1;-><init>()V
+HSPLandroidx/activity/compose/ActivityResultRegistryKt$rememberLauncherForActivityResult$key$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/activity/compose/ActivityResultRegistryKt$rememberLauncherForActivityResult$key$1;->invoke()Ljava/lang/String;
+HSPLandroidx/activity/compose/ActivityResultRegistryKt;->rememberLauncherForActivityResult(Landroidx/activity/result/contract/ActivityResultContract;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)Landroidx/activity/compose/ManagedActivityResultLauncher;
+HSPLandroidx/activity/compose/ComponentActivityKt;-><clinit>()V
+HSPLandroidx/activity/compose/ComponentActivityKt;->setContent$default(Landroidx/activity/ComponentActivity;Landroidx/compose/runtime/CompositionContext;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V
+HSPLandroidx/activity/compose/ComponentActivityKt;->setContent(Landroidx/activity/ComponentActivity;Landroidx/compose/runtime/CompositionContext;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/activity/compose/ComponentActivityKt;->setOwners(Landroidx/activity/ComponentActivity;)V
+HSPLandroidx/activity/compose/LocalActivityResultRegistryOwner$LocalComposition$1;-><clinit>()V
+HSPLandroidx/activity/compose/LocalActivityResultRegistryOwner$LocalComposition$1;-><init>()V
+HSPLandroidx/activity/compose/LocalActivityResultRegistryOwner$LocalComposition$1;->invoke()Landroidx/activity/result/ActivityResultRegistryOwner;
+HSPLandroidx/activity/compose/LocalActivityResultRegistryOwner$LocalComposition$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/activity/compose/LocalActivityResultRegistryOwner;-><clinit>()V
+HSPLandroidx/activity/compose/LocalActivityResultRegistryOwner;-><init>()V
+HSPLandroidx/activity/compose/LocalActivityResultRegistryOwner;->getCurrent(Landroidx/compose/runtime/Composer;I)Landroidx/activity/result/ActivityResultRegistryOwner;
+HSPLandroidx/activity/compose/ManagedActivityResultLauncher;-><clinit>()V
+HSPLandroidx/activity/compose/ManagedActivityResultLauncher;-><init>(Landroidx/activity/compose/ActivityResultLauncherHolder;Landroidx/compose/runtime/State;)V
+HSPLandroidx/activity/contextaware/ContextAwareHelper;-><init>()V
+HSPLandroidx/activity/contextaware/ContextAwareHelper;->addOnContextAvailableListener(Landroidx/activity/contextaware/OnContextAvailableListener;)V
+HSPLandroidx/activity/contextaware/ContextAwareHelper;->dispatchOnContextAvailable(Landroid/content/Context;)V
+HSPLandroidx/activity/result/ActivityResultLauncher;-><init>()V
+HSPLandroidx/activity/result/ActivityResultRegistry$3;-><init>(Landroidx/activity/result/ActivityResultRegistry;Ljava/lang/String;Landroidx/activity/result/contract/ActivityResultContract;)V
+HSPLandroidx/activity/result/ActivityResultRegistry$3;->unregister()V
+HSPLandroidx/activity/result/ActivityResultRegistry$CallbackAndContract;-><init>(Landroidx/activity/result/ActivityResultCallback;Landroidx/activity/result/contract/ActivityResultContract;)V
+HSPLandroidx/activity/result/ActivityResultRegistry;-><init>()V
+HSPLandroidx/activity/result/ActivityResultRegistry;->bindRcKey(ILjava/lang/String;)V
+HSPLandroidx/activity/result/ActivityResultRegistry;->generateRandomNumber()I
+HSPLandroidx/activity/result/ActivityResultRegistry;->register(Ljava/lang/String;Landroidx/activity/result/contract/ActivityResultContract;Landroidx/activity/result/ActivityResultCallback;)Landroidx/activity/result/ActivityResultLauncher;
+HSPLandroidx/activity/result/ActivityResultRegistry;->registerKey(Ljava/lang/String;)V
+HSPLandroidx/activity/result/ActivityResultRegistry;->unregister(Ljava/lang/String;)V
+HSPLandroidx/activity/result/contract/ActivityResultContract;-><init>()V
+HSPLandroidx/activity/result/contract/ActivityResultContracts$StartIntentSenderForResult$Companion;-><init>()V
+HSPLandroidx/activity/result/contract/ActivityResultContracts$StartIntentSenderForResult$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/activity/result/contract/ActivityResultContracts$StartIntentSenderForResult;-><clinit>()V
+HSPLandroidx/activity/result/contract/ActivityResultContracts$StartIntentSenderForResult;-><init>()V
+HSPLandroidx/arch/core/executor/ArchTaskExecutor$$ExternalSyntheticLambda0;-><init>()V
+HSPLandroidx/arch/core/executor/ArchTaskExecutor$$ExternalSyntheticLambda1;-><init>()V
+HSPLandroidx/arch/core/executor/ArchTaskExecutor;-><clinit>()V
+HSPLandroidx/arch/core/executor/ArchTaskExecutor;-><init>()V
+HSPLandroidx/arch/core/executor/ArchTaskExecutor;->getInstance()Landroidx/arch/core/executor/ArchTaskExecutor;
+HSPLandroidx/arch/core/executor/ArchTaskExecutor;->isMainThread()Z
+HSPLandroidx/arch/core/executor/DefaultTaskExecutor$1;-><init>(Landroidx/arch/core/executor/DefaultTaskExecutor;)V
+HSPLandroidx/arch/core/executor/DefaultTaskExecutor;-><init>()V
+HSPLandroidx/arch/core/executor/DefaultTaskExecutor;->isMainThread()Z
+HSPLandroidx/arch/core/executor/TaskExecutor;-><init>()V
+HSPLandroidx/arch/core/internal/FastSafeIterableMap;-><init>()V
+HSPLandroidx/arch/core/internal/FastSafeIterableMap;->ceil(Ljava/lang/Object;)Ljava/util/Map$Entry;
+HSPLandroidx/arch/core/internal/FastSafeIterableMap;->contains(Ljava/lang/Object;)Z
+HSPLandroidx/arch/core/internal/FastSafeIterableMap;->get(Ljava/lang/Object;)Landroidx/arch/core/internal/SafeIterableMap$Entry;
+HSPLandroidx/arch/core/internal/FastSafeIterableMap;->putIfAbsent(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/arch/core/internal/FastSafeIterableMap;->remove(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/arch/core/internal/SafeIterableMap$AscendingIterator;-><init>(Landroidx/arch/core/internal/SafeIterableMap$Entry;Landroidx/arch/core/internal/SafeIterableMap$Entry;)V
+HSPLandroidx/arch/core/internal/SafeIterableMap$Entry;-><init>(Ljava/lang/Object;Ljava/lang/Object;)V
+HSPLandroidx/arch/core/internal/SafeIterableMap$Entry;->getKey()Ljava/lang/Object;
+HSPLandroidx/arch/core/internal/SafeIterableMap$Entry;->getValue()Ljava/lang/Object;
+HSPLandroidx/arch/core/internal/SafeIterableMap$IteratorWithAdditions;-><init>(Landroidx/arch/core/internal/SafeIterableMap;)V
+HSPLandroidx/arch/core/internal/SafeIterableMap$IteratorWithAdditions;->hasNext()Z
+HSPLandroidx/arch/core/internal/SafeIterableMap$IteratorWithAdditions;->next()Ljava/lang/Object;
+HSPLandroidx/arch/core/internal/SafeIterableMap$IteratorWithAdditions;->next()Ljava/util/Map$Entry;
+HSPLandroidx/arch/core/internal/SafeIterableMap$IteratorWithAdditions;->supportRemove(Landroidx/arch/core/internal/SafeIterableMap$Entry;)V
+HSPLandroidx/arch/core/internal/SafeIterableMap$ListIterator;-><init>(Landroidx/arch/core/internal/SafeIterableMap$Entry;Landroidx/arch/core/internal/SafeIterableMap$Entry;)V
+HSPLandroidx/arch/core/internal/SafeIterableMap$ListIterator;->hasNext()Z
+HSPLandroidx/arch/core/internal/SafeIterableMap$SupportRemove;-><init>()V
+HSPLandroidx/arch/core/internal/SafeIterableMap;-><init>()V
+HSPLandroidx/arch/core/internal/SafeIterableMap;->eldest()Ljava/util/Map$Entry;
+HSPLandroidx/arch/core/internal/SafeIterableMap;->get(Ljava/lang/Object;)Landroidx/arch/core/internal/SafeIterableMap$Entry;
+HSPLandroidx/arch/core/internal/SafeIterableMap;->iterator()Ljava/util/Iterator;
+HSPLandroidx/arch/core/internal/SafeIterableMap;->iteratorWithAdditions()Landroidx/arch/core/internal/SafeIterableMap$IteratorWithAdditions;
+HSPLandroidx/arch/core/internal/SafeIterableMap;->newest()Ljava/util/Map$Entry;
+HSPLandroidx/arch/core/internal/SafeIterableMap;->put(Ljava/lang/Object;Ljava/lang/Object;)Landroidx/arch/core/internal/SafeIterableMap$Entry;
+HSPLandroidx/arch/core/internal/SafeIterableMap;->putIfAbsent(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/arch/core/internal/SafeIterableMap;->remove(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/arch/core/internal/SafeIterableMap;->size()I
+HSPLandroidx/collection/ArraySet$Companion;-><init>()V
+HSPLandroidx/collection/ArraySet$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/collection/ArraySet;-><clinit>()V
+HSPLandroidx/collection/ArraySet;-><init>()V
+HSPLandroidx/collection/ArraySet;-><init>(I)V
+HSPLandroidx/collection/ArraySet;-><init>(IILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/collection/ArraySet;->add(Ljava/lang/Object;)Z
+HSPLandroidx/collection/ArraySet;->allocArrays(I)V
+HSPLandroidx/collection/ArraySet;->clear()V
+HSPLandroidx/collection/ArraySet;->indexOf(Ljava/lang/Object;I)I
+HSPLandroidx/collection/ArraySet;->toArray()[Ljava/lang/Object;
+HSPLandroidx/collection/LruCache;-><init>(I)V
+HSPLandroidx/collection/SimpleArrayMap;-><init>()V
+HSPLandroidx/collection/SimpleArrayMap;-><init>(I)V
+HSPLandroidx/collection/SimpleArrayMap;-><init>(IILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/collection/SparseArrayCompat;-><init>()V
+HSPLandroidx/collection/SparseArrayCompat;-><init>(I)V
+HSPLandroidx/collection/SparseArrayCompat;-><init>(IILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/collection/internal/ContainerHelpersKt;-><clinit>()V
+HSPLandroidx/collection/internal/ContainerHelpersKt;->idealByteArraySize(I)I
+HSPLandroidx/collection/internal/ContainerHelpersKt;->idealIntArraySize(I)I
+HSPLandroidx/collection/internal/Lock;-><init>()V
+HSPLandroidx/collection/internal/LruHashMap;-><init>(IF)V
+HSPLandroidx/compose/animation/core/Animatable$runAnimation$2$1;-><init>(Landroidx/compose/animation/core/Animatable;Landroidx/compose/animation/core/AnimationState;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/Ref$BooleanRef;)V
+HSPLandroidx/compose/animation/core/Animatable$runAnimation$2$1;->invoke(Landroidx/compose/animation/core/AnimationScope;)V
+HSPLandroidx/compose/animation/core/Animatable$runAnimation$2$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/Animatable$runAnimation$2;-><init>(Landroidx/compose/animation/core/Animatable;Ljava/lang/Object;Landroidx/compose/animation/core/Animation;JLkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/animation/core/Animatable$runAnimation$2;->create(Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/animation/core/Animatable$runAnimation$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/Animatable$runAnimation$2;->invoke(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/Animatable$runAnimation$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/Animatable;-><clinit>()V
+HSPLandroidx/compose/animation/core/Animatable;-><init>(Ljava/lang/Object;Landroidx/compose/animation/core/TwoWayConverter;Ljava/lang/Object;Ljava/lang/String;)V
+HSPLandroidx/compose/animation/core/Animatable;-><init>(Ljava/lang/Object;Landroidx/compose/animation/core/TwoWayConverter;Ljava/lang/Object;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/animation/core/Animatable;->access$clampToBounds(Landroidx/compose/animation/core/Animatable;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/Animatable;->access$endAnimation(Landroidx/compose/animation/core/Animatable;)V
+HSPLandroidx/compose/animation/core/Animatable;->access$setRunning(Landroidx/compose/animation/core/Animatable;Z)V
+HSPLandroidx/compose/animation/core/Animatable;->access$setTargetValue(Landroidx/compose/animation/core/Animatable;Ljava/lang/Object;)V
+HSPLandroidx/compose/animation/core/Animatable;->animateTo$default(Landroidx/compose/animation/core/Animatable;Ljava/lang/Object;Landroidx/compose/animation/core/AnimationSpec;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/Animatable;->animateTo(Ljava/lang/Object;Landroidx/compose/animation/core/AnimationSpec;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/Animatable;->asState()Landroidx/compose/runtime/State;
+HSPLandroidx/compose/animation/core/Animatable;->clampToBounds(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/Animatable;->createVector(Ljava/lang/Object;F)Landroidx/compose/animation/core/AnimationVector;
+HSPLandroidx/compose/animation/core/Animatable;->endAnimation()V
+HSPLandroidx/compose/animation/core/Animatable;->getInternalState$animation_core_release()Landroidx/compose/animation/core/AnimationState;
+HSPLandroidx/compose/animation/core/Animatable;->getTargetValue()Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/Animatable;->getTypeConverter()Landroidx/compose/animation/core/TwoWayConverter;
+HSPLandroidx/compose/animation/core/Animatable;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/Animatable;->getVelocity()Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/Animatable;->getVelocityVector()Landroidx/compose/animation/core/AnimationVector;
+HSPLandroidx/compose/animation/core/Animatable;->runAnimation(Landroidx/compose/animation/core/Animation;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/Animatable;->setRunning(Z)V
+HSPLandroidx/compose/animation/core/Animatable;->setTargetValue(Ljava/lang/Object;)V
+HSPLandroidx/compose/animation/core/AnimatableKt;->Animatable$default(FFILjava/lang/Object;)Landroidx/compose/animation/core/Animatable;
+HSPLandroidx/compose/animation/core/AnimatableKt;->Animatable(FF)Landroidx/compose/animation/core/Animatable;
+HSPLandroidx/compose/animation/core/AnimateAsStateKt$animateValueAsState$2;-><init>(Lkotlinx/coroutines/channels/Channel;Ljava/lang/Object;)V
+HSPLandroidx/compose/animation/core/AnimateAsStateKt$animateValueAsState$2;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/AnimateAsStateKt$animateValueAsState$2;->invoke()V
+HSPLandroidx/compose/animation/core/AnimateAsStateKt$animateValueAsState$3$1;-><init>(Ljava/lang/Object;Landroidx/compose/animation/core/Animatable;Landroidx/compose/runtime/State;Landroidx/compose/runtime/State;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/animation/core/AnimateAsStateKt$animateValueAsState$3$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/animation/core/AnimateAsStateKt$animateValueAsState$3$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/AnimateAsStateKt$animateValueAsState$3;-><init>(Lkotlinx/coroutines/channels/Channel;Landroidx/compose/animation/core/Animatable;Landroidx/compose/runtime/State;Landroidx/compose/runtime/State;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/animation/core/AnimateAsStateKt$animateValueAsState$3;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/animation/core/AnimateAsStateKt$animateValueAsState$3;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/AnimateAsStateKt;-><clinit>()V
+HSPLandroidx/compose/animation/core/AnimateAsStateKt;->animateFloatAsState(FLandroidx/compose/animation/core/AnimationSpec;FLjava/lang/String;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/animation/core/AnimateAsStateKt;->animateValueAsState(Ljava/lang/Object;Landroidx/compose/animation/core/TwoWayConverter;Landroidx/compose/animation/core/AnimationSpec;Ljava/lang/Object;Ljava/lang/String;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/animation/core/Animation;->isFinishedFromNanos(J)Z
+HSPLandroidx/compose/animation/core/AnimationEndReason;->$values()[Landroidx/compose/animation/core/AnimationEndReason;
+HSPLandroidx/compose/animation/core/AnimationEndReason;-><clinit>()V
+HSPLandroidx/compose/animation/core/AnimationEndReason;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/animation/core/AnimationKt;->TargetBasedAnimation(Landroidx/compose/animation/core/AnimationSpec;Landroidx/compose/animation/core/TwoWayConverter;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Landroidx/compose/animation/core/TargetBasedAnimation;
+HSPLandroidx/compose/animation/core/AnimationResult;-><clinit>()V
+HSPLandroidx/compose/animation/core/AnimationResult;-><init>(Landroidx/compose/animation/core/AnimationState;Landroidx/compose/animation/core/AnimationEndReason;)V
+HSPLandroidx/compose/animation/core/AnimationScope;-><clinit>()V
+HSPLandroidx/compose/animation/core/AnimationScope;-><init>(Ljava/lang/Object;Landroidx/compose/animation/core/TwoWayConverter;Landroidx/compose/animation/core/AnimationVector;JLjava/lang/Object;JZLkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/animation/core/AnimationScope;->getFinishedTimeNanos()J
+HSPLandroidx/compose/animation/core/AnimationScope;->getLastFrameTimeNanos()J
+HSPLandroidx/compose/animation/core/AnimationScope;->getStartTimeNanos()J
+HSPLandroidx/compose/animation/core/AnimationScope;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/AnimationScope;->getVelocityVector()Landroidx/compose/animation/core/AnimationVector;
+HSPLandroidx/compose/animation/core/AnimationScope;->isRunning()Z
+HSPLandroidx/compose/animation/core/AnimationScope;->setFinishedTimeNanos$animation_core_release(J)V
+HSPLandroidx/compose/animation/core/AnimationScope;->setLastFrameTimeNanos$animation_core_release(J)V
+HSPLandroidx/compose/animation/core/AnimationScope;->setRunning$animation_core_release(Z)V
+HSPLandroidx/compose/animation/core/AnimationScope;->setValue$animation_core_release(Ljava/lang/Object;)V
+HSPLandroidx/compose/animation/core/AnimationScope;->setVelocityVector$animation_core_release(Landroidx/compose/animation/core/AnimationVector;)V
+HSPLandroidx/compose/animation/core/AnimationSpecKt;->spring$default(FFLjava/lang/Object;ILjava/lang/Object;)Landroidx/compose/animation/core/SpringSpec;
+HSPLandroidx/compose/animation/core/AnimationSpecKt;->spring(FFLjava/lang/Object;)Landroidx/compose/animation/core/SpringSpec;
+HSPLandroidx/compose/animation/core/AnimationState;-><clinit>()V
+HSPLandroidx/compose/animation/core/AnimationState;-><init>(Landroidx/compose/animation/core/TwoWayConverter;Ljava/lang/Object;Landroidx/compose/animation/core/AnimationVector;JJZ)V
+HSPLandroidx/compose/animation/core/AnimationState;-><init>(Landroidx/compose/animation/core/TwoWayConverter;Ljava/lang/Object;Landroidx/compose/animation/core/AnimationVector;JJZILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/animation/core/AnimationState;->getLastFrameTimeNanos()J
+HSPLandroidx/compose/animation/core/AnimationState;->getTypeConverter()Landroidx/compose/animation/core/TwoWayConverter;
+HSPLandroidx/compose/animation/core/AnimationState;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/AnimationState;->getVelocityVector()Landroidx/compose/animation/core/AnimationVector;
+HSPLandroidx/compose/animation/core/AnimationState;->isRunning()Z
+HSPLandroidx/compose/animation/core/AnimationState;->setFinishedTimeNanos$animation_core_release(J)V
+HSPLandroidx/compose/animation/core/AnimationState;->setLastFrameTimeNanos$animation_core_release(J)V
+HSPLandroidx/compose/animation/core/AnimationState;->setRunning$animation_core_release(Z)V
+HSPLandroidx/compose/animation/core/AnimationState;->setValue$animation_core_release(Ljava/lang/Object;)V
+HSPLandroidx/compose/animation/core/AnimationState;->setVelocityVector$animation_core_release(Landroidx/compose/animation/core/AnimationVector;)V
+HSPLandroidx/compose/animation/core/AnimationStateKt;->copy$default(Landroidx/compose/animation/core/AnimationState;Ljava/lang/Object;Landroidx/compose/animation/core/AnimationVector;JJZILjava/lang/Object;)Landroidx/compose/animation/core/AnimationState;
+HSPLandroidx/compose/animation/core/AnimationStateKt;->copy(Landroidx/compose/animation/core/AnimationState;Ljava/lang/Object;Landroidx/compose/animation/core/AnimationVector;JJZ)Landroidx/compose/animation/core/AnimationState;
+HSPLandroidx/compose/animation/core/AnimationStateKt;->createZeroVectorFrom(Landroidx/compose/animation/core/TwoWayConverter;Ljava/lang/Object;)Landroidx/compose/animation/core/AnimationVector;
+HSPLandroidx/compose/animation/core/AnimationVector1D;-><clinit>()V
+HSPLandroidx/compose/animation/core/AnimationVector1D;-><init>(F)V
+HSPLandroidx/compose/animation/core/AnimationVector1D;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/animation/core/AnimationVector1D;->get$animation_core_release(I)F
+HSPLandroidx/compose/animation/core/AnimationVector1D;->getSize$animation_core_release()I
+HSPLandroidx/compose/animation/core/AnimationVector1D;->getValue()F
+HSPLandroidx/compose/animation/core/AnimationVector1D;->newVector$animation_core_release()Landroidx/compose/animation/core/AnimationVector1D;
+HSPLandroidx/compose/animation/core/AnimationVector1D;->newVector$animation_core_release()Landroidx/compose/animation/core/AnimationVector;
+HSPLandroidx/compose/animation/core/AnimationVector1D;->reset$animation_core_release()V
+HSPLandroidx/compose/animation/core/AnimationVector1D;->set$animation_core_release(IF)V
+HSPLandroidx/compose/animation/core/AnimationVector;-><clinit>()V
+HSPLandroidx/compose/animation/core/AnimationVector;-><init>()V
+HSPLandroidx/compose/animation/core/AnimationVector;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/animation/core/AnimationVectorsKt;->copy(Landroidx/compose/animation/core/AnimationVector;)Landroidx/compose/animation/core/AnimationVector;
+HSPLandroidx/compose/animation/core/AnimationVectorsKt;->copyFrom(Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;)V
+HSPLandroidx/compose/animation/core/AnimationVectorsKt;->newInstance(Landroidx/compose/animation/core/AnimationVector;)Landroidx/compose/animation/core/AnimationVector;
+HSPLandroidx/compose/animation/core/CubicBezierEasing;-><init>(FFFF)V
+HSPLandroidx/compose/animation/core/CubicBezierEasing;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/animation/core/CubicBezierEasing;->evaluateCubic(FFF)F
+HSPLandroidx/compose/animation/core/CubicBezierEasing;->transform(F)F
+HSPLandroidx/compose/animation/core/EasingKt$LinearEasing$1;-><clinit>()V
+HSPLandroidx/compose/animation/core/EasingKt$LinearEasing$1;-><init>()V
+HSPLandroidx/compose/animation/core/EasingKt;-><clinit>()V
+HSPLandroidx/compose/animation/core/EasingKt;->getFastOutSlowInEasing()Landroidx/compose/animation/core/Easing;
+HSPLandroidx/compose/animation/core/EasingKt;->getLinearEasing()Landroidx/compose/animation/core/Easing;
+HSPLandroidx/compose/animation/core/FloatTweenSpec;-><clinit>()V
+HSPLandroidx/compose/animation/core/FloatTweenSpec;-><init>(IILandroidx/compose/animation/core/Easing;)V
+HSPLandroidx/compose/animation/core/FloatTweenSpec;->clampPlayTime(J)J
+HSPLandroidx/compose/animation/core/FloatTweenSpec;->getValueFromNanos(JFFF)F
+HSPLandroidx/compose/animation/core/FloatTweenSpec;->getVelocityFromNanos(JFFF)F
+HSPLandroidx/compose/animation/core/MutatePriority;->$values()[Landroidx/compose/animation/core/MutatePriority;
+HSPLandroidx/compose/animation/core/MutatePriority;-><clinit>()V
+HSPLandroidx/compose/animation/core/MutatePriority;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/animation/core/MutatorMutex$Mutator;-><init>(Landroidx/compose/animation/core/MutatePriority;Lkotlinx/coroutines/Job;)V
+HSPLandroidx/compose/animation/core/MutatorMutex$mutate$2;-><init>(Landroidx/compose/animation/core/MutatePriority;Landroidx/compose/animation/core/MutatorMutex;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/animation/core/MutatorMutex$mutate$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/animation/core/MutatorMutex$mutate$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/MutatorMutex$mutate$2;->invoke(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/MutatorMutex$mutate$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/MutatorMutex;-><init>()V
+HSPLandroidx/compose/animation/core/MutatorMutex;->access$getCurrentMutator$p(Landroidx/compose/animation/core/MutatorMutex;)Ljava/util/concurrent/atomic/AtomicReference;
+HSPLandroidx/compose/animation/core/MutatorMutex;->access$getMutex$p(Landroidx/compose/animation/core/MutatorMutex;)Lkotlinx/coroutines/sync/Mutex;
+HSPLandroidx/compose/animation/core/MutatorMutex;->access$tryMutateOrCancel(Landroidx/compose/animation/core/MutatorMutex;Landroidx/compose/animation/core/MutatorMutex$Mutator;)V
+HSPLandroidx/compose/animation/core/MutatorMutex;->mutate$default(Landroidx/compose/animation/core/MutatorMutex;Landroidx/compose/animation/core/MutatePriority;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/MutatorMutex;->mutate(Landroidx/compose/animation/core/MutatePriority;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/MutatorMutex;->tryMutateOrCancel(Landroidx/compose/animation/core/MutatorMutex$Mutator;)V
+HSPLandroidx/compose/animation/core/SpringSpec;-><init>(FFLjava/lang/Object;)V
+HSPLandroidx/compose/animation/core/SpringSpec;-><init>(FFLjava/lang/Object;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/animation/core/SpringSpec;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/animation/core/SuspendAnimationKt$animate$4;-><init>(Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/animation/core/SuspendAnimationKt$animate$4;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/SuspendAnimationKt$animate$6$1;-><init>(Landroidx/compose/animation/core/AnimationState;)V
+HSPLandroidx/compose/animation/core/SuspendAnimationKt$animate$6;-><init>(Lkotlin/jvm/internal/Ref$ObjectRef;Ljava/lang/Object;Landroidx/compose/animation/core/Animation;Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationState;FLkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/animation/core/SuspendAnimationKt$animate$6;->invoke(J)V
+HSPLandroidx/compose/animation/core/SuspendAnimationKt$animate$6;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/SuspendAnimationKt$animate$9;-><init>(Lkotlin/jvm/internal/Ref$ObjectRef;FLandroidx/compose/animation/core/Animation;Landroidx/compose/animation/core/AnimationState;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/animation/core/SuspendAnimationKt$animate$9;->invoke(J)V
+HSPLandroidx/compose/animation/core/SuspendAnimationKt$animate$9;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/SuspendAnimationKt$callWithFrameNanos$2;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/animation/core/SuspendAnimationKt$callWithFrameNanos$2;->invoke(J)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/SuspendAnimationKt$callWithFrameNanos$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/SuspendAnimationKt;->access$doAnimationFrameWithScale(Landroidx/compose/animation/core/AnimationScope;JFLandroidx/compose/animation/core/Animation;Landroidx/compose/animation/core/AnimationState;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/animation/core/SuspendAnimationKt;->animate(Landroidx/compose/animation/core/AnimationState;Landroidx/compose/animation/core/Animation;JLkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/SuspendAnimationKt;->callWithFrameNanos(Landroidx/compose/animation/core/Animation;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/SuspendAnimationKt;->doAnimationFrame(Landroidx/compose/animation/core/AnimationScope;JJLandroidx/compose/animation/core/Animation;Landroidx/compose/animation/core/AnimationState;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/animation/core/SuspendAnimationKt;->doAnimationFrameWithScale(Landroidx/compose/animation/core/AnimationScope;JFLandroidx/compose/animation/core/Animation;Landroidx/compose/animation/core/AnimationState;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/animation/core/SuspendAnimationKt;->getDurationScale(Lkotlin/coroutines/CoroutineContext;)F
+HSPLandroidx/compose/animation/core/SuspendAnimationKt;->updateState(Landroidx/compose/animation/core/AnimationScope;Landroidx/compose/animation/core/AnimationState;)V
+HSPLandroidx/compose/animation/core/TargetBasedAnimation;-><clinit>()V
+HSPLandroidx/compose/animation/core/TargetBasedAnimation;-><init>(Landroidx/compose/animation/core/AnimationSpec;Landroidx/compose/animation/core/TwoWayConverter;Ljava/lang/Object;Ljava/lang/Object;Landroidx/compose/animation/core/AnimationVector;)V
+HSPLandroidx/compose/animation/core/TargetBasedAnimation;-><init>(Landroidx/compose/animation/core/VectorizedAnimationSpec;Landroidx/compose/animation/core/TwoWayConverter;Ljava/lang/Object;Ljava/lang/Object;Landroidx/compose/animation/core/AnimationVector;)V
+HSPLandroidx/compose/animation/core/TargetBasedAnimation;->getDurationNanos()J
+HSPLandroidx/compose/animation/core/TargetBasedAnimation;->getTargetValue()Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/TargetBasedAnimation;->getTypeConverter()Landroidx/compose/animation/core/TwoWayConverter;
+HSPLandroidx/compose/animation/core/TargetBasedAnimation;->getValueFromNanos(J)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/TargetBasedAnimation;->getVelocityVectorFromNanos(J)Landroidx/compose/animation/core/AnimationVector;
+HSPLandroidx/compose/animation/core/TargetBasedAnimation;->isInfinite()Z
+HSPLandroidx/compose/animation/core/TweenSpec;-><init>(IILandroidx/compose/animation/core/Easing;)V
+HSPLandroidx/compose/animation/core/TweenSpec;-><init>(IILandroidx/compose/animation/core/Easing;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/animation/core/TweenSpec;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/animation/core/TweenSpec;->vectorize(Landroidx/compose/animation/core/TwoWayConverter;)Landroidx/compose/animation/core/VectorizedAnimationSpec;
+HSPLandroidx/compose/animation/core/TweenSpec;->vectorize(Landroidx/compose/animation/core/TwoWayConverter;)Landroidx/compose/animation/core/VectorizedTweenSpec;
+HSPLandroidx/compose/animation/core/TwoWayConverterImpl;-><init>(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/animation/core/TwoWayConverterImpl;->getConvertFromVector()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/animation/core/TwoWayConverterImpl;->getConvertToVector()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/animation/core/VectorConvertersKt$DpOffsetToVector$1;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$DpOffsetToVector$1;-><init>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$DpOffsetToVector$2;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$DpOffsetToVector$2;-><init>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$DpToVector$1;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$DpToVector$1;-><init>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$DpToVector$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/VectorConvertersKt$DpToVector$1;->invoke-0680j_4(F)Landroidx/compose/animation/core/AnimationVector1D;
+HSPLandroidx/compose/animation/core/VectorConvertersKt$DpToVector$2;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$DpToVector$2;-><init>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$DpToVector$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/VectorConvertersKt$DpToVector$2;->invoke-u2uoSUM(Landroidx/compose/animation/core/AnimationVector1D;)F
+HSPLandroidx/compose/animation/core/VectorConvertersKt$FloatToVector$1;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$FloatToVector$1;-><init>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$FloatToVector$1;->invoke(F)Landroidx/compose/animation/core/AnimationVector1D;
+HSPLandroidx/compose/animation/core/VectorConvertersKt$FloatToVector$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/animation/core/VectorConvertersKt$FloatToVector$2;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$FloatToVector$2;-><init>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$IntOffsetToVector$1;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$IntOffsetToVector$1;-><init>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$IntOffsetToVector$2;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$IntOffsetToVector$2;-><init>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$IntSizeToVector$1;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$IntSizeToVector$1;-><init>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$IntSizeToVector$2;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$IntSizeToVector$2;-><init>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$IntToVector$1;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$IntToVector$1;-><init>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$IntToVector$2;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$IntToVector$2;-><init>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$OffsetToVector$1;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$OffsetToVector$1;-><init>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$OffsetToVector$2;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$OffsetToVector$2;-><init>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$RectToVector$1;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$RectToVector$1;-><init>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$RectToVector$2;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$RectToVector$2;-><init>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$SizeToVector$1;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$SizeToVector$1;-><init>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$SizeToVector$2;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt$SizeToVector$2;-><init>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorConvertersKt;->TwoWayConverter(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Landroidx/compose/animation/core/TwoWayConverter;
+HSPLandroidx/compose/animation/core/VectorConvertersKt;->getVectorConverter(Landroidx/compose/ui/geometry/Offset$Companion;)Landroidx/compose/animation/core/TwoWayConverter;
+HSPLandroidx/compose/animation/core/VectorConvertersKt;->getVectorConverter(Landroidx/compose/ui/geometry/Rect$Companion;)Landroidx/compose/animation/core/TwoWayConverter;
+HSPLandroidx/compose/animation/core/VectorConvertersKt;->getVectorConverter(Landroidx/compose/ui/geometry/Size$Companion;)Landroidx/compose/animation/core/TwoWayConverter;
+HSPLandroidx/compose/animation/core/VectorConvertersKt;->getVectorConverter(Landroidx/compose/ui/unit/Dp$Companion;)Landroidx/compose/animation/core/TwoWayConverter;
+HSPLandroidx/compose/animation/core/VectorConvertersKt;->getVectorConverter(Landroidx/compose/ui/unit/DpOffset$Companion;)Landroidx/compose/animation/core/TwoWayConverter;
+HSPLandroidx/compose/animation/core/VectorConvertersKt;->getVectorConverter(Landroidx/compose/ui/unit/IntOffset$Companion;)Landroidx/compose/animation/core/TwoWayConverter;
+HSPLandroidx/compose/animation/core/VectorConvertersKt;->getVectorConverter(Landroidx/compose/ui/unit/IntSize$Companion;)Landroidx/compose/animation/core/TwoWayConverter;
+HSPLandroidx/compose/animation/core/VectorConvertersKt;->getVectorConverter(Lkotlin/jvm/internal/FloatCompanionObject;)Landroidx/compose/animation/core/TwoWayConverter;
+HSPLandroidx/compose/animation/core/VectorConvertersKt;->getVectorConverter(Lkotlin/jvm/internal/IntCompanionObject;)Landroidx/compose/animation/core/TwoWayConverter;
+HSPLandroidx/compose/animation/core/VectorConvertersKt;->lerp(FFF)F
+HSPLandroidx/compose/animation/core/VectorizedAnimationSpec;->getEndVelocity(Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;)Landroidx/compose/animation/core/AnimationVector;
+HSPLandroidx/compose/animation/core/VectorizedDurationBasedAnimationSpec;->getDurationNanos(Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;)J
+HSPLandroidx/compose/animation/core/VectorizedFiniteAnimationSpec;->isInfinite()Z
+HSPLandroidx/compose/animation/core/VectorizedFloatAnimationSpec$1;-><init>(Landroidx/compose/animation/core/FloatAnimationSpec;)V
+HSPLandroidx/compose/animation/core/VectorizedFloatAnimationSpec$1;->get(I)Landroidx/compose/animation/core/FloatAnimationSpec;
+HSPLandroidx/compose/animation/core/VectorizedFloatAnimationSpec;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorizedFloatAnimationSpec;-><init>(Landroidx/compose/animation/core/Animations;)V
+HSPLandroidx/compose/animation/core/VectorizedFloatAnimationSpec;-><init>(Landroidx/compose/animation/core/FloatAnimationSpec;)V
+HSPLandroidx/compose/animation/core/VectorizedFloatAnimationSpec;->getValueFromNanos(JLandroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;)Landroidx/compose/animation/core/AnimationVector;
+HSPLandroidx/compose/animation/core/VectorizedFloatAnimationSpec;->getVelocityFromNanos(JLandroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;)Landroidx/compose/animation/core/AnimationVector;
+HSPLandroidx/compose/animation/core/VectorizedTweenSpec;-><clinit>()V
+HSPLandroidx/compose/animation/core/VectorizedTweenSpec;-><init>(IILandroidx/compose/animation/core/Easing;)V
+HSPLandroidx/compose/animation/core/VectorizedTweenSpec;->getDelayMillis()I
+HSPLandroidx/compose/animation/core/VectorizedTweenSpec;->getDurationMillis()I
+HSPLandroidx/compose/animation/core/VectorizedTweenSpec;->getValueFromNanos(JLandroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;)Landroidx/compose/animation/core/AnimationVector;
+HSPLandroidx/compose/animation/core/VectorizedTweenSpec;->getVelocityFromNanos(JLandroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;)Landroidx/compose/animation/core/AnimationVector;
+HSPLandroidx/compose/animation/core/VisibilityThresholdsKt;-><clinit>()V
+HSPLandroidx/compose/animation/core/VisibilityThresholdsKt;->getVisibilityThreshold(Landroidx/compose/ui/geometry/Offset$Companion;)J
+HSPLandroidx/compose/animation/core/VisibilityThresholdsKt;->getVisibilityThreshold(Landroidx/compose/ui/geometry/Rect$Companion;)Landroidx/compose/ui/geometry/Rect;
+HSPLandroidx/compose/animation/core/VisibilityThresholdsKt;->getVisibilityThreshold(Landroidx/compose/ui/geometry/Size$Companion;)J
+HSPLandroidx/compose/animation/core/VisibilityThresholdsKt;->getVisibilityThreshold(Landroidx/compose/ui/unit/Dp$Companion;)F
+HSPLandroidx/compose/animation/core/VisibilityThresholdsKt;->getVisibilityThreshold(Landroidx/compose/ui/unit/IntOffset$Companion;)J
+HSPLandroidx/compose/animation/core/VisibilityThresholdsKt;->getVisibilityThreshold(Landroidx/compose/ui/unit/IntSize$Companion;)J
+HSPLandroidx/compose/animation/core/VisibilityThresholdsKt;->getVisibilityThreshold(Lkotlin/jvm/internal/IntCompanionObject;)I
+HSPLandroidx/compose/foundation/Background;-><init>(Landroidx/compose/ui/graphics/Color;Landroidx/compose/ui/graphics/Brush;FLandroidx/compose/ui/graphics/Shape;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/foundation/Background;-><init>(Landroidx/compose/ui/graphics/Color;Landroidx/compose/ui/graphics/Brush;FLandroidx/compose/ui/graphics/Shape;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/foundation/Background;-><init>(Landroidx/compose/ui/graphics/Color;Landroidx/compose/ui/graphics/Brush;FLandroidx/compose/ui/graphics/Shape;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/foundation/Background;->draw(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;)V
+HSPLandroidx/compose/foundation/Background;->drawOutline(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;)V
+HSPLandroidx/compose/foundation/Background;->drawRect(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;)V
+HSPLandroidx/compose/foundation/Background;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/foundation/BackgroundKt;->background-bw27NRU$default(Landroidx/compose/ui/Modifier;JLandroidx/compose/ui/graphics/Shape;ILjava/lang/Object;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/BackgroundKt;->background-bw27NRU(Landroidx/compose/ui/Modifier;JLandroidx/compose/ui/graphics/Shape;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/CanvasKt;->Canvas(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/foundation/ClickableKt$PressedInteractionSourceDisposableEffect$1$invoke$$inlined$onDispose$1;-><init>(Landroidx/compose/runtime/MutableState;Ljava/util/Map;Landroidx/compose/foundation/interaction/MutableInteractionSource;)V
+HSPLandroidx/compose/foundation/ClickableKt$PressedInteractionSourceDisposableEffect$1;-><init>(Landroidx/compose/runtime/MutableState;Ljava/util/Map;Landroidx/compose/foundation/interaction/MutableInteractionSource;)V
+HSPLandroidx/compose/foundation/ClickableKt$PressedInteractionSourceDisposableEffect$1;->invoke(Landroidx/compose/runtime/DisposableEffectScope;)Landroidx/compose/runtime/DisposableEffectResult;
+HSPLandroidx/compose/foundation/ClickableKt$PressedInteractionSourceDisposableEffect$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/ClickableKt$clickable$4$1$1$1;-><init>(Landroidx/compose/ui/input/ScrollContainerInfo;)V
+HSPLandroidx/compose/foundation/ClickableKt$clickable$4$1$1;-><init>(Landroidx/compose/runtime/MutableState;)V
+HSPLandroidx/compose/foundation/ClickableKt$clickable$4$1$1;->invoke(Landroidx/compose/ui/input/ScrollContainerInfo;)V
+HSPLandroidx/compose/foundation/ClickableKt$clickable$4$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/ClickableKt$clickable$4$delayPressInteraction$1$1;-><clinit>()V
+HSPLandroidx/compose/foundation/ClickableKt$clickable$4$delayPressInteraction$1$1;-><init>()V
+HSPLandroidx/compose/foundation/ClickableKt$clickable$4$gesture$1$1$1;-><init>(ZLandroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/runtime/MutableState;Landroidx/compose/runtime/MutableState;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/ClickableKt$clickable$4$gesture$1$1$2;-><init>(ZLandroidx/compose/runtime/State;)V
+HSPLandroidx/compose/foundation/ClickableKt$clickable$4$gesture$1$1;-><init>(Landroidx/compose/runtime/MutableState;ZLandroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/runtime/MutableState;Landroidx/compose/runtime/MutableState;Landroidx/compose/runtime/State;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/ClickableKt$clickable$4$gesture$1$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/foundation/ClickableKt$clickable$4$gesture$1$1;->invoke(Landroidx/compose/ui/input/pointer/PointerInputScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/ClickableKt$clickable$4$gesture$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/ClickableKt$clickable$4$gesture$1$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/ClickableKt$clickable$4;-><init>(Lkotlin/jvm/functions/Function0;ZLandroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/foundation/Indication;Ljava/lang/String;Landroidx/compose/ui/semantics/Role;)V
+HSPLandroidx/compose/foundation/ClickableKt$clickable$4;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/ClickableKt$clickable$4;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/ClickableKt$genericClickableWithoutGesture$clickSemantics$1$1;-><init>(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/foundation/ClickableKt$genericClickableWithoutGesture$clickSemantics$1;-><init>(Landroidx/compose/ui/semantics/Role;Ljava/lang/String;Lkotlin/jvm/functions/Function0;Ljava/lang/String;ZLkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/foundation/ClickableKt$genericClickableWithoutGesture$clickSemantics$1;->invoke(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;)V
+HSPLandroidx/compose/foundation/ClickableKt$genericClickableWithoutGesture$clickSemantics$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/ClickableKt$genericClickableWithoutGesture$detectPressAndClickFromKey$1;-><init>(ZLjava/util/Map;Landroidx/compose/runtime/State;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function0;Landroidx/compose/foundation/interaction/MutableInteractionSource;)V
+HSPLandroidx/compose/foundation/ClickableKt;->PressedInteractionSourceDisposableEffect(Landroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/runtime/MutableState;Ljava/util/Map;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/foundation/ClickableKt;->clickable-O2vRcR0$default(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/foundation/Indication;ZLjava/lang/String;Landroidx/compose/ui/semantics/Role;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/ClickableKt;->clickable-O2vRcR0(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/foundation/Indication;ZLjava/lang/String;Landroidx/compose/ui/semantics/Role;Lkotlin/jvm/functions/Function0;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/ClickableKt;->genericClickableWithoutGesture-bdNGguI(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/foundation/Indication;Lkotlinx/coroutines/CoroutineScope;Ljava/util/Map;Landroidx/compose/runtime/State;ZLjava/lang/String;Landroidx/compose/ui/semantics/Role;Ljava/lang/String;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/ClickableKt;->genericClickableWithoutGesture_bdNGguI$clickSemantics(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/semantics/Role;Ljava/lang/String;Lkotlin/jvm/functions/Function0;Ljava/lang/String;ZLkotlin/jvm/functions/Function0;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/ClickableKt;->genericClickableWithoutGesture_bdNGguI$detectPressAndClickFromKey(Landroidx/compose/ui/Modifier;ZLjava/util/Map;Landroidx/compose/runtime/State;Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function0;Landroidx/compose/foundation/interaction/MutableInteractionSource;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/DarkThemeKt;->isSystemInDarkTheme(Landroidx/compose/runtime/Composer;I)Z
+HSPLandroidx/compose/foundation/DarkTheme_androidKt;->_isSystemInDarkTheme(Landroidx/compose/runtime/Composer;I)Z
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$1$1$invoke$$inlined$onDispose$1;-><init>(Landroidx/compose/runtime/MutableState;Landroidx/compose/foundation/interaction/MutableInteractionSource;)V
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$1$1;-><init>(Landroidx/compose/runtime/MutableState;Landroidx/compose/foundation/interaction/MutableInteractionSource;)V
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$1$1;->invoke(Landroidx/compose/runtime/DisposableEffectScope;)Landroidx/compose/runtime/DisposableEffectResult;
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$2$invoke$$inlined$onDispose$1;-><init>()V
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$2;-><init>(ZLkotlinx/coroutines/CoroutineScope;Landroidx/compose/runtime/MutableState;Landroidx/compose/foundation/interaction/MutableInteractionSource;)V
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$2;->invoke(Landroidx/compose/runtime/DisposableEffectScope;)Landroidx/compose/runtime/DisposableEffectResult;
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$3$1;-><init>(Landroidx/compose/ui/focus/FocusRequester;Landroidx/compose/runtime/MutableState;)V
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$3;-><init>(Landroidx/compose/runtime/MutableState;Landroidx/compose/ui/focus/FocusRequester;)V
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$3;->invoke(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;)V
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$3;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$4$1;-><init>(Landroidx/compose/runtime/MutableState;)V
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$4$1;->invoke(Landroidx/compose/foundation/lazy/layout/PinnableParent;)V
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$4$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$5$3;-><init>(Landroidx/compose/runtime/MutableState;Landroidx/compose/foundation/interaction/MutableInteractionSource;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$5$3;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$5$3;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$5;-><init>(Lkotlinx/coroutines/CoroutineScope;Landroidx/compose/runtime/MutableState;Landroidx/compose/foundation/relocation/BringIntoViewRequester;Landroidx/compose/runtime/MutableState;Landroidx/compose/runtime/MutableState;Landroidx/compose/foundation/interaction/MutableInteractionSource;)V
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$5;->invoke(Landroidx/compose/ui/focus/FocusState;)V
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2$5;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2;-><init>(Landroidx/compose/foundation/interaction/MutableInteractionSource;Z)V
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2;->access$invoke$lambda$3(Landroidx/compose/runtime/MutableState;Landroidx/compose/foundation/lazy/layout/PinnableParent;)V
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2;->access$invoke$lambda$5(Landroidx/compose/runtime/MutableState;)Z
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2;->access$invoke$lambda$6(Landroidx/compose/runtime/MutableState;Z)V
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2;->invoke$lambda$3(Landroidx/compose/runtime/MutableState;Landroidx/compose/foundation/lazy/layout/PinnableParent;)V
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2;->invoke$lambda$5(Landroidx/compose/runtime/MutableState;)Z
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2;->invoke$lambda$6(Landroidx/compose/runtime/MutableState;Z)V
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/FocusableKt$focusable$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/FocusableKt$focusableInNonTouchMode$2$1;-><init>(Landroidx/compose/ui/input/InputModeManager;)V
+HSPLandroidx/compose/foundation/FocusableKt$focusableInNonTouchMode$2$1;->invoke(Landroidx/compose/ui/focus/FocusProperties;)V
+HSPLandroidx/compose/foundation/FocusableKt$focusableInNonTouchMode$2$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/FocusableKt$focusableInNonTouchMode$2;-><init>(ZLandroidx/compose/foundation/interaction/MutableInteractionSource;)V
+HSPLandroidx/compose/foundation/FocusableKt$focusableInNonTouchMode$2;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/FocusableKt$focusableInNonTouchMode$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/FocusableKt;-><clinit>()V
+HSPLandroidx/compose/foundation/FocusableKt;->access$onPinnableParentAvailable(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/FocusableKt;->focusable(Landroidx/compose/ui/Modifier;ZLandroidx/compose/foundation/interaction/MutableInteractionSource;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/FocusableKt;->focusableInNonTouchMode(Landroidx/compose/ui/Modifier;ZLandroidx/compose/foundation/interaction/MutableInteractionSource;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/FocusableKt;->onPinnableParentAvailable(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/HoverableKt$hoverable$2$1$1$invoke$$inlined$onDispose$1;-><init>(Landroidx/compose/runtime/MutableState;Landroidx/compose/foundation/interaction/MutableInteractionSource;)V
+HSPLandroidx/compose/foundation/HoverableKt$hoverable$2$1$1;-><init>(Landroidx/compose/runtime/MutableState;Landroidx/compose/foundation/interaction/MutableInteractionSource;)V
+HSPLandroidx/compose/foundation/HoverableKt$hoverable$2$1$1;->invoke(Landroidx/compose/runtime/DisposableEffectScope;)Landroidx/compose/runtime/DisposableEffectResult;
+HSPLandroidx/compose/foundation/HoverableKt$hoverable$2$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/HoverableKt$hoverable$2$2$1;-><init>(ZLandroidx/compose/runtime/MutableState;Landroidx/compose/foundation/interaction/MutableInteractionSource;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/HoverableKt$hoverable$2$2$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/foundation/HoverableKt$hoverable$2$2$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/HoverableKt$hoverable$2$3$1;-><init>(Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineScope;Landroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/runtime/MutableState;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/HoverableKt$hoverable$2$3$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/foundation/HoverableKt$hoverable$2$3$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/HoverableKt$hoverable$2$3;-><init>(Lkotlinx/coroutines/CoroutineScope;Landroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/runtime/MutableState;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/HoverableKt$hoverable$2$3;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/foundation/HoverableKt$hoverable$2$3;->invoke(Landroidx/compose/ui/input/pointer/PointerInputScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/HoverableKt$hoverable$2$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/HoverableKt$hoverable$2$3;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/HoverableKt$hoverable$2;-><init>(Landroidx/compose/foundation/interaction/MutableInteractionSource;Z)V
+HSPLandroidx/compose/foundation/HoverableKt$hoverable$2;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/HoverableKt$hoverable$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/HoverableKt;->hoverable(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/interaction/MutableInteractionSource;Z)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/IndicationKt$LocalIndication$1;-><clinit>()V
+HSPLandroidx/compose/foundation/IndicationKt$LocalIndication$1;-><init>()V
+HSPLandroidx/compose/foundation/IndicationKt$indication$2;-><init>(Landroidx/compose/foundation/Indication;Landroidx/compose/foundation/interaction/InteractionSource;)V
+HSPLandroidx/compose/foundation/IndicationKt$indication$2;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/IndicationKt$indication$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/IndicationKt;-><clinit>()V
+HSPLandroidx/compose/foundation/IndicationKt;->getLocalIndication()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/foundation/IndicationKt;->indication(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/interaction/InteractionSource;Landroidx/compose/foundation/Indication;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/IndicationModifier;-><init>(Landroidx/compose/foundation/IndicationInstance;)V
+HSPLandroidx/compose/foundation/IndicationModifier;->draw(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;)V
+HSPLandroidx/compose/foundation/MutatePriority;->$values()[Landroidx/compose/foundation/MutatePriority;
+HSPLandroidx/compose/foundation/MutatePriority;-><clinit>()V
+HSPLandroidx/compose/foundation/MutatePriority;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/foundation/MutatorMutex$Mutator;-><init>(Landroidx/compose/foundation/MutatePriority;Lkotlinx/coroutines/Job;)V
+HSPLandroidx/compose/foundation/MutatorMutex$mutateWith$2;-><init>(Landroidx/compose/foundation/MutatePriority;Landroidx/compose/foundation/MutatorMutex;Lkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/MutatorMutex$mutateWith$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/foundation/MutatorMutex$mutateWith$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/MutatorMutex$mutateWith$2;->invoke(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/MutatorMutex$mutateWith$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/MutatorMutex;-><init>()V
+HSPLandroidx/compose/foundation/MutatorMutex;->access$getCurrentMutator$p(Landroidx/compose/foundation/MutatorMutex;)Ljava/util/concurrent/atomic/AtomicReference;
+HSPLandroidx/compose/foundation/MutatorMutex;->access$getMutex$p(Landroidx/compose/foundation/MutatorMutex;)Lkotlinx/coroutines/sync/Mutex;
+HSPLandroidx/compose/foundation/MutatorMutex;->access$tryMutateOrCancel(Landroidx/compose/foundation/MutatorMutex;Landroidx/compose/foundation/MutatorMutex$Mutator;)V
+HSPLandroidx/compose/foundation/MutatorMutex;->mutateWith(Ljava/lang/Object;Landroidx/compose/foundation/MutatePriority;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/MutatorMutex;->tryMutateOrCancel(Landroidx/compose/foundation/MutatorMutex$Mutator;)V
+HSPLandroidx/compose/foundation/PinnableParentConsumer;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/foundation/PinnableParentConsumer;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/foundation/PinnableParentConsumer;->onModifierLocalsUpdated(Landroidx/compose/ui/modifier/ModifierLocalReadScope;)V
+HSPLandroidx/compose/foundation/gestures/DefaultDraggableState$drag$2;-><init>(Landroidx/compose/foundation/gestures/DefaultDraggableState;Landroidx/compose/foundation/MutatePriority;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/gestures/DefaultDraggableState$drag$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/foundation/gestures/DefaultDraggableState$drag$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/DefaultDraggableState$drag$2;->invoke(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/DefaultDraggableState$drag$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/DefaultDraggableState$dragScope$1;-><init>(Landroidx/compose/foundation/gestures/DefaultDraggableState;)V
+HSPLandroidx/compose/foundation/gestures/DefaultDraggableState$dragScope$1;->dragBy(F)V
+HSPLandroidx/compose/foundation/gestures/DefaultDraggableState;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/foundation/gestures/DefaultDraggableState;->access$getDragScope$p(Landroidx/compose/foundation/gestures/DefaultDraggableState;)Landroidx/compose/foundation/gestures/DragScope;
+HSPLandroidx/compose/foundation/gestures/DefaultDraggableState;->access$getScrollMutex$p(Landroidx/compose/foundation/gestures/DefaultDraggableState;)Landroidx/compose/foundation/MutatorMutex;
+HSPLandroidx/compose/foundation/gestures/DefaultDraggableState;->drag(Landroidx/compose/foundation/MutatePriority;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/DefaultDraggableState;->getOnDelta()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/foundation/gestures/DragLogic;-><init>(Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/MutableState;Landroidx/compose/foundation/interaction/MutableInteractionSource;)V
+HSPLandroidx/compose/foundation/gestures/DraggableKt$awaitDownAndSlop$1;-><init>(Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$1;-><init>(Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$3;-><clinit>()V
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$3;-><init>()V
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$4;-><init>(Z)V
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$5;-><init>(Lkotlin/jvm/functions/Function3;Landroidx/compose/foundation/gestures/Orientation;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$1$1$invoke$$inlined$onDispose$1;-><init>(Landroidx/compose/runtime/MutableState;Landroidx/compose/foundation/interaction/MutableInteractionSource;)V
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$1$1;-><init>(Landroidx/compose/runtime/MutableState;Landroidx/compose/foundation/interaction/MutableInteractionSource;)V
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$1$1;->invoke(Landroidx/compose/runtime/DisposableEffectScope;)Landroidx/compose/runtime/DisposableEffectResult;
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$2;-><init>(Lkotlinx/coroutines/channels/Channel;Landroidx/compose/foundation/gestures/DraggableState;Landroidx/compose/runtime/State;Landroidx/compose/foundation/gestures/Orientation;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$3$1$1;-><init>(Lkotlinx/coroutines/CoroutineScope;Landroidx/compose/runtime/State;Landroidx/compose/runtime/State;Landroidx/compose/foundation/gestures/Orientation;Lkotlinx/coroutines/channels/Channel;ZLkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$3$1$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$3$1$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$3$1;-><init>(Landroidx/compose/ui/input/pointer/PointerInputScope;Landroidx/compose/runtime/State;Landroidx/compose/runtime/State;Landroidx/compose/foundation/gestures/Orientation;Lkotlinx/coroutines/channels/Channel;ZLkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$3$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$3$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$3$1;->invoke(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$3$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$3;-><init>(ZLandroidx/compose/runtime/State;Landroidx/compose/runtime/State;Landroidx/compose/foundation/gestures/Orientation;Lkotlinx/coroutines/channels/Channel;ZLkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$3;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$3;->invoke(Landroidx/compose/ui/input/pointer/PointerInputScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$3;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9;-><init>(Landroidx/compose/foundation/interaction/MutableInteractionSource;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Landroidx/compose/foundation/gestures/DraggableState;Landroidx/compose/foundation/gestures/Orientation;ZZ)V
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/gestures/DraggableKt$draggable$9;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/DraggableKt;->DraggableState(Lkotlin/jvm/functions/Function1;)Landroidx/compose/foundation/gestures/DraggableState;
+HSPLandroidx/compose/foundation/gestures/DraggableKt;->access$awaitDownAndSlop(Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;Landroidx/compose/runtime/State;Landroidx/compose/runtime/State;Landroidx/compose/ui/input/pointer/util/VelocityTracker;Landroidx/compose/foundation/gestures/Orientation;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/DraggableKt;->awaitDownAndSlop(Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;Landroidx/compose/runtime/State;Landroidx/compose/runtime/State;Landroidx/compose/ui/input/pointer/util/VelocityTracker;Landroidx/compose/foundation/gestures/Orientation;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/DraggableKt;->draggable$default(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/gestures/DraggableState;Landroidx/compose/foundation/gestures/Orientation;ZLandroidx/compose/foundation/interaction/MutableInteractionSource;ZLkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;ZILjava/lang/Object;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/gestures/DraggableKt;->draggable(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/gestures/DraggableState;Landroidx/compose/foundation/gestures/Orientation;ZLandroidx/compose/foundation/interaction/MutableInteractionSource;ZLkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Z)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/gestures/DraggableKt;->draggable(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/gestures/DraggableState;Lkotlin/jvm/functions/Function1;Landroidx/compose/foundation/gestures/Orientation;ZLandroidx/compose/foundation/interaction/MutableInteractionSource;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Z)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/gestures/DraggableState;->drag$default(Landroidx/compose/foundation/gestures/DraggableState;Landroidx/compose/foundation/MutatePriority;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/ForEachGestureKt$awaitEachGesture$2;-><init>(Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/gestures/ForEachGestureKt$awaitEachGesture$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/foundation/gestures/ForEachGestureKt$awaitEachGesture$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/ForEachGestureKt;->awaitEachGesture(Landroidx/compose/ui/input/pointer/PointerInputScope;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/Orientation;->$values()[Landroidx/compose/foundation/gestures/Orientation;
+HSPLandroidx/compose/foundation/gestures/Orientation;-><clinit>()V
+HSPLandroidx/compose/foundation/gestures/Orientation;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/foundation/gestures/PressGestureScopeImpl$reset$1;-><init>(Landroidx/compose/foundation/gestures/PressGestureScopeImpl;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/gestures/PressGestureScopeImpl;-><init>(Landroidx/compose/ui/unit/Density;)V
+HSPLandroidx/compose/foundation/gestures/PressGestureScopeImpl;->reset(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$NoPressGesture$1;-><init>(Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$awaitFirstDown$2;-><init>(Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$awaitFirstDown$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1$1;-><init>(Landroidx/compose/foundation/gestures/PressGestureScopeImpl;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1;-><init>(Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;Landroidx/compose/foundation/gestures/PressGestureScopeImpl;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1;->invoke(Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2;-><init>(Landroidx/compose/ui/input/pointer/PointerInputScope;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;Landroidx/compose/foundation/gestures/PressGestureScopeImpl;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2;->invoke(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1;-><init>(Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Landroidx/compose/foundation/gestures/PressGestureScopeImpl;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1;->invoke(Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2;-><init>(Landroidx/compose/ui/input/pointer/PointerInputScope;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2;->invoke(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt;-><clinit>()V
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt;->awaitFirstDown$default(Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;ZLandroidx/compose/ui/input/pointer/PointerEventPass;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt;->awaitFirstDown(Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;ZLandroidx/compose/ui/input/pointer/PointerEventPass;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt;->detectTapAndPress(Landroidx/compose/ui/input/pointer/PointerInputScope;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt;->detectTapGestures$default(Landroidx/compose/ui/input/pointer/PointerInputScope;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/gestures/TapGestureDetectorKt;->detectTapGestures(Landroidx/compose/ui/input/pointer/PointerInputScope;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/interaction/InteractionSourceKt;->MutableInteractionSource()Landroidx/compose/foundation/interaction/MutableInteractionSource;
+HSPLandroidx/compose/foundation/interaction/MutableInteractionSourceImpl;-><init>()V
+HSPLandroidx/compose/foundation/interaction/MutableInteractionSourceImpl;->getInteractions()Lkotlinx/coroutines/flow/Flow;
+HSPLandroidx/compose/foundation/interaction/MutableInteractionSourceImpl;->getInteractions()Lkotlinx/coroutines/flow/MutableSharedFlow;
+HSPLandroidx/compose/foundation/interaction/PressInteraction$Press;-><clinit>()V
+HSPLandroidx/compose/foundation/interaction/PressInteraction$Press;-><init>(J)V
+HSPLandroidx/compose/foundation/interaction/PressInteraction$Press;-><init>(JLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/foundation/layout/Arrangement$Bottom$1;-><init>()V
+HSPLandroidx/compose/foundation/layout/Arrangement$Center$1;-><init>()V
+HSPLandroidx/compose/foundation/layout/Arrangement$Center$1;->arrange(Landroidx/compose/ui/unit/Density;I[ILandroidx/compose/ui/unit/LayoutDirection;[I)V
+HSPLandroidx/compose/foundation/layout/Arrangement$Center$1;->getSpacing-D9Ej5fM()F
+HSPLandroidx/compose/foundation/layout/Arrangement$End$1;-><init>()V
+HSPLandroidx/compose/foundation/layout/Arrangement$Horizontal;->getSpacing-D9Ej5fM()F
+HSPLandroidx/compose/foundation/layout/Arrangement$SpaceAround$1;-><init>()V
+HSPLandroidx/compose/foundation/layout/Arrangement$SpaceBetween$1;-><init>()V
+HSPLandroidx/compose/foundation/layout/Arrangement$SpaceBetween$1;->arrange(Landroidx/compose/ui/unit/Density;I[ILandroidx/compose/ui/unit/LayoutDirection;[I)V
+HSPLandroidx/compose/foundation/layout/Arrangement$SpaceBetween$1;->getSpacing-D9Ej5fM()F
+HSPLandroidx/compose/foundation/layout/Arrangement$SpaceEvenly$1;-><init>()V
+HSPLandroidx/compose/foundation/layout/Arrangement$Start$1;-><init>()V
+HSPLandroidx/compose/foundation/layout/Arrangement$Start$1;->arrange(Landroidx/compose/ui/unit/Density;I[ILandroidx/compose/ui/unit/LayoutDirection;[I)V
+HSPLandroidx/compose/foundation/layout/Arrangement$Top$1;-><init>()V
+HSPLandroidx/compose/foundation/layout/Arrangement$Top$1;->arrange(Landroidx/compose/ui/unit/Density;I[I[I)V
+HSPLandroidx/compose/foundation/layout/Arrangement$Vertical;->getSpacing-D9Ej5fM()F
+HSPLandroidx/compose/foundation/layout/Arrangement;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/Arrangement;-><init>()V
+HSPLandroidx/compose/foundation/layout/Arrangement;->getCenter()Landroidx/compose/foundation/layout/Arrangement$HorizontalOrVertical;
+HSPLandroidx/compose/foundation/layout/Arrangement;->getSpaceBetween()Landroidx/compose/foundation/layout/Arrangement$HorizontalOrVertical;
+HSPLandroidx/compose/foundation/layout/Arrangement;->getStart()Landroidx/compose/foundation/layout/Arrangement$Horizontal;
+HSPLandroidx/compose/foundation/layout/Arrangement;->getTop()Landroidx/compose/foundation/layout/Arrangement$Vertical;
+HSPLandroidx/compose/foundation/layout/Arrangement;->placeCenter$foundation_layout_release(I[I[IZ)V
+HSPLandroidx/compose/foundation/layout/Arrangement;->placeLeftOrTop$foundation_layout_release([I[IZ)V
+HSPLandroidx/compose/foundation/layout/Arrangement;->placeSpaceBetween$foundation_layout_release(I[I[IZ)V
+HSPLandroidx/compose/foundation/layout/BoxKt$EmptyBoxMeasurePolicy$1$measure$1;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/BoxKt$EmptyBoxMeasurePolicy$1$measure$1;-><init>()V
+HSPLandroidx/compose/foundation/layout/BoxKt$EmptyBoxMeasurePolicy$1$measure$1;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+HSPLandroidx/compose/foundation/layout/BoxKt$EmptyBoxMeasurePolicy$1$measure$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/layout/BoxKt$EmptyBoxMeasurePolicy$1;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/BoxKt$EmptyBoxMeasurePolicy$1;-><init>()V
+HSPLandroidx/compose/foundation/layout/BoxKt$EmptyBoxMeasurePolicy$1;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Ljava/util/List;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/foundation/layout/BoxKt$boxMeasurePolicy$1$measure$2;-><init>(Landroidx/compose/ui/layout/Placeable;Landroidx/compose/ui/layout/Measurable;Landroidx/compose/ui/layout/MeasureScope;IILandroidx/compose/ui/Alignment;)V
+HSPLandroidx/compose/foundation/layout/BoxKt$boxMeasurePolicy$1$measure$2;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+HSPLandroidx/compose/foundation/layout/BoxKt$boxMeasurePolicy$1$measure$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/layout/BoxKt$boxMeasurePolicy$1$measure$5;-><init>([Landroidx/compose/ui/layout/Placeable;Ljava/util/List;Landroidx/compose/ui/layout/MeasureScope;Lkotlin/jvm/internal/Ref$IntRef;Lkotlin/jvm/internal/Ref$IntRef;Landroidx/compose/ui/Alignment;)V
+HSPLandroidx/compose/foundation/layout/BoxKt$boxMeasurePolicy$1$measure$5;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+HSPLandroidx/compose/foundation/layout/BoxKt$boxMeasurePolicy$1$measure$5;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/layout/BoxKt$boxMeasurePolicy$1;-><init>(ZLandroidx/compose/ui/Alignment;)V
+HSPLandroidx/compose/foundation/layout/BoxKt$boxMeasurePolicy$1;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Ljava/util/List;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/foundation/layout/BoxKt;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/BoxKt;->Box(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/foundation/layout/BoxKt;->access$getMatchesParentSize(Landroidx/compose/ui/layout/Measurable;)Z
+HSPLandroidx/compose/foundation/layout/BoxKt;->access$placeInBox(Landroidx/compose/ui/layout/Placeable$PlacementScope;Landroidx/compose/ui/layout/Placeable;Landroidx/compose/ui/layout/Measurable;Landroidx/compose/ui/unit/LayoutDirection;IILandroidx/compose/ui/Alignment;)V
+HSPLandroidx/compose/foundation/layout/BoxKt;->boxMeasurePolicy(Landroidx/compose/ui/Alignment;Z)Landroidx/compose/ui/layout/MeasurePolicy;
+HSPLandroidx/compose/foundation/layout/BoxKt;->getBoxChildData(Landroidx/compose/ui/layout/Measurable;)Landroidx/compose/foundation/layout/BoxChildData;
+HSPLandroidx/compose/foundation/layout/BoxKt;->getMatchesParentSize(Landroidx/compose/ui/layout/Measurable;)Z
+HSPLandroidx/compose/foundation/layout/BoxKt;->placeInBox(Landroidx/compose/ui/layout/Placeable$PlacementScope;Landroidx/compose/ui/layout/Placeable;Landroidx/compose/ui/layout/Measurable;Landroidx/compose/ui/unit/LayoutDirection;IILandroidx/compose/ui/Alignment;)V
+HSPLandroidx/compose/foundation/layout/BoxKt;->rememberBoxMeasurePolicy(Landroidx/compose/ui/Alignment;ZLandroidx/compose/runtime/Composer;I)Landroidx/compose/ui/layout/MeasurePolicy;
+HSPLandroidx/compose/foundation/layout/BoxScopeInstance;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/BoxScopeInstance;-><init>()V
+HSPLandroidx/compose/foundation/layout/BoxWithConstraintsKt$BoxWithConstraints$1$1$measurables$1;-><init>(Lkotlin/jvm/functions/Function3;Landroidx/compose/foundation/layout/BoxWithConstraintsScopeImpl;I)V
+HSPLandroidx/compose/foundation/layout/BoxWithConstraintsKt$BoxWithConstraints$1$1$measurables$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/foundation/layout/BoxWithConstraintsKt$BoxWithConstraints$1$1$measurables$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/layout/BoxWithConstraintsKt$BoxWithConstraints$1$1;-><init>(Landroidx/compose/ui/layout/MeasurePolicy;Lkotlin/jvm/functions/Function3;I)V
+HSPLandroidx/compose/foundation/layout/BoxWithConstraintsKt$BoxWithConstraints$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/layout/BoxWithConstraintsKt$BoxWithConstraints$1$1;->invoke-0kLqBqw(Landroidx/compose/ui/layout/SubcomposeMeasureScope;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/foundation/layout/BoxWithConstraintsKt;->BoxWithConstraints(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/Alignment;ZLkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V
+HSPLandroidx/compose/foundation/layout/BoxWithConstraintsScopeImpl;-><init>(Landroidx/compose/ui/unit/Density;J)V
+HSPLandroidx/compose/foundation/layout/BoxWithConstraintsScopeImpl;-><init>(Landroidx/compose/ui/unit/Density;JLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/foundation/layout/BoxWithConstraintsScopeImpl;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/foundation/layout/BoxWithConstraintsScopeImpl;->getConstraints-msEJaDk()J
+HSPLandroidx/compose/foundation/layout/ColumnKt$DefaultColumnMeasurePolicy$1;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/ColumnKt$DefaultColumnMeasurePolicy$1;-><init>()V
+HSPLandroidx/compose/foundation/layout/ColumnKt$DefaultColumnMeasurePolicy$1;->invoke(I[ILandroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/ui/unit/Density;[I)V
+HSPLandroidx/compose/foundation/layout/ColumnKt$DefaultColumnMeasurePolicy$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/layout/ColumnKt;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/ColumnKt;->columnMeasurePolicy(Landroidx/compose/foundation/layout/Arrangement$Vertical;Landroidx/compose/ui/Alignment$Horizontal;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/layout/MeasurePolicy;
+HSPLandroidx/compose/foundation/layout/ColumnScopeInstance;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/ColumnScopeInstance;-><init>()V
+HSPLandroidx/compose/foundation/layout/ColumnScopeInstance;->align(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/Alignment$Horizontal;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/layout/CrossAxisAlignment$CenterCrossAxisAlignment;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/CrossAxisAlignment$CenterCrossAxisAlignment;-><init>()V
+HSPLandroidx/compose/foundation/layout/CrossAxisAlignment$Companion;-><init>()V
+HSPLandroidx/compose/foundation/layout/CrossAxisAlignment$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/foundation/layout/CrossAxisAlignment$Companion;->horizontal$foundation_layout_release(Landroidx/compose/ui/Alignment$Horizontal;)Landroidx/compose/foundation/layout/CrossAxisAlignment;
+HSPLandroidx/compose/foundation/layout/CrossAxisAlignment$Companion;->vertical$foundation_layout_release(Landroidx/compose/ui/Alignment$Vertical;)Landroidx/compose/foundation/layout/CrossAxisAlignment;
+HSPLandroidx/compose/foundation/layout/CrossAxisAlignment$EndCrossAxisAlignment;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/CrossAxisAlignment$EndCrossAxisAlignment;-><init>()V
+HSPLandroidx/compose/foundation/layout/CrossAxisAlignment$HorizontalCrossAxisAlignment;-><init>(Landroidx/compose/ui/Alignment$Horizontal;)V
+HSPLandroidx/compose/foundation/layout/CrossAxisAlignment$HorizontalCrossAxisAlignment;->align$foundation_layout_release(ILandroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/ui/layout/Placeable;I)I
+HSPLandroidx/compose/foundation/layout/CrossAxisAlignment$StartCrossAxisAlignment;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/CrossAxisAlignment$StartCrossAxisAlignment;-><init>()V
+HSPLandroidx/compose/foundation/layout/CrossAxisAlignment$VerticalCrossAxisAlignment;-><init>(Landroidx/compose/ui/Alignment$Vertical;)V
+HSPLandroidx/compose/foundation/layout/CrossAxisAlignment$VerticalCrossAxisAlignment;->align$foundation_layout_release(ILandroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/ui/layout/Placeable;I)I
+HSPLandroidx/compose/foundation/layout/CrossAxisAlignment;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/CrossAxisAlignment;-><init>()V
+HSPLandroidx/compose/foundation/layout/CrossAxisAlignment;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/foundation/layout/CrossAxisAlignment;->isRelative$foundation_layout_release()Z
+HSPLandroidx/compose/foundation/layout/Direction;->$values()[Landroidx/compose/foundation/layout/Direction;
+HSPLandroidx/compose/foundation/layout/Direction;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/Direction;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/foundation/layout/FillModifier$measure$1;-><init>(Landroidx/compose/ui/layout/Placeable;)V
+HSPLandroidx/compose/foundation/layout/FillModifier$measure$1;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+HSPLandroidx/compose/foundation/layout/FillModifier$measure$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/layout/FillModifier;-><init>(Landroidx/compose/foundation/layout/Direction;FLkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/foundation/layout/FillModifier;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/foundation/layout/FillModifier;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/foundation/layout/HorizontalAlignModifier;-><init>(Landroidx/compose/ui/Alignment$Horizontal;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/foundation/layout/HorizontalAlignModifier;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/foundation/layout/HorizontalAlignModifier;->modifyParentData(Landroidx/compose/ui/unit/Density;Ljava/lang/Object;)Landroidx/compose/foundation/layout/RowColumnParentData;
+HSPLandroidx/compose/foundation/layout/HorizontalAlignModifier;->modifyParentData(Landroidx/compose/ui/unit/Density;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/layout/LayoutOrientation;->$values()[Landroidx/compose/foundation/layout/LayoutOrientation;
+HSPLandroidx/compose/foundation/layout/LayoutOrientation;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/LayoutOrientation;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/foundation/layout/OffsetKt;->offset(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/layout/OffsetPxModifier$measure$1;-><init>(Landroidx/compose/foundation/layout/OffsetPxModifier;Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Placeable;)V
+HSPLandroidx/compose/foundation/layout/OffsetPxModifier$measure$1;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+HSPLandroidx/compose/foundation/layout/OffsetPxModifier$measure$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/layout/OffsetPxModifier;-><init>(Lkotlin/jvm/functions/Function1;ZLkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/foundation/layout/OffsetPxModifier;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/foundation/layout/OffsetPxModifier;->getOffset()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/foundation/layout/OffsetPxModifier;->getRtlAware()Z
+HSPLandroidx/compose/foundation/layout/OffsetPxModifier;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/foundation/layout/OrientationIndependentConstraints;-><init>(IIII)V
+HSPLandroidx/compose/foundation/layout/OrientationIndependentConstraints;-><init>(JLandroidx/compose/foundation/layout/LayoutOrientation;)V
+HSPLandroidx/compose/foundation/layout/OrientationIndependentConstraints;-><init>(JLandroidx/compose/foundation/layout/LayoutOrientation;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/foundation/layout/OrientationIndependentConstraints;->copy$default(Landroidx/compose/foundation/layout/OrientationIndependentConstraints;IIIIILjava/lang/Object;)Landroidx/compose/foundation/layout/OrientationIndependentConstraints;
+HSPLandroidx/compose/foundation/layout/OrientationIndependentConstraints;->copy(IIII)Landroidx/compose/foundation/layout/OrientationIndependentConstraints;
+HSPLandroidx/compose/foundation/layout/OrientationIndependentConstraints;->getCrossAxisMax()I
+HSPLandroidx/compose/foundation/layout/OrientationIndependentConstraints;->getCrossAxisMin()I
+HSPLandroidx/compose/foundation/layout/OrientationIndependentConstraints;->getMainAxisMax()I
+HSPLandroidx/compose/foundation/layout/OrientationIndependentConstraints;->getMainAxisMin()I
+HSPLandroidx/compose/foundation/layout/OrientationIndependentConstraints;->toBoxConstraints-OenEA2s(Landroidx/compose/foundation/layout/LayoutOrientation;)J
+HSPLandroidx/compose/foundation/layout/PaddingKt;->PaddingValues-YgX7TsA$default(FFILjava/lang/Object;)Landroidx/compose/foundation/layout/PaddingValues;
+HSPLandroidx/compose/foundation/layout/PaddingKt;->PaddingValues-YgX7TsA(FF)Landroidx/compose/foundation/layout/PaddingValues;
+HSPLandroidx/compose/foundation/layout/PaddingKt;->PaddingValues-a9UjIt4(FFFF)Landroidx/compose/foundation/layout/PaddingValues;
+HSPLandroidx/compose/foundation/layout/PaddingKt;->padding(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/layout/PaddingValues;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/layout/PaddingKt;->padding-3ABfNKs(Landroidx/compose/ui/Modifier;F)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/layout/PaddingKt;->padding-VpY3zN4$default(Landroidx/compose/ui/Modifier;FFILjava/lang/Object;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/layout/PaddingKt;->padding-VpY3zN4(Landroidx/compose/ui/Modifier;FF)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/layout/PaddingKt;->padding-qDBjuR0$default(Landroidx/compose/ui/Modifier;FFFFILjava/lang/Object;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/layout/PaddingKt;->padding-qDBjuR0(Landroidx/compose/ui/Modifier;FFFF)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/layout/PaddingModifier$measure$1;-><init>(Landroidx/compose/foundation/layout/PaddingModifier;Landroidx/compose/ui/layout/Placeable;Landroidx/compose/ui/layout/MeasureScope;)V
+HSPLandroidx/compose/foundation/layout/PaddingModifier$measure$1;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+HSPLandroidx/compose/foundation/layout/PaddingModifier$measure$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/layout/PaddingModifier;-><init>(FFFFZLkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/foundation/layout/PaddingModifier;-><init>(FFFFZLkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/foundation/layout/PaddingModifier;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/foundation/layout/PaddingModifier;->getRtlAware()Z
+HSPLandroidx/compose/foundation/layout/PaddingModifier;->getStart-D9Ej5fM()F
+HSPLandroidx/compose/foundation/layout/PaddingModifier;->getTop-D9Ej5fM()F
+HSPLandroidx/compose/foundation/layout/PaddingModifier;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/foundation/layout/PaddingValuesImpl;-><init>(FFFF)V
+HSPLandroidx/compose/foundation/layout/PaddingValuesImpl;-><init>(FFFFLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/foundation/layout/PaddingValuesImpl;->calculateBottomPadding-D9Ej5fM()F
+HSPLandroidx/compose/foundation/layout/PaddingValuesImpl;->calculateLeftPadding-u2uoSUM(Landroidx/compose/ui/unit/LayoutDirection;)F
+HSPLandroidx/compose/foundation/layout/PaddingValuesImpl;->calculateRightPadding-u2uoSUM(Landroidx/compose/ui/unit/LayoutDirection;)F
+HSPLandroidx/compose/foundation/layout/PaddingValuesImpl;->calculateTopPadding-D9Ej5fM()F
+HSPLandroidx/compose/foundation/layout/PaddingValuesImpl;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/foundation/layout/PaddingValuesModifier$measure$2;-><init>(Landroidx/compose/ui/layout/Placeable;Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/foundation/layout/PaddingValuesModifier;)V
+HSPLandroidx/compose/foundation/layout/PaddingValuesModifier$measure$2;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+HSPLandroidx/compose/foundation/layout/PaddingValuesModifier$measure$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/layout/PaddingValuesModifier;-><init>(Landroidx/compose/foundation/layout/PaddingValues;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/foundation/layout/PaddingValuesModifier;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/foundation/layout/PaddingValuesModifier;->getPaddingValues()Landroidx/compose/foundation/layout/PaddingValues;
+HSPLandroidx/compose/foundation/layout/PaddingValuesModifier;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/foundation/layout/RowColumnImplKt$rowColumnMeasurePolicy$1$measure$4;-><init>(Ljava/util/List;[Landroidx/compose/ui/layout/Placeable;Lkotlin/jvm/functions/Function5;ILandroidx/compose/ui/layout/MeasureScope;[ILandroidx/compose/foundation/layout/LayoutOrientation;[Landroidx/compose/foundation/layout/RowColumnParentData;Landroidx/compose/foundation/layout/CrossAxisAlignment;ILkotlin/jvm/internal/Ref$IntRef;)V
+HSPLandroidx/compose/foundation/layout/RowColumnImplKt$rowColumnMeasurePolicy$1$measure$4;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+HSPLandroidx/compose/foundation/layout/RowColumnImplKt$rowColumnMeasurePolicy$1$measure$4;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/layout/RowColumnImplKt$rowColumnMeasurePolicy$1;-><init>(Landroidx/compose/foundation/layout/LayoutOrientation;FLandroidx/compose/foundation/layout/SizeMode;Lkotlin/jvm/functions/Function5;Landroidx/compose/foundation/layout/CrossAxisAlignment;)V
+HSPLandroidx/compose/foundation/layout/RowColumnImplKt$rowColumnMeasurePolicy$1;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Ljava/util/List;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/foundation/layout/RowColumnImplKt;->access$getCrossAxisAlignment(Landroidx/compose/foundation/layout/RowColumnParentData;)Landroidx/compose/foundation/layout/CrossAxisAlignment;
+HSPLandroidx/compose/foundation/layout/RowColumnImplKt;->access$getData(Landroidx/compose/ui/layout/IntrinsicMeasurable;)Landroidx/compose/foundation/layout/RowColumnParentData;
+HSPLandroidx/compose/foundation/layout/RowColumnImplKt;->access$getWeight(Landroidx/compose/foundation/layout/RowColumnParentData;)F
+HSPLandroidx/compose/foundation/layout/RowColumnImplKt;->access$isRelative(Landroidx/compose/foundation/layout/RowColumnParentData;)Z
+HSPLandroidx/compose/foundation/layout/RowColumnImplKt;->access$rowColumnMeasurePolicy_TDGSqEk$crossAxisSize(Landroidx/compose/ui/layout/Placeable;Landroidx/compose/foundation/layout/LayoutOrientation;)I
+HSPLandroidx/compose/foundation/layout/RowColumnImplKt;->access$rowColumnMeasurePolicy_TDGSqEk$mainAxisSize(Landroidx/compose/ui/layout/Placeable;Landroidx/compose/foundation/layout/LayoutOrientation;)I
+HSPLandroidx/compose/foundation/layout/RowColumnImplKt;->getCrossAxisAlignment(Landroidx/compose/foundation/layout/RowColumnParentData;)Landroidx/compose/foundation/layout/CrossAxisAlignment;
+HSPLandroidx/compose/foundation/layout/RowColumnImplKt;->getData(Landroidx/compose/ui/layout/IntrinsicMeasurable;)Landroidx/compose/foundation/layout/RowColumnParentData;
+HSPLandroidx/compose/foundation/layout/RowColumnImplKt;->getWeight(Landroidx/compose/foundation/layout/RowColumnParentData;)F
+HSPLandroidx/compose/foundation/layout/RowColumnImplKt;->isRelative(Landroidx/compose/foundation/layout/RowColumnParentData;)Z
+HSPLandroidx/compose/foundation/layout/RowColumnImplKt;->rowColumnMeasurePolicy-TDGSqEk(Landroidx/compose/foundation/layout/LayoutOrientation;Lkotlin/jvm/functions/Function5;FLandroidx/compose/foundation/layout/SizeMode;Landroidx/compose/foundation/layout/CrossAxisAlignment;)Landroidx/compose/ui/layout/MeasurePolicy;
+HSPLandroidx/compose/foundation/layout/RowColumnImplKt;->rowColumnMeasurePolicy_TDGSqEk$crossAxisSize(Landroidx/compose/ui/layout/Placeable;Landroidx/compose/foundation/layout/LayoutOrientation;)I
+HSPLandroidx/compose/foundation/layout/RowColumnImplKt;->rowColumnMeasurePolicy_TDGSqEk$mainAxisSize(Landroidx/compose/ui/layout/Placeable;Landroidx/compose/foundation/layout/LayoutOrientation;)I
+HSPLandroidx/compose/foundation/layout/RowColumnParentData;-><init>(FZLandroidx/compose/foundation/layout/CrossAxisAlignment;)V
+HSPLandroidx/compose/foundation/layout/RowColumnParentData;-><init>(FZLandroidx/compose/foundation/layout/CrossAxisAlignment;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/foundation/layout/RowColumnParentData;->getCrossAxisAlignment()Landroidx/compose/foundation/layout/CrossAxisAlignment;
+HSPLandroidx/compose/foundation/layout/RowColumnParentData;->getWeight()F
+HSPLandroidx/compose/foundation/layout/RowColumnParentData;->setCrossAxisAlignment(Landroidx/compose/foundation/layout/CrossAxisAlignment;)V
+HSPLandroidx/compose/foundation/layout/RowKt$DefaultRowMeasurePolicy$1;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/RowKt$DefaultRowMeasurePolicy$1;-><init>()V
+HSPLandroidx/compose/foundation/layout/RowKt$rowMeasurePolicy$1$1;-><init>(Landroidx/compose/foundation/layout/Arrangement$Horizontal;)V
+HSPLandroidx/compose/foundation/layout/RowKt$rowMeasurePolicy$1$1;->invoke(I[ILandroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/ui/unit/Density;[I)V
+HSPLandroidx/compose/foundation/layout/RowKt$rowMeasurePolicy$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/layout/RowKt;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/RowKt;->rowMeasurePolicy(Landroidx/compose/foundation/layout/Arrangement$Horizontal;Landroidx/compose/ui/Alignment$Vertical;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/layout/MeasurePolicy;
+HSPLandroidx/compose/foundation/layout/RowScopeInstance;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/RowScopeInstance;-><init>()V
+HSPLandroidx/compose/foundation/layout/SizeKt$createFillHeightModifier$1;-><init>(F)V
+HSPLandroidx/compose/foundation/layout/SizeKt$createFillSizeModifier$1;-><init>(F)V
+HSPLandroidx/compose/foundation/layout/SizeKt$createFillWidthModifier$1;-><init>(F)V
+HSPLandroidx/compose/foundation/layout/SizeKt$createWrapContentHeightModifier$1;-><init>(Landroidx/compose/ui/Alignment$Vertical;)V
+HSPLandroidx/compose/foundation/layout/SizeKt$createWrapContentHeightModifier$2;-><init>(Landroidx/compose/ui/Alignment$Vertical;Z)V
+HSPLandroidx/compose/foundation/layout/SizeKt$createWrapContentSizeModifier$1;-><init>(Landroidx/compose/ui/Alignment;)V
+HSPLandroidx/compose/foundation/layout/SizeKt$createWrapContentSizeModifier$2;-><init>(Landroidx/compose/ui/Alignment;Z)V
+HSPLandroidx/compose/foundation/layout/SizeKt$createWrapContentWidthModifier$1;-><init>(Landroidx/compose/ui/Alignment$Horizontal;)V
+HSPLandroidx/compose/foundation/layout/SizeKt$createWrapContentWidthModifier$2;-><init>(Landroidx/compose/ui/Alignment$Horizontal;Z)V
+HSPLandroidx/compose/foundation/layout/SizeKt;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/SizeKt;->createFillHeightModifier(F)Landroidx/compose/foundation/layout/FillModifier;
+HSPLandroidx/compose/foundation/layout/SizeKt;->createFillSizeModifier(F)Landroidx/compose/foundation/layout/FillModifier;
+HSPLandroidx/compose/foundation/layout/SizeKt;->createFillWidthModifier(F)Landroidx/compose/foundation/layout/FillModifier;
+HSPLandroidx/compose/foundation/layout/SizeKt;->createWrapContentHeightModifier(Landroidx/compose/ui/Alignment$Vertical;Z)Landroidx/compose/foundation/layout/WrapContentModifier;
+HSPLandroidx/compose/foundation/layout/SizeKt;->createWrapContentSizeModifier(Landroidx/compose/ui/Alignment;Z)Landroidx/compose/foundation/layout/WrapContentModifier;
+HSPLandroidx/compose/foundation/layout/SizeKt;->createWrapContentWidthModifier(Landroidx/compose/ui/Alignment$Horizontal;Z)Landroidx/compose/foundation/layout/WrapContentModifier;
+HSPLandroidx/compose/foundation/layout/SizeKt;->defaultMinSize-VpY3zN4$default(Landroidx/compose/ui/Modifier;FFILjava/lang/Object;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/layout/SizeKt;->defaultMinSize-VpY3zN4(Landroidx/compose/ui/Modifier;FF)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/layout/SizeKt;->fillMaxSize$default(Landroidx/compose/ui/Modifier;FILjava/lang/Object;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/layout/SizeKt;->fillMaxSize(Landroidx/compose/ui/Modifier;F)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/layout/SizeKt;->fillMaxWidth$default(Landroidx/compose/ui/Modifier;FILjava/lang/Object;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/layout/SizeKt;->fillMaxWidth(Landroidx/compose/ui/Modifier;F)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/layout/SizeKt;->height-3ABfNKs(Landroidx/compose/ui/Modifier;F)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/layout/SizeKt;->size-3ABfNKs(Landroidx/compose/ui/Modifier;F)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/layout/SizeKt;->width-3ABfNKs(Landroidx/compose/ui/Modifier;F)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/layout/SizeMode;->$values()[Landroidx/compose/foundation/layout/SizeMode;
+HSPLandroidx/compose/foundation/layout/SizeMode;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/SizeMode;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/foundation/layout/SizeModifier$measure$1;-><init>(Landroidx/compose/ui/layout/Placeable;)V
+HSPLandroidx/compose/foundation/layout/SizeModifier$measure$1;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+HSPLandroidx/compose/foundation/layout/SizeModifier$measure$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/layout/SizeModifier;-><init>(FFFFZLkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/foundation/layout/SizeModifier;-><init>(FFFFZLkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/foundation/layout/SizeModifier;-><init>(FFFFZLkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/foundation/layout/SizeModifier;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/foundation/layout/SizeModifier;->getTargetConstraints-OenEA2s(Landroidx/compose/ui/unit/Density;)J
+HSPLandroidx/compose/foundation/layout/SizeModifier;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/foundation/layout/SpacerKt;->Spacer(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/foundation/layout/SpacerMeasurePolicy$measure$1$1;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/SpacerMeasurePolicy$measure$1$1;-><init>()V
+HSPLandroidx/compose/foundation/layout/SpacerMeasurePolicy$measure$1$1;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+HSPLandroidx/compose/foundation/layout/SpacerMeasurePolicy$measure$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/layout/SpacerMeasurePolicy;-><clinit>()V
+HSPLandroidx/compose/foundation/layout/SpacerMeasurePolicy;-><init>()V
+HSPLandroidx/compose/foundation/layout/SpacerMeasurePolicy;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Ljava/util/List;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/foundation/layout/UnspecifiedConstraintsModifier$measure$1;-><init>(Landroidx/compose/ui/layout/Placeable;)V
+HSPLandroidx/compose/foundation/layout/UnspecifiedConstraintsModifier$measure$1;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+HSPLandroidx/compose/foundation/layout/UnspecifiedConstraintsModifier$measure$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/layout/UnspecifiedConstraintsModifier;-><init>(FFLkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/foundation/layout/UnspecifiedConstraintsModifier;-><init>(FFLkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/foundation/layout/UnspecifiedConstraintsModifier;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/foundation/layout/UnspecifiedConstraintsModifier;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/foundation/layout/WrapContentModifier;-><init>(Landroidx/compose/foundation/layout/Direction;ZLkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/foundation/lazy/layout/PinnableParentKt$ModifierLocalPinnableParent$1;-><clinit>()V
+HSPLandroidx/compose/foundation/lazy/layout/PinnableParentKt$ModifierLocalPinnableParent$1;-><init>()V
+HSPLandroidx/compose/foundation/lazy/layout/PinnableParentKt$ModifierLocalPinnableParent$1;->invoke()Landroidx/compose/foundation/lazy/layout/PinnableParent;
+HSPLandroidx/compose/foundation/lazy/layout/PinnableParentKt$ModifierLocalPinnableParent$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/foundation/lazy/layout/PinnableParentKt;-><clinit>()V
+HSPLandroidx/compose/foundation/lazy/layout/PinnableParentKt;->getModifierLocalPinnableParent()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/foundation/relocation/AndroidBringIntoViewParent;-><init>(Landroid/view/View;)V
+HSPLandroidx/compose/foundation/relocation/BringIntoViewChildModifier;-><init>(Landroidx/compose/foundation/relocation/BringIntoViewParent;)V
+HSPLandroidx/compose/foundation/relocation/BringIntoViewChildModifier;->onModifierLocalsUpdated(Landroidx/compose/ui/modifier/ModifierLocalReadScope;)V
+HSPLandroidx/compose/foundation/relocation/BringIntoViewChildModifier;->onPlaced(Landroidx/compose/ui/layout/LayoutCoordinates;)V
+HSPLandroidx/compose/foundation/relocation/BringIntoViewKt$ModifierLocalBringIntoViewParent$1;-><clinit>()V
+HSPLandroidx/compose/foundation/relocation/BringIntoViewKt$ModifierLocalBringIntoViewParent$1;-><init>()V
+HSPLandroidx/compose/foundation/relocation/BringIntoViewKt$ModifierLocalBringIntoViewParent$1;->invoke()Landroidx/compose/foundation/relocation/BringIntoViewParent;
+HSPLandroidx/compose/foundation/relocation/BringIntoViewKt$ModifierLocalBringIntoViewParent$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/foundation/relocation/BringIntoViewKt;-><clinit>()V
+HSPLandroidx/compose/foundation/relocation/BringIntoViewKt;->getModifierLocalBringIntoViewParent()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/foundation/relocation/BringIntoViewRequesterImpl;-><init>()V
+HSPLandroidx/compose/foundation/relocation/BringIntoViewRequesterImpl;->getModifiers()Landroidx/compose/runtime/collection/MutableVector;
+HSPLandroidx/compose/foundation/relocation/BringIntoViewRequesterKt$bringIntoViewRequester$2$1$invoke$$inlined$onDispose$1;-><init>(Landroidx/compose/foundation/relocation/BringIntoViewRequester;Landroidx/compose/foundation/relocation/BringIntoViewRequesterModifier;)V
+HSPLandroidx/compose/foundation/relocation/BringIntoViewRequesterKt$bringIntoViewRequester$2$1;-><init>(Landroidx/compose/foundation/relocation/BringIntoViewRequester;Landroidx/compose/foundation/relocation/BringIntoViewRequesterModifier;)V
+HSPLandroidx/compose/foundation/relocation/BringIntoViewRequesterKt$bringIntoViewRequester$2$1;->invoke(Landroidx/compose/runtime/DisposableEffectScope;)Landroidx/compose/runtime/DisposableEffectResult;
+HSPLandroidx/compose/foundation/relocation/BringIntoViewRequesterKt$bringIntoViewRequester$2$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/relocation/BringIntoViewRequesterKt$bringIntoViewRequester$2;-><init>(Landroidx/compose/foundation/relocation/BringIntoViewRequester;)V
+HSPLandroidx/compose/foundation/relocation/BringIntoViewRequesterKt$bringIntoViewRequester$2;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/relocation/BringIntoViewRequesterKt$bringIntoViewRequester$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/relocation/BringIntoViewRequesterKt;->BringIntoViewRequester()Landroidx/compose/foundation/relocation/BringIntoViewRequester;
+HSPLandroidx/compose/foundation/relocation/BringIntoViewRequesterKt;->bringIntoViewRequester(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/relocation/BringIntoViewRequester;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/relocation/BringIntoViewRequesterModifier;-><init>(Landroidx/compose/foundation/relocation/BringIntoViewParent;)V
+HSPLandroidx/compose/foundation/relocation/BringIntoViewResponder_androidKt;->rememberDefaultBringIntoViewParent(Landroidx/compose/runtime/Composer;I)Landroidx/compose/foundation/relocation/BringIntoViewParent;
+HSPLandroidx/compose/foundation/shape/CornerBasedShape;-><clinit>()V
+HSPLandroidx/compose/foundation/shape/CornerBasedShape;-><init>(Landroidx/compose/foundation/shape/CornerSize;Landroidx/compose/foundation/shape/CornerSize;Landroidx/compose/foundation/shape/CornerSize;Landroidx/compose/foundation/shape/CornerSize;)V
+HSPLandroidx/compose/foundation/shape/CornerBasedShape;->createOutline-Pq9zytI(JLandroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/ui/unit/Density;)Landroidx/compose/ui/graphics/Outline;
+HSPLandroidx/compose/foundation/shape/CornerSizeKt$ZeroCornerSize$1;-><init>()V
+HSPLandroidx/compose/foundation/shape/CornerSizeKt;-><clinit>()V
+HSPLandroidx/compose/foundation/shape/CornerSizeKt;->CornerSize(I)Landroidx/compose/foundation/shape/CornerSize;
+HSPLandroidx/compose/foundation/shape/CornerSizeKt;->CornerSize-0680j_4(F)Landroidx/compose/foundation/shape/CornerSize;
+HSPLandroidx/compose/foundation/shape/DpCornerSize;-><init>(F)V
+HSPLandroidx/compose/foundation/shape/DpCornerSize;-><init>(FLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/foundation/shape/DpCornerSize;->toPx-TmRCtEA(JLandroidx/compose/ui/unit/Density;)F
+HSPLandroidx/compose/foundation/shape/PercentCornerSize;-><init>(F)V
+HSPLandroidx/compose/foundation/shape/PercentCornerSize;->toPx-TmRCtEA(JLandroidx/compose/ui/unit/Density;)F
+HSPLandroidx/compose/foundation/shape/RoundedCornerShape;-><clinit>()V
+HSPLandroidx/compose/foundation/shape/RoundedCornerShape;-><init>(Landroidx/compose/foundation/shape/CornerSize;Landroidx/compose/foundation/shape/CornerSize;Landroidx/compose/foundation/shape/CornerSize;Landroidx/compose/foundation/shape/CornerSize;)V
+HSPLandroidx/compose/foundation/shape/RoundedCornerShape;->createOutline-LjSzlW0(JFFFFLandroidx/compose/ui/unit/LayoutDirection;)Landroidx/compose/ui/graphics/Outline;
+HSPLandroidx/compose/foundation/shape/RoundedCornerShape;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/foundation/shape/RoundedCornerShapeKt;-><clinit>()V
+HSPLandroidx/compose/foundation/shape/RoundedCornerShapeKt;->RoundedCornerShape(I)Landroidx/compose/foundation/shape/RoundedCornerShape;
+HSPLandroidx/compose/foundation/shape/RoundedCornerShapeKt;->RoundedCornerShape(Landroidx/compose/foundation/shape/CornerSize;)Landroidx/compose/foundation/shape/RoundedCornerShape;
+HSPLandroidx/compose/foundation/shape/RoundedCornerShapeKt;->RoundedCornerShape-0680j_4(F)Landroidx/compose/foundation/shape/RoundedCornerShape;
+HSPLandroidx/compose/foundation/shape/RoundedCornerShapeKt;->RoundedCornerShape-a9UjIt4(FFFF)Landroidx/compose/foundation/shape/RoundedCornerShape;
+HSPLandroidx/compose/foundation/shape/RoundedCornerShapeKt;->getCircleShape()Landroidx/compose/foundation/shape/RoundedCornerShape;
+HSPLandroidx/compose/foundation/text/BasicTextKt$BasicText-4YKlhWE$$inlined$Layout$1;-><init>(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/foundation/text/BasicTextKt$BasicText-4YKlhWE$$inlined$Layout$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/foundation/text/BasicTextKt;->BasicText-4YKlhWE(Ljava/lang/String;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/text/TextStyle;Lkotlin/jvm/functions/Function1;IZIILandroidx/compose/runtime/Composer;II)V
+HSPLandroidx/compose/foundation/text/CoreTextKt;-><clinit>()V
+HSPLandroidx/compose/foundation/text/CoreTextKt;->updateTextDelegate-x_uQXYA(Landroidx/compose/foundation/text/TextDelegate;Ljava/lang/String;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;ZIII)Landroidx/compose/foundation/text/TextDelegate;
+HSPLandroidx/compose/foundation/text/HeightInLinesModifierKt$heightInLines$2;-><init>(IILandroidx/compose/ui/text/TextStyle;)V
+HSPLandroidx/compose/foundation/text/HeightInLinesModifierKt$heightInLines$2;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/text/HeightInLinesModifierKt$heightInLines$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/text/HeightInLinesModifierKt;->heightInLines$default(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/text/TextStyle;IIILjava/lang/Object;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/text/HeightInLinesModifierKt;->heightInLines(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/text/TextStyle;II)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/text/HeightInLinesModifierKt;->validateMinMaxLines(II)V
+HSPLandroidx/compose/foundation/text/TextController$coreModifiers$1;-><init>(Landroidx/compose/foundation/text/TextController;)V
+HSPLandroidx/compose/foundation/text/TextController$coreModifiers$1;->invoke(Landroidx/compose/ui/layout/LayoutCoordinates;)V
+HSPLandroidx/compose/foundation/text/TextController$coreModifiers$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/text/TextController$createSemanticsModifierFor$1$1;-><init>(Landroidx/compose/foundation/text/TextController;)V
+HSPLandroidx/compose/foundation/text/TextController$createSemanticsModifierFor$1;-><init>(Landroidx/compose/ui/text/AnnotatedString;Landroidx/compose/foundation/text/TextController;)V
+HSPLandroidx/compose/foundation/text/TextController$createSemanticsModifierFor$1;->invoke(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;)V
+HSPLandroidx/compose/foundation/text/TextController$createSemanticsModifierFor$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/text/TextController$drawTextAndSelectionBehind$1;-><init>(Landroidx/compose/foundation/text/TextController;)V
+HSPLandroidx/compose/foundation/text/TextController$drawTextAndSelectionBehind$1;->invoke(Landroidx/compose/ui/graphics/drawscope/DrawScope;)V
+HSPLandroidx/compose/foundation/text/TextController$drawTextAndSelectionBehind$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/text/TextController$measurePolicy$1$measure$2;-><init>(Ljava/util/List;)V
+HSPLandroidx/compose/foundation/text/TextController$measurePolicy$1$measure$2;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+HSPLandroidx/compose/foundation/text/TextController$measurePolicy$1$measure$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/foundation/text/TextController$measurePolicy$1;-><init>(Landroidx/compose/foundation/text/TextController;)V
+HSPLandroidx/compose/foundation/text/TextController$measurePolicy$1;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Ljava/util/List;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/foundation/text/TextController;-><init>(Landroidx/compose/foundation/text/TextState;)V
+HSPLandroidx/compose/foundation/text/TextController;->access$getSelectionRegistrar$p(Landroidx/compose/foundation/text/TextController;)Landroidx/compose/foundation/text/selection/SelectionRegistrar;
+HSPLandroidx/compose/foundation/text/TextController;->createSemanticsModifierFor(Landroidx/compose/ui/text/AnnotatedString;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/text/TextController;->drawTextAndSelectionBehind(Landroidx/compose/ui/Modifier;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/text/TextController;->getMeasurePolicy()Landroidx/compose/ui/layout/MeasurePolicy;
+HSPLandroidx/compose/foundation/text/TextController;->getModifiers()Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/foundation/text/TextController;->getState()Landroidx/compose/foundation/text/TextState;
+HSPLandroidx/compose/foundation/text/TextController;->onRemembered()V
+HSPLandroidx/compose/foundation/text/TextController;->setTextDelegate(Landroidx/compose/foundation/text/TextDelegate;)V
+HSPLandroidx/compose/foundation/text/TextController;->update(Landroidx/compose/foundation/text/selection/SelectionRegistrar;)V
+HSPLandroidx/compose/foundation/text/TextDelegate$Companion;-><init>()V
+HSPLandroidx/compose/foundation/text/TextDelegate$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/foundation/text/TextDelegate$Companion;->paint(Landroidx/compose/ui/graphics/Canvas;Landroidx/compose/ui/text/TextLayoutResult;)V
+HSPLandroidx/compose/foundation/text/TextDelegate;-><clinit>()V
+HSPLandroidx/compose/foundation/text/TextDelegate;-><init>(Landroidx/compose/ui/text/AnnotatedString;Landroidx/compose/ui/text/TextStyle;IIZILandroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;Ljava/util/List;)V
+HSPLandroidx/compose/foundation/text/TextDelegate;-><init>(Landroidx/compose/ui/text/AnnotatedString;Landroidx/compose/ui/text/TextStyle;IIZILandroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/foundation/text/TextDelegate;-><init>(Landroidx/compose/ui/text/AnnotatedString;Landroidx/compose/ui/text/TextStyle;IIZILandroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/foundation/text/TextDelegate;->getDensity()Landroidx/compose/ui/unit/Density;
+HSPLandroidx/compose/foundation/text/TextDelegate;->getFontFamilyResolver()Landroidx/compose/ui/text/font/FontFamily$Resolver;
+HSPLandroidx/compose/foundation/text/TextDelegate;->getMaxIntrinsicWidth()I
+HSPLandroidx/compose/foundation/text/TextDelegate;->getMaxLines()I
+HSPLandroidx/compose/foundation/text/TextDelegate;->getMinLines()I
+HSPLandroidx/compose/foundation/text/TextDelegate;->getNonNullIntrinsics()Landroidx/compose/ui/text/MultiParagraphIntrinsics;
+HSPLandroidx/compose/foundation/text/TextDelegate;->getOverflow-gIe3tQ8()I
+HSPLandroidx/compose/foundation/text/TextDelegate;->getSoftWrap()Z
+HSPLandroidx/compose/foundation/text/TextDelegate;->getStyle()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/foundation/text/TextDelegate;->getText()Landroidx/compose/ui/text/AnnotatedString;
+HSPLandroidx/compose/foundation/text/TextDelegate;->layout-NN6Ew-U(JLandroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/ui/text/TextLayoutResult;)Landroidx/compose/ui/text/TextLayoutResult;
+HSPLandroidx/compose/foundation/text/TextDelegate;->layoutIntrinsics(Landroidx/compose/ui/unit/LayoutDirection;)V
+HSPLandroidx/compose/foundation/text/TextDelegate;->layoutText-K40F9xA(JLandroidx/compose/ui/unit/LayoutDirection;)Landroidx/compose/ui/text/MultiParagraph;
+HSPLandroidx/compose/foundation/text/TextDelegateKt;->ceilToIntPx(F)I
+HSPLandroidx/compose/foundation/text/TextLayoutHelperKt;->canReuse-7_7YC6M(Landroidx/compose/ui/text/TextLayoutResult;Landroidx/compose/ui/text/AnnotatedString;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;IZILandroidx/compose/ui/unit/Density;Landroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/ui/text/font/FontFamily$Resolver;J)Z
+HSPLandroidx/compose/foundation/text/TextState$onTextLayout$1;-><clinit>()V
+HSPLandroidx/compose/foundation/text/TextState$onTextLayout$1;-><init>()V
+HSPLandroidx/compose/foundation/text/TextState;-><init>(Landroidx/compose/foundation/text/TextDelegate;J)V
+HSPLandroidx/compose/foundation/text/TextState;->getDrawScopeInvalidation()Lkotlin/Unit;
+HSPLandroidx/compose/foundation/text/TextState;->getLayoutInvalidation()Lkotlin/Unit;
+HSPLandroidx/compose/foundation/text/TextState;->getLayoutResult()Landroidx/compose/ui/text/TextLayoutResult;
+HSPLandroidx/compose/foundation/text/TextState;->getOnTextLayout()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/foundation/text/TextState;->getSelectableId()J
+HSPLandroidx/compose/foundation/text/TextState;->getTextDelegate()Landroidx/compose/foundation/text/TextDelegate;
+HSPLandroidx/compose/foundation/text/TextState;->setDrawScopeInvalidation(Lkotlin/Unit;)V
+HSPLandroidx/compose/foundation/text/TextState;->setLayoutCoordinates(Landroidx/compose/ui/layout/LayoutCoordinates;)V
+HSPLandroidx/compose/foundation/text/TextState;->setLayoutResult(Landroidx/compose/ui/text/TextLayoutResult;)V
+HSPLandroidx/compose/foundation/text/TextState;->setOnTextLayout(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/foundation/text/selection/SelectionRegistrarKt$LocalSelectionRegistrar$1;-><clinit>()V
+HSPLandroidx/compose/foundation/text/selection/SelectionRegistrarKt$LocalSelectionRegistrar$1;-><init>()V
+HSPLandroidx/compose/foundation/text/selection/SelectionRegistrarKt$LocalSelectionRegistrar$1;->invoke()Landroidx/compose/foundation/text/selection/SelectionRegistrar;
+HSPLandroidx/compose/foundation/text/selection/SelectionRegistrarKt$LocalSelectionRegistrar$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/foundation/text/selection/SelectionRegistrarKt;-><clinit>()V
+HSPLandroidx/compose/foundation/text/selection/SelectionRegistrarKt;->getLocalSelectionRegistrar()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/foundation/text/selection/SelectionRegistrarKt;->hasSelection(Landroidx/compose/foundation/text/selection/SelectionRegistrar;J)Z
+HSPLandroidx/compose/foundation/text/selection/TextSelectionColors;-><init>(JJ)V
+HSPLandroidx/compose/foundation/text/selection/TextSelectionColors;-><init>(JJLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/foundation/text/selection/TextSelectionColors;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/foundation/text/selection/TextSelectionColorsKt$LocalTextSelectionColors$1;-><clinit>()V
+HSPLandroidx/compose/foundation/text/selection/TextSelectionColorsKt$LocalTextSelectionColors$1;-><init>()V
+HSPLandroidx/compose/foundation/text/selection/TextSelectionColorsKt;-><clinit>()V
+HSPLandroidx/compose/foundation/text/selection/TextSelectionColorsKt;->getLocalTextSelectionColors()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/material/ripple/AndroidRippleIndicationInstance$onInvalidateRipple$1;-><init>(Landroidx/compose/material/ripple/AndroidRippleIndicationInstance;)V
+HSPLandroidx/compose/material/ripple/AndroidRippleIndicationInstance;-><init>(ZFLandroidx/compose/runtime/State;Landroidx/compose/runtime/State;Landroidx/compose/material/ripple/RippleContainer;)V
+HSPLandroidx/compose/material/ripple/AndroidRippleIndicationInstance;-><init>(ZFLandroidx/compose/runtime/State;Landroidx/compose/runtime/State;Landroidx/compose/material/ripple/RippleContainer;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/material/ripple/AndroidRippleIndicationInstance;->drawIndication(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;)V
+HSPLandroidx/compose/material/ripple/AndroidRippleIndicationInstance;->getInvalidateTick()Z
+HSPLandroidx/compose/material/ripple/AndroidRippleIndicationInstance;->getRippleHostView()Landroidx/compose/material/ripple/RippleHostView;
+HSPLandroidx/compose/material/ripple/AndroidRippleIndicationInstance;->onRemembered()V
+HSPLandroidx/compose/material/ripple/PlatformRipple;-><init>(ZFLandroidx/compose/runtime/State;)V
+HSPLandroidx/compose/material/ripple/PlatformRipple;-><init>(ZFLandroidx/compose/runtime/State;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/material/ripple/PlatformRipple;->findNearestViewGroup(Landroidx/compose/runtime/Composer;I)Landroid/view/ViewGroup;
+HSPLandroidx/compose/material/ripple/PlatformRipple;->rememberUpdatedRippleInstance-942rkJo(Landroidx/compose/foundation/interaction/InteractionSource;ZFLandroidx/compose/runtime/State;Landroidx/compose/runtime/State;Landroidx/compose/runtime/Composer;I)Landroidx/compose/material/ripple/RippleIndicationInstance;
+HSPLandroidx/compose/material/ripple/Ripple$rememberUpdatedInstance$1$1;-><init>(Landroidx/compose/material/ripple/RippleIndicationInstance;Lkotlinx/coroutines/CoroutineScope;)V
+HSPLandroidx/compose/material/ripple/Ripple$rememberUpdatedInstance$1;-><init>(Landroidx/compose/foundation/interaction/InteractionSource;Landroidx/compose/material/ripple/RippleIndicationInstance;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/material/ripple/Ripple$rememberUpdatedInstance$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/material/ripple/Ripple$rememberUpdatedInstance$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material/ripple/Ripple;-><init>(ZFLandroidx/compose/runtime/State;)V
+HSPLandroidx/compose/material/ripple/Ripple;-><init>(ZFLandroidx/compose/runtime/State;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/material/ripple/Ripple;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/material/ripple/Ripple;->rememberUpdatedInstance(Landroidx/compose/foundation/interaction/InteractionSource;Landroidx/compose/runtime/Composer;I)Landroidx/compose/foundation/IndicationInstance;
+HSPLandroidx/compose/material/ripple/RippleAlpha;-><init>(FFFF)V
+HSPLandroidx/compose/material/ripple/RippleAlpha;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/material/ripple/RippleAlpha;->getPressedAlpha()F
+HSPLandroidx/compose/material/ripple/RippleAnimationKt;-><clinit>()V
+HSPLandroidx/compose/material/ripple/RippleAnimationKt;->getRippleEndRadius-cSwnlzA(Landroidx/compose/ui/unit/Density;ZJ)F
+HSPLandroidx/compose/material/ripple/RippleContainer;-><init>(Landroid/content/Context;)V
+HSPLandroidx/compose/material/ripple/RippleHostMap;-><init>()V
+HSPLandroidx/compose/material/ripple/RippleHostView$Companion;-><init>()V
+HSPLandroidx/compose/material/ripple/RippleHostView$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/material/ripple/RippleHostView;-><clinit>()V
+HSPLandroidx/compose/material/ripple/RippleHostView;-><init>(Landroid/content/Context;)V
+HSPLandroidx/compose/material/ripple/RippleHostView;->refreshDrawableState()V
+HSPLandroidx/compose/material/ripple/RippleIndicationInstance;-><init>(ZLandroidx/compose/runtime/State;)V
+HSPLandroidx/compose/material/ripple/RippleIndicationInstance;->drawStateLayer-H2RKhps(Landroidx/compose/ui/graphics/drawscope/DrawScope;FJ)V
+HSPLandroidx/compose/material/ripple/RippleKt;-><clinit>()V
+HSPLandroidx/compose/material/ripple/RippleKt;->rememberRipple-9IZ8Weo(ZFJLandroidx/compose/runtime/Composer;II)Landroidx/compose/foundation/Indication;
+HSPLandroidx/compose/material/ripple/RippleThemeKt$LocalRippleTheme$1;-><clinit>()V
+HSPLandroidx/compose/material/ripple/RippleThemeKt$LocalRippleTheme$1;-><init>()V
+HSPLandroidx/compose/material/ripple/RippleThemeKt;-><clinit>()V
+HSPLandroidx/compose/material/ripple/RippleThemeKt;->getLocalRippleTheme()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/material/ripple/StateLayer;-><init>(ZLandroidx/compose/runtime/State;)V
+HSPLandroidx/compose/material/ripple/StateLayer;->drawStateLayer-H2RKhps(Landroidx/compose/ui/graphics/drawscope/DrawScope;FJ)V
+HSPLandroidx/compose/material3/ButtonColors;-><init>(JJJJ)V
+HSPLandroidx/compose/material3/ButtonColors;-><init>(JJJJLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/material3/ButtonColors;->containerColor$material3_release(ZLandroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/material3/ButtonColors;->contentColor$material3_release(ZLandroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/material3/ButtonColors;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/material3/ButtonDefaults;-><clinit>()V
+HSPLandroidx/compose/material3/ButtonDefaults;-><init>()V
+HSPLandroidx/compose/material3/ButtonDefaults;->filledTonalButtonColors-ro_MJ88(JJJJLandroidx/compose/runtime/Composer;II)Landroidx/compose/material3/ButtonColors;
+HSPLandroidx/compose/material3/ButtonDefaults;->filledTonalButtonElevation-R_JCAzs(FFFFFLandroidx/compose/runtime/Composer;II)Landroidx/compose/material3/ButtonElevation;
+HSPLandroidx/compose/material3/ButtonDefaults;->getContentPadding()Landroidx/compose/foundation/layout/PaddingValues;
+HSPLandroidx/compose/material3/ButtonDefaults;->getFilledTonalShape(Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/graphics/Shape;
+HSPLandroidx/compose/material3/ButtonDefaults;->getMinHeight-D9Ej5fM()F
+HSPLandroidx/compose/material3/ButtonDefaults;->getMinWidth-D9Ej5fM()F
+HSPLandroidx/compose/material3/ButtonDefaults;->getTextButtonContentPadding()Landroidx/compose/foundation/layout/PaddingValues;
+HSPLandroidx/compose/material3/ButtonDefaults;->getTextShape(Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/graphics/Shape;
+HSPLandroidx/compose/material3/ButtonDefaults;->textButtonColors-ro_MJ88(JJJJLandroidx/compose/runtime/Composer;II)Landroidx/compose/material3/ButtonColors;
+HSPLandroidx/compose/material3/ButtonElevation$animateElevation$1$1$1;-><init>(Landroidx/compose/runtime/snapshots/SnapshotStateList;)V
+HSPLandroidx/compose/material3/ButtonElevation$animateElevation$1$1;-><init>(Landroidx/compose/foundation/interaction/InteractionSource;Landroidx/compose/runtime/snapshots/SnapshotStateList;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/material3/ButtonElevation$animateElevation$1$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/material3/ButtonElevation$animateElevation$1$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/ButtonElevation$animateElevation$3;-><init>(Landroidx/compose/animation/core/Animatable;Landroidx/compose/material3/ButtonElevation;FLandroidx/compose/foundation/interaction/Interaction;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/material3/ButtonElevation$animateElevation$3;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/material3/ButtonElevation$animateElevation$3;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/ButtonElevation;-><init>(FFFFF)V
+HSPLandroidx/compose/material3/ButtonElevation;-><init>(FFFFFLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/material3/ButtonElevation;->access$getPressedElevation$p(Landroidx/compose/material3/ButtonElevation;)F
+HSPLandroidx/compose/material3/ButtonElevation;->animateElevation(ZLandroidx/compose/foundation/interaction/InteractionSource;Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/material3/ButtonElevation;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/material3/ButtonElevation;->shadowElevation$material3_release(ZLandroidx/compose/foundation/interaction/InteractionSource;Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/material3/ButtonElevation;->tonalElevation$material3_release(ZLandroidx/compose/foundation/interaction/InteractionSource;Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/material3/ButtonKt$Button$2$1$1;-><init>(Landroidx/compose/foundation/layout/PaddingValues;Lkotlin/jvm/functions/Function3;I)V
+HSPLandroidx/compose/material3/ButtonKt$Button$2$1$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/material3/ButtonKt$Button$2$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/ButtonKt$Button$2$1;-><init>(Landroidx/compose/foundation/layout/PaddingValues;Lkotlin/jvm/functions/Function3;I)V
+HSPLandroidx/compose/material3/ButtonKt$Button$2$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/material3/ButtonKt$Button$2$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/ButtonKt$Button$2;-><init>(JLandroidx/compose/foundation/layout/PaddingValues;Lkotlin/jvm/functions/Function3;I)V
+HSPLandroidx/compose/material3/ButtonKt$Button$2;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/material3/ButtonKt$Button$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/ButtonKt$Button$3;-><init>(Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/Modifier;ZLandroidx/compose/ui/graphics/Shape;Landroidx/compose/material3/ButtonColors;Landroidx/compose/material3/ButtonElevation;Landroidx/compose/foundation/BorderStroke;Landroidx/compose/foundation/layout/PaddingValues;Landroidx/compose/foundation/interaction/MutableInteractionSource;Lkotlin/jvm/functions/Function3;II)V
+HSPLandroidx/compose/material3/ButtonKt;->Button(Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/Modifier;ZLandroidx/compose/ui/graphics/Shape;Landroidx/compose/material3/ButtonColors;Landroidx/compose/material3/ButtonElevation;Landroidx/compose/foundation/BorderStroke;Landroidx/compose/foundation/layout/PaddingValues;Landroidx/compose/foundation/interaction/MutableInteractionSource;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V
+HSPLandroidx/compose/material3/ButtonKt;->FilledTonalButton(Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/Modifier;ZLandroidx/compose/ui/graphics/Shape;Landroidx/compose/material3/ButtonColors;Landroidx/compose/material3/ButtonElevation;Landroidx/compose/foundation/BorderStroke;Landroidx/compose/foundation/layout/PaddingValues;Landroidx/compose/foundation/interaction/MutableInteractionSource;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V
+HSPLandroidx/compose/material3/ButtonKt;->TextButton(Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/Modifier;ZLandroidx/compose/ui/graphics/Shape;Landroidx/compose/material3/ButtonColors;Landroidx/compose/material3/ButtonElevation;Landroidx/compose/foundation/BorderStroke;Landroidx/compose/foundation/layout/PaddingValues;Landroidx/compose/foundation/interaction/MutableInteractionSource;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V
+HSPLandroidx/compose/material3/CardColors;-><init>(JJJJ)V
+HSPLandroidx/compose/material3/CardColors;-><init>(JJJJLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/material3/CardColors;->containerColor$material3_release(ZLandroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/material3/CardColors;->contentColor$material3_release(ZLandroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/material3/CardColors;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/material3/CardDefaults;-><clinit>()V
+HSPLandroidx/compose/material3/CardDefaults;-><init>()V
+HSPLandroidx/compose/material3/CardDefaults;->cardColors-ro_MJ88(JJJJLandroidx/compose/runtime/Composer;II)Landroidx/compose/material3/CardColors;
+HSPLandroidx/compose/material3/CardDefaults;->cardElevation-aqJV_2Y(FFFFFFLandroidx/compose/runtime/Composer;II)Landroidx/compose/material3/CardElevation;
+HSPLandroidx/compose/material3/CardDefaults;->getShape(Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/graphics/Shape;
+HSPLandroidx/compose/material3/CardElevation;-><init>(FFFFFF)V
+HSPLandroidx/compose/material3/CardElevation;-><init>(FFFFFFLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/material3/CardElevation;->access$getDefaultElevation$p(Landroidx/compose/material3/CardElevation;)F
+HSPLandroidx/compose/material3/CardElevation;->shadowElevation$material3_release(ZLandroidx/compose/foundation/interaction/InteractionSource;Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/material3/CardElevation;->tonalElevation$material3_release(ZLandroidx/compose/foundation/interaction/InteractionSource;Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/material3/CardKt$Card$1;-><init>(Lkotlin/jvm/functions/Function3;I)V
+HSPLandroidx/compose/material3/CardKt$Card$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/material3/CardKt$Card$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/CardKt$Card$2;-><init>(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/graphics/Shape;Landroidx/compose/material3/CardColors;Landroidx/compose/material3/CardElevation;Landroidx/compose/foundation/BorderStroke;Lkotlin/jvm/functions/Function3;II)V
+HSPLandroidx/compose/material3/CardKt;->Card(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/graphics/Shape;Landroidx/compose/material3/CardColors;Landroidx/compose/material3/CardElevation;Landroidx/compose/foundation/BorderStroke;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V
+HSPLandroidx/compose/material3/ChipColors;-><init>(JJJJJJJJ)V
+HSPLandroidx/compose/material3/ChipColors;-><init>(JJJJJJJJLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/material3/ChipColors;->containerColor$material3_release(ZLandroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/material3/ChipColors;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/material3/ChipColors;->labelColor$material3_release(ZLandroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/material3/ChipColors;->leadingIconContentColor$material3_release(ZLandroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/material3/ChipColors;->trailingIconContentColor$material3_release(ZLandroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/material3/ChipElevation$animateElevation$1$1$1;-><init>(Landroidx/compose/runtime/snapshots/SnapshotStateList;)V
+HSPLandroidx/compose/material3/ChipElevation$animateElevation$1$1;-><init>(Landroidx/compose/foundation/interaction/InteractionSource;Landroidx/compose/runtime/snapshots/SnapshotStateList;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/material3/ChipElevation$animateElevation$1$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/material3/ChipElevation$animateElevation$1$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/ChipElevation$animateElevation$3;-><init>(Landroidx/compose/animation/core/Animatable;Landroidx/compose/material3/ChipElevation;FLandroidx/compose/foundation/interaction/Interaction;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/material3/ChipElevation$animateElevation$3;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/material3/ChipElevation$animateElevation$3;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/ChipElevation;-><init>(FFFFFF)V
+HSPLandroidx/compose/material3/ChipElevation;-><init>(FFFFFFLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/material3/ChipElevation;->access$getPressedElevation$p(Landroidx/compose/material3/ChipElevation;)F
+HSPLandroidx/compose/material3/ChipElevation;->animateElevation(ZLandroidx/compose/foundation/interaction/InteractionSource;Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/material3/ChipElevation;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/material3/ChipElevation;->shadowElevation$material3_release(ZLandroidx/compose/foundation/interaction/InteractionSource;Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/material3/ChipElevation;->tonalElevation$material3_release(ZLandroidx/compose/foundation/interaction/InteractionSource;Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/material3/ChipKt$Chip$1;-><init>(Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/text/TextStyle;JLkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/material3/ChipColors;ZIFLandroidx/compose/foundation/layout/PaddingValues;I)V
+HSPLandroidx/compose/material3/ChipKt$Chip$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/material3/ChipKt$Chip$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/ChipKt$Chip$2;-><init>(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function0;ZLkotlin/jvm/functions/Function2;Landroidx/compose/ui/text/TextStyle;JLkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/graphics/Shape;Landroidx/compose/material3/ChipColors;Landroidx/compose/material3/ChipElevation;Landroidx/compose/foundation/BorderStroke;FLandroidx/compose/foundation/layout/PaddingValues;Landroidx/compose/foundation/interaction/MutableInteractionSource;II)V
+HSPLandroidx/compose/material3/ChipKt$ChipContent$1;-><init>(FLandroidx/compose/foundation/layout/PaddingValues;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/functions/Function2;JLkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;J)V
+HSPLandroidx/compose/material3/ChipKt$ChipContent$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/material3/ChipKt$ChipContent$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/ChipKt$SuggestionChip$2;-><init>(Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/Modifier;ZLkotlin/jvm/functions/Function2;Landroidx/compose/ui/graphics/Shape;Landroidx/compose/material3/ChipColors;Landroidx/compose/material3/ChipElevation;Landroidx/compose/material3/ChipBorder;Landroidx/compose/foundation/interaction/MutableInteractionSource;II)V
+HSPLandroidx/compose/material3/ChipKt;-><clinit>()V
+HSPLandroidx/compose/material3/ChipKt;->Chip-nkUnTEs(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function0;ZLkotlin/jvm/functions/Function2;Landroidx/compose/ui/text/TextStyle;JLkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/graphics/Shape;Landroidx/compose/material3/ChipColors;Landroidx/compose/material3/ChipElevation;Landroidx/compose/foundation/BorderStroke;FLandroidx/compose/foundation/layout/PaddingValues;Landroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/runtime/Composer;II)V
+HSPLandroidx/compose/material3/ChipKt;->ChipContent-fe0OD_I(Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/text/TextStyle;JLkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;JJFLandroidx/compose/foundation/layout/PaddingValues;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/material3/ChipKt;->SuggestionChip(Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/Modifier;ZLkotlin/jvm/functions/Function2;Landroidx/compose/ui/graphics/Shape;Landroidx/compose/material3/ChipColors;Landroidx/compose/material3/ChipElevation;Landroidx/compose/material3/ChipBorder;Landroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/runtime/Composer;II)V
+HSPLandroidx/compose/material3/ChipKt;->access$ChipContent-fe0OD_I(Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/text/TextStyle;JLkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;JJFLandroidx/compose/foundation/layout/PaddingValues;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/material3/ChipKt;->access$getHorizontalElementsPadding$p()F
+HSPLandroidx/compose/material3/ColorResourceHelper;-><clinit>()V
+HSPLandroidx/compose/material3/ColorResourceHelper;-><init>()V
+HSPLandroidx/compose/material3/ColorResourceHelper;->getColor-WaAFU9c(Landroid/content/Context;I)J
+HSPLandroidx/compose/material3/ColorScheme;-><init>(JJJJJJJJJJJJJJJJJJJJJJJJJJJJJ)V
+HSPLandroidx/compose/material3/ColorScheme;-><init>(JJJJJJJJJJJJJJJJJJJJJJJJJJJJJLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/material3/ColorScheme;->copy-G1PFc-w$default(Landroidx/compose/material3/ColorScheme;JJJJJJJJJJJJJJJJJJJJJJJJJJJJJILjava/lang/Object;)Landroidx/compose/material3/ColorScheme;
+HSPLandroidx/compose/material3/ColorScheme;->copy-G1PFc-w(JJJJJJJJJJJJJJJJJJJJJJJJJJJJJ)Landroidx/compose/material3/ColorScheme;
+HSPLandroidx/compose/material3/ColorScheme;->getBackground-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getError-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getErrorContainer-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getInverseOnSurface-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getInversePrimary-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getInverseSurface-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getOnBackground-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getOnError-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getOnErrorContainer-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getOnPrimary-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getOnPrimaryContainer-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getOnSecondary-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getOnSecondaryContainer-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getOnSurface-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getOnSurfaceVariant-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getOnTertiary-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getOnTertiaryContainer-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getOutline-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getOutlineVariant-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getPrimary-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getPrimaryContainer-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getScrim-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getSecondary-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getSecondaryContainer-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getSurface-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getSurfaceTint-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getSurfaceVariant-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getTertiary-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->getTertiaryContainer-0d7_KjU()J
+HSPLandroidx/compose/material3/ColorScheme;->setBackground-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setError-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setErrorContainer-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setInverseOnSurface-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setInversePrimary-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setInverseSurface-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setOnBackground-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setOnError-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setOnErrorContainer-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setOnPrimary-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setOnPrimaryContainer-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setOnSecondary-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setOnSecondaryContainer-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setOnSurface-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setOnSurfaceVariant-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setOnTertiary-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setOnTertiaryContainer-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setOutline-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setOutlineVariant-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setPrimary-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setPrimaryContainer-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setScrim-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setSecondary-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setSecondaryContainer-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setSurface-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setSurfaceTint-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setSurfaceVariant-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setTertiary-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorScheme;->setTertiaryContainer-8_81llA$material3_release(J)V
+HSPLandroidx/compose/material3/ColorSchemeKt$LocalColorScheme$1;-><clinit>()V
+HSPLandroidx/compose/material3/ColorSchemeKt$LocalColorScheme$1;-><init>()V
+HSPLandroidx/compose/material3/ColorSchemeKt$WhenMappings;-><clinit>()V
+HSPLandroidx/compose/material3/ColorSchemeKt;-><clinit>()V
+HSPLandroidx/compose/material3/ColorSchemeKt;->contentColorFor-4WTKRHQ(Landroidx/compose/material3/ColorScheme;J)J
+HSPLandroidx/compose/material3/ColorSchemeKt;->contentColorFor-ek8zF_U(JLandroidx/compose/runtime/Composer;I)J
+HSPLandroidx/compose/material3/ColorSchemeKt;->fromToken(Landroidx/compose/material3/ColorScheme;Landroidx/compose/material3/tokens/ColorSchemeKeyTokens;)J
+HSPLandroidx/compose/material3/ColorSchemeKt;->getLocalColorScheme()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/material3/ColorSchemeKt;->lightColorScheme-G1PFc-w$default(JJJJJJJJJJJJJJJJJJJJJJJJJJJJJILjava/lang/Object;)Landroidx/compose/material3/ColorScheme;
+HSPLandroidx/compose/material3/ColorSchemeKt;->lightColorScheme-G1PFc-w(JJJJJJJJJJJJJJJJJJJJJJJJJJJJJ)Landroidx/compose/material3/ColorScheme;
+HSPLandroidx/compose/material3/ColorSchemeKt;->surfaceColorAtElevation-3ABfNKs(Landroidx/compose/material3/ColorScheme;F)J
+HSPLandroidx/compose/material3/ColorSchemeKt;->toColor(Landroidx/compose/material3/tokens/ColorSchemeKeyTokens;Landroidx/compose/runtime/Composer;I)J
+HSPLandroidx/compose/material3/ColorSchemeKt;->updateColorSchemeFrom(Landroidx/compose/material3/ColorScheme;Landroidx/compose/material3/ColorScheme;)V
+HSPLandroidx/compose/material3/ContentColorKt$LocalContentColor$1;-><clinit>()V
+HSPLandroidx/compose/material3/ContentColorKt$LocalContentColor$1;-><init>()V
+HSPLandroidx/compose/material3/ContentColorKt;-><clinit>()V
+HSPLandroidx/compose/material3/ContentColorKt;->getLocalContentColor()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/material3/DividerKt;->Divider-9IZ8Weo(Landroidx/compose/ui/Modifier;FJLandroidx/compose/runtime/Composer;II)V
+HSPLandroidx/compose/material3/DynamicTonalPaletteKt;->dynamicLightColorScheme(Landroid/content/Context;)Landroidx/compose/material3/ColorScheme;
+HSPLandroidx/compose/material3/DynamicTonalPaletteKt;->dynamicTonalPalette(Landroid/content/Context;)Landroidx/compose/material3/TonalPalette;
+HSPLandroidx/compose/material3/ElevationDefaults;-><clinit>()V
+HSPLandroidx/compose/material3/ElevationDefaults;-><init>()V
+HSPLandroidx/compose/material3/ElevationDefaults;->outgoingAnimationSpecForInteraction(Landroidx/compose/foundation/interaction/Interaction;)Landroidx/compose/animation/core/AnimationSpec;
+HSPLandroidx/compose/material3/ElevationKt;-><clinit>()V
+HSPLandroidx/compose/material3/ElevationKt;->access$getDefaultOutgoingSpec$p()Landroidx/compose/animation/core/TweenSpec;
+HSPLandroidx/compose/material3/ElevationKt;->animateElevation-rAjV9yQ(Landroidx/compose/animation/core/Animatable;FLandroidx/compose/foundation/interaction/Interaction;Landroidx/compose/foundation/interaction/Interaction;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/IconKt;-><clinit>()V
+HSPLandroidx/compose/material3/IconKt;->Icon-ww6aTOc(Landroidx/compose/ui/graphics/ImageBitmap;Ljava/lang/String;Landroidx/compose/ui/Modifier;JLandroidx/compose/runtime/Composer;II)V
+HSPLandroidx/compose/material3/IconKt;->Icon-ww6aTOc(Landroidx/compose/ui/graphics/painter/Painter;Ljava/lang/String;Landroidx/compose/ui/Modifier;JLandroidx/compose/runtime/Composer;II)V
+HSPLandroidx/compose/material3/IconKt;->defaultSizeFor(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/graphics/painter/Painter;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/material3/IconKt;->isInfinite-uvyYCjk(J)Z
+HSPLandroidx/compose/material3/MaterialRippleTheme;-><clinit>()V
+HSPLandroidx/compose/material3/MaterialRippleTheme;-><init>()V
+HSPLandroidx/compose/material3/MaterialRippleTheme;->defaultColor-WaAFU9c(Landroidx/compose/runtime/Composer;I)J
+HSPLandroidx/compose/material3/MaterialRippleTheme;->rippleAlpha(Landroidx/compose/runtime/Composer;I)Landroidx/compose/material/ripple/RippleAlpha;
+HSPLandroidx/compose/material3/MaterialTheme;-><clinit>()V
+HSPLandroidx/compose/material3/MaterialTheme;-><init>()V
+HSPLandroidx/compose/material3/MaterialTheme;->getColorScheme(Landroidx/compose/runtime/Composer;I)Landroidx/compose/material3/ColorScheme;
+HSPLandroidx/compose/material3/MaterialTheme;->getShapes(Landroidx/compose/runtime/Composer;I)Landroidx/compose/material3/Shapes;
+HSPLandroidx/compose/material3/MaterialTheme;->getTypography(Landroidx/compose/runtime/Composer;I)Landroidx/compose/material3/Typography;
+HSPLandroidx/compose/material3/MaterialThemeKt$MaterialTheme$1;-><init>(Landroidx/compose/material3/Typography;Lkotlin/jvm/functions/Function2;I)V
+HSPLandroidx/compose/material3/MaterialThemeKt$MaterialTheme$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/material3/MaterialThemeKt$MaterialTheme$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/MaterialThemeKt$MaterialTheme$2;-><init>(Landroidx/compose/material3/ColorScheme;Landroidx/compose/material3/Shapes;Landroidx/compose/material3/Typography;Lkotlin/jvm/functions/Function2;II)V
+HSPLandroidx/compose/material3/MaterialThemeKt;-><clinit>()V
+HSPLandroidx/compose/material3/MaterialThemeKt;->MaterialTheme(Landroidx/compose/material3/ColorScheme;Landroidx/compose/material3/Shapes;Landroidx/compose/material3/Typography;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V
+HSPLandroidx/compose/material3/MaterialThemeKt;->access$getDefaultRippleAlpha$p()Landroidx/compose/material/ripple/RippleAlpha;
+HSPLandroidx/compose/material3/MaterialThemeKt;->rememberTextSelectionColors(Landroidx/compose/material3/ColorScheme;Landroidx/compose/runtime/Composer;I)Landroidx/compose/foundation/text/selection/TextSelectionColors;
+HSPLandroidx/compose/material3/MinimumTouchTargetModifier$measure$1;-><init>(ILandroidx/compose/ui/layout/Placeable;I)V
+HSPLandroidx/compose/material3/MinimumTouchTargetModifier$measure$1;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+HSPLandroidx/compose/material3/MinimumTouchTargetModifier$measure$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/MinimumTouchTargetModifier;-><init>(J)V
+HSPLandroidx/compose/material3/MinimumTouchTargetModifier;-><init>(JLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/material3/MinimumTouchTargetModifier;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/material3/MinimumTouchTargetModifier;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/material3/ShapeDefaults;-><clinit>()V
+HSPLandroidx/compose/material3/ShapeDefaults;-><init>()V
+HSPLandroidx/compose/material3/ShapeDefaults;->getExtraLarge()Landroidx/compose/foundation/shape/CornerBasedShape;
+HSPLandroidx/compose/material3/ShapeDefaults;->getExtraSmall()Landroidx/compose/foundation/shape/CornerBasedShape;
+HSPLandroidx/compose/material3/Shapes;-><init>(Landroidx/compose/foundation/shape/CornerBasedShape;Landroidx/compose/foundation/shape/CornerBasedShape;Landroidx/compose/foundation/shape/CornerBasedShape;Landroidx/compose/foundation/shape/CornerBasedShape;Landroidx/compose/foundation/shape/CornerBasedShape;)V
+HSPLandroidx/compose/material3/Shapes;-><init>(Landroidx/compose/foundation/shape/CornerBasedShape;Landroidx/compose/foundation/shape/CornerBasedShape;Landroidx/compose/foundation/shape/CornerBasedShape;Landroidx/compose/foundation/shape/CornerBasedShape;Landroidx/compose/foundation/shape/CornerBasedShape;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/material3/Shapes;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/material3/Shapes;->getMedium()Landroidx/compose/foundation/shape/CornerBasedShape;
+HSPLandroidx/compose/material3/ShapesKt$LocalShapes$1;-><clinit>()V
+HSPLandroidx/compose/material3/ShapesKt$LocalShapes$1;-><init>()V
+HSPLandroidx/compose/material3/ShapesKt$WhenMappings;-><clinit>()V
+HSPLandroidx/compose/material3/ShapesKt;-><clinit>()V
+HSPLandroidx/compose/material3/ShapesKt;->fromToken(Landroidx/compose/material3/Shapes;Landroidx/compose/material3/tokens/ShapeKeyTokens;)Landroidx/compose/ui/graphics/Shape;
+HSPLandroidx/compose/material3/ShapesKt;->getLocalShapes()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/material3/ShapesKt;->toShape(Landroidx/compose/material3/tokens/ShapeKeyTokens;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/graphics/Shape;
+HSPLandroidx/compose/material3/SuggestionChipDefaults;-><clinit>()V
+HSPLandroidx/compose/material3/SuggestionChipDefaults;-><init>()V
+HSPLandroidx/compose/material3/SuggestionChipDefaults;->getHeight-D9Ej5fM()F
+HSPLandroidx/compose/material3/SuggestionChipDefaults;->suggestionChipColors-5tl4gsc(JJJJJJLandroidx/compose/runtime/Composer;II)Landroidx/compose/material3/ChipColors;
+HSPLandroidx/compose/material3/SuggestionChipDefaults;->suggestionChipElevation-aqJV_2Y(FFFFFFLandroidx/compose/runtime/Composer;II)Landroidx/compose/material3/ChipElevation;
+HSPLandroidx/compose/material3/SurfaceKt$LocalAbsoluteTonalElevation$1;-><clinit>()V
+HSPLandroidx/compose/material3/SurfaceKt$LocalAbsoluteTonalElevation$1;-><init>()V
+HSPLandroidx/compose/material3/SurfaceKt$LocalAbsoluteTonalElevation$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/material3/SurfaceKt$LocalAbsoluteTonalElevation$1;->invoke-D9Ej5fM()F
+HSPLandroidx/compose/material3/SurfaceKt$Surface$1$1;-><clinit>()V
+HSPLandroidx/compose/material3/SurfaceKt$Surface$1$1;-><init>()V
+HSPLandroidx/compose/material3/SurfaceKt$Surface$1$1;->invoke(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;)V
+HSPLandroidx/compose/material3/SurfaceKt$Surface$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/SurfaceKt$Surface$1$2;-><init>(Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/material3/SurfaceKt$Surface$1$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/material3/SurfaceKt$Surface$1$2;->invoke(Landroidx/compose/ui/input/pointer/PointerInputScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/SurfaceKt$Surface$1$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/SurfaceKt$Surface$1$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/SurfaceKt$Surface$1;-><init>(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/graphics/Shape;JFILandroidx/compose/foundation/BorderStroke;FLkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/material3/SurfaceKt$Surface$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/material3/SurfaceKt$Surface$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/SurfaceKt$Surface$3;-><init>(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/graphics/Shape;JFILandroidx/compose/foundation/BorderStroke;FLandroidx/compose/foundation/interaction/MutableInteractionSource;ZLkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function2;I)V
+HSPLandroidx/compose/material3/SurfaceKt$Surface$3;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/material3/SurfaceKt$Surface$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/SurfaceKt;-><clinit>()V
+HSPLandroidx/compose/material3/SurfaceKt;->Surface-T9BRK9s(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/graphics/Shape;JJFFLandroidx/compose/foundation/BorderStroke;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V
+HSPLandroidx/compose/material3/SurfaceKt;->Surface-o_FOJdg(Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/Modifier;ZLandroidx/compose/ui/graphics/Shape;JJFFLandroidx/compose/foundation/BorderStroke;Landroidx/compose/foundation/interaction/MutableInteractionSource;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;III)V
+HSPLandroidx/compose/material3/SurfaceKt;->access$surface-8ww4TTg(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/graphics/Shape;JLandroidx/compose/foundation/BorderStroke;F)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/material3/SurfaceKt;->access$surfaceColorAtElevation-CLU3JFs(JFLandroidx/compose/runtime/Composer;I)J
+HSPLandroidx/compose/material3/SurfaceKt;->surface-8ww4TTg(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/graphics/Shape;JLandroidx/compose/foundation/BorderStroke;F)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/material3/SurfaceKt;->surfaceColorAtElevation-CLU3JFs(JFLandroidx/compose/runtime/Composer;I)J
+HSPLandroidx/compose/material3/TextKt$LocalTextStyle$1;-><clinit>()V
+HSPLandroidx/compose/material3/TextKt$LocalTextStyle$1;-><init>()V
+HSPLandroidx/compose/material3/TextKt$LocalTextStyle$1;->invoke()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/material3/TextKt$LocalTextStyle$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/material3/TextKt$ProvideTextStyle$1;-><init>(Landroidx/compose/ui/text/TextStyle;Lkotlin/jvm/functions/Function2;I)V
+HSPLandroidx/compose/material3/TextKt$Text$1;-><clinit>()V
+HSPLandroidx/compose/material3/TextKt$Text$1;-><init>()V
+HSPLandroidx/compose/material3/TextKt$Text$1;->invoke(Landroidx/compose/ui/text/TextLayoutResult;)V
+HSPLandroidx/compose/material3/TextKt$Text$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/TextKt$Text$2;-><init>(Ljava/lang/String;Landroidx/compose/ui/Modifier;JJLandroidx/compose/ui/text/font/FontStyle;Landroidx/compose/ui/text/font/FontWeight;Landroidx/compose/ui/text/font/FontFamily;JLandroidx/compose/ui/text/style/TextDecoration;Landroidx/compose/ui/text/style/TextAlign;JIZIILkotlin/jvm/functions/Function1;Landroidx/compose/ui/text/TextStyle;III)V
+HSPLandroidx/compose/material3/TextKt;-><clinit>()V
+HSPLandroidx/compose/material3/TextKt;->ProvideTextStyle(Landroidx/compose/ui/text/TextStyle;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/material3/TextKt;->Text--4IGK_g(Ljava/lang/String;Landroidx/compose/ui/Modifier;JJLandroidx/compose/ui/text/font/FontStyle;Landroidx/compose/ui/text/font/FontWeight;Landroidx/compose/ui/text/font/FontFamily;JLandroidx/compose/ui/text/style/TextDecoration;Landroidx/compose/ui/text/style/TextAlign;JIZIILkotlin/jvm/functions/Function1;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/runtime/Composer;III)V
+HSPLandroidx/compose/material3/TextKt;->getLocalTextStyle()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/material3/TonalPalette;-><init>(JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ)V
+HSPLandroidx/compose/material3/TonalPalette;-><init>(JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/material3/TonalPalette;->getNeutral10-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getNeutral20-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getNeutral95-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getNeutral99-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getNeutralVariant30-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getNeutralVariant50-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getNeutralVariant90-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getPrimary10-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getPrimary100-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getPrimary40-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getPrimary80-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getPrimary90-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getSecondary10-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getSecondary100-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getSecondary40-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getSecondary90-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getTertiary10-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getTertiary100-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getTertiary40-0d7_KjU()J
+HSPLandroidx/compose/material3/TonalPalette;->getTertiary90-0d7_KjU()J
+HSPLandroidx/compose/material3/TouchTargetKt$LocalMinimumTouchTargetEnforcement$1;-><clinit>()V
+HSPLandroidx/compose/material3/TouchTargetKt$LocalMinimumTouchTargetEnforcement$1;-><init>()V
+HSPLandroidx/compose/material3/TouchTargetKt$LocalMinimumTouchTargetEnforcement$1;->invoke()Ljava/lang/Boolean;
+HSPLandroidx/compose/material3/TouchTargetKt$LocalMinimumTouchTargetEnforcement$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/material3/TouchTargetKt$minimumTouchTargetSize$2;-><clinit>()V
+HSPLandroidx/compose/material3/TouchTargetKt$minimumTouchTargetSize$2;-><init>()V
+HSPLandroidx/compose/material3/TouchTargetKt$minimumTouchTargetSize$2;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/material3/TouchTargetKt$minimumTouchTargetSize$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/material3/TouchTargetKt;-><clinit>()V
+HSPLandroidx/compose/material3/TouchTargetKt;->getLocalMinimumTouchTargetEnforcement()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/material3/TouchTargetKt;->minimumTouchTargetSize(Landroidx/compose/ui/Modifier;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/material3/Typography;-><init>(Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;)V
+HSPLandroidx/compose/material3/Typography;-><init>(Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/material3/Typography;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/material3/Typography;->getBodyLarge()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/material3/Typography;->getBodyMedium()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/material3/Typography;->getLabelLarge()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/material3/Typography;->getTitleLarge()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/material3/Typography;->getTitleMedium()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/material3/TypographyKt$LocalTypography$1;-><clinit>()V
+HSPLandroidx/compose/material3/TypographyKt$LocalTypography$1;-><init>()V
+HSPLandroidx/compose/material3/TypographyKt$WhenMappings;-><clinit>()V
+HSPLandroidx/compose/material3/TypographyKt;-><clinit>()V
+HSPLandroidx/compose/material3/TypographyKt;->fromToken(Landroidx/compose/material3/Typography;Landroidx/compose/material3/tokens/TypographyKeyTokens;)Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/material3/TypographyKt;->getLocalTypography()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/material3/tokens/ColorLightTokens;-><clinit>()V
+HSPLandroidx/compose/material3/tokens/ColorLightTokens;-><init>()V
+HSPLandroidx/compose/material3/tokens/ColorLightTokens;->getError-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/ColorLightTokens;->getErrorContainer-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/ColorLightTokens;->getOnError-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/ColorLightTokens;->getOnErrorContainer-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/ColorLightTokens;->getOutlineVariant-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/ColorLightTokens;->getScrim-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/ColorSchemeKeyTokens;->$values()[Landroidx/compose/material3/tokens/ColorSchemeKeyTokens;
+HSPLandroidx/compose/material3/tokens/ColorSchemeKeyTokens;-><clinit>()V
+HSPLandroidx/compose/material3/tokens/ColorSchemeKeyTokens;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/material3/tokens/ColorSchemeKeyTokens;->values()[Landroidx/compose/material3/tokens/ColorSchemeKeyTokens;
+HSPLandroidx/compose/material3/tokens/ElevationTokens;-><clinit>()V
+HSPLandroidx/compose/material3/tokens/ElevationTokens;-><init>()V
+HSPLandroidx/compose/material3/tokens/ElevationTokens;->getLevel0-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/ElevationTokens;->getLevel1-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/ElevationTokens;->getLevel2-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/ElevationTokens;->getLevel3-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/ElevationTokens;->getLevel4-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/FilledButtonTokens;-><clinit>()V
+HSPLandroidx/compose/material3/tokens/FilledButtonTokens;-><init>()V
+HSPLandroidx/compose/material3/tokens/FilledButtonTokens;->getIconSize-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/FilledCardTokens;-><clinit>()V
+HSPLandroidx/compose/material3/tokens/FilledCardTokens;-><init>()V
+HSPLandroidx/compose/material3/tokens/FilledCardTokens;->getContainerElevation-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/FilledCardTokens;->getContainerShape()Landroidx/compose/material3/tokens/ShapeKeyTokens;
+HSPLandroidx/compose/material3/tokens/FilledCardTokens;->getDisabledContainerColor()Landroidx/compose/material3/tokens/ColorSchemeKeyTokens;
+HSPLandroidx/compose/material3/tokens/FilledCardTokens;->getDisabledContainerElevation-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/FilledCardTokens;->getDraggedContainerElevation-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/FilledCardTokens;->getFocusContainerElevation-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/FilledCardTokens;->getHoverContainerElevation-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/FilledCardTokens;->getPressedContainerElevation-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/FilledTonalButtonTokens;-><clinit>()V
+HSPLandroidx/compose/material3/tokens/FilledTonalButtonTokens;-><init>()V
+HSPLandroidx/compose/material3/tokens/FilledTonalButtonTokens;->getContainerElevation-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/FilledTonalButtonTokens;->getContainerShape()Landroidx/compose/material3/tokens/ShapeKeyTokens;
+HSPLandroidx/compose/material3/tokens/FilledTonalButtonTokens;->getDisabledContainerColor()Landroidx/compose/material3/tokens/ColorSchemeKeyTokens;
+HSPLandroidx/compose/material3/tokens/FilledTonalButtonTokens;->getDisabledLabelTextColor()Landroidx/compose/material3/tokens/ColorSchemeKeyTokens;
+HSPLandroidx/compose/material3/tokens/FilledTonalButtonTokens;->getFocusContainerElevation-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/FilledTonalButtonTokens;->getHoverContainerElevation-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/FilledTonalButtonTokens;->getPressedContainerElevation-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/IconButtonTokens;-><clinit>()V
+HSPLandroidx/compose/material3/tokens/IconButtonTokens;-><init>()V
+HSPLandroidx/compose/material3/tokens/IconButtonTokens;->getIconSize-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/PaletteTokens;-><clinit>()V
+HSPLandroidx/compose/material3/tokens/PaletteTokens;-><init>()V
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getError10-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getError100-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getError40-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getError90-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getNeutral0-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getNeutral10-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getNeutral20-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getNeutral95-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getNeutral99-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getNeutralVariant30-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getNeutralVariant50-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getNeutralVariant80-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getNeutralVariant90-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getPrimary10-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getPrimary100-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getPrimary40-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getPrimary80-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getPrimary90-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getSecondary10-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getSecondary100-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getSecondary40-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getSecondary90-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getTertiary10-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getTertiary100-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getTertiary40-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/PaletteTokens;->getTertiary90-0d7_KjU()J
+HSPLandroidx/compose/material3/tokens/ShapeKeyTokens;->$values()[Landroidx/compose/material3/tokens/ShapeKeyTokens;
+HSPLandroidx/compose/material3/tokens/ShapeKeyTokens;-><clinit>()V
+HSPLandroidx/compose/material3/tokens/ShapeKeyTokens;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/material3/tokens/ShapeKeyTokens;->values()[Landroidx/compose/material3/tokens/ShapeKeyTokens;
+HSPLandroidx/compose/material3/tokens/ShapeTokens;-><clinit>()V
+HSPLandroidx/compose/material3/tokens/ShapeTokens;-><init>()V
+HSPLandroidx/compose/material3/tokens/ShapeTokens;->getCornerExtraLarge()Landroidx/compose/foundation/shape/RoundedCornerShape;
+HSPLandroidx/compose/material3/tokens/ShapeTokens;->getCornerExtraSmall()Landroidx/compose/foundation/shape/RoundedCornerShape;
+HSPLandroidx/compose/material3/tokens/ShapeTokens;->getCornerLarge()Landroidx/compose/foundation/shape/RoundedCornerShape;
+HSPLandroidx/compose/material3/tokens/ShapeTokens;->getCornerMedium()Landroidx/compose/foundation/shape/RoundedCornerShape;
+HSPLandroidx/compose/material3/tokens/ShapeTokens;->getCornerSmall()Landroidx/compose/foundation/shape/RoundedCornerShape;
+HSPLandroidx/compose/material3/tokens/SuggestionChipTokens;-><clinit>()V
+HSPLandroidx/compose/material3/tokens/SuggestionChipTokens;-><init>()V
+HSPLandroidx/compose/material3/tokens/SuggestionChipTokens;->getContainerHeight-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/SuggestionChipTokens;->getDisabledLabelTextColor()Landroidx/compose/material3/tokens/ColorSchemeKeyTokens;
+HSPLandroidx/compose/material3/tokens/SuggestionChipTokens;->getDisabledLeadingIconColor()Landroidx/compose/material3/tokens/ColorSchemeKeyTokens;
+HSPLandroidx/compose/material3/tokens/SuggestionChipTokens;->getDraggedContainerElevation-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/SuggestionChipTokens;->getFlatContainerElevation-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/SuggestionChipTokens;->getLabelTextFont()Landroidx/compose/material3/tokens/TypographyKeyTokens;
+HSPLandroidx/compose/material3/tokens/SuggestionChipTokens;->getLeadingIconSize-D9Ej5fM()F
+HSPLandroidx/compose/material3/tokens/TextButtonTokens;-><clinit>()V
+HSPLandroidx/compose/material3/tokens/TextButtonTokens;-><init>()V
+HSPLandroidx/compose/material3/tokens/TextButtonTokens;->getContainerShape()Landroidx/compose/material3/tokens/ShapeKeyTokens;
+HSPLandroidx/compose/material3/tokens/TextButtonTokens;->getDisabledLabelTextColor()Landroidx/compose/material3/tokens/ColorSchemeKeyTokens;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;-><clinit>()V
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;-><init>()V
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getBodyLargeFont()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getBodyLargeLineHeight-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getBodyLargeSize-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getBodyLargeTracking-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getBodyLargeWeight()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getBodyMediumFont()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getBodyMediumLineHeight-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getBodyMediumSize-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getBodyMediumTracking-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getBodyMediumWeight()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getBodySmallFont()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getBodySmallLineHeight-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getBodySmallSize-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getBodySmallTracking-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getBodySmallWeight()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getDisplayLargeFont()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getDisplayLargeLineHeight-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getDisplayLargeSize-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getDisplayLargeTracking-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getDisplayLargeWeight()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getDisplayMediumFont()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getDisplayMediumLineHeight-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getDisplayMediumSize-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getDisplayMediumTracking-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getDisplayMediumWeight()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getDisplaySmallFont()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getDisplaySmallLineHeight-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getDisplaySmallSize-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getDisplaySmallTracking-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getDisplaySmallWeight()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getHeadlineLargeFont()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getHeadlineLargeLineHeight-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getHeadlineLargeSize-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getHeadlineLargeTracking-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getHeadlineLargeWeight()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getHeadlineMediumFont()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getHeadlineMediumLineHeight-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getHeadlineMediumSize-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getHeadlineMediumTracking-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getHeadlineMediumWeight()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getHeadlineSmallFont()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getHeadlineSmallLineHeight-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getHeadlineSmallSize-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getHeadlineSmallTracking-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getHeadlineSmallWeight()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getLabelLargeFont()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getLabelLargeLineHeight-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getLabelLargeSize-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getLabelLargeTracking-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getLabelLargeWeight()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getLabelMediumFont()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getLabelMediumLineHeight-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getLabelMediumSize-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getLabelMediumTracking-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getLabelMediumWeight()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getLabelSmallFont()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getLabelSmallLineHeight-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getLabelSmallSize-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getLabelSmallTracking-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getLabelSmallWeight()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getTitleLargeFont()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getTitleLargeLineHeight-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getTitleLargeSize-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getTitleLargeTracking-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getTitleLargeWeight()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getTitleMediumFont()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getTitleMediumLineHeight-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getTitleMediumSize-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getTitleMediumTracking-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getTitleMediumWeight()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getTitleSmallFont()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getTitleSmallLineHeight-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getTitleSmallSize-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getTitleSmallTracking-XSAIIZE()J
+HSPLandroidx/compose/material3/tokens/TypeScaleTokens;->getTitleSmallWeight()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/material3/tokens/TypefaceTokens;-><clinit>()V
+HSPLandroidx/compose/material3/tokens/TypefaceTokens;-><init>()V
+HSPLandroidx/compose/material3/tokens/TypefaceTokens;->getBrand()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/material3/tokens/TypefaceTokens;->getPlain()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/material3/tokens/TypefaceTokens;->getWeightMedium()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/material3/tokens/TypefaceTokens;->getWeightRegular()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/material3/tokens/TypographyKeyTokens;->$values()[Landroidx/compose/material3/tokens/TypographyKeyTokens;
+HSPLandroidx/compose/material3/tokens/TypographyKeyTokens;-><clinit>()V
+HSPLandroidx/compose/material3/tokens/TypographyKeyTokens;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/material3/tokens/TypographyKeyTokens;->values()[Landroidx/compose/material3/tokens/TypographyKeyTokens;
+HSPLandroidx/compose/material3/tokens/TypographyTokens;-><clinit>()V
+HSPLandroidx/compose/material3/tokens/TypographyTokens;-><init>()V
+HSPLandroidx/compose/material3/tokens/TypographyTokens;->getBodySmall()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/material3/tokens/TypographyTokens;->getDisplayLarge()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/material3/tokens/TypographyTokens;->getDisplayMedium()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/material3/tokens/TypographyTokens;->getDisplaySmall()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/material3/tokens/TypographyTokens;->getHeadlineLarge()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/material3/tokens/TypographyTokens;->getHeadlineMedium()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/material3/tokens/TypographyTokens;->getHeadlineSmall()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/material3/tokens/TypographyTokens;->getLabelMedium()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/material3/tokens/TypographyTokens;->getLabelSmall()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/material3/tokens/TypographyTokens;->getTitleSmall()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/runtime/AbstractApplier;-><clinit>()V
+HSPLandroidx/compose/runtime/AbstractApplier;-><init>(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/AbstractApplier;->down(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/AbstractApplier;->getCurrent()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/AbstractApplier;->getRoot()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/AbstractApplier;->setCurrent(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/AbstractApplier;->up()V
+HSPLandroidx/compose/runtime/ActualAndroid_androidKt$DefaultMonotonicFrameClock$2;-><clinit>()V
+HSPLandroidx/compose/runtime/ActualAndroid_androidKt$DefaultMonotonicFrameClock$2;-><init>()V
+HSPLandroidx/compose/runtime/ActualAndroid_androidKt;-><clinit>()V
+HSPLandroidx/compose/runtime/ActualAndroid_androidKt;->createSnapshotMutableState(Ljava/lang/Object;Landroidx/compose/runtime/SnapshotMutationPolicy;)Landroidx/compose/runtime/snapshots/SnapshotMutableState;
+HSPLandroidx/compose/runtime/ActualJvm_jvmKt;->identityHashCode(Ljava/lang/Object;)I
+HSPLandroidx/compose/runtime/ActualJvm_jvmKt;->invokeComposable(Landroidx/compose/runtime/Composer;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/runtime/ActualJvm_jvmKt;->invokeComposableForResult(Landroidx/compose/runtime/Composer;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Anchor;-><init>(I)V
+HSPLandroidx/compose/runtime/Anchor;->getLocation$runtime_release()I
+HSPLandroidx/compose/runtime/Anchor;->getValid()Z
+HSPLandroidx/compose/runtime/Anchor;->setLocation$runtime_release(I)V
+HSPLandroidx/compose/runtime/Anchor;->toIndexFor(Landroidx/compose/runtime/SlotTable;)I
+HSPLandroidx/compose/runtime/Anchor;->toIndexFor(Landroidx/compose/runtime/SlotWriter;)I
+HSPLandroidx/compose/runtime/Applier;->onBeginChanges()V
+HSPLandroidx/compose/runtime/Applier;->onEndChanges()V
+HSPLandroidx/compose/runtime/BroadcastFrameClock$FrameAwaiter;-><init>(Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/runtime/BroadcastFrameClock$FrameAwaiter;->resume(J)V
+HSPLandroidx/compose/runtime/BroadcastFrameClock$withFrameNanos$2$1;-><init>(Landroidx/compose/runtime/BroadcastFrameClock;Lkotlin/jvm/internal/Ref$ObjectRef;)V
+HSPLandroidx/compose/runtime/BroadcastFrameClock;-><clinit>()V
+HSPLandroidx/compose/runtime/BroadcastFrameClock;-><init>(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/runtime/BroadcastFrameClock;->access$getAwaiters$p(Landroidx/compose/runtime/BroadcastFrameClock;)Ljava/util/List;
+HSPLandroidx/compose/runtime/BroadcastFrameClock;->access$getFailureCause$p(Landroidx/compose/runtime/BroadcastFrameClock;)Ljava/lang/Throwable;
+HSPLandroidx/compose/runtime/BroadcastFrameClock;->access$getLock$p(Landroidx/compose/runtime/BroadcastFrameClock;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/BroadcastFrameClock;->access$getOnNewAwaiters$p(Landroidx/compose/runtime/BroadcastFrameClock;)Lkotlin/jvm/functions/Function0;
+HSPLandroidx/compose/runtime/BroadcastFrameClock;->fold(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/BroadcastFrameClock;->get(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
+HSPLandroidx/compose/runtime/BroadcastFrameClock;->getHasAwaiters()Z
+HSPLandroidx/compose/runtime/BroadcastFrameClock;->sendFrame(J)V
+HSPLandroidx/compose/runtime/BroadcastFrameClock;->withFrameNanos(Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposableSingletons$CompositionKt$lambda-1$1;-><clinit>()V
+HSPLandroidx/compose/runtime/ComposableSingletons$CompositionKt$lambda-1$1;-><init>()V
+HSPLandroidx/compose/runtime/ComposableSingletons$CompositionKt$lambda-2$1;-><clinit>()V
+HSPLandroidx/compose/runtime/ComposableSingletons$CompositionKt$lambda-2$1;-><init>()V
+HSPLandroidx/compose/runtime/ComposableSingletons$CompositionKt;-><clinit>()V
+HSPLandroidx/compose/runtime/ComposableSingletons$CompositionKt;-><init>()V
+HSPLandroidx/compose/runtime/ComposableSingletons$CompositionKt;->getLambda-1$runtime_release()Lkotlin/jvm/functions/Function2;
+HSPLandroidx/compose/runtime/ComposablesKt;->getCurrentCompositeKeyHash(Landroidx/compose/runtime/Composer;I)I
+HSPLandroidx/compose/runtime/ComposablesKt;->rememberCompositionContext(Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/CompositionContext;
+HSPLandroidx/compose/runtime/Composer$Companion$Empty$1;-><init>()V
+HSPLandroidx/compose/runtime/Composer$Companion;-><clinit>()V
+HSPLandroidx/compose/runtime/Composer$Companion;-><init>()V
+HSPLandroidx/compose/runtime/Composer$Companion;->getEmpty()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Composer;-><clinit>()V
+HSPLandroidx/compose/runtime/ComposerImpl$CompositionContextHolder;-><init>(Landroidx/compose/runtime/ComposerImpl$CompositionContextImpl;)V
+HSPLandroidx/compose/runtime/ComposerImpl$CompositionContextHolder;->getRef()Landroidx/compose/runtime/ComposerImpl$CompositionContextImpl;
+HSPLandroidx/compose/runtime/ComposerImpl$CompositionContextHolder;->onRemembered()V
+HSPLandroidx/compose/runtime/ComposerImpl$CompositionContextImpl;-><init>(Landroidx/compose/runtime/ComposerImpl;IZ)V
+HSPLandroidx/compose/runtime/ComposerImpl$CompositionContextImpl;->composeInitial$runtime_release(Landroidx/compose/runtime/ControlledComposition;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/runtime/ComposerImpl$CompositionContextImpl;->doneComposing$runtime_release()V
+HSPLandroidx/compose/runtime/ComposerImpl$CompositionContextImpl;->getCollectingParameterInformation$runtime_release()Z
+HSPLandroidx/compose/runtime/ComposerImpl$CompositionContextImpl;->getCompositionLocalScope$runtime_release()Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;
+HSPLandroidx/compose/runtime/ComposerImpl$CompositionContextImpl;->getCompositionLocalScope()Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;
+HSPLandroidx/compose/runtime/ComposerImpl$CompositionContextImpl;->getCompoundHashKey$runtime_release()I
+HSPLandroidx/compose/runtime/ComposerImpl$CompositionContextImpl;->getEffectCoroutineContext$runtime_release()Lkotlin/coroutines/CoroutineContext;
+HSPLandroidx/compose/runtime/ComposerImpl$CompositionContextImpl;->invalidate$runtime_release(Landroidx/compose/runtime/ControlledComposition;)V
+HSPLandroidx/compose/runtime/ComposerImpl$CompositionContextImpl;->registerComposer$runtime_release(Landroidx/compose/runtime/Composer;)V
+HSPLandroidx/compose/runtime/ComposerImpl$CompositionContextImpl;->setCompositionLocalScope(Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;)V
+HSPLandroidx/compose/runtime/ComposerImpl$CompositionContextImpl;->startComposing$runtime_release()V
+HSPLandroidx/compose/runtime/ComposerImpl$CompositionContextImpl;->updateCompositionLocalScope(Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;)V
+HSPLandroidx/compose/runtime/ComposerImpl$apply$operation$1;-><init>(Lkotlin/jvm/functions/Function2;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerImpl$apply$operation$1;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+HSPLandroidx/compose/runtime/ComposerImpl$apply$operation$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl$createNode$2;-><init>(Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Anchor;I)V
+HSPLandroidx/compose/runtime/ComposerImpl$createNode$2;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+HSPLandroidx/compose/runtime/ComposerImpl$createNode$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl$createNode$3;-><init>(Landroidx/compose/runtime/Anchor;I)V
+HSPLandroidx/compose/runtime/ComposerImpl$createNode$3;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+HSPLandroidx/compose/runtime/ComposerImpl$createNode$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl$doCompose$2$3;-><init>(Landroidx/compose/runtime/ComposerImpl;)V
+HSPLandroidx/compose/runtime/ComposerImpl$doCompose$2$4;-><init>(Landroidx/compose/runtime/ComposerImpl;)V
+HSPLandroidx/compose/runtime/ComposerImpl$doCompose$2$5;-><init>(Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/ComposerImpl;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerImpl$doCompose$2$5;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl$doCompose$2$5;->invoke()V
+HSPLandroidx/compose/runtime/ComposerImpl$doCompose$lambda$37$$inlined$sortBy$1;-><init>()V
+HSPLandroidx/compose/runtime/ComposerImpl$doCompose$lambda$37$$inlined$sortBy$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
+HSPLandroidx/compose/runtime/ComposerImpl$endRestartGroup$1$1;-><init>(Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/ComposerImpl;)V
+HSPLandroidx/compose/runtime/ComposerImpl$endRestartGroup$1$1;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+HSPLandroidx/compose/runtime/ComposerImpl$endRestartGroup$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl$realizeDowns$1;-><init>([Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerImpl$realizeDowns$1;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+HSPLandroidx/compose/runtime/ComposerImpl$realizeDowns$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl$realizeOperationLocation$2;-><init>(I)V
+HSPLandroidx/compose/runtime/ComposerImpl$realizeOperationLocation$2;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+HSPLandroidx/compose/runtime/ComposerImpl$realizeOperationLocation$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl$realizeUps$1;-><init>(I)V
+HSPLandroidx/compose/runtime/ComposerImpl$realizeUps$1;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+HSPLandroidx/compose/runtime/ComposerImpl$realizeUps$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl$recordInsert$1;-><init>(Landroidx/compose/runtime/SlotTable;Landroidx/compose/runtime/Anchor;)V
+HSPLandroidx/compose/runtime/ComposerImpl$recordInsert$1;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+HSPLandroidx/compose/runtime/ComposerImpl$recordInsert$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl$recordInsert$2;-><init>(Landroidx/compose/runtime/SlotTable;Landroidx/compose/runtime/Anchor;Ljava/util/List;)V
+HSPLandroidx/compose/runtime/ComposerImpl$recordInsert$2;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+HSPLandroidx/compose/runtime/ComposerImpl$recordInsert$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl$recordSideEffect$1;-><init>(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/runtime/ComposerImpl$recordSideEffect$1;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+HSPLandroidx/compose/runtime/ComposerImpl$recordSideEffect$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl$recordSlotEditing$1;-><init>(Landroidx/compose/runtime/Anchor;)V
+HSPLandroidx/compose/runtime/ComposerImpl$recordSlotEditing$1;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+HSPLandroidx/compose/runtime/ComposerImpl$recordSlotEditing$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl$startProviders$currentProviders$1;-><init>([Landroidx/compose/runtime/ProvidedValue;Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;)V
+HSPLandroidx/compose/runtime/ComposerImpl$startProviders$currentProviders$1;->invoke(Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;
+HSPLandroidx/compose/runtime/ComposerImpl$startProviders$currentProviders$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl$startReaderGroup$1;-><init>(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerImpl$startReaderGroup$1;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+HSPLandroidx/compose/runtime/ComposerImpl$startReaderGroup$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl$updateValue$1;-><init>(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerImpl$updateValue$1;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+HSPLandroidx/compose/runtime/ComposerImpl$updateValue$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl$updateValue$2;-><init>(Ljava/lang/Object;I)V
+HSPLandroidx/compose/runtime/ComposerImpl$updateValue$2;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+HSPLandroidx/compose/runtime/ComposerImpl$updateValue$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl;-><init>(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/CompositionContext;Landroidx/compose/runtime/SlotTable;Ljava/util/Set;Ljava/util/List;Ljava/util/List;Landroidx/compose/runtime/ControlledComposition;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->access$endGroup(Landroidx/compose/runtime/ComposerImpl;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->access$getChildrenComposing$p(Landroidx/compose/runtime/ComposerImpl;)I
+HSPLandroidx/compose/runtime/ComposerImpl;->access$getForciblyRecompose$p(Landroidx/compose/runtime/ComposerImpl;)Z
+HSPLandroidx/compose/runtime/ComposerImpl;->access$getParentContext$p(Landroidx/compose/runtime/ComposerImpl;)Landroidx/compose/runtime/CompositionContext;
+HSPLandroidx/compose/runtime/ComposerImpl;->access$getProvidersInvalid$p(Landroidx/compose/runtime/ComposerImpl;)Z
+HSPLandroidx/compose/runtime/ComposerImpl;->access$setChildrenComposing$p(Landroidx/compose/runtime/ComposerImpl;I)V
+HSPLandroidx/compose/runtime/ComposerImpl;->access$startGroup(Landroidx/compose/runtime/ComposerImpl;ILjava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->addRecomposeScope()V
+HSPLandroidx/compose/runtime/ComposerImpl;->apply(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->buildContext()Landroidx/compose/runtime/CompositionContext;
+HSPLandroidx/compose/runtime/ComposerImpl;->changed(J)Z
+HSPLandroidx/compose/runtime/ComposerImpl;->changed(Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/ComposerImpl;->changed(Z)Z
+HSPLandroidx/compose/runtime/ComposerImpl;->changedInstance(Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/ComposerImpl;->changesApplied$runtime_release()V
+HSPLandroidx/compose/runtime/ComposerImpl;->cleanUpCompose()V
+HSPLandroidx/compose/runtime/ComposerImpl;->clearUpdatedNodeCounts()V
+HSPLandroidx/compose/runtime/ComposerImpl;->composeContent$runtime_release(Landroidx/compose/runtime/collection/IdentityArrayMap;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->compoundKeyOf(III)I
+HSPLandroidx/compose/runtime/ComposerImpl;->consume(Landroidx/compose/runtime/CompositionLocal;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl;->createNode(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->currentCompositionLocalScope$default(Landroidx/compose/runtime/ComposerImpl;Ljava/lang/Integer;ILjava/lang/Object;)Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;
+HSPLandroidx/compose/runtime/ComposerImpl;->currentCompositionLocalScope(Ljava/lang/Integer;)Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;
+HSPLandroidx/compose/runtime/ComposerImpl;->disableReusing()V
+HSPLandroidx/compose/runtime/ComposerImpl;->doCompose(Landroidx/compose/runtime/collection/IdentityArrayMap;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->doRecordDownsFor(II)V
+HSPLandroidx/compose/runtime/ComposerImpl;->enableReusing()V
+HSPLandroidx/compose/runtime/ComposerImpl;->end(Z)V
+HSPLandroidx/compose/runtime/ComposerImpl;->endDefaults()V
+HSPLandroidx/compose/runtime/ComposerImpl;->endGroup()V
+HSPLandroidx/compose/runtime/ComposerImpl;->endNode()V
+HSPLandroidx/compose/runtime/ComposerImpl;->endProviders()V
+HSPLandroidx/compose/runtime/ComposerImpl;->endReplaceableGroup()V
+HSPLandroidx/compose/runtime/ComposerImpl;->endRestartGroup()Landroidx/compose/runtime/ScopeUpdateScope;
+HSPLandroidx/compose/runtime/ComposerImpl;->endReusableGroup()V
+HSPLandroidx/compose/runtime/ComposerImpl;->endRoot()V
+HSPLandroidx/compose/runtime/ComposerImpl;->ensureWriter()V
+HSPLandroidx/compose/runtime/ComposerImpl;->enterGroup(ZLandroidx/compose/runtime/Pending;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->exitGroup(IZ)V
+HSPLandroidx/compose/runtime/ComposerImpl;->finalizeCompose()V
+HSPLandroidx/compose/runtime/ComposerImpl;->getApplier()Landroidx/compose/runtime/Applier;
+HSPLandroidx/compose/runtime/ComposerImpl;->getApplyCoroutineContext()Lkotlin/coroutines/CoroutineContext;
+HSPLandroidx/compose/runtime/ComposerImpl;->getAreChildrenComposing$runtime_release()Z
+HSPLandroidx/compose/runtime/ComposerImpl;->getComposition()Landroidx/compose/runtime/ControlledComposition;
+HSPLandroidx/compose/runtime/ComposerImpl;->getCompoundKeyHash()I
+HSPLandroidx/compose/runtime/ComposerImpl;->getCurrentRecomposeScope$runtime_release()Landroidx/compose/runtime/RecomposeScopeImpl;
+HSPLandroidx/compose/runtime/ComposerImpl;->getDefaultsInvalid()Z
+HSPLandroidx/compose/runtime/ComposerImpl;->getInserting()Z
+HSPLandroidx/compose/runtime/ComposerImpl;->getNode(Landroidx/compose/runtime/SlotReader;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl;->getRecomposeScope()Landroidx/compose/runtime/RecomposeScope;
+HSPLandroidx/compose/runtime/ComposerImpl;->getSkipping()Z
+HSPLandroidx/compose/runtime/ComposerImpl;->groupCompoundKeyPart(Landroidx/compose/runtime/SlotReader;I)I
+HSPLandroidx/compose/runtime/ComposerImpl;->insertedGroupVirtualIndex(I)I
+HSPLandroidx/compose/runtime/ComposerImpl;->isComposing$runtime_release()Z
+HSPLandroidx/compose/runtime/ComposerImpl;->nextSlot()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl;->nodeIndexOf(IIII)I
+HSPLandroidx/compose/runtime/ComposerImpl;->prepareCompose$runtime_release(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->realizeDowns()V
+HSPLandroidx/compose/runtime/ComposerImpl;->realizeDowns([Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->realizeMovement()V
+HSPLandroidx/compose/runtime/ComposerImpl;->realizeOperationLocation$default(Landroidx/compose/runtime/ComposerImpl;ZILjava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->realizeOperationLocation(Z)V
+HSPLandroidx/compose/runtime/ComposerImpl;->realizeUps()V
+HSPLandroidx/compose/runtime/ComposerImpl;->recompose$runtime_release(Landroidx/compose/runtime/collection/IdentityArrayMap;)Z
+HSPLandroidx/compose/runtime/ComposerImpl;->recomposeToGroupEnd()V
+HSPLandroidx/compose/runtime/ComposerImpl;->record(Lkotlin/jvm/functions/Function3;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->recordApplierOperation(Lkotlin/jvm/functions/Function3;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->recordDown(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->recordEndGroup()V
+HSPLandroidx/compose/runtime/ComposerImpl;->recordEndRoot()V
+HSPLandroidx/compose/runtime/ComposerImpl;->recordFixup(Lkotlin/jvm/functions/Function3;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->recordInsert(Landroidx/compose/runtime/Anchor;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->recordInsertUpFixup(Lkotlin/jvm/functions/Function3;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->recordReaderMoving(I)V
+HSPLandroidx/compose/runtime/ComposerImpl;->recordSideEffect(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->recordSlotEditing()V
+HSPLandroidx/compose/runtime/ComposerImpl;->recordSlotEditingOperation(Lkotlin/jvm/functions/Function3;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->recordSlotTableOperation$default(Landroidx/compose/runtime/ComposerImpl;ZLkotlin/jvm/functions/Function3;ILjava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->recordSlotTableOperation(ZLkotlin/jvm/functions/Function3;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->recordUp()V
+HSPLandroidx/compose/runtime/ComposerImpl;->recordUpsAndDowns(III)V
+HSPLandroidx/compose/runtime/ComposerImpl;->recordUsed(Landroidx/compose/runtime/RecomposeScope;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->registerInsertUpFixup()V
+HSPLandroidx/compose/runtime/ComposerImpl;->rememberedValue()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl;->resolveCompositionLocal(Landroidx/compose/runtime/CompositionLocal;Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerImpl;->skipCurrentGroup()V
+HSPLandroidx/compose/runtime/ComposerImpl;->skipGroup()V
+HSPLandroidx/compose/runtime/ComposerImpl;->skipReaderToGroupEnd()V
+HSPLandroidx/compose/runtime/ComposerImpl;->skipToGroupEnd()V
+HSPLandroidx/compose/runtime/ComposerImpl;->start(ILjava/lang/Object;ZLjava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->startDefaults()V
+HSPLandroidx/compose/runtime/ComposerImpl;->startGroup(I)V
+HSPLandroidx/compose/runtime/ComposerImpl;->startGroup(ILjava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->startNode()V
+HSPLandroidx/compose/runtime/ComposerImpl;->startProviders([Landroidx/compose/runtime/ProvidedValue;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->startReaderGroup(ZLjava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->startReplaceableGroup(I)V
+HSPLandroidx/compose/runtime/ComposerImpl;->startRestartGroup(I)Landroidx/compose/runtime/Composer;
+HSPLandroidx/compose/runtime/ComposerImpl;->startReusableGroup(ILjava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->startReusableNode()V
+HSPLandroidx/compose/runtime/ComposerImpl;->startRoot()V
+HSPLandroidx/compose/runtime/ComposerImpl;->tryImminentInvalidation$runtime_release(Landroidx/compose/runtime/RecomposeScopeImpl;Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/ComposerImpl;->updateCompoundKeyWhenWeEnterGroup(ILjava/lang/Object;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->updateCompoundKeyWhenWeEnterGroupKeyHash(I)V
+HSPLandroidx/compose/runtime/ComposerImpl;->updateCompoundKeyWhenWeExitGroup(ILjava/lang/Object;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->updateCompoundKeyWhenWeExitGroupKeyHash(I)V
+HSPLandroidx/compose/runtime/ComposerImpl;->updateNodeCount(II)V
+HSPLandroidx/compose/runtime/ComposerImpl;->updateNodeCountOverrides(II)V
+HSPLandroidx/compose/runtime/ComposerImpl;->updateProviderMapGroup(Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;)Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;
+HSPLandroidx/compose/runtime/ComposerImpl;->updateRememberedValue(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->updateValue(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerImpl;->updatedNodeCount(I)I
+HSPLandroidx/compose/runtime/ComposerImpl;->useNode()V
+HSPLandroidx/compose/runtime/ComposerImpl;->validateNodeExpected()V
+HSPLandroidx/compose/runtime/ComposerImpl;->validateNodeNotExpected()V
+HSPLandroidx/compose/runtime/ComposerKt$endGroupInstance$1;-><clinit>()V
+HSPLandroidx/compose/runtime/ComposerKt$endGroupInstance$1;-><init>()V
+HSPLandroidx/compose/runtime/ComposerKt$endGroupInstance$1;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+HSPLandroidx/compose/runtime/ComposerKt$endGroupInstance$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerKt$removeCurrentGroupInstance$1;-><clinit>()V
+HSPLandroidx/compose/runtime/ComposerKt$removeCurrentGroupInstance$1;-><init>()V
+HSPLandroidx/compose/runtime/ComposerKt$resetSlotsInstance$1;-><clinit>()V
+HSPLandroidx/compose/runtime/ComposerKt$resetSlotsInstance$1;-><init>()V
+HSPLandroidx/compose/runtime/ComposerKt$skipToGroupEndInstance$1;-><clinit>()V
+HSPLandroidx/compose/runtime/ComposerKt$skipToGroupEndInstance$1;-><init>()V
+HSPLandroidx/compose/runtime/ComposerKt$startRootGroup$1;-><clinit>()V
+HSPLandroidx/compose/runtime/ComposerKt$startRootGroup$1;-><init>()V
+HSPLandroidx/compose/runtime/ComposerKt$startRootGroup$1;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+HSPLandroidx/compose/runtime/ComposerKt$startRootGroup$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerKt;-><clinit>()V
+HSPLandroidx/compose/runtime/ComposerKt;->access$asBool(I)Z
+HSPLandroidx/compose/runtime/ComposerKt;->access$asInt(Z)I
+HSPLandroidx/compose/runtime/ComposerKt;->access$compositionLocalMapOf([Landroidx/compose/runtime/ProvidedValue;Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;
+HSPLandroidx/compose/runtime/ComposerKt;->access$firstInRange(Ljava/util/List;II)Landroidx/compose/runtime/Invalidation;
+HSPLandroidx/compose/runtime/ComposerKt;->access$getEndGroupInstance$p()Lkotlin/jvm/functions/Function3;
+HSPLandroidx/compose/runtime/ComposerKt;->access$getJoinedKey(Landroidx/compose/runtime/KeyInfo;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerKt;->access$getStartRootGroup$p()Lkotlin/jvm/functions/Function3;
+HSPLandroidx/compose/runtime/ComposerKt;->access$insertIfMissing(Ljava/util/List;ILandroidx/compose/runtime/RecomposeScopeImpl;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerKt;->access$multiMap()Ljava/util/HashMap;
+HSPLandroidx/compose/runtime/ComposerKt;->access$nearestCommonRootOf(Landroidx/compose/runtime/SlotReader;III)I
+HSPLandroidx/compose/runtime/ComposerKt;->access$pop(Ljava/util/HashMap;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerKt;->access$put(Ljava/util/HashMap;Ljava/lang/Object;Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/ComposerKt;->access$removeLocation(Ljava/util/List;I)Landroidx/compose/runtime/Invalidation;
+HSPLandroidx/compose/runtime/ComposerKt;->asBool(I)Z
+HSPLandroidx/compose/runtime/ComposerKt;->asInt(Z)I
+HSPLandroidx/compose/runtime/ComposerKt;->compositionLocalMapOf([Landroidx/compose/runtime/ProvidedValue;Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;
+HSPLandroidx/compose/runtime/ComposerKt;->contains(Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;Landroidx/compose/runtime/CompositionLocal;)Z
+HSPLandroidx/compose/runtime/ComposerKt;->findInsertLocation(Ljava/util/List;I)I
+HSPLandroidx/compose/runtime/ComposerKt;->findLocation(Ljava/util/List;I)I
+HSPLandroidx/compose/runtime/ComposerKt;->firstInRange(Ljava/util/List;II)Landroidx/compose/runtime/Invalidation;
+HSPLandroidx/compose/runtime/ComposerKt;->getCompositionLocalMap()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerKt;->getInvocation()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerKt;->getJoinedKey(Landroidx/compose/runtime/KeyInfo;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerKt;->getProvider()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerKt;->getProviderMaps()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerKt;->getProviderValues()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerKt;->getReference()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerKt;->getValueOf(Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;Landroidx/compose/runtime/CompositionLocal;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerKt;->insertIfMissing(Ljava/util/List;ILandroidx/compose/runtime/RecomposeScopeImpl;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/ComposerKt;->isTraceInProgress()Z
+HSPLandroidx/compose/runtime/ComposerKt;->multiMap()Ljava/util/HashMap;
+HSPLandroidx/compose/runtime/ComposerKt;->nearestCommonRootOf(Landroidx/compose/runtime/SlotReader;III)I
+HSPLandroidx/compose/runtime/ComposerKt;->pop(Ljava/util/HashMap;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/ComposerKt;->put(Ljava/util/HashMap;Ljava/lang/Object;Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/ComposerKt;->remove(Ljava/util/HashMap;Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Unit;
+HSPLandroidx/compose/runtime/ComposerKt;->removeLocation(Ljava/util/List;I)Landroidx/compose/runtime/Invalidation;
+HSPLandroidx/compose/runtime/ComposerKt;->runtimeCheck(Z)V
+HSPLandroidx/compose/runtime/CompositionContext;-><clinit>()V
+HSPLandroidx/compose/runtime/CompositionContext;-><init>()V
+HSPLandroidx/compose/runtime/CompositionContext;->doneComposing$runtime_release()V
+HSPLandroidx/compose/runtime/CompositionContext;->getCompositionLocalScope$runtime_release()Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;
+HSPLandroidx/compose/runtime/CompositionContext;->registerComposer$runtime_release(Landroidx/compose/runtime/Composer;)V
+HSPLandroidx/compose/runtime/CompositionContext;->startComposing$runtime_release()V
+HSPLandroidx/compose/runtime/CompositionContextKt;-><clinit>()V
+HSPLandroidx/compose/runtime/CompositionContextKt;->access$getEmptyCompositionLocalMap$p()Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;
+HSPLandroidx/compose/runtime/CompositionImpl$RememberEventDispatcher;-><init>(Ljava/util/Set;)V
+HSPLandroidx/compose/runtime/CompositionImpl$RememberEventDispatcher;->dispatchAbandons()V
+HSPLandroidx/compose/runtime/CompositionImpl$RememberEventDispatcher;->dispatchRememberObservers()V
+HSPLandroidx/compose/runtime/CompositionImpl$RememberEventDispatcher;->dispatchSideEffects()V
+HSPLandroidx/compose/runtime/CompositionImpl$RememberEventDispatcher;->forgetting(Landroidx/compose/runtime/RememberObserver;)V
+HSPLandroidx/compose/runtime/CompositionImpl$RememberEventDispatcher;->remembering(Landroidx/compose/runtime/RememberObserver;)V
+HSPLandroidx/compose/runtime/CompositionImpl$RememberEventDispatcher;->sideEffect(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/runtime/CompositionImpl;-><init>(Landroidx/compose/runtime/CompositionContext;Landroidx/compose/runtime/Applier;Lkotlin/coroutines/CoroutineContext;)V
+HSPLandroidx/compose/runtime/CompositionImpl;-><init>(Landroidx/compose/runtime/CompositionContext;Landroidx/compose/runtime/Applier;Lkotlin/coroutines/CoroutineContext;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/runtime/CompositionImpl;->addPendingInvalidationsLocked$invalidate(Landroidx/compose/runtime/CompositionImpl;ZLkotlin/jvm/internal/Ref$ObjectRef;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/CompositionImpl;->addPendingInvalidationsLocked(Ljava/util/Set;Z)V
+HSPLandroidx/compose/runtime/CompositionImpl;->applyChanges()V
+HSPLandroidx/compose/runtime/CompositionImpl;->applyChangesInLocked(Ljava/util/List;)V
+HSPLandroidx/compose/runtime/CompositionImpl;->applyLateChanges()V
+HSPLandroidx/compose/runtime/CompositionImpl;->changesApplied()V
+HSPLandroidx/compose/runtime/CompositionImpl;->cleanUpDerivedStateObservations()V
+HSPLandroidx/compose/runtime/CompositionImpl;->composeContent(Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/runtime/CompositionImpl;->drainPendingModificationsForCompositionLocked()V
+HSPLandroidx/compose/runtime/CompositionImpl;->drainPendingModificationsLocked()V
+HSPLandroidx/compose/runtime/CompositionImpl;->getAreChildrenComposing()Z
+HSPLandroidx/compose/runtime/CompositionImpl;->getHasInvalidations()Z
+HSPLandroidx/compose/runtime/CompositionImpl;->invalidate(Landroidx/compose/runtime/RecomposeScopeImpl;Ljava/lang/Object;)Landroidx/compose/runtime/InvalidationResult;
+HSPLandroidx/compose/runtime/CompositionImpl;->invalidateChecked(Landroidx/compose/runtime/RecomposeScopeImpl;Landroidx/compose/runtime/Anchor;Ljava/lang/Object;)Landroidx/compose/runtime/InvalidationResult;
+HSPLandroidx/compose/runtime/CompositionImpl;->invalidateScopeOfLocked(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/CompositionImpl;->isComposing()Z
+HSPLandroidx/compose/runtime/CompositionImpl;->isDisposed()Z
+HSPLandroidx/compose/runtime/CompositionImpl;->prepareCompose(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/runtime/CompositionImpl;->recompose()Z
+HSPLandroidx/compose/runtime/CompositionImpl;->recordModificationsOf(Ljava/util/Set;)V
+HSPLandroidx/compose/runtime/CompositionImpl;->recordReadOf(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/CompositionImpl;->recordWriteOf(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/CompositionImpl;->removeObservation$runtime_release(Ljava/lang/Object;Landroidx/compose/runtime/RecomposeScopeImpl;)V
+HSPLandroidx/compose/runtime/CompositionImpl;->setContent(Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/runtime/CompositionImpl;->takeInvalidations()Landroidx/compose/runtime/collection/IdentityArrayMap;
+HSPLandroidx/compose/runtime/CompositionKt;-><clinit>()V
+HSPLandroidx/compose/runtime/CompositionKt;->Composition(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/CompositionContext;)Landroidx/compose/runtime/Composition;
+HSPLandroidx/compose/runtime/CompositionKt;->access$addValue(Landroidx/compose/runtime/collection/IdentityArrayMap;Ljava/lang/Object;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/CompositionKt;->access$getPendingApplyNoModifications$p()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/CompositionKt;->addValue(Landroidx/compose/runtime/collection/IdentityArrayMap;Ljava/lang/Object;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/CompositionLocal;-><init>(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/runtime/CompositionLocal;-><init>(Lkotlin/jvm/functions/Function0;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/runtime/CompositionLocal;->getDefaultValueHolder$runtime_release()Landroidx/compose/runtime/LazyValueHolder;
+HSPLandroidx/compose/runtime/CompositionLocalKt;->CompositionLocalProvider([Landroidx/compose/runtime/ProvidedValue;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/runtime/CompositionLocalKt;->compositionLocalOf$default(Landroidx/compose/runtime/SnapshotMutationPolicy;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/runtime/CompositionLocalKt;->compositionLocalOf(Landroidx/compose/runtime/SnapshotMutationPolicy;Lkotlin/jvm/functions/Function0;)Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/runtime/CompositionLocalKt;->staticCompositionLocalOf(Lkotlin/jvm/functions/Function0;)Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/runtime/CompositionScopedCoroutineScopeCanceller;-><init>(Lkotlinx/coroutines/CoroutineScope;)V
+HSPLandroidx/compose/runtime/CompositionScopedCoroutineScopeCanceller;->getCoroutineScope()Lkotlinx/coroutines/CoroutineScope;
+HSPLandroidx/compose/runtime/CompositionScopedCoroutineScopeCanceller;->onRemembered()V
+HSPLandroidx/compose/runtime/DisposableEffectImpl;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/runtime/DisposableEffectImpl;->onForgotten()V
+HSPLandroidx/compose/runtime/DisposableEffectImpl;->onRemembered()V
+HSPLandroidx/compose/runtime/DisposableEffectScope;-><clinit>()V
+HSPLandroidx/compose/runtime/DisposableEffectScope;-><init>()V
+HSPLandroidx/compose/runtime/DynamicProvidableCompositionLocal;-><init>(Landroidx/compose/runtime/SnapshotMutationPolicy;Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/runtime/DynamicProvidableCompositionLocal;->provided$runtime_release(Ljava/lang/Object;Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/runtime/EffectsKt;-><clinit>()V
+HSPLandroidx/compose/runtime/EffectsKt;->DisposableEffect(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/runtime/EffectsKt;->DisposableEffect(Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/runtime/EffectsKt;->DisposableEffect(Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/runtime/EffectsKt;->LaunchedEffect(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/runtime/EffectsKt;->LaunchedEffect(Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/runtime/EffectsKt;->LaunchedEffect(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/runtime/EffectsKt;->LaunchedEffect([Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/runtime/EffectsKt;->SideEffect(Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/runtime/EffectsKt;->access$getInternalDisposableEffectScope$p()Landroidx/compose/runtime/DisposableEffectScope;
+HSPLandroidx/compose/runtime/EffectsKt;->createCompositionCoroutineScope(Lkotlin/coroutines/CoroutineContext;Landroidx/compose/runtime/Composer;)Lkotlinx/coroutines/CoroutineScope;
+HSPLandroidx/compose/runtime/GroupInfo;-><init>(III)V
+HSPLandroidx/compose/runtime/GroupInfo;->getNodeCount()I
+HSPLandroidx/compose/runtime/GroupInfo;->getNodeIndex()I
+HSPLandroidx/compose/runtime/GroupInfo;->getSlotIndex()I
+HSPLandroidx/compose/runtime/IntStack;-><init>()V
+HSPLandroidx/compose/runtime/IntStack;->clear()V
+HSPLandroidx/compose/runtime/IntStack;->getSize()I
+HSPLandroidx/compose/runtime/IntStack;->isEmpty()Z
+HSPLandroidx/compose/runtime/IntStack;->peek()I
+HSPLandroidx/compose/runtime/IntStack;->peekOr(I)I
+HSPLandroidx/compose/runtime/IntStack;->pop()I
+HSPLandroidx/compose/runtime/IntStack;->push(I)V
+HSPLandroidx/compose/runtime/Invalidation;-><init>(Landroidx/compose/runtime/RecomposeScopeImpl;ILandroidx/compose/runtime/collection/IdentityArraySet;)V
+HSPLandroidx/compose/runtime/Invalidation;->getLocation()I
+HSPLandroidx/compose/runtime/Invalidation;->getScope()Landroidx/compose/runtime/RecomposeScopeImpl;
+HSPLandroidx/compose/runtime/Invalidation;->isInvalid()Z
+HSPLandroidx/compose/runtime/Invalidation;->setInstances(Landroidx/compose/runtime/collection/IdentityArraySet;)V
+HSPLandroidx/compose/runtime/InvalidationResult;->$values()[Landroidx/compose/runtime/InvalidationResult;
+HSPLandroidx/compose/runtime/InvalidationResult;-><clinit>()V
+HSPLandroidx/compose/runtime/InvalidationResult;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/runtime/KeyInfo;-><init>(ILjava/lang/Object;III)V
+HSPLandroidx/compose/runtime/KeyInfo;->getKey()I
+HSPLandroidx/compose/runtime/KeyInfo;->getLocation()I
+HSPLandroidx/compose/runtime/KeyInfo;->getNodes()I
+HSPLandroidx/compose/runtime/KeyInfo;->getObjectKey()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Latch;-><init>()V
+HSPLandroidx/compose/runtime/Latch;->await(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Latch;->closeLatch()V
+HSPLandroidx/compose/runtime/Latch;->isOpen()Z
+HSPLandroidx/compose/runtime/Latch;->openLatch()V
+HSPLandroidx/compose/runtime/LaunchedEffectImpl;-><init>(Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/runtime/LaunchedEffectImpl;->onForgotten()V
+HSPLandroidx/compose/runtime/LaunchedEffectImpl;->onRemembered()V
+HSPLandroidx/compose/runtime/LazyValueHolder;-><init>(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/runtime/LazyValueHolder;->getCurrent()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/LazyValueHolder;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/MonotonicFrameClock$DefaultImpls;->fold(Landroidx/compose/runtime/MonotonicFrameClock;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/MonotonicFrameClock$DefaultImpls;->get(Landroidx/compose/runtime/MonotonicFrameClock;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
+HSPLandroidx/compose/runtime/MonotonicFrameClock$DefaultImpls;->minusKey(Landroidx/compose/runtime/MonotonicFrameClock;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
+HSPLandroidx/compose/runtime/MonotonicFrameClock$Key;-><clinit>()V
+HSPLandroidx/compose/runtime/MonotonicFrameClock$Key;-><init>()V
+HSPLandroidx/compose/runtime/MonotonicFrameClock;-><clinit>()V
+HSPLandroidx/compose/runtime/MonotonicFrameClock;->getKey()Lkotlin/coroutines/CoroutineContext$Key;
+HSPLandroidx/compose/runtime/MonotonicFrameClockKt;->getMonotonicFrameClock(Lkotlin/coroutines/CoroutineContext;)Landroidx/compose/runtime/MonotonicFrameClock;
+HSPLandroidx/compose/runtime/MonotonicFrameClockKt;->withFrameNanos(Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/NeverEqualPolicy;-><clinit>()V
+HSPLandroidx/compose/runtime/NeverEqualPolicy;-><init>()V
+HSPLandroidx/compose/runtime/NeverEqualPolicy;->equivalent(Ljava/lang/Object;Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/OpaqueKey;-><init>(Ljava/lang/String;)V
+HSPLandroidx/compose/runtime/OpaqueKey;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/OpaqueKey;->hashCode()I
+HSPLandroidx/compose/runtime/ParcelableSnapshotMutableState$Companion$CREATOR$1;-><init>()V
+HSPLandroidx/compose/runtime/ParcelableSnapshotMutableState$Companion;-><init>()V
+HSPLandroidx/compose/runtime/ParcelableSnapshotMutableState$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/runtime/ParcelableSnapshotMutableState;-><clinit>()V
+HSPLandroidx/compose/runtime/ParcelableSnapshotMutableState;-><init>(Ljava/lang/Object;Landroidx/compose/runtime/SnapshotMutationPolicy;)V
+HSPLandroidx/compose/runtime/PausableMonotonicFrameClock$withFrameNanos$1;-><init>(Landroidx/compose/runtime/PausableMonotonicFrameClock;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/runtime/PausableMonotonicFrameClock$withFrameNanos$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/PausableMonotonicFrameClock;-><clinit>()V
+HSPLandroidx/compose/runtime/PausableMonotonicFrameClock;-><init>(Landroidx/compose/runtime/MonotonicFrameClock;)V
+HSPLandroidx/compose/runtime/PausableMonotonicFrameClock;->fold(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/PausableMonotonicFrameClock;->get(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
+HSPLandroidx/compose/runtime/PausableMonotonicFrameClock;->minusKey(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
+HSPLandroidx/compose/runtime/PausableMonotonicFrameClock;->pause()V
+HSPLandroidx/compose/runtime/PausableMonotonicFrameClock;->resume()V
+HSPLandroidx/compose/runtime/PausableMonotonicFrameClock;->withFrameNanos(Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Pending$keyMap$2;-><init>(Landroidx/compose/runtime/Pending;)V
+HSPLandroidx/compose/runtime/Pending$keyMap$2;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Pending$keyMap$2;->invoke()Ljava/util/HashMap;
+HSPLandroidx/compose/runtime/Pending;-><init>(Ljava/util/List;I)V
+HSPLandroidx/compose/runtime/Pending;->getGroupIndex()I
+HSPLandroidx/compose/runtime/Pending;->getKeyInfos()Ljava/util/List;
+HSPLandroidx/compose/runtime/Pending;->getKeyMap()Ljava/util/HashMap;
+HSPLandroidx/compose/runtime/Pending;->getNext(ILjava/lang/Object;)Landroidx/compose/runtime/KeyInfo;
+HSPLandroidx/compose/runtime/Pending;->getStartIndex()I
+HSPLandroidx/compose/runtime/Pending;->getUsed()Ljava/util/List;
+HSPLandroidx/compose/runtime/Pending;->nodePositionOf(Landroidx/compose/runtime/KeyInfo;)I
+HSPLandroidx/compose/runtime/Pending;->recordUsed(Landroidx/compose/runtime/KeyInfo;)Z
+HSPLandroidx/compose/runtime/Pending;->registerInsert(Landroidx/compose/runtime/KeyInfo;I)V
+HSPLandroidx/compose/runtime/Pending;->registerMoveSlot(II)V
+HSPLandroidx/compose/runtime/Pending;->setGroupIndex(I)V
+HSPLandroidx/compose/runtime/Pending;->slotPositionOf(Landroidx/compose/runtime/KeyInfo;)I
+HSPLandroidx/compose/runtime/Pending;->updatedNodeCountOf(Landroidx/compose/runtime/KeyInfo;)I
+HSPLandroidx/compose/runtime/PrioritySet;-><init>(Ljava/util/List;)V
+HSPLandroidx/compose/runtime/PrioritySet;-><init>(Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/runtime/PrioritySet;->add(I)V
+HSPLandroidx/compose/runtime/PrioritySet;->isNotEmpty()Z
+HSPLandroidx/compose/runtime/PrioritySet;->takeMax()I
+HSPLandroidx/compose/runtime/ProvidableCompositionLocal;-><init>(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/runtime/ProvidableCompositionLocal;->provides(Ljava/lang/Object;)Landroidx/compose/runtime/ProvidedValue;
+HSPLandroidx/compose/runtime/ProvidableCompositionLocal;->providesDefault(Ljava/lang/Object;)Landroidx/compose/runtime/ProvidedValue;
+HSPLandroidx/compose/runtime/ProvidedValue;-><clinit>()V
+HSPLandroidx/compose/runtime/ProvidedValue;-><init>(Landroidx/compose/runtime/CompositionLocal;Ljava/lang/Object;Z)V
+HSPLandroidx/compose/runtime/ProvidedValue;->getCanOverride()Z
+HSPLandroidx/compose/runtime/ProvidedValue;->getCompositionLocal()Landroidx/compose/runtime/CompositionLocal;
+HSPLandroidx/compose/runtime/ProvidedValue;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/RecomposeScopeImpl$end$1$2;-><init>(Landroidx/compose/runtime/RecomposeScopeImpl;ILandroidx/compose/runtime/collection/IdentityArrayIntMap;)V
+HSPLandroidx/compose/runtime/RecomposeScopeImpl$end$1$2;->invoke(Landroidx/compose/runtime/Composition;)V
+HSPLandroidx/compose/runtime/RecomposeScopeImpl$end$1$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;-><init>(Landroidx/compose/runtime/CompositionImpl;)V
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->access$getCurrentToken$p(Landroidx/compose/runtime/RecomposeScopeImpl;)I
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->access$getTrackedInstances$p(Landroidx/compose/runtime/RecomposeScopeImpl;)Landroidx/compose/runtime/collection/IdentityArrayIntMap;
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->compose(Landroidx/compose/runtime/Composer;)V
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->end(I)Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->getAnchor()Landroidx/compose/runtime/Anchor;
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->getCanRecompose()Z
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->getDefaultsInScope()Z
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->getDefaultsInvalid()Z
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->getRequiresRecompose()Z
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->getRereading()Z
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->getSkipped$runtime_release()Z
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->getUsed()Z
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->getValid()Z
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->invalidate()V
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->invalidateForResult(Ljava/lang/Object;)Landroidx/compose/runtime/InvalidationResult;
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->isConditional()Z
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->isInvalidFor(Landroidx/compose/runtime/collection/IdentityArraySet;)Z
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->recordRead(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->scopeSkipped()V
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->setAnchor(Landroidx/compose/runtime/Anchor;)V
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->setDefaultsInScope(Z)V
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->setDefaultsInvalid(Z)V
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->setRequiresRecompose(Z)V
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->setSkipped(Z)V
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->setUsed(Z)V
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->start(I)V
+HSPLandroidx/compose/runtime/RecomposeScopeImpl;->updateScope(Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/runtime/RecomposeScopeImplKt;->updateChangedFlags(I)I
+HSPLandroidx/compose/runtime/Recomposer$Companion;-><init>()V
+HSPLandroidx/compose/runtime/Recomposer$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/runtime/Recomposer$Companion;->access$addRunning(Landroidx/compose/runtime/Recomposer$Companion;Landroidx/compose/runtime/Recomposer$RecomposerInfoImpl;)V
+HSPLandroidx/compose/runtime/Recomposer$Companion;->addRunning(Landroidx/compose/runtime/Recomposer$RecomposerInfoImpl;)V
+HSPLandroidx/compose/runtime/Recomposer$RecomposerInfoImpl;-><init>(Landroidx/compose/runtime/Recomposer;)V
+HSPLandroidx/compose/runtime/Recomposer$State;->$values()[Landroidx/compose/runtime/Recomposer$State;
+HSPLandroidx/compose/runtime/Recomposer$State;-><clinit>()V
+HSPLandroidx/compose/runtime/Recomposer$State;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/runtime/Recomposer$broadcastFrameClock$1;-><init>(Landroidx/compose/runtime/Recomposer;)V
+HSPLandroidx/compose/runtime/Recomposer$broadcastFrameClock$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer$broadcastFrameClock$1;->invoke()V
+HSPLandroidx/compose/runtime/Recomposer$effectJob$1$1;-><init>(Landroidx/compose/runtime/Recomposer;)V
+HSPLandroidx/compose/runtime/Recomposer$join$2;-><init>(Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/runtime/Recomposer$join$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/runtime/Recomposer$join$2;->invoke(Landroidx/compose/runtime/Recomposer$State;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer$join$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer$join$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer$performRecompose$1$1;-><init>(Landroidx/compose/runtime/collection/IdentityArraySet;Landroidx/compose/runtime/ControlledComposition;)V
+HSPLandroidx/compose/runtime/Recomposer$performRecompose$1$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer$performRecompose$1$1;->invoke()V
+HSPLandroidx/compose/runtime/Recomposer$readObserverOf$1;-><init>(Landroidx/compose/runtime/ControlledComposition;)V
+HSPLandroidx/compose/runtime/Recomposer$readObserverOf$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer$readObserverOf$1;->invoke(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/Recomposer$recompositionRunner$2$2;-><init>(Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/MonotonicFrameClock;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/runtime/Recomposer$recompositionRunner$2$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/runtime/Recomposer$recompositionRunner$2$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer$recompositionRunner$2$2;->invoke(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer$recompositionRunner$2$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer$recompositionRunner$2$unregisterApplyObserver$1;-><init>(Landroidx/compose/runtime/Recomposer;)V
+HSPLandroidx/compose/runtime/Recomposer$recompositionRunner$2$unregisterApplyObserver$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer$recompositionRunner$2$unregisterApplyObserver$1;->invoke(Ljava/util/Set;Landroidx/compose/runtime/snapshots/Snapshot;)V
+HSPLandroidx/compose/runtime/Recomposer$recompositionRunner$2;-><init>(Landroidx/compose/runtime/Recomposer;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/MonotonicFrameClock;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/runtime/Recomposer$recompositionRunner$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/runtime/Recomposer$recompositionRunner$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer$recompositionRunner$2;->invoke(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer$recompositionRunner$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer$runRecomposeAndApplyChanges$2$2;-><init>(Landroidx/compose/runtime/Recomposer;Ljava/util/List;Ljava/util/List;Ljava/util/Set;Ljava/util/List;Ljava/util/Set;)V
+HSPLandroidx/compose/runtime/Recomposer$runRecomposeAndApplyChanges$2$2;->invoke(J)V
+HSPLandroidx/compose/runtime/Recomposer$runRecomposeAndApplyChanges$2$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer$runRecomposeAndApplyChanges$2;-><init>(Landroidx/compose/runtime/Recomposer;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/runtime/Recomposer$runRecomposeAndApplyChanges$2;->access$invokeSuspend$fillToInsert(Ljava/util/List;Landroidx/compose/runtime/Recomposer;)V
+HSPLandroidx/compose/runtime/Recomposer$runRecomposeAndApplyChanges$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer$runRecomposeAndApplyChanges$2;->invoke(Lkotlinx/coroutines/CoroutineScope;Landroidx/compose/runtime/MonotonicFrameClock;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer$runRecomposeAndApplyChanges$2;->invokeSuspend$fillToInsert(Ljava/util/List;Landroidx/compose/runtime/Recomposer;)V
+HSPLandroidx/compose/runtime/Recomposer$runRecomposeAndApplyChanges$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer$writeObserverOf$1;-><init>(Landroidx/compose/runtime/ControlledComposition;Landroidx/compose/runtime/collection/IdentityArraySet;)V
+HSPLandroidx/compose/runtime/Recomposer$writeObserverOf$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer$writeObserverOf$1;->invoke(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/Recomposer;-><clinit>()V
+HSPLandroidx/compose/runtime/Recomposer;-><init>(Lkotlin/coroutines/CoroutineContext;)V
+HSPLandroidx/compose/runtime/Recomposer;->access$awaitWorkAvailable(Landroidx/compose/runtime/Recomposer;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer;->access$deriveStateLocked(Landroidx/compose/runtime/Recomposer;)Lkotlinx/coroutines/CancellableContinuation;
+HSPLandroidx/compose/runtime/Recomposer;->access$discardUnusedValues(Landroidx/compose/runtime/Recomposer;)V
+HSPLandroidx/compose/runtime/Recomposer;->access$getBroadcastFrameClock$p(Landroidx/compose/runtime/Recomposer;)Landroidx/compose/runtime/BroadcastFrameClock;
+HSPLandroidx/compose/runtime/Recomposer;->access$getCompositionInvalidations$p(Landroidx/compose/runtime/Recomposer;)Ljava/util/List;
+HSPLandroidx/compose/runtime/Recomposer;->access$getCompositionValuesAwaitingInsert$p(Landroidx/compose/runtime/Recomposer;)Ljava/util/List;
+HSPLandroidx/compose/runtime/Recomposer;->access$getHasFrameWorkLocked(Landroidx/compose/runtime/Recomposer;)Z
+HSPLandroidx/compose/runtime/Recomposer;->access$getHasSchedulingWork(Landroidx/compose/runtime/Recomposer;)Z
+HSPLandroidx/compose/runtime/Recomposer;->access$getKnownCompositions$p(Landroidx/compose/runtime/Recomposer;)Ljava/util/List;
+HSPLandroidx/compose/runtime/Recomposer;->access$getRecomposerInfo$p(Landroidx/compose/runtime/Recomposer;)Landroidx/compose/runtime/Recomposer$RecomposerInfoImpl;
+HSPLandroidx/compose/runtime/Recomposer;->access$getShouldKeepRecomposing(Landroidx/compose/runtime/Recomposer;)Z
+HSPLandroidx/compose/runtime/Recomposer;->access$getSnapshotInvalidations$p(Landroidx/compose/runtime/Recomposer;)Ljava/util/Set;
+HSPLandroidx/compose/runtime/Recomposer;->access$getStateLock$p(Landroidx/compose/runtime/Recomposer;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer;->access$get_runningRecomposers$cp()Lkotlinx/coroutines/flow/MutableStateFlow;
+HSPLandroidx/compose/runtime/Recomposer;->access$get_state$p(Landroidx/compose/runtime/Recomposer;)Lkotlinx/coroutines/flow/MutableStateFlow;
+HSPLandroidx/compose/runtime/Recomposer;->access$performRecompose(Landroidx/compose/runtime/Recomposer;Landroidx/compose/runtime/ControlledComposition;Landroidx/compose/runtime/collection/IdentityArraySet;)Landroidx/compose/runtime/ControlledComposition;
+HSPLandroidx/compose/runtime/Recomposer;->access$recordComposerModificationsLocked(Landroidx/compose/runtime/Recomposer;)V
+HSPLandroidx/compose/runtime/Recomposer;->access$registerRunnerJob(Landroidx/compose/runtime/Recomposer;Lkotlinx/coroutines/Job;)V
+HSPLandroidx/compose/runtime/Recomposer;->access$setChangeCount$p(Landroidx/compose/runtime/Recomposer;J)V
+HSPLandroidx/compose/runtime/Recomposer;->access$setWorkContinuation$p(Landroidx/compose/runtime/Recomposer;Lkotlinx/coroutines/CancellableContinuation;)V
+HSPLandroidx/compose/runtime/Recomposer;->applyAndCheck(Landroidx/compose/runtime/snapshots/MutableSnapshot;)V
+HSPLandroidx/compose/runtime/Recomposer;->awaitWorkAvailable(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer;->composeInitial$runtime_release(Landroidx/compose/runtime/ControlledComposition;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/runtime/Recomposer;->deriveStateLocked()Lkotlinx/coroutines/CancellableContinuation;
+HSPLandroidx/compose/runtime/Recomposer;->discardUnusedValues()V
+HSPLandroidx/compose/runtime/Recomposer;->getChangeCount()J
+HSPLandroidx/compose/runtime/Recomposer;->getCollectingParameterInformation$runtime_release()Z
+HSPLandroidx/compose/runtime/Recomposer;->getCompoundHashKey$runtime_release()I
+HSPLandroidx/compose/runtime/Recomposer;->getCurrentState()Lkotlinx/coroutines/flow/StateFlow;
+HSPLandroidx/compose/runtime/Recomposer;->getEffectCoroutineContext$runtime_release()Lkotlin/coroutines/CoroutineContext;
+HSPLandroidx/compose/runtime/Recomposer;->getHasFrameWorkLocked()Z
+HSPLandroidx/compose/runtime/Recomposer;->getHasSchedulingWork()Z
+HSPLandroidx/compose/runtime/Recomposer;->getShouldKeepRecomposing()Z
+HSPLandroidx/compose/runtime/Recomposer;->invalidate$runtime_release(Landroidx/compose/runtime/ControlledComposition;)V
+HSPLandroidx/compose/runtime/Recomposer;->join(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer;->performInitialMovableContentInserts(Landroidx/compose/runtime/ControlledComposition;)V
+HSPLandroidx/compose/runtime/Recomposer;->performRecompose(Landroidx/compose/runtime/ControlledComposition;Landroidx/compose/runtime/collection/IdentityArraySet;)Landroidx/compose/runtime/ControlledComposition;
+HSPLandroidx/compose/runtime/Recomposer;->readObserverOf(Landroidx/compose/runtime/ControlledComposition;)Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/runtime/Recomposer;->recompositionRunner(Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer;->recordComposerModificationsLocked()V
+HSPLandroidx/compose/runtime/Recomposer;->registerRunnerJob(Lkotlinx/coroutines/Job;)V
+HSPLandroidx/compose/runtime/Recomposer;->runRecomposeAndApplyChanges(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Recomposer;->writeObserverOf(Landroidx/compose/runtime/ControlledComposition;Landroidx/compose/runtime/collection/IdentityArraySet;)Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/runtime/ReferentialEqualityPolicy;-><clinit>()V
+HSPLandroidx/compose/runtime/ReferentialEqualityPolicy;-><init>()V
+HSPLandroidx/compose/runtime/SkippableUpdater;-><init>(Landroidx/compose/runtime/Composer;)V
+HSPLandroidx/compose/runtime/SkippableUpdater;->box-impl(Landroidx/compose/runtime/Composer;)Landroidx/compose/runtime/SkippableUpdater;
+HSPLandroidx/compose/runtime/SkippableUpdater;->constructor-impl(Landroidx/compose/runtime/Composer;)Landroidx/compose/runtime/Composer;
+HSPLandroidx/compose/runtime/SkippableUpdater;->unbox-impl()Landroidx/compose/runtime/Composer;
+HSPLandroidx/compose/runtime/SlotReader;-><init>(Landroidx/compose/runtime/SlotTable;)V
+HSPLandroidx/compose/runtime/SlotReader;->anchor(I)Landroidx/compose/runtime/Anchor;
+HSPLandroidx/compose/runtime/SlotReader;->aux([II)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotReader;->beginEmpty()V
+HSPLandroidx/compose/runtime/SlotReader;->close()V
+HSPLandroidx/compose/runtime/SlotReader;->endEmpty()V
+HSPLandroidx/compose/runtime/SlotReader;->endGroup()V
+HSPLandroidx/compose/runtime/SlotReader;->extractKeys()Ljava/util/List;
+HSPLandroidx/compose/runtime/SlotReader;->getCurrentGroup()I
+HSPLandroidx/compose/runtime/SlotReader;->getGroupAux()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotReader;->getGroupEnd()I
+HSPLandroidx/compose/runtime/SlotReader;->getGroupKey()I
+HSPLandroidx/compose/runtime/SlotReader;->getGroupObjectKey()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotReader;->getGroupSlotIndex()I
+HSPLandroidx/compose/runtime/SlotReader;->getInEmpty()Z
+HSPLandroidx/compose/runtime/SlotReader;->getParent()I
+HSPLandroidx/compose/runtime/SlotReader;->getParentNodes()I
+HSPLandroidx/compose/runtime/SlotReader;->getSize()I
+HSPLandroidx/compose/runtime/SlotReader;->getTable$runtime_release()Landroidx/compose/runtime/SlotTable;
+HSPLandroidx/compose/runtime/SlotReader;->groupAux(I)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotReader;->groupGet(I)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotReader;->groupGet(II)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotReader;->groupKey(I)I
+HSPLandroidx/compose/runtime/SlotReader;->groupObjectKey(I)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotReader;->groupSize(I)I
+HSPLandroidx/compose/runtime/SlotReader;->hasObjectKey(I)Z
+HSPLandroidx/compose/runtime/SlotReader;->isGroupEnd()Z
+HSPLandroidx/compose/runtime/SlotReader;->isNode()Z
+HSPLandroidx/compose/runtime/SlotReader;->isNode(I)Z
+HSPLandroidx/compose/runtime/SlotReader;->next()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotReader;->node(I)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotReader;->node([II)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotReader;->nodeCount(I)I
+HSPLandroidx/compose/runtime/SlotReader;->objectKey([II)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotReader;->parent(I)I
+HSPLandroidx/compose/runtime/SlotReader;->reposition(I)V
+HSPLandroidx/compose/runtime/SlotReader;->restoreParent(I)V
+HSPLandroidx/compose/runtime/SlotReader;->skipGroup()I
+HSPLandroidx/compose/runtime/SlotReader;->skipToGroupEnd()V
+HSPLandroidx/compose/runtime/SlotReader;->startGroup()V
+HSPLandroidx/compose/runtime/SlotReader;->startNode()V
+HSPLandroidx/compose/runtime/SlotTable;-><init>()V
+HSPLandroidx/compose/runtime/SlotTable;->anchorIndex(Landroidx/compose/runtime/Anchor;)I
+HSPLandroidx/compose/runtime/SlotTable;->close$runtime_release(Landroidx/compose/runtime/SlotReader;)V
+HSPLandroidx/compose/runtime/SlotTable;->close$runtime_release(Landroidx/compose/runtime/SlotWriter;[II[Ljava/lang/Object;ILjava/util/ArrayList;)V
+HSPLandroidx/compose/runtime/SlotTable;->getAnchors$runtime_release()Ljava/util/ArrayList;
+HSPLandroidx/compose/runtime/SlotTable;->getGroups()[I
+HSPLandroidx/compose/runtime/SlotTable;->getGroupsSize()I
+HSPLandroidx/compose/runtime/SlotTable;->getSlots()[Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotTable;->getSlotsSize()I
+HSPLandroidx/compose/runtime/SlotTable;->isEmpty()Z
+HSPLandroidx/compose/runtime/SlotTable;->openReader()Landroidx/compose/runtime/SlotReader;
+HSPLandroidx/compose/runtime/SlotTable;->openWriter()Landroidx/compose/runtime/SlotWriter;
+HSPLandroidx/compose/runtime/SlotTable;->ownsAnchor(Landroidx/compose/runtime/Anchor;)Z
+HSPLandroidx/compose/runtime/SlotTable;->setTo$runtime_release([II[Ljava/lang/Object;ILjava/util/ArrayList;)V
+HSPLandroidx/compose/runtime/SlotTableKt;->access$auxIndex([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->access$containsAnyMark([II)Z
+HSPLandroidx/compose/runtime/SlotTableKt;->access$containsMark([II)Z
+HSPLandroidx/compose/runtime/SlotTableKt;->access$countOneBits(I)I
+HSPLandroidx/compose/runtime/SlotTableKt;->access$dataAnchor([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->access$groupInfo([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->access$groupSize([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->access$hasAux([II)Z
+HSPLandroidx/compose/runtime/SlotTableKt;->access$hasMark([II)Z
+HSPLandroidx/compose/runtime/SlotTableKt;->access$hasObjectKey([II)Z
+HSPLandroidx/compose/runtime/SlotTableKt;->access$initGroup([IIIZZZII)V
+HSPLandroidx/compose/runtime/SlotTableKt;->access$isNode([II)Z
+HSPLandroidx/compose/runtime/SlotTableKt;->access$key([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->access$locationOf(Ljava/util/ArrayList;II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->access$nodeCount([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->access$nodeIndex([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->access$objectKeyIndex([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->access$parentAnchor([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->access$search(Ljava/util/ArrayList;II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->access$slotAnchor([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->access$updateContainsMark([IIZ)V
+HSPLandroidx/compose/runtime/SlotTableKt;->access$updateDataAnchor([III)V
+HSPLandroidx/compose/runtime/SlotTableKt;->access$updateGroupSize([III)V
+HSPLandroidx/compose/runtime/SlotTableKt;->access$updateMark([IIZ)V
+HSPLandroidx/compose/runtime/SlotTableKt;->access$updateNodeCount([III)V
+HSPLandroidx/compose/runtime/SlotTableKt;->access$updateParentAnchor([III)V
+HSPLandroidx/compose/runtime/SlotTableKt;->auxIndex([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->containsAnyMark([II)Z
+HSPLandroidx/compose/runtime/SlotTableKt;->containsMark([II)Z
+HSPLandroidx/compose/runtime/SlotTableKt;->countOneBits(I)I
+HSPLandroidx/compose/runtime/SlotTableKt;->dataAnchor([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->groupInfo([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->groupSize([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->hasAux([II)Z
+HSPLandroidx/compose/runtime/SlotTableKt;->hasMark([II)Z
+HSPLandroidx/compose/runtime/SlotTableKt;->hasObjectKey([II)Z
+HSPLandroidx/compose/runtime/SlotTableKt;->initGroup([IIIZZZII)V
+HSPLandroidx/compose/runtime/SlotTableKt;->isNode([II)Z
+HSPLandroidx/compose/runtime/SlotTableKt;->key([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->locationOf(Ljava/util/ArrayList;II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->nodeCount([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->nodeIndex([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->objectKeyIndex([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->parentAnchor([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->search(Ljava/util/ArrayList;II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->slotAnchor([II)I
+HSPLandroidx/compose/runtime/SlotTableKt;->updateContainsMark([IIZ)V
+HSPLandroidx/compose/runtime/SlotTableKt;->updateDataAnchor([III)V
+HSPLandroidx/compose/runtime/SlotTableKt;->updateGroupSize([III)V
+HSPLandroidx/compose/runtime/SlotTableKt;->updateMark([IIZ)V
+HSPLandroidx/compose/runtime/SlotTableKt;->updateNodeCount([III)V
+HSPLandroidx/compose/runtime/SlotTableKt;->updateParentAnchor([III)V
+HSPLandroidx/compose/runtime/SlotWriter$Companion;-><init>()V
+HSPLandroidx/compose/runtime/SlotWriter$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/runtime/SlotWriter$Companion;->access$moveGroup(Landroidx/compose/runtime/SlotWriter$Companion;Landroidx/compose/runtime/SlotWriter;ILandroidx/compose/runtime/SlotWriter;ZZ)Ljava/util/List;
+HSPLandroidx/compose/runtime/SlotWriter$Companion;->moveGroup(Landroidx/compose/runtime/SlotWriter;ILandroidx/compose/runtime/SlotWriter;ZZ)Ljava/util/List;
+HSPLandroidx/compose/runtime/SlotWriter;-><clinit>()V
+HSPLandroidx/compose/runtime/SlotWriter;-><init>(Landroidx/compose/runtime/SlotTable;)V
+HSPLandroidx/compose/runtime/SlotWriter;->access$containsAnyGroupMarks(Landroidx/compose/runtime/SlotWriter;I)Z
+HSPLandroidx/compose/runtime/SlotWriter;->access$dataIndex(Landroidx/compose/runtime/SlotWriter;I)I
+HSPLandroidx/compose/runtime/SlotWriter;->access$dataIndex(Landroidx/compose/runtime/SlotWriter;[II)I
+HSPLandroidx/compose/runtime/SlotWriter;->access$dataIndexToDataAnchor(Landroidx/compose/runtime/SlotWriter;IIII)I
+HSPLandroidx/compose/runtime/SlotWriter;->access$getAnchors$p(Landroidx/compose/runtime/SlotWriter;)Ljava/util/ArrayList;
+HSPLandroidx/compose/runtime/SlotWriter;->access$getCurrentSlot$p(Landroidx/compose/runtime/SlotWriter;)I
+HSPLandroidx/compose/runtime/SlotWriter;->access$getGroupGapStart$p(Landroidx/compose/runtime/SlotWriter;)I
+HSPLandroidx/compose/runtime/SlotWriter;->access$getGroups$p(Landroidx/compose/runtime/SlotWriter;)[I
+HSPLandroidx/compose/runtime/SlotWriter;->access$getNodeCount$p(Landroidx/compose/runtime/SlotWriter;)I
+HSPLandroidx/compose/runtime/SlotWriter;->access$getSlots$p(Landroidx/compose/runtime/SlotWriter;)[Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotWriter;->access$getSlotsGapLen$p(Landroidx/compose/runtime/SlotWriter;)I
+HSPLandroidx/compose/runtime/SlotWriter;->access$getSlotsGapOwner$p(Landroidx/compose/runtime/SlotWriter;)I
+HSPLandroidx/compose/runtime/SlotWriter;->access$getSlotsGapStart$p(Landroidx/compose/runtime/SlotWriter;)I
+HSPLandroidx/compose/runtime/SlotWriter;->access$insertGroups(Landroidx/compose/runtime/SlotWriter;I)V
+HSPLandroidx/compose/runtime/SlotWriter;->access$insertSlots(Landroidx/compose/runtime/SlotWriter;II)V
+HSPLandroidx/compose/runtime/SlotWriter;->access$setCurrentGroup$p(Landroidx/compose/runtime/SlotWriter;I)V
+HSPLandroidx/compose/runtime/SlotWriter;->access$setCurrentSlot$p(Landroidx/compose/runtime/SlotWriter;I)V
+HSPLandroidx/compose/runtime/SlotWriter;->access$setNodeCount$p(Landroidx/compose/runtime/SlotWriter;I)V
+HSPLandroidx/compose/runtime/SlotWriter;->access$setSlotsGapOwner$p(Landroidx/compose/runtime/SlotWriter;I)V
+HSPLandroidx/compose/runtime/SlotWriter;->advanceBy(I)V
+HSPLandroidx/compose/runtime/SlotWriter;->anchor(I)Landroidx/compose/runtime/Anchor;
+HSPLandroidx/compose/runtime/SlotWriter;->anchorIndex(Landroidx/compose/runtime/Anchor;)I
+HSPLandroidx/compose/runtime/SlotWriter;->auxIndex([II)I
+HSPLandroidx/compose/runtime/SlotWriter;->beginInsert()V
+HSPLandroidx/compose/runtime/SlotWriter;->childContainsAnyMarks(I)Z
+HSPLandroidx/compose/runtime/SlotWriter;->close()V
+HSPLandroidx/compose/runtime/SlotWriter;->containsAnyGroupMarks(I)Z
+HSPLandroidx/compose/runtime/SlotWriter;->containsGroupMark(I)Z
+HSPLandroidx/compose/runtime/SlotWriter;->dataAnchorToDataIndex(III)I
+HSPLandroidx/compose/runtime/SlotWriter;->dataIndex(I)I
+HSPLandroidx/compose/runtime/SlotWriter;->dataIndex([II)I
+HSPLandroidx/compose/runtime/SlotWriter;->dataIndexToDataAddress(I)I
+HSPLandroidx/compose/runtime/SlotWriter;->dataIndexToDataAnchor(IIII)I
+HSPLandroidx/compose/runtime/SlotWriter;->endGroup()I
+HSPLandroidx/compose/runtime/SlotWriter;->endInsert()V
+HSPLandroidx/compose/runtime/SlotWriter;->ensureStarted(I)V
+HSPLandroidx/compose/runtime/SlotWriter;->ensureStarted(Landroidx/compose/runtime/Anchor;)V
+HSPLandroidx/compose/runtime/SlotWriter;->getCapacity()I
+HSPLandroidx/compose/runtime/SlotWriter;->getClosed()Z
+HSPLandroidx/compose/runtime/SlotWriter;->getCurrentGroup()I
+HSPLandroidx/compose/runtime/SlotWriter;->getParent()I
+HSPLandroidx/compose/runtime/SlotWriter;->getSize$runtime_release()I
+HSPLandroidx/compose/runtime/SlotWriter;->getTable$runtime_release()Landroidx/compose/runtime/SlotTable;
+HSPLandroidx/compose/runtime/SlotWriter;->groupAux(I)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotWriter;->groupIndexToAddress(I)I
+HSPLandroidx/compose/runtime/SlotWriter;->groupKey(I)I
+HSPLandroidx/compose/runtime/SlotWriter;->groupObjectKey(I)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotWriter;->groupSize(I)I
+HSPLandroidx/compose/runtime/SlotWriter;->insertGroups(I)V
+HSPLandroidx/compose/runtime/SlotWriter;->insertSlots(II)V
+HSPLandroidx/compose/runtime/SlotWriter;->markGroup$default(Landroidx/compose/runtime/SlotWriter;IILjava/lang/Object;)V
+HSPLandroidx/compose/runtime/SlotWriter;->markGroup(I)V
+HSPLandroidx/compose/runtime/SlotWriter;->moveFrom(Landroidx/compose/runtime/SlotTable;I)Ljava/util/List;
+HSPLandroidx/compose/runtime/SlotWriter;->moveGroupGapTo(I)V
+HSPLandroidx/compose/runtime/SlotWriter;->moveSlotGapTo(II)V+]Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/SlotWriter;
+HSPLandroidx/compose/runtime/SlotWriter;->node(I)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotWriter;->node(Landroidx/compose/runtime/Anchor;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotWriter;->nodeIndex([II)I
+HSPLandroidx/compose/runtime/SlotWriter;->parent(I)I
+HSPLandroidx/compose/runtime/SlotWriter;->parent([II)I
+HSPLandroidx/compose/runtime/SlotWriter;->parentAnchorToIndex(I)I+]Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/SlotWriter;
+HSPLandroidx/compose/runtime/SlotWriter;->parentIndexToAnchor(II)I
+HSPLandroidx/compose/runtime/SlotWriter;->recalculateMarks()V
+HSPLandroidx/compose/runtime/SlotWriter;->removeAnchors(II)Z
+HSPLandroidx/compose/runtime/SlotWriter;->removeGroup()Z
+HSPLandroidx/compose/runtime/SlotWriter;->removeGroups(II)Z
+HSPLandroidx/compose/runtime/SlotWriter;->removeSlots(III)V
+HSPLandroidx/compose/runtime/SlotWriter;->restoreCurrentGroupEnd()I
+HSPLandroidx/compose/runtime/SlotWriter;->saveCurrentGroupEnd()V
+HSPLandroidx/compose/runtime/SlotWriter;->set(ILjava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotWriter;->set(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/SlotWriter;->skip()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotWriter;->skipGroup()I
+HSPLandroidx/compose/runtime/SlotWriter;->skipToGroupEnd()V
+HSPLandroidx/compose/runtime/SlotWriter;->slotIndex([II)I
+HSPLandroidx/compose/runtime/SlotWriter;->startData(ILjava/lang/Object;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/SlotWriter;->startGroup()V
+HSPLandroidx/compose/runtime/SlotWriter;->startGroup(ILjava/lang/Object;)V
+HSPLandroidx/compose/runtime/SlotWriter;->startGroup(ILjava/lang/Object;ZLjava/lang/Object;)V
+HSPLandroidx/compose/runtime/SlotWriter;->startNode(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/SlotWriter;->update(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SlotWriter;->updateAnchors(II)V
+HSPLandroidx/compose/runtime/SlotWriter;->updateAux(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/SlotWriter;->updateContainsMark(I)V
+HSPLandroidx/compose/runtime/SlotWriter;->updateContainsMarkNow(ILandroidx/compose/runtime/PrioritySet;)V
+HSPLandroidx/compose/runtime/SlotWriter;->updateNode(Landroidx/compose/runtime/Anchor;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/SlotWriter;->updateNodeOfGroup(ILjava/lang/Object;)V
+HSPLandroidx/compose/runtime/SnapshotMutableStateImpl$StateStateRecord;-><init>(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/SnapshotMutableStateImpl$StateStateRecord;->create()Landroidx/compose/runtime/snapshots/StateRecord;
+HSPLandroidx/compose/runtime/SnapshotMutableStateImpl$StateStateRecord;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SnapshotMutableStateImpl$StateStateRecord;->setValue(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/SnapshotMutableStateImpl;-><init>(Ljava/lang/Object;Landroidx/compose/runtime/SnapshotMutationPolicy;)V
+HSPLandroidx/compose/runtime/SnapshotMutableStateImpl;->getFirstStateRecord()Landroidx/compose/runtime/snapshots/StateRecord;
+HSPLandroidx/compose/runtime/SnapshotMutableStateImpl;->getPolicy()Landroidx/compose/runtime/SnapshotMutationPolicy;
+HSPLandroidx/compose/runtime/SnapshotMutableStateImpl;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/SnapshotMutableStateImpl;->prependStateRecord(Landroidx/compose/runtime/snapshots/StateRecord;)V
+HSPLandroidx/compose/runtime/SnapshotMutableStateImpl;->setValue(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/SnapshotStateKt;->mutableStateListOf()Landroidx/compose/runtime/snapshots/SnapshotStateList;
+HSPLandroidx/compose/runtime/SnapshotStateKt;->mutableStateOf$default(Ljava/lang/Object;Landroidx/compose/runtime/SnapshotMutationPolicy;ILjava/lang/Object;)Landroidx/compose/runtime/MutableState;
+HSPLandroidx/compose/runtime/SnapshotStateKt;->mutableStateOf(Ljava/lang/Object;Landroidx/compose/runtime/SnapshotMutationPolicy;)Landroidx/compose/runtime/MutableState;
+HSPLandroidx/compose/runtime/SnapshotStateKt;->neverEqualPolicy()Landroidx/compose/runtime/SnapshotMutationPolicy;
+HSPLandroidx/compose/runtime/SnapshotStateKt;->observeDerivedStateRecalculations(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/runtime/SnapshotStateKt;->referentialEqualityPolicy()Landroidx/compose/runtime/SnapshotMutationPolicy;
+HSPLandroidx/compose/runtime/SnapshotStateKt;->rememberUpdatedState(Ljava/lang/Object;Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/runtime/SnapshotStateKt;->snapshotFlow(Lkotlin/jvm/functions/Function0;)Lkotlinx/coroutines/flow/Flow;
+HSPLandroidx/compose/runtime/SnapshotStateKt;->structuralEqualityPolicy()Landroidx/compose/runtime/SnapshotMutationPolicy;
+HSPLandroidx/compose/runtime/SnapshotStateKt__DerivedStateKt;-><clinit>()V
+HSPLandroidx/compose/runtime/SnapshotStateKt__DerivedStateKt;->observeDerivedStateRecalculations(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/runtime/SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1;-><init>(Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/runtime/SnapshotStateKt__SnapshotFlowKt;->snapshotFlow(Lkotlin/jvm/functions/Function0;)Lkotlinx/coroutines/flow/Flow;
+HSPLandroidx/compose/runtime/SnapshotStateKt__SnapshotMutationPolicyKt;->neverEqualPolicy()Landroidx/compose/runtime/SnapshotMutationPolicy;
+HSPLandroidx/compose/runtime/SnapshotStateKt__SnapshotMutationPolicyKt;->referentialEqualityPolicy()Landroidx/compose/runtime/SnapshotMutationPolicy;
+HSPLandroidx/compose/runtime/SnapshotStateKt__SnapshotMutationPolicyKt;->structuralEqualityPolicy()Landroidx/compose/runtime/SnapshotMutationPolicy;
+HSPLandroidx/compose/runtime/SnapshotStateKt__SnapshotStateKt;->mutableStateListOf()Landroidx/compose/runtime/snapshots/SnapshotStateList;
+HSPLandroidx/compose/runtime/SnapshotStateKt__SnapshotStateKt;->mutableStateOf$default(Ljava/lang/Object;Landroidx/compose/runtime/SnapshotMutationPolicy;ILjava/lang/Object;)Landroidx/compose/runtime/MutableState;
+HSPLandroidx/compose/runtime/SnapshotStateKt__SnapshotStateKt;->mutableStateOf(Ljava/lang/Object;Landroidx/compose/runtime/SnapshotMutationPolicy;)Landroidx/compose/runtime/MutableState;
+HSPLandroidx/compose/runtime/SnapshotStateKt__SnapshotStateKt;->rememberUpdatedState(Ljava/lang/Object;Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/runtime/SnapshotThreadLocal;-><init>()V
+HSPLandroidx/compose/runtime/SnapshotThreadLocal;->get()Ljava/lang/Object;+]Landroidx/compose/runtime/internal/ThreadMap;Landroidx/compose/runtime/internal/ThreadMap;
+HSPLandroidx/compose/runtime/SnapshotThreadLocal;->set(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/Stack;-><init>()V
+HSPLandroidx/compose/runtime/Stack;->clear()V
+HSPLandroidx/compose/runtime/Stack;->getSize()I
+HSPLandroidx/compose/runtime/Stack;->isEmpty()Z
+HSPLandroidx/compose/runtime/Stack;->isNotEmpty()Z
+HSPLandroidx/compose/runtime/Stack;->peek()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Stack;->pop()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Stack;->push(Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/Stack;->toArray()[Ljava/lang/Object;
+HSPLandroidx/compose/runtime/StaticProvidableCompositionLocal;-><init>(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/runtime/StaticProvidableCompositionLocal;->provided$runtime_release(Ljava/lang/Object;Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/runtime/StaticValueHolder;-><init>(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/StaticValueHolder;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/StaticValueHolder;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/StructuralEqualityPolicy;-><clinit>()V
+HSPLandroidx/compose/runtime/StructuralEqualityPolicy;-><init>()V
+HSPLandroidx/compose/runtime/StructuralEqualityPolicy;->equivalent(Ljava/lang/Object;Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/Trace;-><clinit>()V
+HSPLandroidx/compose/runtime/Trace;-><init>()V
+HSPLandroidx/compose/runtime/Trace;->beginSection(Ljava/lang/String;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/Trace;->endSection(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/Updater;->constructor-impl(Landroidx/compose/runtime/Composer;)Landroidx/compose/runtime/Composer;
+HSPLandroidx/compose/runtime/Updater;->set-impl(Landroidx/compose/runtime/Composer;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/runtime/collection/IdentityArrayIntMap;-><init>()V
+HSPLandroidx/compose/runtime/collection/IdentityArrayIntMap;->add(Ljava/lang/Object;I)I
+HSPLandroidx/compose/runtime/collection/IdentityArrayIntMap;->find(Ljava/lang/Object;)I
+HSPLandroidx/compose/runtime/collection/IdentityArrayIntMap;->getKeys()[Ljava/lang/Object;
+HSPLandroidx/compose/runtime/collection/IdentityArrayIntMap;->getSize()I
+HSPLandroidx/compose/runtime/collection/IdentityArrayIntMap;->getValues()[I
+HSPLandroidx/compose/runtime/collection/IdentityArrayIntMap;->setSize(I)V
+HSPLandroidx/compose/runtime/collection/IdentityArrayMap;-><init>(I)V
+HSPLandroidx/compose/runtime/collection/IdentityArrayMap;-><init>(IILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/runtime/collection/IdentityArrayMap;->contains(Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/collection/IdentityArrayMap;->find(Ljava/lang/Object;)I
+HSPLandroidx/compose/runtime/collection/IdentityArrayMap;->get(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/collection/IdentityArrayMap;->getKeys$runtime_release()[Ljava/lang/Object;
+HSPLandroidx/compose/runtime/collection/IdentityArrayMap;->getSize$runtime_release()I
+HSPLandroidx/compose/runtime/collection/IdentityArrayMap;->getValues$runtime_release()[Ljava/lang/Object;
+HSPLandroidx/compose/runtime/collection/IdentityArrayMap;->isNotEmpty()Z
+HSPLandroidx/compose/runtime/collection/IdentityArrayMap;->set(Ljava/lang/Object;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/collection/IdentityArraySet;-><init>()V
+HSPLandroidx/compose/runtime/collection/IdentityArraySet;->add(Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/collection/IdentityArraySet;->clear()V
+HSPLandroidx/compose/runtime/collection/IdentityArraySet;->contains(Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/collection/IdentityArraySet;->find(Ljava/lang/Object;)I
+HSPLandroidx/compose/runtime/collection/IdentityArraySet;->get(I)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/collection/IdentityArraySet;->getSize()I
+HSPLandroidx/compose/runtime/collection/IdentityArraySet;->getValues()[Ljava/lang/Object;
+HSPLandroidx/compose/runtime/collection/IdentityArraySet;->isNotEmpty()Z
+HSPLandroidx/compose/runtime/collection/IdentityArraySet;->remove(Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/collection/IdentityArraySet;->setSize(I)V
+HSPLandroidx/compose/runtime/collection/IdentityArraySet;->size()I+]Landroidx/compose/runtime/collection/IdentityArraySet;Landroidx/compose/runtime/collection/IdentityArraySet;
+HSPLandroidx/compose/runtime/collection/IdentityScopeMap;-><init>()V
+HSPLandroidx/compose/runtime/collection/IdentityScopeMap;->access$find(Landroidx/compose/runtime/collection/IdentityScopeMap;Ljava/lang/Object;)I
+HSPLandroidx/compose/runtime/collection/IdentityScopeMap;->access$scopeSetAt(Landroidx/compose/runtime/collection/IdentityScopeMap;I)Landroidx/compose/runtime/collection/IdentityArraySet;
+HSPLandroidx/compose/runtime/collection/IdentityScopeMap;->add(Ljava/lang/Object;Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/collection/IdentityScopeMap;->contains(Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/collection/IdentityScopeMap;->find(Ljava/lang/Object;)I
+HSPLandroidx/compose/runtime/collection/IdentityScopeMap;->getOrCreateIdentitySet(Ljava/lang/Object;)Landroidx/compose/runtime/collection/IdentityArraySet;
+HSPLandroidx/compose/runtime/collection/IdentityScopeMap;->getScopeSets()[Landroidx/compose/runtime/collection/IdentityArraySet;
+HSPLandroidx/compose/runtime/collection/IdentityScopeMap;->getSize()I
+HSPLandroidx/compose/runtime/collection/IdentityScopeMap;->getValueOrder()[I
+HSPLandroidx/compose/runtime/collection/IdentityScopeMap;->getValues()[Ljava/lang/Object;
+HSPLandroidx/compose/runtime/collection/IdentityScopeMap;->remove(Ljava/lang/Object;Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/collection/IdentityScopeMap;->scopeSetAt(I)Landroidx/compose/runtime/collection/IdentityArraySet;
+HSPLandroidx/compose/runtime/collection/IdentityScopeMap;->setSize(I)V
+HSPLandroidx/compose/runtime/collection/MutableVector$MutableVectorList;-><init>(Landroidx/compose/runtime/collection/MutableVector;)V
+HSPLandroidx/compose/runtime/collection/MutableVector$MutableVectorList;->get(I)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/collection/MutableVector$MutableVectorList;->getSize()I
+HSPLandroidx/compose/runtime/collection/MutableVector$MutableVectorList;->indexOf(Ljava/lang/Object;)I
+HSPLandroidx/compose/runtime/collection/MutableVector$MutableVectorList;->isEmpty()Z
+HSPLandroidx/compose/runtime/collection/MutableVector$MutableVectorList;->size()I
+HSPLandroidx/compose/runtime/collection/MutableVector;-><clinit>()V
+HSPLandroidx/compose/runtime/collection/MutableVector;-><init>([Ljava/lang/Object;I)V
+HSPLandroidx/compose/runtime/collection/MutableVector;->add(ILjava/lang/Object;)V
+HSPLandroidx/compose/runtime/collection/MutableVector;->add(Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/collection/MutableVector;->addAll(ILandroidx/compose/runtime/collection/MutableVector;)Z
+HSPLandroidx/compose/runtime/collection/MutableVector;->asMutableList()Ljava/util/List;
+HSPLandroidx/compose/runtime/collection/MutableVector;->clear()V
+HSPLandroidx/compose/runtime/collection/MutableVector;->contains(Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/collection/MutableVector;->ensureCapacity(I)V
+HSPLandroidx/compose/runtime/collection/MutableVector;->getContent()[Ljava/lang/Object;
+HSPLandroidx/compose/runtime/collection/MutableVector;->getSize()I
+HSPLandroidx/compose/runtime/collection/MutableVector;->indexOf(Ljava/lang/Object;)I
+HSPLandroidx/compose/runtime/collection/MutableVector;->isEmpty()Z
+HSPLandroidx/compose/runtime/collection/MutableVector;->isNotEmpty()Z
+HSPLandroidx/compose/runtime/collection/MutableVector;->remove(Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/collection/MutableVector;->removeAt(I)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/collection/MutableVector;->removeRange(II)V
+HSPLandroidx/compose/runtime/collection/MutableVector;->set(ILjava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/collection/MutableVector;->sortWith(Ljava/util/Comparator;)V
+HSPLandroidx/compose/runtime/collection/MutableVectorKt;->access$checkIndex(Ljava/util/List;I)V
+HSPLandroidx/compose/runtime/collection/MutableVectorKt;->checkIndex(Ljava/util/List;I)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/ExtensionsKt;->persistentHashMapOf()Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/ExtensionsKt;->persistentListOf()Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentList;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/ExtensionsKt;->persistentSetOf()Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentSet;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/AbstractPersistentList;-><init>()V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/SmallPersistentVector$Companion;-><init>()V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/SmallPersistentVector$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/SmallPersistentVector$Companion;->getEMPTY()Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/SmallPersistentVector;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/SmallPersistentVector;-><clinit>()V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/SmallPersistentVector;-><init>([Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/SmallPersistentVector;->access$getEMPTY$cp()Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/SmallPersistentVector;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/SmallPersistentVector;->getSize()I
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/UtilsKt;->persistentVectorOf()Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentList;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/MapEntry;-><init>(Ljava/lang/Object;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/MapEntry;->getKey()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/MapEntry;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap$Companion;-><init>()V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap$Companion;->emptyOf$runtime_release()Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;-><clinit>()V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;-><init>(Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;I)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;->access$getEMPTY$cp()Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;->builder()Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap$Builder;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;->builder()Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilder;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;->containsKey(Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;->createEntries()Landroidx/compose/runtime/external/kotlinx/collections/immutable/ImmutableSet;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;->get(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;->getEntries()Ljava/util/Set;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;->getNode$runtime_release()Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;->getSize()I
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;->put(Ljava/lang/Object;Ljava/lang/Object;)Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBaseIterator;-><init>(Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;[Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeBaseIterator;)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBaseIterator;->checkHasNext()V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBaseIterator;->ensureNextEntryIsReady()V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBaseIterator;->hasNext()Z
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBaseIterator;->moveToNextNodeWithData(I)I
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBaseIterator;->next()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilder;-><init>(Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilder;->build()Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilder;->build()Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilder;->getModCount$runtime_release()I
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilder;->getOwnership$runtime_release()Landroidx/compose/runtime/external/kotlinx/collections/immutable/internal/MutabilityOwnership;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilder;->getSize()I
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilder;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilder;->putAll(Ljava/util/Map;)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilder;->setModCount$runtime_release(I)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilder;->setOperationResult$runtime_release(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilder;->setSize(I)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapEntries;-><init>(Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapEntries;->getSize()I
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapEntries;->iterator()Ljava/util/Iterator;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapEntriesIterator;-><init>(Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode$Companion;-><init>()V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode$Companion;->getEMPTY$runtime_release()Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode$ModificationResult;-><init>(Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;I)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode$ModificationResult;->getNode()Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode$ModificationResult;->getSizeDelta()I
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;-><clinit>()V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;-><init>(II[Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;-><init>(II[Ljava/lang/Object;Landroidx/compose/runtime/external/kotlinx/collections/immutable/internal/MutabilityOwnership;)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->access$getEMPTY$cp()Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->asInsertResult()Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode$ModificationResult;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->containsKey(ILjava/lang/Object;I)Z
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->elementsIdentityEquals(Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;)Z
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->entryCount$runtime_release()I
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->entryKeyIndex$runtime_release(I)I
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->get(ILjava/lang/Object;I)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->getBuffer$runtime_release()[Ljava/lang/Object;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->hasEntryAt$runtime_release(I)Z
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->hasNodeAt(I)Z
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->insertEntryAt(ILjava/lang/Object;Ljava/lang/Object;)Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->keyAtIndex(I)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->makeNode(ILjava/lang/Object;Ljava/lang/Object;ILjava/lang/Object;Ljava/lang/Object;ILandroidx/compose/runtime/external/kotlinx/collections/immutable/internal/MutabilityOwnership;)Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->mutableInsertEntryAt(ILjava/lang/Object;Ljava/lang/Object;Landroidx/compose/runtime/external/kotlinx/collections/immutable/internal/MutabilityOwnership;)Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->mutablePut(ILjava/lang/Object;Ljava/lang/Object;ILandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilder;)Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->mutablePutAll(Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;ILandroidx/compose/runtime/external/kotlinx/collections/immutable/internal/DeltaCounter;Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilder;)Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->mutablePutAllFromOtherNodeCell(Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;IILandroidx/compose/runtime/external/kotlinx/collections/immutable/internal/DeltaCounter;Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilder;)Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->mutableUpdateValueAtIndex(ILjava/lang/Object;Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilder;)Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->nodeAtIndex$runtime_release(I)Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->nodeIndex$runtime_release(I)I
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->put(ILjava/lang/Object;Ljava/lang/Object;I)Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode$ModificationResult;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->valueAtKeyIndex(I)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeBaseIterator;-><init>()V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeBaseIterator;->currentNode()Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeBaseIterator;->getBuffer()[Ljava/lang/Object;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeBaseIterator;->getIndex()I
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeBaseIterator;->hasNextKey()Z
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeBaseIterator;->hasNextNode()Z
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeBaseIterator;->reset([Ljava/lang/Object;I)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeBaseIterator;->reset([Ljava/lang/Object;II)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeBaseIterator;->setIndex(I)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeEntriesIterator;-><init>()V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeEntriesIterator;->next()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeEntriesIterator;->next()Ljava/util/Map$Entry;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeKt;->access$insertEntryAtIndex([Ljava/lang/Object;ILjava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeKt;->indexSegment(II)I
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeKt;->insertEntryAtIndex([Ljava/lang/Object;ILjava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/Links;-><init>()V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/Links;-><init>(Ljava/lang/Object;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/PersistentOrderedSet$Companion;-><init>()V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/PersistentOrderedSet$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/PersistentOrderedSet$Companion;->emptyOf$runtime_release()Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentSet;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/PersistentOrderedSet;-><clinit>()V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/PersistentOrderedSet;-><init>(Ljava/lang/Object;Ljava/lang/Object;Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/PersistentOrderedSet;->access$getEMPTY$cp()Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/PersistentOrderedSet;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/PersistentOrderedSet;->add(Ljava/lang/Object;)Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentSet;
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/PersistentOrderedSet;->getSize()I
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/internal/CommonFunctionsKt;->assert(Z)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/internal/DeltaCounter;-><init>(I)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/internal/DeltaCounter;-><init>(IILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/internal/DeltaCounter;->getCount()I
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/internal/DeltaCounter;->setCount(I)V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/internal/EndOfChain;-><clinit>()V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/internal/EndOfChain;-><init>()V
+HSPLandroidx/compose/runtime/external/kotlinx/collections/immutable/internal/MutabilityOwnership;-><init>()V
+HSPLandroidx/compose/runtime/internal/ComposableLambdaImpl$invoke$1;-><init>(Landroidx/compose/runtime/internal/ComposableLambdaImpl;Ljava/lang/Object;I)V
+HSPLandroidx/compose/runtime/internal/ComposableLambdaImpl$invoke$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/runtime/internal/ComposableLambdaImpl$invoke$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/internal/ComposableLambdaImpl;-><init>(IZ)V
+HSPLandroidx/compose/runtime/internal/ComposableLambdaImpl;->invoke(Landroidx/compose/runtime/Composer;I)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/internal/ComposableLambdaImpl;->invoke(Ljava/lang/Object;Landroidx/compose/runtime/Composer;I)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/internal/ComposableLambdaImpl;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/internal/ComposableLambdaImpl;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/internal/ComposableLambdaImpl;->trackRead(Landroidx/compose/runtime/Composer;)V
+HSPLandroidx/compose/runtime/internal/ComposableLambdaImpl;->trackWrite()V
+HSPLandroidx/compose/runtime/internal/ComposableLambdaImpl;->update(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/internal/ComposableLambdaKt;->bitsForSlot(II)I
+HSPLandroidx/compose/runtime/internal/ComposableLambdaKt;->composableLambda(Landroidx/compose/runtime/Composer;IZLjava/lang/Object;)Landroidx/compose/runtime/internal/ComposableLambda;
+HSPLandroidx/compose/runtime/internal/ComposableLambdaKt;->composableLambdaInstance(IZLjava/lang/Object;)Landroidx/compose/runtime/internal/ComposableLambda;
+HSPLandroidx/compose/runtime/internal/ComposableLambdaKt;->differentBits(I)I
+HSPLandroidx/compose/runtime/internal/ComposableLambdaKt;->replacableWith(Landroidx/compose/runtime/RecomposeScope;Landroidx/compose/runtime/RecomposeScope;)Z
+HSPLandroidx/compose/runtime/internal/ComposableLambdaKt;->sameBits(I)I
+HSPLandroidx/compose/runtime/internal/ThreadMap;-><init>(I[J[Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/internal/ThreadMap;->find(J)I
+HSPLandroidx/compose/runtime/internal/ThreadMap;->get(J)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/internal/ThreadMap;->newWith(JLjava/lang/Object;)Landroidx/compose/runtime/internal/ThreadMap;
+HSPLandroidx/compose/runtime/internal/ThreadMap;->trySet(JLjava/lang/Object;)Z
+HSPLandroidx/compose/runtime/internal/ThreadMapKt;-><clinit>()V
+HSPLandroidx/compose/runtime/internal/ThreadMapKt;->getEmptyThreadMap()Landroidx/compose/runtime/internal/ThreadMap;
+HSPLandroidx/compose/runtime/saveable/RememberSaveableKt$rememberSaveable$1$invoke$$inlined$onDispose$1;-><init>(Landroidx/compose/runtime/saveable/SaveableStateRegistry$Entry;)V
+HSPLandroidx/compose/runtime/saveable/RememberSaveableKt$rememberSaveable$1$valueProvider$1$1$1;-><init>(Landroidx/compose/runtime/saveable/SaveableStateRegistry;)V
+HSPLandroidx/compose/runtime/saveable/RememberSaveableKt$rememberSaveable$1$valueProvider$1;-><init>(Landroidx/compose/runtime/State;Landroidx/compose/runtime/State;Landroidx/compose/runtime/saveable/SaveableStateRegistry;)V
+HSPLandroidx/compose/runtime/saveable/RememberSaveableKt$rememberSaveable$1$valueProvider$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/saveable/RememberSaveableKt$rememberSaveable$1;-><init>(Landroidx/compose/runtime/saveable/SaveableStateRegistry;Ljava/lang/String;Landroidx/compose/runtime/State;Landroidx/compose/runtime/State;)V
+HSPLandroidx/compose/runtime/saveable/RememberSaveableKt$rememberSaveable$1;->invoke(Landroidx/compose/runtime/DisposableEffectScope;)Landroidx/compose/runtime/DisposableEffectResult;
+HSPLandroidx/compose/runtime/saveable/RememberSaveableKt$rememberSaveable$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/saveable/RememberSaveableKt;-><clinit>()V
+HSPLandroidx/compose/runtime/saveable/RememberSaveableKt;->access$requireCanBeSaved(Landroidx/compose/runtime/saveable/SaveableStateRegistry;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/saveable/RememberSaveableKt;->rememberSaveable([Ljava/lang/Object;Landroidx/compose/runtime/saveable/Saver;Ljava/lang/String;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;II)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/saveable/RememberSaveableKt;->requireCanBeSaved(Landroidx/compose/runtime/saveable/SaveableStateRegistry;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/saveable/SaveableStateRegistryImpl$registerProvider$3;-><init>(Landroidx/compose/runtime/saveable/SaveableStateRegistryImpl;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/runtime/saveable/SaveableStateRegistryImpl;-><init>(Ljava/util/Map;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/runtime/saveable/SaveableStateRegistryImpl;->canBeSaved(Ljava/lang/Object;)Z
+HSPLandroidx/compose/runtime/saveable/SaveableStateRegistryImpl;->consumeRestored(Ljava/lang/String;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/saveable/SaveableStateRegistryImpl;->registerProvider(Ljava/lang/String;Lkotlin/jvm/functions/Function0;)Landroidx/compose/runtime/saveable/SaveableStateRegistry$Entry;
+HSPLandroidx/compose/runtime/saveable/SaveableStateRegistryKt$LocalSaveableStateRegistry$1;-><clinit>()V
+HSPLandroidx/compose/runtime/saveable/SaveableStateRegistryKt$LocalSaveableStateRegistry$1;-><init>()V
+HSPLandroidx/compose/runtime/saveable/SaveableStateRegistryKt;-><clinit>()V
+HSPLandroidx/compose/runtime/saveable/SaveableStateRegistryKt;->SaveableStateRegistry(Ljava/util/Map;Lkotlin/jvm/functions/Function1;)Landroidx/compose/runtime/saveable/SaveableStateRegistry;
+HSPLandroidx/compose/runtime/saveable/SaveableStateRegistryKt;->getLocalSaveableStateRegistry()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/runtime/saveable/SaverKt$AutoSaver$1;-><clinit>()V
+HSPLandroidx/compose/runtime/saveable/SaverKt$AutoSaver$1;-><init>()V
+HSPLandroidx/compose/runtime/saveable/SaverKt$AutoSaver$1;->invoke(Landroidx/compose/runtime/saveable/SaverScope;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/saveable/SaverKt$AutoSaver$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/saveable/SaverKt$AutoSaver$2;-><clinit>()V
+HSPLandroidx/compose/runtime/saveable/SaverKt$AutoSaver$2;-><init>()V
+HSPLandroidx/compose/runtime/saveable/SaverKt$Saver$1;-><init>(Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/runtime/saveable/SaverKt$Saver$1;->save(Landroidx/compose/runtime/saveable/SaverScope;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/saveable/SaverKt;-><clinit>()V
+HSPLandroidx/compose/runtime/saveable/SaverKt;->Saver(Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)Landroidx/compose/runtime/saveable/Saver;
+HSPLandroidx/compose/runtime/saveable/SaverKt;->autoSaver()Landroidx/compose/runtime/saveable/Saver;
+HSPLandroidx/compose/runtime/snapshots/GlobalSnapshot$takeNestedMutableSnapshot$1;-><init>(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/runtime/snapshots/GlobalSnapshot$takeNestedMutableSnapshot$1;->invoke(Landroidx/compose/runtime/snapshots/SnapshotIdSet;)Landroidx/compose/runtime/snapshots/MutableSnapshot;
+HSPLandroidx/compose/runtime/snapshots/GlobalSnapshot$takeNestedMutableSnapshot$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/snapshots/GlobalSnapshot;-><init>(ILandroidx/compose/runtime/snapshots/SnapshotIdSet;)V
+HSPLandroidx/compose/runtime/snapshots/GlobalSnapshot;->dispose()V
+HSPLandroidx/compose/runtime/snapshots/GlobalSnapshot;->notifyObjectsInitialized$runtime_release()V
+HSPLandroidx/compose/runtime/snapshots/GlobalSnapshot;->takeNestedMutableSnapshot(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Landroidx/compose/runtime/snapshots/MutableSnapshot;
+HSPLandroidx/compose/runtime/snapshots/ListUtilsKt;->fastToSet(Ljava/util/List;)Ljava/util/Set;
+HSPLandroidx/compose/runtime/snapshots/MutableSnapshot;-><clinit>()V
+HSPLandroidx/compose/runtime/snapshots/MutableSnapshot;-><init>(ILandroidx/compose/runtime/snapshots/SnapshotIdSet;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/runtime/snapshots/MutableSnapshot;->apply()Landroidx/compose/runtime/snapshots/SnapshotApplyResult;
+HSPLandroidx/compose/runtime/snapshots/MutableSnapshot;->closeLocked$runtime_release()V
+HSPLandroidx/compose/runtime/snapshots/MutableSnapshot;->dispose()V
+HSPLandroidx/compose/runtime/snapshots/MutableSnapshot;->getModified$runtime_release()Ljava/util/Set;
+HSPLandroidx/compose/runtime/snapshots/MutableSnapshot;->getPreviousIds$runtime_release()Landroidx/compose/runtime/snapshots/SnapshotIdSet;
+HSPLandroidx/compose/runtime/snapshots/MutableSnapshot;->getReadObserver$runtime_release()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/runtime/snapshots/MutableSnapshot;->getReadOnly()Z
+HSPLandroidx/compose/runtime/snapshots/MutableSnapshot;->getWriteObserver$runtime_release()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/runtime/snapshots/MutableSnapshot;->innerApplyLocked$runtime_release(ILjava/util/Map;Landroidx/compose/runtime/snapshots/SnapshotIdSet;)Landroidx/compose/runtime/snapshots/SnapshotApplyResult;
+HSPLandroidx/compose/runtime/snapshots/MutableSnapshot;->nestedDeactivated$runtime_release(Landroidx/compose/runtime/snapshots/Snapshot;)V
+HSPLandroidx/compose/runtime/snapshots/MutableSnapshot;->recordModified$runtime_release(Landroidx/compose/runtime/snapshots/StateObject;)V
+HSPLandroidx/compose/runtime/snapshots/MutableSnapshot;->releasePinnedSnapshotsForCloseLocked$runtime_release()V
+HSPLandroidx/compose/runtime/snapshots/MutableSnapshot;->releasePreviouslyPinnedSnapshotsLocked$runtime_release()V
+HSPLandroidx/compose/runtime/snapshots/MutableSnapshot;->setModified(Ljava/util/Set;)V
+HSPLandroidx/compose/runtime/snapshots/Snapshot$Companion$registerApplyObserver$2;-><init>(Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/runtime/snapshots/Snapshot$Companion$registerGlobalWriteObserver$2;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/runtime/snapshots/Snapshot$Companion;-><init>()V
+HSPLandroidx/compose/runtime/snapshots/Snapshot$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/runtime/snapshots/Snapshot$Companion;->createNonObservableSnapshot()Landroidx/compose/runtime/snapshots/Snapshot;
+HSPLandroidx/compose/runtime/snapshots/Snapshot$Companion;->getCurrent()Landroidx/compose/runtime/snapshots/Snapshot;
+HSPLandroidx/compose/runtime/snapshots/Snapshot$Companion;->notifyObjectsInitialized()V
+HSPLandroidx/compose/runtime/snapshots/Snapshot$Companion;->observe(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/snapshots/Snapshot$Companion;->registerApplyObserver(Lkotlin/jvm/functions/Function2;)Landroidx/compose/runtime/snapshots/ObserverHandle;
+HSPLandroidx/compose/runtime/snapshots/Snapshot$Companion;->registerGlobalWriteObserver(Lkotlin/jvm/functions/Function1;)Landroidx/compose/runtime/snapshots/ObserverHandle;
+HSPLandroidx/compose/runtime/snapshots/Snapshot$Companion;->sendApplyNotifications()V
+HSPLandroidx/compose/runtime/snapshots/Snapshot$Companion;->takeMutableSnapshot(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Landroidx/compose/runtime/snapshots/MutableSnapshot;
+HSPLandroidx/compose/runtime/snapshots/Snapshot;-><clinit>()V
+HSPLandroidx/compose/runtime/snapshots/Snapshot;-><init>(ILandroidx/compose/runtime/snapshots/SnapshotIdSet;)V
+HSPLandroidx/compose/runtime/snapshots/Snapshot;-><init>(ILandroidx/compose/runtime/snapshots/SnapshotIdSet;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/runtime/snapshots/Snapshot;->dispose()V
+HSPLandroidx/compose/runtime/snapshots/Snapshot;->getDisposed$runtime_release()Z
+HSPLandroidx/compose/runtime/snapshots/Snapshot;->getId()I
+HSPLandroidx/compose/runtime/snapshots/Snapshot;->getInvalid$runtime_release()Landroidx/compose/runtime/snapshots/SnapshotIdSet;
+HSPLandroidx/compose/runtime/snapshots/Snapshot;->makeCurrent()Landroidx/compose/runtime/snapshots/Snapshot;
+HSPLandroidx/compose/runtime/snapshots/Snapshot;->releasePinnedSnapshotLocked$runtime_release()V
+HSPLandroidx/compose/runtime/snapshots/Snapshot;->releasePinnedSnapshotsForCloseLocked$runtime_release()V
+HSPLandroidx/compose/runtime/snapshots/Snapshot;->restoreCurrent(Landroidx/compose/runtime/snapshots/Snapshot;)V
+HSPLandroidx/compose/runtime/snapshots/Snapshot;->setDisposed$runtime_release(Z)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotApplyResult$Success;-><clinit>()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotApplyResult$Success;-><init>()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotApplyResult;-><clinit>()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotApplyResult;-><init>()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotApplyResult;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotDoubleIndexHeap;-><init>()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotDoubleIndexHeap;->add(I)I
+HSPLandroidx/compose/runtime/snapshots/SnapshotDoubleIndexHeap;->allocateHandle()I
+HSPLandroidx/compose/runtime/snapshots/SnapshotDoubleIndexHeap;->ensure(I)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotDoubleIndexHeap;->freeHandle(I)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotDoubleIndexHeap;->lowestOrDefault(I)I
+HSPLandroidx/compose/runtime/snapshots/SnapshotDoubleIndexHeap;->remove(I)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotDoubleIndexHeap;->shiftDown(I)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotDoubleIndexHeap;->shiftUp(I)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotDoubleIndexHeap;->swap(II)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotIdSet$Companion;-><init>()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotIdSet$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotIdSet$Companion;->getEMPTY()Landroidx/compose/runtime/snapshots/SnapshotIdSet;
+HSPLandroidx/compose/runtime/snapshots/SnapshotIdSet;-><clinit>()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotIdSet;-><init>(JJI[I)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotIdSet;->access$getEMPTY$cp()Landroidx/compose/runtime/snapshots/SnapshotIdSet;
+HSPLandroidx/compose/runtime/snapshots/SnapshotIdSet;->andNot(Landroidx/compose/runtime/snapshots/SnapshotIdSet;)Landroidx/compose/runtime/snapshots/SnapshotIdSet;
+HSPLandroidx/compose/runtime/snapshots/SnapshotIdSet;->clear(I)Landroidx/compose/runtime/snapshots/SnapshotIdSet;
+HSPLandroidx/compose/runtime/snapshots/SnapshotIdSet;->get(I)Z
+HSPLandroidx/compose/runtime/snapshots/SnapshotIdSet;->lowest(I)I
+HSPLandroidx/compose/runtime/snapshots/SnapshotIdSet;->or(Landroidx/compose/runtime/snapshots/SnapshotIdSet;)Landroidx/compose/runtime/snapshots/SnapshotIdSet;
+HSPLandroidx/compose/runtime/snapshots/SnapshotIdSet;->set(I)Landroidx/compose/runtime/snapshots/SnapshotIdSet;
+HSPLandroidx/compose/runtime/snapshots/SnapshotIdSetKt;->access$lowestBitOf(J)I
+HSPLandroidx/compose/runtime/snapshots/SnapshotIdSetKt;->lowestBitOf(J)I
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt$advanceGlobalSnapshot$2;-><clinit>()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt$advanceGlobalSnapshot$2;-><init>()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt$advanceGlobalSnapshot$2;->invoke(Landroidx/compose/runtime/snapshots/SnapshotIdSet;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt$advanceGlobalSnapshot$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt$emptyLambda$1;-><clinit>()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt$emptyLambda$1;-><init>()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt$emptyLambda$1;->invoke(Landroidx/compose/runtime/snapshots/SnapshotIdSet;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt$emptyLambda$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt$mergedWriteObserver$1;-><init>(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt$mergedWriteObserver$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt$mergedWriteObserver$1;->invoke(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt$takeNewSnapshot$1;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt$takeNewSnapshot$1;->invoke(Landroidx/compose/runtime/snapshots/SnapshotIdSet;)Landroidx/compose/runtime/snapshots/Snapshot;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt$takeNewSnapshot$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;-><clinit>()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->access$advanceGlobalSnapshot()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->access$advanceGlobalSnapshot(Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->access$getApplyObservers$p()Ljava/util/List;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->access$getCurrentGlobalSnapshot$p()Ljava/util/concurrent/atomic/AtomicReference;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->access$getEmptyLambda$p()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->access$getGlobalWriteObservers$p()Ljava/util/List;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->access$getNextSnapshotId$p()I
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->access$getOpenSnapshots$p()Landroidx/compose/runtime/snapshots/SnapshotIdSet;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->access$getThreadSnapshot$p()Landroidx/compose/runtime/SnapshotThreadLocal;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->access$mergedReadObserver(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Z)Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->access$mergedWriteObserver(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->access$optimisticMerges(Landroidx/compose/runtime/snapshots/MutableSnapshot;Landroidx/compose/runtime/snapshots/MutableSnapshot;Landroidx/compose/runtime/snapshots/SnapshotIdSet;)Ljava/util/Map;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->access$readable(Landroidx/compose/runtime/snapshots/StateRecord;ILandroidx/compose/runtime/snapshots/SnapshotIdSet;)Landroidx/compose/runtime/snapshots/StateRecord;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->access$setNextSnapshotId$p(I)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->access$setOpenSnapshots$p(Landroidx/compose/runtime/snapshots/SnapshotIdSet;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->access$takeNewGlobalSnapshot(Landroidx/compose/runtime/snapshots/Snapshot;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->access$takeNewSnapshot(Lkotlin/jvm/functions/Function1;)Landroidx/compose/runtime/snapshots/Snapshot;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->access$validateOpen(Landroidx/compose/runtime/snapshots/Snapshot;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->advanceGlobalSnapshot()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->advanceGlobalSnapshot(Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->createTransparentSnapshotWithNoParentReadObserver$default(Landroidx/compose/runtime/snapshots/Snapshot;Lkotlin/jvm/functions/Function1;ZILjava/lang/Object;)Landroidx/compose/runtime/snapshots/Snapshot;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->createTransparentSnapshotWithNoParentReadObserver(Landroidx/compose/runtime/snapshots/Snapshot;Lkotlin/jvm/functions/Function1;Z)Landroidx/compose/runtime/snapshots/Snapshot;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->current(Landroidx/compose/runtime/snapshots/StateRecord;)Landroidx/compose/runtime/snapshots/StateRecord;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->currentSnapshot()Landroidx/compose/runtime/snapshots/Snapshot;+]Landroidx/compose/runtime/SnapshotThreadLocal;Landroidx/compose/runtime/SnapshotThreadLocal;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->getLock()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->getSnapshotInitializer()Landroidx/compose/runtime/snapshots/Snapshot;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->mergedReadObserver$default(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ZILjava/lang/Object;)Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->mergedReadObserver(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Z)Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->mergedWriteObserver(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->newOverwritableRecord(Landroidx/compose/runtime/snapshots/StateRecord;Landroidx/compose/runtime/snapshots/StateObject;)Landroidx/compose/runtime/snapshots/StateRecord;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->notifyWrite(Landroidx/compose/runtime/snapshots/Snapshot;Landroidx/compose/runtime/snapshots/StateObject;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->optimisticMerges(Landroidx/compose/runtime/snapshots/MutableSnapshot;Landroidx/compose/runtime/snapshots/MutableSnapshot;Landroidx/compose/runtime/snapshots/SnapshotIdSet;)Ljava/util/Map;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->overwritableRecord(Landroidx/compose/runtime/snapshots/StateRecord;Landroidx/compose/runtime/snapshots/StateObject;Landroidx/compose/runtime/snapshots/Snapshot;Landroidx/compose/runtime/snapshots/StateRecord;)Landroidx/compose/runtime/snapshots/StateRecord;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->readable(Landroidx/compose/runtime/snapshots/StateRecord;ILandroidx/compose/runtime/snapshots/SnapshotIdSet;)Landroidx/compose/runtime/snapshots/StateRecord;+]Landroidx/compose/runtime/snapshots/StateRecord;Landroidx/compose/runtime/DerivedSnapshotState$ResultRecord;,Landroidx/compose/runtime/SnapshotMutableStateImpl$StateStateRecord;,Landroidx/compose/runtime/snapshots/SnapshotStateList$StateListStateRecord;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->readable(Landroidx/compose/runtime/snapshots/StateRecord;Landroidx/compose/runtime/snapshots/StateObject;)Landroidx/compose/runtime/snapshots/StateRecord;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->releasePinningLocked(I)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->takeNewGlobalSnapshot(Landroidx/compose/runtime/snapshots/Snapshot;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->takeNewSnapshot(Lkotlin/jvm/functions/Function1;)Landroidx/compose/runtime/snapshots/Snapshot;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->trackPinning(ILandroidx/compose/runtime/snapshots/SnapshotIdSet;)I
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->used(Landroidx/compose/runtime/snapshots/StateObject;)Landroidx/compose/runtime/snapshots/StateRecord;
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->valid(IILandroidx/compose/runtime/snapshots/SnapshotIdSet;)Z
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->valid(Landroidx/compose/runtime/snapshots/StateRecord;ILandroidx/compose/runtime/snapshots/SnapshotIdSet;)Z
+HSPLandroidx/compose/runtime/snapshots/SnapshotKt;->validateOpen(Landroidx/compose/runtime/snapshots/Snapshot;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateList$StateListStateRecord;-><init>(Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentList;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateList$StateListStateRecord;->getList$runtime_release()Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentList;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateList;-><init>()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateList;->getFirstStateRecord()Landroidx/compose/runtime/snapshots/StateRecord;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateList;->getReadable$runtime_release()Landroidx/compose/runtime/snapshots/SnapshotStateList$StateListStateRecord;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateList;->isEmpty()Z
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap$derivedStateEnterObserver$1;-><init>(Landroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap$derivedStateExitObserver$1;-><init>(Landroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->access$clearObsoleteStateReads(Landroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->access$getCurrentScope$p(Landroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->access$getCurrentScopeReads$p(Landroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;)Landroidx/compose/runtime/collection/IdentityArrayIntMap;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->access$getCurrentToken$p(Landroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;)I
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->access$getScopeToValues$p(Landroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;)Landroidx/compose/runtime/collection/IdentityArrayMap;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->access$setCurrentScope$p(Landroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->access$setCurrentScopeReads$p(Landroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;Landroidx/compose/runtime/collection/IdentityArrayIntMap;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->access$setCurrentToken$p(Landroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;I)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->clearObsoleteStateReads(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->getDerivedStateEnterObserver()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->getDerivedStateExitObserver()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->getOnChanged()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->notifyInvalidatedScopes()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->recordInvalidation(Ljava/util/Set;)Z+]Landroidx/compose/runtime/collection/IdentityArraySet;Landroidx/compose/runtime/collection/IdentityArraySet;]Landroidx/compose/runtime/collection/IdentityScopeMap;Landroidx/compose/runtime/collection/IdentityScopeMap;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->recordRead(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->removeObservation(Ljava/lang/Object;Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$applyObserver$1$2;-><init>(Landroidx/compose/runtime/snapshots/SnapshotStateObserver;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$applyObserver$1$2;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$applyObserver$1$2;->invoke()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$applyObserver$1;-><init>(Landroidx/compose/runtime/snapshots/SnapshotStateObserver;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$applyObserver$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$applyObserver$1;->invoke(Ljava/util/Set;Landroidx/compose/runtime/snapshots/Snapshot;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$observeReads$1$1;-><init>(Landroidx/compose/runtime/snapshots/SnapshotStateObserver;Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$observeReads$1$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$observeReads$1$1;->invoke()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$readObserver$1;-><init>(Landroidx/compose/runtime/snapshots/SnapshotStateObserver;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$readObserver$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver$readObserver$1;->invoke(Ljava/lang/Object;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver;-><clinit>()V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver;->access$getCurrentMap$p(Landroidx/compose/runtime/snapshots/SnapshotStateObserver;)Landroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver;->access$getObservedScopeMaps$p(Landroidx/compose/runtime/snapshots/SnapshotStateObserver;)Landroidx/compose/runtime/collection/MutableVector;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver;->access$getOnChangedExecutor$p(Landroidx/compose/runtime/snapshots/SnapshotStateObserver;)Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver;->access$getReadObserver$p(Landroidx/compose/runtime/snapshots/SnapshotStateObserver;)Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver;->access$isPaused$p(Landroidx/compose/runtime/snapshots/SnapshotStateObserver;)Z
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver;->ensureMap(Lkotlin/jvm/functions/Function1;)Landroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver;->observeReads(Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/runtime/snapshots/SnapshotStateObserver;->start()V
+HSPLandroidx/compose/runtime/snapshots/StateRecord;-><clinit>()V
+HSPLandroidx/compose/runtime/snapshots/StateRecord;-><init>()V
+HSPLandroidx/compose/runtime/snapshots/StateRecord;->getNext$runtime_release()Landroidx/compose/runtime/snapshots/StateRecord;
+HSPLandroidx/compose/runtime/snapshots/StateRecord;->getSnapshotId$runtime_release()I
+HSPLandroidx/compose/runtime/snapshots/StateRecord;->setNext$runtime_release(Landroidx/compose/runtime/snapshots/StateRecord;)V
+HSPLandroidx/compose/runtime/snapshots/StateRecord;->setSnapshotId$runtime_release(I)V
+HSPLandroidx/compose/runtime/snapshots/TransparentObserverMutableSnapshot;-><init>(Landroidx/compose/runtime/snapshots/MutableSnapshot;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ZZ)V
+HSPLandroidx/compose/runtime/snapshots/TransparentObserverMutableSnapshot;->apply()Landroidx/compose/runtime/snapshots/SnapshotApplyResult;
+HSPLandroidx/compose/runtime/snapshots/TransparentObserverMutableSnapshot;->dispose()V
+HSPLandroidx/compose/runtime/snapshots/TransparentObserverMutableSnapshot;->getCurrentSnapshot()Landroidx/compose/runtime/snapshots/MutableSnapshot;
+HSPLandroidx/compose/runtime/snapshots/TransparentObserverMutableSnapshot;->getId()I+]Landroidx/compose/runtime/snapshots/Snapshot;Landroidx/compose/runtime/snapshots/GlobalSnapshot;,Landroidx/compose/runtime/snapshots/MutableSnapshot;,Landroidx/compose/runtime/snapshots/NestedMutableSnapshot;,Landroidx/compose/runtime/snapshots/TransparentObserverMutableSnapshot;
+HSPLandroidx/compose/runtime/snapshots/TransparentObserverMutableSnapshot;->getInvalid$runtime_release()Landroidx/compose/runtime/snapshots/SnapshotIdSet;
+HSPLandroidx/compose/runtime/snapshots/TransparentObserverMutableSnapshot;->getReadOnly()Z
+HSPLandroidx/compose/runtime/snapshots/TransparentObserverMutableSnapshot;->notifyObjectsInitialized$runtime_release()V
+HSPLandroidx/compose/runtime/snapshots/TransparentObserverMutableSnapshot;->recordModified$runtime_release(Landroidx/compose/runtime/snapshots/StateObject;)V
+HSPLandroidx/compose/runtime/snapshots/TransparentObserverMutableSnapshot;->takeNestedMutableSnapshot(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Landroidx/compose/runtime/snapshots/MutableSnapshot;
+HSPLandroidx/compose/runtime/tooling/InspectionTablesKt$LocalInspectionTables$1;-><clinit>()V
+HSPLandroidx/compose/runtime/tooling/InspectionTablesKt$LocalInspectionTables$1;-><init>()V
+HSPLandroidx/compose/runtime/tooling/InspectionTablesKt$LocalInspectionTables$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/runtime/tooling/InspectionTablesKt$LocalInspectionTables$1;->invoke()Ljava/util/Set;
+HSPLandroidx/compose/runtime/tooling/InspectionTablesKt;-><clinit>()V
+HSPLandroidx/compose/runtime/tooling/InspectionTablesKt;->getLocalInspectionTables()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/ui/ActualKt;->areObjectsOfSameType(Ljava/lang/Object;Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/Alignment$Companion;-><clinit>()V
+HSPLandroidx/compose/ui/Alignment$Companion;-><init>()V
+HSPLandroidx/compose/ui/Alignment$Companion;->getCenter()Landroidx/compose/ui/Alignment;
+HSPLandroidx/compose/ui/Alignment$Companion;->getCenterHorizontally()Landroidx/compose/ui/Alignment$Horizontal;
+HSPLandroidx/compose/ui/Alignment$Companion;->getCenterVertically()Landroidx/compose/ui/Alignment$Vertical;
+HSPLandroidx/compose/ui/Alignment$Companion;->getStart()Landroidx/compose/ui/Alignment$Horizontal;
+HSPLandroidx/compose/ui/Alignment$Companion;->getTop()Landroidx/compose/ui/Alignment$Vertical;
+HSPLandroidx/compose/ui/Alignment$Companion;->getTopStart()Landroidx/compose/ui/Alignment;
+HSPLandroidx/compose/ui/Alignment;-><clinit>()V
+HSPLandroidx/compose/ui/BiasAlignment$Horizontal;-><init>(F)V
+HSPLandroidx/compose/ui/BiasAlignment$Horizontal;->align(IILandroidx/compose/ui/unit/LayoutDirection;)I
+HSPLandroidx/compose/ui/BiasAlignment$Horizontal;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/BiasAlignment$Vertical;-><init>(F)V
+HSPLandroidx/compose/ui/BiasAlignment$Vertical;->align(II)I
+HSPLandroidx/compose/ui/BiasAlignment$Vertical;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/BiasAlignment;-><init>(FF)V
+HSPLandroidx/compose/ui/BiasAlignment;->align-KFBX0sM(JJLandroidx/compose/ui/unit/LayoutDirection;)J
+HSPLandroidx/compose/ui/BiasAlignment;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/CombinedModifier;-><clinit>()V
+HSPLandroidx/compose/ui/CombinedModifier;-><init>(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/Modifier;)V
+HSPLandroidx/compose/ui/CombinedModifier;->all(Lkotlin/jvm/functions/Function1;)Z
+HSPLandroidx/compose/ui/CombinedModifier;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/CombinedModifier;->foldIn(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/CombinedModifier;->getInner$ui_release()Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/CombinedModifier;->getOuter$ui_release()Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/ComposedModifier;-><init>(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function3;)V
+HSPLandroidx/compose/ui/ComposedModifier;->getFactory()Lkotlin/jvm/functions/Function3;
+HSPLandroidx/compose/ui/ComposedModifierKt$WrapFocusEventModifier$1;-><clinit>()V
+HSPLandroidx/compose/ui/ComposedModifierKt$WrapFocusEventModifier$1;-><init>()V
+HSPLandroidx/compose/ui/ComposedModifierKt$WrapFocusRequesterModifier$1;-><clinit>()V
+HSPLandroidx/compose/ui/ComposedModifierKt$WrapFocusRequesterModifier$1;-><init>()V
+HSPLandroidx/compose/ui/ComposedModifierKt$materialize$1;-><clinit>()V
+HSPLandroidx/compose/ui/ComposedModifierKt$materialize$1;-><init>()V
+HSPLandroidx/compose/ui/ComposedModifierKt$materialize$1;->invoke(Landroidx/compose/ui/Modifier$Element;)Ljava/lang/Boolean;
+HSPLandroidx/compose/ui/ComposedModifierKt$materialize$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/ComposedModifierKt$materialize$result$1;-><init>(Landroidx/compose/runtime/Composer;)V
+HSPLandroidx/compose/ui/ComposedModifierKt$materialize$result$1;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/Modifier$Element;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/ComposedModifierKt$materialize$result$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/ComposedModifierKt;-><clinit>()V
+HSPLandroidx/compose/ui/ComposedModifierKt;->composed(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function3;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/ComposedModifierKt;->materialize(Landroidx/compose/runtime/Composer;Landroidx/compose/ui/Modifier;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/Modifier$Companion;-><clinit>()V
+HSPLandroidx/compose/ui/Modifier$Companion;-><init>()V
+HSPLandroidx/compose/ui/Modifier$Companion;->all(Lkotlin/jvm/functions/Function1;)Z
+HSPLandroidx/compose/ui/Modifier$Companion;->then(Landroidx/compose/ui/Modifier;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/Modifier$Element;->all(Lkotlin/jvm/functions/Function1;)Z
+HSPLandroidx/compose/ui/Modifier$Element;->foldIn(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/Modifier$Node;-><clinit>()V
+HSPLandroidx/compose/ui/Modifier$Node;-><init>()V
+HSPLandroidx/compose/ui/Modifier$Node;->attach$ui_release()V
+HSPLandroidx/compose/ui/Modifier$Node;->getAggregateChildKindSet$ui_release()I
+HSPLandroidx/compose/ui/Modifier$Node;->getChild$ui_release()Landroidx/compose/ui/Modifier$Node;
+HSPLandroidx/compose/ui/Modifier$Node;->getCoordinator$ui_release()Landroidx/compose/ui/node/NodeCoordinator;
+HSPLandroidx/compose/ui/Modifier$Node;->getKindSet$ui_release()I
+HSPLandroidx/compose/ui/Modifier$Node;->getNode()Landroidx/compose/ui/Modifier$Node;
+HSPLandroidx/compose/ui/Modifier$Node;->getParent$ui_release()Landroidx/compose/ui/Modifier$Node;
+HSPLandroidx/compose/ui/Modifier$Node;->isAttached()Z
+HSPLandroidx/compose/ui/Modifier$Node;->onAttach()V
+HSPLandroidx/compose/ui/Modifier$Node;->setAggregateChildKindSet$ui_release(I)V
+HSPLandroidx/compose/ui/Modifier$Node;->setChild$ui_release(Landroidx/compose/ui/Modifier$Node;)V
+HSPLandroidx/compose/ui/Modifier$Node;->setKindSet$ui_release(I)V
+HSPLandroidx/compose/ui/Modifier$Node;->setParent$ui_release(Landroidx/compose/ui/Modifier$Node;)V
+HSPLandroidx/compose/ui/Modifier$Node;->sideEffect(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/ui/Modifier$Node;->updateCoordinator$ui_release(Landroidx/compose/ui/node/NodeCoordinator;)V
+HSPLandroidx/compose/ui/Modifier;-><clinit>()V
+HSPLandroidx/compose/ui/Modifier;->then(Landroidx/compose/ui/Modifier;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/MotionDurationScale$DefaultImpls;->fold(Landroidx/compose/ui/MotionDurationScale;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/MotionDurationScale$DefaultImpls;->get(Landroidx/compose/ui/MotionDurationScale;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
+HSPLandroidx/compose/ui/MotionDurationScale$DefaultImpls;->minusKey(Landroidx/compose/ui/MotionDurationScale;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
+HSPLandroidx/compose/ui/MotionDurationScale$Key;-><clinit>()V
+HSPLandroidx/compose/ui/MotionDurationScale$Key;-><init>()V
+HSPLandroidx/compose/ui/MotionDurationScale;-><clinit>()V
+HSPLandroidx/compose/ui/MotionDurationScale;->getKey()Lkotlin/coroutines/CoroutineContext$Key;
+HSPLandroidx/compose/ui/autofill/AndroidAutofill;-><init>(Landroid/view/View;Landroidx/compose/ui/autofill/AutofillTree;)V
+HSPLandroidx/compose/ui/autofill/AndroidAutofill;->getAutofillManager()Landroid/view/autofill/AutofillManager;
+HSPLandroidx/compose/ui/autofill/AutofillCallback;-><clinit>()V
+HSPLandroidx/compose/ui/autofill/AutofillCallback;-><init>()V
+HSPLandroidx/compose/ui/autofill/AutofillCallback;->register(Landroidx/compose/ui/autofill/AndroidAutofill;)V
+HSPLandroidx/compose/ui/autofill/AutofillTree;-><clinit>()V
+HSPLandroidx/compose/ui/autofill/AutofillTree;-><init>()V
+HSPLandroidx/compose/ui/draw/ClipKt;->clip(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/graphics/Shape;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/draw/DrawBackgroundModifier;-><init>(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/draw/DrawBackgroundModifier;->draw(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;)V
+HSPLandroidx/compose/ui/draw/DrawBackgroundModifier;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/draw/DrawModifierKt;->drawBehind(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/draw/PainterModifier$measure$1;-><init>(Landroidx/compose/ui/layout/Placeable;)V
+HSPLandroidx/compose/ui/draw/PainterModifier$measure$1;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+HSPLandroidx/compose/ui/draw/PainterModifier$measure$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/draw/PainterModifier;-><init>(Landroidx/compose/ui/graphics/painter/Painter;ZLandroidx/compose/ui/Alignment;Landroidx/compose/ui/layout/ContentScale;FLandroidx/compose/ui/graphics/ColorFilter;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/draw/PainterModifier;->draw(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;)V
+HSPLandroidx/compose/ui/draw/PainterModifier;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/draw/PainterModifier;->getUseIntrinsicSize()Z
+HSPLandroidx/compose/ui/draw/PainterModifier;->hasSpecifiedAndFiniteHeight-uvyYCjk(J)Z
+HSPLandroidx/compose/ui/draw/PainterModifier;->hasSpecifiedAndFiniteWidth-uvyYCjk(J)Z
+HSPLandroidx/compose/ui/draw/PainterModifier;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/ui/draw/PainterModifier;->modifyConstraints-ZezNO4M(J)J
+HSPLandroidx/compose/ui/draw/PainterModifierKt;->paint$default(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/graphics/painter/Painter;ZLandroidx/compose/ui/Alignment;Landroidx/compose/ui/layout/ContentScale;FLandroidx/compose/ui/graphics/ColorFilter;ILjava/lang/Object;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/draw/PainterModifierKt;->paint(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/graphics/painter/Painter;ZLandroidx/compose/ui/Alignment;Landroidx/compose/ui/layout/ContentScale;FLandroidx/compose/ui/graphics/ColorFilter;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/draw/ShadowKt$shadow$2$1;-><init>(FLandroidx/compose/ui/graphics/Shape;ZJJ)V
+HSPLandroidx/compose/ui/draw/ShadowKt$shadow$2$1;->invoke(Landroidx/compose/ui/graphics/GraphicsLayerScope;)V
+HSPLandroidx/compose/ui/draw/ShadowKt$shadow$2$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/draw/ShadowKt;->shadow-s4CzXII$default(Landroidx/compose/ui/Modifier;FLandroidx/compose/ui/graphics/Shape;ZJJILjava/lang/Object;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/draw/ShadowKt;->shadow-s4CzXII(Landroidx/compose/ui/Modifier;FLandroidx/compose/ui/graphics/Shape;ZJJ)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/focus/FocusChangedModifierKt$onFocusChanged$2$1$1;-><init>(Landroidx/compose/runtime/MutableState;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/focus/FocusChangedModifierKt$onFocusChanged$2$1$1;->invoke(Landroidx/compose/ui/focus/FocusState;)V
+HSPLandroidx/compose/ui/focus/FocusChangedModifierKt$onFocusChanged$2$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusChangedModifierKt$onFocusChanged$2;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/focus/FocusChangedModifierKt$onFocusChanged$2;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/focus/FocusChangedModifierKt$onFocusChanged$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusChangedModifierKt;->onFocusChanged(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/focus/FocusEventModifierKt$ModifierLocalFocusEvent$1;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusEventModifierKt$ModifierLocalFocusEvent$1;-><init>()V
+HSPLandroidx/compose/ui/focus/FocusEventModifierKt$ModifierLocalFocusEvent$1;->invoke()Landroidx/compose/ui/focus/FocusEventModifierLocal;
+HSPLandroidx/compose/ui/focus/FocusEventModifierKt$ModifierLocalFocusEvent$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusEventModifierKt$onFocusEvent$2$1$1;-><init>(Landroidx/compose/ui/focus/FocusEventModifierLocal;)V
+HSPLandroidx/compose/ui/focus/FocusEventModifierKt$onFocusEvent$2$1$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusEventModifierKt$onFocusEvent$2$1$1;->invoke()V
+HSPLandroidx/compose/ui/focus/FocusEventModifierKt$onFocusEvent$2;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/focus/FocusEventModifierKt$onFocusEvent$2;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/focus/FocusEventModifierKt$onFocusEvent$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusEventModifierKt;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusEventModifierKt;->getModifierLocalFocusEvent()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/focus/FocusEventModifierKt;->onFocusEvent(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/focus/FocusEventModifierLocal;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/focus/FocusEventModifierLocal;->addFocusModifier(Landroidx/compose/ui/focus/FocusModifier;)V
+HSPLandroidx/compose/ui/focus/FocusEventModifierLocal;->getKey()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/focus/FocusEventModifierLocal;->getValue()Landroidx/compose/ui/focus/FocusEventModifierLocal;
+HSPLandroidx/compose/ui/focus/FocusEventModifierLocal;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusEventModifierLocal;->notifyIfNoFocusModifiers()V
+HSPLandroidx/compose/ui/focus/FocusEventModifierLocal;->onModifierLocalsUpdated(Landroidx/compose/ui/modifier/ModifierLocalReadScope;)V
+HSPLandroidx/compose/ui/focus/FocusEventModifierLocal;->propagateFocusEvent()V
+HSPLandroidx/compose/ui/focus/FocusEventModifierLocal;->removeFocusModifier(Landroidx/compose/ui/focus/FocusModifier;)V
+HSPLandroidx/compose/ui/focus/FocusManagerImpl;-><init>(Landroidx/compose/ui/focus/FocusModifier;)V
+HSPLandroidx/compose/ui/focus/FocusManagerImpl;-><init>(Landroidx/compose/ui/focus/FocusModifier;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/focus/FocusManagerImpl;->fetchUpdatedFocusProperties()V
+HSPLandroidx/compose/ui/focus/FocusManagerImpl;->getModifier()Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/focus/FocusManagerImpl;->setLayoutDirection(Landroidx/compose/ui/unit/LayoutDirection;)V
+HSPLandroidx/compose/ui/focus/FocusManagerKt;->access$updateProperties(Landroidx/compose/ui/focus/FocusModifier;)V
+HSPLandroidx/compose/ui/focus/FocusManagerKt;->updateProperties(Landroidx/compose/ui/focus/FocusModifier;)V
+HSPLandroidx/compose/ui/focus/FocusModifier$Companion$RefreshFocusProperties$1;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusModifier$Companion$RefreshFocusProperties$1;-><init>()V
+HSPLandroidx/compose/ui/focus/FocusModifier$Companion;-><init>()V
+HSPLandroidx/compose/ui/focus/FocusModifier$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/focus/FocusModifier$Companion;->getRefreshFocusProperties()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/ui/focus/FocusModifier;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusModifier;-><init>(Landroidx/compose/ui/focus/FocusStateImpl;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/focus/FocusModifier;-><init>(Landroidx/compose/ui/focus/FocusStateImpl;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/focus/FocusModifier;->access$getRefreshFocusProperties$cp()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/ui/focus/FocusModifier;->getChildren()Landroidx/compose/runtime/collection/MutableVector;
+HSPLandroidx/compose/ui/focus/FocusModifier;->getCoordinator()Landroidx/compose/ui/node/NodeCoordinator;
+HSPLandroidx/compose/ui/focus/FocusModifier;->getFocusEventListener()Landroidx/compose/ui/focus/FocusEventModifierLocal;
+HSPLandroidx/compose/ui/focus/FocusModifier;->getFocusProperties()Landroidx/compose/ui/focus/FocusProperties;
+HSPLandroidx/compose/ui/focus/FocusModifier;->getFocusPropertiesModifier()Landroidx/compose/ui/focus/FocusPropertiesModifier;
+HSPLandroidx/compose/ui/focus/FocusModifier;->getFocusState()Landroidx/compose/ui/focus/FocusStateImpl;
+HSPLandroidx/compose/ui/focus/FocusModifier;->getKey()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/focus/FocusModifier;->getKeyInputChildren()Landroidx/compose/runtime/collection/MutableVector;
+HSPLandroidx/compose/ui/focus/FocusModifier;->getValue()Landroidx/compose/ui/focus/FocusModifier;
+HSPLandroidx/compose/ui/focus/FocusModifier;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusModifier;->onModifierLocalsUpdated(Landroidx/compose/ui/modifier/ModifierLocalReadScope;)V
+HSPLandroidx/compose/ui/focus/FocusModifier;->onPlaced(Landroidx/compose/ui/layout/LayoutCoordinates;)V
+HSPLandroidx/compose/ui/focus/FocusModifier;->setFocusState(Landroidx/compose/ui/focus/FocusStateImpl;)V
+HSPLandroidx/compose/ui/focus/FocusModifier;->setModifierLocalReadScope(Landroidx/compose/ui/modifier/ModifierLocalReadScope;)V
+HSPLandroidx/compose/ui/focus/FocusModifierKt$ModifierLocalParentFocusModifier$1;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusModifierKt$ModifierLocalParentFocusModifier$1;-><init>()V
+HSPLandroidx/compose/ui/focus/FocusModifierKt$ModifierLocalParentFocusModifier$1;->invoke()Landroidx/compose/ui/focus/FocusModifier;
+HSPLandroidx/compose/ui/focus/FocusModifierKt$ModifierLocalParentFocusModifier$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusModifierKt$ResetFocusModifierLocals$1;-><init>()V
+HSPLandroidx/compose/ui/focus/FocusModifierKt$ResetFocusModifierLocals$1;->getKey()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/focus/FocusModifierKt$ResetFocusModifierLocals$1;->getValue()Landroidx/compose/ui/focus/FocusPropertiesModifier;
+HSPLandroidx/compose/ui/focus/FocusModifierKt$ResetFocusModifierLocals$1;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusModifierKt$ResetFocusModifierLocals$2;-><init>()V
+HSPLandroidx/compose/ui/focus/FocusModifierKt$ResetFocusModifierLocals$2;->getKey()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/focus/FocusModifierKt$ResetFocusModifierLocals$2;->getValue()Landroidx/compose/ui/focus/FocusEventModifierLocal;
+HSPLandroidx/compose/ui/focus/FocusModifierKt$ResetFocusModifierLocals$2;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusModifierKt$ResetFocusModifierLocals$3;-><init>()V
+HSPLandroidx/compose/ui/focus/FocusModifierKt$ResetFocusModifierLocals$3;->getKey()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/focus/FocusModifierKt$ResetFocusModifierLocals$3;->getValue()Landroidx/compose/ui/focus/FocusRequesterModifierLocal;
+HSPLandroidx/compose/ui/focus/FocusModifierKt$ResetFocusModifierLocals$3;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusModifierKt$focusTarget$2$1$1;-><init>(Landroidx/compose/ui/focus/FocusModifier;)V
+HSPLandroidx/compose/ui/focus/FocusModifierKt$focusTarget$2$1$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusModifierKt$focusTarget$2$1$1;->invoke()V
+HSPLandroidx/compose/ui/focus/FocusModifierKt$focusTarget$2;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusModifierKt$focusTarget$2;-><init>()V
+HSPLandroidx/compose/ui/focus/FocusModifierKt$focusTarget$2;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/focus/FocusModifierKt$focusTarget$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusModifierKt;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusModifierKt;->focusTarget(Landroidx/compose/ui/Modifier;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/focus/FocusModifierKt;->focusTarget(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/focus/FocusModifier;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/focus/FocusModifierKt;->getModifierLocalParentFocusModifier()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/focus/FocusPropertiesImpl$enter$1;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusPropertiesImpl$enter$1;-><init>()V
+HSPLandroidx/compose/ui/focus/FocusPropertiesImpl$exit$1;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusPropertiesImpl$exit$1;-><init>()V
+HSPLandroidx/compose/ui/focus/FocusPropertiesImpl;-><init>()V
+HSPLandroidx/compose/ui/focus/FocusPropertiesImpl;->getCanFocus()Z
+HSPLandroidx/compose/ui/focus/FocusPropertiesImpl;->setCanFocus(Z)V
+HSPLandroidx/compose/ui/focus/FocusPropertiesImpl;->setDown(Landroidx/compose/ui/focus/FocusRequester;)V
+HSPLandroidx/compose/ui/focus/FocusPropertiesImpl;->setEnd(Landroidx/compose/ui/focus/FocusRequester;)V
+HSPLandroidx/compose/ui/focus/FocusPropertiesImpl;->setEnter(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/focus/FocusPropertiesImpl;->setExit(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/focus/FocusPropertiesImpl;->setLeft(Landroidx/compose/ui/focus/FocusRequester;)V
+HSPLandroidx/compose/ui/focus/FocusPropertiesImpl;->setNext(Landroidx/compose/ui/focus/FocusRequester;)V
+HSPLandroidx/compose/ui/focus/FocusPropertiesImpl;->setPrevious(Landroidx/compose/ui/focus/FocusRequester;)V
+HSPLandroidx/compose/ui/focus/FocusPropertiesImpl;->setRight(Landroidx/compose/ui/focus/FocusRequester;)V
+HSPLandroidx/compose/ui/focus/FocusPropertiesImpl;->setStart(Landroidx/compose/ui/focus/FocusRequester;)V
+HSPLandroidx/compose/ui/focus/FocusPropertiesImpl;->setUp(Landroidx/compose/ui/focus/FocusRequester;)V
+HSPLandroidx/compose/ui/focus/FocusPropertiesKt$ModifierLocalFocusProperties$1;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusPropertiesKt$ModifierLocalFocusProperties$1;-><init>()V
+HSPLandroidx/compose/ui/focus/FocusPropertiesKt$ModifierLocalFocusProperties$1;->invoke()Landroidx/compose/ui/focus/FocusPropertiesModifier;
+HSPLandroidx/compose/ui/focus/FocusPropertiesKt$ModifierLocalFocusProperties$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusPropertiesKt$clear$1;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusPropertiesKt$clear$1;-><init>()V
+HSPLandroidx/compose/ui/focus/FocusPropertiesKt$clear$2;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusPropertiesKt$clear$2;-><init>()V
+HSPLandroidx/compose/ui/focus/FocusPropertiesKt$refreshFocusProperties$1;-><init>(Landroidx/compose/ui/focus/FocusModifier;)V
+HSPLandroidx/compose/ui/focus/FocusPropertiesKt$refreshFocusProperties$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusPropertiesKt$refreshFocusProperties$1;->invoke()V
+HSPLandroidx/compose/ui/focus/FocusPropertiesKt;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusPropertiesKt;->clear(Landroidx/compose/ui/focus/FocusProperties;)V
+HSPLandroidx/compose/ui/focus/FocusPropertiesKt;->focusProperties(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/focus/FocusPropertiesKt;->getModifierLocalFocusProperties()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/focus/FocusPropertiesKt;->refreshFocusProperties(Landroidx/compose/ui/focus/FocusModifier;)V
+HSPLandroidx/compose/ui/focus/FocusPropertiesKt;->setUpdatedProperties(Landroidx/compose/ui/focus/FocusModifier;Landroidx/compose/ui/focus/FocusProperties;)V
+HSPLandroidx/compose/ui/focus/FocusPropertiesModifier;-><init>(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/focus/FocusPropertiesModifier;->calculateProperties(Landroidx/compose/ui/focus/FocusProperties;)V
+HSPLandroidx/compose/ui/focus/FocusPropertiesModifier;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/focus/FocusPropertiesModifier;->getKey()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/focus/FocusPropertiesModifier;->getParent()Landroidx/compose/ui/focus/FocusPropertiesModifier;
+HSPLandroidx/compose/ui/focus/FocusPropertiesModifier;->getValue()Landroidx/compose/ui/focus/FocusPropertiesModifier;
+HSPLandroidx/compose/ui/focus/FocusPropertiesModifier;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusPropertiesModifier;->onModifierLocalsUpdated(Landroidx/compose/ui/modifier/ModifierLocalReadScope;)V
+HSPLandroidx/compose/ui/focus/FocusPropertiesModifier;->setParent(Landroidx/compose/ui/focus/FocusPropertiesModifier;)V
+HSPLandroidx/compose/ui/focus/FocusRequester$Companion;-><init>()V
+HSPLandroidx/compose/ui/focus/FocusRequester$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/focus/FocusRequester$Companion;->getDefault()Landroidx/compose/ui/focus/FocusRequester;
+HSPLandroidx/compose/ui/focus/FocusRequester;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusRequester;-><init>()V
+HSPLandroidx/compose/ui/focus/FocusRequester;->access$getDefault$cp()Landroidx/compose/ui/focus/FocusRequester;
+HSPLandroidx/compose/ui/focus/FocusRequester;->getFocusRequesterModifierLocals$ui_release()Landroidx/compose/runtime/collection/MutableVector;
+HSPLandroidx/compose/ui/focus/FocusRequesterModifierKt$ModifierLocalFocusRequester$1;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusRequesterModifierKt$ModifierLocalFocusRequester$1;-><init>()V
+HSPLandroidx/compose/ui/focus/FocusRequesterModifierKt$ModifierLocalFocusRequester$1;->invoke()Landroidx/compose/ui/focus/FocusRequesterModifierLocal;
+HSPLandroidx/compose/ui/focus/FocusRequesterModifierKt$ModifierLocalFocusRequester$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusRequesterModifierKt$focusRequester$2;-><init>(Landroidx/compose/ui/focus/FocusRequester;)V
+HSPLandroidx/compose/ui/focus/FocusRequesterModifierKt$focusRequester$2;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/focus/FocusRequesterModifierKt$focusRequester$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusRequesterModifierKt;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusRequesterModifierKt;->focusRequester(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/focus/FocusRequester;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/focus/FocusRequesterModifierKt;->getModifierLocalFocusRequester()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/focus/FocusRequesterModifierLocal;-><init>(Landroidx/compose/ui/focus/FocusRequester;)V
+HSPLandroidx/compose/ui/focus/FocusRequesterModifierLocal;->addFocusModifier(Landroidx/compose/ui/focus/FocusModifier;)V
+HSPLandroidx/compose/ui/focus/FocusRequesterModifierLocal;->getKey()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/focus/FocusRequesterModifierLocal;->getValue()Landroidx/compose/ui/focus/FocusRequesterModifierLocal;
+HSPLandroidx/compose/ui/focus/FocusRequesterModifierLocal;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/ui/focus/FocusRequesterModifierLocal;->onModifierLocalsUpdated(Landroidx/compose/ui/modifier/ModifierLocalReadScope;)V
+HSPLandroidx/compose/ui/focus/FocusStateImpl$WhenMappings;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusStateImpl;->$values()[Landroidx/compose/ui/focus/FocusStateImpl;
+HSPLandroidx/compose/ui/focus/FocusStateImpl;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusStateImpl;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/ui/focus/FocusStateImpl;->isFocused()Z
+HSPLandroidx/compose/ui/focus/FocusStateImpl;->values()[Landroidx/compose/ui/focus/FocusStateImpl;
+HSPLandroidx/compose/ui/focus/FocusTransactionsKt$WhenMappings;-><clinit>()V
+HSPLandroidx/compose/ui/focus/FocusTransactionsKt;->activateNode(Landroidx/compose/ui/focus/FocusModifier;)V
+HSPLandroidx/compose/ui/focus/FocusTransactionsKt;->deactivateNode(Landroidx/compose/ui/focus/FocusModifier;)V
+HSPLandroidx/compose/ui/focus/FocusTransactionsKt;->sendOnFocusEvent(Landroidx/compose/ui/focus/FocusModifier;)V
+HSPLandroidx/compose/ui/geometry/CornerRadius$Companion;-><init>()V
+HSPLandroidx/compose/ui/geometry/CornerRadius$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/geometry/CornerRadius$Companion;->getZero-kKHJgLs()J
+HSPLandroidx/compose/ui/geometry/CornerRadius;-><clinit>()V
+HSPLandroidx/compose/ui/geometry/CornerRadius;->access$getZero$cp()J
+HSPLandroidx/compose/ui/geometry/CornerRadius;->constructor-impl(J)J
+HSPLandroidx/compose/ui/geometry/CornerRadius;->getX-impl(J)F
+HSPLandroidx/compose/ui/geometry/CornerRadius;->getY-impl(J)F
+HSPLandroidx/compose/ui/geometry/CornerRadiusKt;->CornerRadius$default(FFILjava/lang/Object;)J
+HSPLandroidx/compose/ui/geometry/CornerRadiusKt;->CornerRadius(FF)J
+HSPLandroidx/compose/ui/geometry/Offset$Companion;-><init>()V
+HSPLandroidx/compose/ui/geometry/Offset$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/geometry/Offset$Companion;->getInfinite-F1C5BW0()J
+HSPLandroidx/compose/ui/geometry/Offset$Companion;->getUnspecified-F1C5BW0()J
+HSPLandroidx/compose/ui/geometry/Offset$Companion;->getZero-F1C5BW0()J
+HSPLandroidx/compose/ui/geometry/Offset;-><clinit>()V
+HSPLandroidx/compose/ui/geometry/Offset;-><init>(J)V
+HSPLandroidx/compose/ui/geometry/Offset;->access$getInfinite$cp()J
+HSPLandroidx/compose/ui/geometry/Offset;->access$getUnspecified$cp()J
+HSPLandroidx/compose/ui/geometry/Offset;->access$getZero$cp()J
+HSPLandroidx/compose/ui/geometry/Offset;->box-impl(J)Landroidx/compose/ui/geometry/Offset;
+HSPLandroidx/compose/ui/geometry/Offset;->constructor-impl(J)J
+HSPLandroidx/compose/ui/geometry/Offset;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/geometry/Offset;->equals-impl(JLjava/lang/Object;)Z
+HSPLandroidx/compose/ui/geometry/Offset;->getDistance-impl(J)F
+HSPLandroidx/compose/ui/geometry/Offset;->getX-impl(J)F
+HSPLandroidx/compose/ui/geometry/Offset;->getY-impl(J)F
+HSPLandroidx/compose/ui/geometry/Offset;->unbox-impl()J
+HSPLandroidx/compose/ui/geometry/OffsetKt;->Offset(FF)J
+HSPLandroidx/compose/ui/geometry/Rect$Companion;-><init>()V
+HSPLandroidx/compose/ui/geometry/Rect$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/geometry/Rect$Companion;->getZero()Landroidx/compose/ui/geometry/Rect;
+HSPLandroidx/compose/ui/geometry/Rect;-><clinit>()V
+HSPLandroidx/compose/ui/geometry/Rect;-><init>(FFFF)V
+HSPLandroidx/compose/ui/geometry/Rect;->access$getZero$cp()Landroidx/compose/ui/geometry/Rect;
+HSPLandroidx/compose/ui/geometry/Rect;->getBottom()F
+HSPLandroidx/compose/ui/geometry/Rect;->getLeft()F
+HSPLandroidx/compose/ui/geometry/Rect;->getRight()F
+HSPLandroidx/compose/ui/geometry/Rect;->getTop()F
+HSPLandroidx/compose/ui/geometry/RectKt;->Rect-tz77jQw(JJ)Landroidx/compose/ui/geometry/Rect;
+HSPLandroidx/compose/ui/geometry/RoundRect$Companion;-><init>()V
+HSPLandroidx/compose/ui/geometry/RoundRect$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/geometry/RoundRect;-><clinit>()V
+HSPLandroidx/compose/ui/geometry/RoundRect;-><init>(FFFFJJJJ)V
+HSPLandroidx/compose/ui/geometry/RoundRect;-><init>(FFFFJJJJLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/geometry/RoundRect;->getBottom()F
+HSPLandroidx/compose/ui/geometry/RoundRect;->getBottomLeftCornerRadius-kKHJgLs()J
+HSPLandroidx/compose/ui/geometry/RoundRect;->getBottomRightCornerRadius-kKHJgLs()J
+HSPLandroidx/compose/ui/geometry/RoundRect;->getHeight()F
+HSPLandroidx/compose/ui/geometry/RoundRect;->getLeft()F
+HSPLandroidx/compose/ui/geometry/RoundRect;->getRight()F
+HSPLandroidx/compose/ui/geometry/RoundRect;->getTop()F
+HSPLandroidx/compose/ui/geometry/RoundRect;->getTopLeftCornerRadius-kKHJgLs()J
+HSPLandroidx/compose/ui/geometry/RoundRect;->getTopRightCornerRadius-kKHJgLs()J
+HSPLandroidx/compose/ui/geometry/RoundRect;->getWidth()F
+HSPLandroidx/compose/ui/geometry/RoundRectKt;->RoundRect(FFFFFF)Landroidx/compose/ui/geometry/RoundRect;
+HSPLandroidx/compose/ui/geometry/RoundRectKt;->RoundRect-ZAM2FJo(Landroidx/compose/ui/geometry/Rect;JJJJ)Landroidx/compose/ui/geometry/RoundRect;
+HSPLandroidx/compose/ui/geometry/RoundRectKt;->RoundRect-gG7oq9Y(FFFFJ)Landroidx/compose/ui/geometry/RoundRect;
+HSPLandroidx/compose/ui/geometry/RoundRectKt;->isSimple(Landroidx/compose/ui/geometry/RoundRect;)Z
+HSPLandroidx/compose/ui/geometry/Size$Companion;-><init>()V
+HSPLandroidx/compose/ui/geometry/Size$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/geometry/Size$Companion;->getUnspecified-NH-jbRc()J
+HSPLandroidx/compose/ui/geometry/Size$Companion;->getZero-NH-jbRc()J
+HSPLandroidx/compose/ui/geometry/Size;-><clinit>()V
+HSPLandroidx/compose/ui/geometry/Size;-><init>(J)V
+HSPLandroidx/compose/ui/geometry/Size;->access$getUnspecified$cp()J
+HSPLandroidx/compose/ui/geometry/Size;->access$getZero$cp()J
+HSPLandroidx/compose/ui/geometry/Size;->box-impl(J)Landroidx/compose/ui/geometry/Size;
+HSPLandroidx/compose/ui/geometry/Size;->constructor-impl(J)J
+HSPLandroidx/compose/ui/geometry/Size;->equals-impl(JLjava/lang/Object;)Z
+HSPLandroidx/compose/ui/geometry/Size;->equals-impl0(JJ)Z
+HSPLandroidx/compose/ui/geometry/Size;->getHeight-impl(J)F
+HSPLandroidx/compose/ui/geometry/Size;->getMinDimension-impl(J)F
+HSPLandroidx/compose/ui/geometry/Size;->getWidth-impl(J)F
+HSPLandroidx/compose/ui/geometry/Size;->unbox-impl()J
+HSPLandroidx/compose/ui/geometry/SizeKt;->Size(FF)J
+HSPLandroidx/compose/ui/geometry/SizeKt;->toRect-uvyYCjk(J)Landroidx/compose/ui/geometry/Rect;
+HSPLandroidx/compose/ui/graphics/AndroidBlendMode_androidKt;->toAndroidBlendMode-s9anfk8(I)Landroid/graphics/BlendMode;
+HSPLandroidx/compose/ui/graphics/AndroidCanvas;-><init>()V
+HSPLandroidx/compose/ui/graphics/AndroidCanvas;->disableZ()V
+HSPLandroidx/compose/ui/graphics/AndroidCanvas;->drawImageRect-HPBpro0(Landroidx/compose/ui/graphics/ImageBitmap;JJJJLandroidx/compose/ui/graphics/Paint;)V
+HSPLandroidx/compose/ui/graphics/AndroidCanvas;->drawPath(Landroidx/compose/ui/graphics/Path;Landroidx/compose/ui/graphics/Paint;)V
+HSPLandroidx/compose/ui/graphics/AndroidCanvas;->drawRect(FFFFLandroidx/compose/ui/graphics/Paint;)V
+HSPLandroidx/compose/ui/graphics/AndroidCanvas;->drawRoundRect(FFFFFFLandroidx/compose/ui/graphics/Paint;)V
+HSPLandroidx/compose/ui/graphics/AndroidCanvas;->enableZ()V
+HSPLandroidx/compose/ui/graphics/AndroidCanvas;->getInternalCanvas()Landroid/graphics/Canvas;
+HSPLandroidx/compose/ui/graphics/AndroidCanvas;->restore()V
+HSPLandroidx/compose/ui/graphics/AndroidCanvas;->save()V
+HSPLandroidx/compose/ui/graphics/AndroidCanvas;->setInternalCanvas(Landroid/graphics/Canvas;)V
+HSPLandroidx/compose/ui/graphics/AndroidCanvas;->translate(FF)V
+HSPLandroidx/compose/ui/graphics/AndroidCanvas_androidKt;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/AndroidCanvas_androidKt;->access$getEmptyCanvas$p()Landroid/graphics/Canvas;
+HSPLandroidx/compose/ui/graphics/AndroidCanvas_androidKt;->getNativeCanvas(Landroidx/compose/ui/graphics/Canvas;)Landroid/graphics/Canvas;
+HSPLandroidx/compose/ui/graphics/AndroidColorFilter_androidKt;->actualTintColorFilter-xETnrds(JI)Landroidx/compose/ui/graphics/ColorFilter;
+HSPLandroidx/compose/ui/graphics/AndroidColorFilter_androidKt;->asAndroidColorFilter(Landroidx/compose/ui/graphics/ColorFilter;)Landroid/graphics/ColorFilter;
+HSPLandroidx/compose/ui/graphics/AndroidImageBitmap;-><init>(Landroid/graphics/Bitmap;)V
+HSPLandroidx/compose/ui/graphics/AndroidImageBitmap;->getBitmap$ui_graphics_release()Landroid/graphics/Bitmap;
+HSPLandroidx/compose/ui/graphics/AndroidImageBitmap;->getHeight()I
+HSPLandroidx/compose/ui/graphics/AndroidImageBitmap;->getWidth()I
+HSPLandroidx/compose/ui/graphics/AndroidImageBitmap_androidKt;->asAndroidBitmap(Landroidx/compose/ui/graphics/ImageBitmap;)Landroid/graphics/Bitmap;
+HSPLandroidx/compose/ui/graphics/AndroidImageBitmap_androidKt;->asImageBitmap(Landroid/graphics/Bitmap;)Landroidx/compose/ui/graphics/ImageBitmap;
+HSPLandroidx/compose/ui/graphics/AndroidPaint;-><init>()V
+HSPLandroidx/compose/ui/graphics/AndroidPaint;-><init>(Landroid/graphics/Paint;)V
+HSPLandroidx/compose/ui/graphics/AndroidPaint;->asFrameworkPaint()Landroid/graphics/Paint;
+HSPLandroidx/compose/ui/graphics/AndroidPaint;->getAlpha()F
+HSPLandroidx/compose/ui/graphics/AndroidPaint;->getBlendMode-0nO6VwU()I
+HSPLandroidx/compose/ui/graphics/AndroidPaint;->getColor-0d7_KjU()J
+HSPLandroidx/compose/ui/graphics/AndroidPaint;->getColorFilter()Landroidx/compose/ui/graphics/ColorFilter;
+HSPLandroidx/compose/ui/graphics/AndroidPaint;->getFilterQuality-f-v9h1I()I
+HSPLandroidx/compose/ui/graphics/AndroidPaint;->getShader()Landroid/graphics/Shader;
+HSPLandroidx/compose/ui/graphics/AndroidPaint;->setAlpha(F)V
+HSPLandroidx/compose/ui/graphics/AndroidPaint;->setColor-8_81llA(J)V
+HSPLandroidx/compose/ui/graphics/AndroidPaint;->setColorFilter(Landroidx/compose/ui/graphics/ColorFilter;)V
+HSPLandroidx/compose/ui/graphics/AndroidPaint;->setShader(Landroid/graphics/Shader;)V
+HSPLandroidx/compose/ui/graphics/AndroidPaint;->setStrokeWidth(F)V
+HSPLandroidx/compose/ui/graphics/AndroidPaint;->setStyle-k9PVt8s(I)V
+HSPLandroidx/compose/ui/graphics/AndroidPaint_androidKt;->Paint()Landroidx/compose/ui/graphics/Paint;
+HSPLandroidx/compose/ui/graphics/AndroidPaint_androidKt;->getNativeAlpha(Landroid/graphics/Paint;)F
+HSPLandroidx/compose/ui/graphics/AndroidPaint_androidKt;->getNativeColor(Landroid/graphics/Paint;)J
+HSPLandroidx/compose/ui/graphics/AndroidPaint_androidKt;->getNativeFilterQuality(Landroid/graphics/Paint;)I
+HSPLandroidx/compose/ui/graphics/AndroidPaint_androidKt;->makeNativePaint()Landroid/graphics/Paint;
+HSPLandroidx/compose/ui/graphics/AndroidPaint_androidKt;->setNativeAlpha(Landroid/graphics/Paint;F)V
+HSPLandroidx/compose/ui/graphics/AndroidPaint_androidKt;->setNativeColor-4WTKRHQ(Landroid/graphics/Paint;J)V
+HSPLandroidx/compose/ui/graphics/AndroidPaint_androidKt;->setNativeColorFilter(Landroid/graphics/Paint;Landroidx/compose/ui/graphics/ColorFilter;)V
+HSPLandroidx/compose/ui/graphics/AndroidPaint_androidKt;->setNativeShader(Landroid/graphics/Paint;Landroid/graphics/Shader;)V
+HSPLandroidx/compose/ui/graphics/AndroidPaint_androidKt;->setNativeStrokeWidth(Landroid/graphics/Paint;F)V
+HSPLandroidx/compose/ui/graphics/AndroidPaint_androidKt;->setNativeStyle--5YerkU(Landroid/graphics/Paint;I)V
+HSPLandroidx/compose/ui/graphics/AndroidPaint_androidKt;->toComposePaint(Landroid/graphics/Paint;)Landroidx/compose/ui/graphics/Paint;
+HSPLandroidx/compose/ui/graphics/AndroidPath;-><init>(Landroid/graphics/Path;)V
+HSPLandroidx/compose/ui/graphics/AndroidPath;-><init>(Landroid/graphics/Path;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/AndroidPath;->addRoundRect(Landroidx/compose/ui/geometry/RoundRect;)V
+HSPLandroidx/compose/ui/graphics/AndroidPath;->getInternalPath()Landroid/graphics/Path;
+HSPLandroidx/compose/ui/graphics/AndroidPath;->reset()V
+HSPLandroidx/compose/ui/graphics/AndroidPath_androidKt;->Path()Landroidx/compose/ui/graphics/Path;
+HSPLandroidx/compose/ui/graphics/BlendMode$Companion;-><init>()V
+HSPLandroidx/compose/ui/graphics/BlendMode$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/BlendMode$Companion;->getClear-0nO6VwU()I
+HSPLandroidx/compose/ui/graphics/BlendMode$Companion;->getDst-0nO6VwU()I
+HSPLandroidx/compose/ui/graphics/BlendMode$Companion;->getDstOver-0nO6VwU()I
+HSPLandroidx/compose/ui/graphics/BlendMode$Companion;->getSrc-0nO6VwU()I
+HSPLandroidx/compose/ui/graphics/BlendMode$Companion;->getSrcIn-0nO6VwU()I
+HSPLandroidx/compose/ui/graphics/BlendMode$Companion;->getSrcOver-0nO6VwU()I
+HSPLandroidx/compose/ui/graphics/BlendMode;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/BlendMode;->access$getClear$cp()I
+HSPLandroidx/compose/ui/graphics/BlendMode;->access$getDst$cp()I
+HSPLandroidx/compose/ui/graphics/BlendMode;->access$getDstOver$cp()I
+HSPLandroidx/compose/ui/graphics/BlendMode;->access$getSrc$cp()I
+HSPLandroidx/compose/ui/graphics/BlendMode;->access$getSrcIn$cp()I
+HSPLandroidx/compose/ui/graphics/BlendMode;->access$getSrcOver$cp()I
+HSPLandroidx/compose/ui/graphics/BlendMode;->constructor-impl(I)I
+HSPLandroidx/compose/ui/graphics/BlendMode;->equals-impl0(II)Z
+HSPLandroidx/compose/ui/graphics/BlendModeColorFilterHelper;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/BlendModeColorFilterHelper;-><init>()V
+HSPLandroidx/compose/ui/graphics/BlendModeColorFilterHelper;->BlendModeColorFilter-xETnrds(JI)Landroid/graphics/BlendModeColorFilter;
+HSPLandroidx/compose/ui/graphics/BlockGraphicsLayerModifier$measure$1;-><init>(Landroidx/compose/ui/layout/Placeable;Landroidx/compose/ui/graphics/BlockGraphicsLayerModifier;)V
+HSPLandroidx/compose/ui/graphics/BlockGraphicsLayerModifier$measure$1;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+HSPLandroidx/compose/ui/graphics/BlockGraphicsLayerModifier$measure$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/graphics/BlockGraphicsLayerModifier;-><init>(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/graphics/BlockGraphicsLayerModifier;->access$getLayerBlock$p(Landroidx/compose/ui/graphics/BlockGraphicsLayerModifier;)Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/ui/graphics/BlockGraphicsLayerModifier;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/graphics/BlockGraphicsLayerModifier;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/ui/graphics/CanvasHolder;-><init>()V
+HSPLandroidx/compose/ui/graphics/CanvasHolder;->getAndroidCanvas()Landroidx/compose/ui/graphics/AndroidCanvas;
+HSPLandroidx/compose/ui/graphics/CanvasUtils;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/CanvasUtils;-><init>()V
+HSPLandroidx/compose/ui/graphics/CanvasUtils;->enableZ(Landroid/graphics/Canvas;Z)V
+HSPLandroidx/compose/ui/graphics/CanvasZHelper;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/CanvasZHelper;-><init>()V
+HSPLandroidx/compose/ui/graphics/CanvasZHelper;->enableZ(Landroid/graphics/Canvas;Z)V
+HSPLandroidx/compose/ui/graphics/Color$Companion;-><init>()V
+HSPLandroidx/compose/ui/graphics/Color$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/Color$Companion;->getBlack-0d7_KjU()J
+HSPLandroidx/compose/ui/graphics/Color$Companion;->getBlue-0d7_KjU()J
+HSPLandroidx/compose/ui/graphics/Color$Companion;->getLightGray-0d7_KjU()J
+HSPLandroidx/compose/ui/graphics/Color$Companion;->getRed-0d7_KjU()J
+HSPLandroidx/compose/ui/graphics/Color$Companion;->getTransparent-0d7_KjU()J
+HSPLandroidx/compose/ui/graphics/Color$Companion;->getUnspecified-0d7_KjU()J
+HSPLandroidx/compose/ui/graphics/Color;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/Color;-><init>(J)V
+HSPLandroidx/compose/ui/graphics/Color;->access$getBlack$cp()J
+HSPLandroidx/compose/ui/graphics/Color;->access$getBlue$cp()J
+HSPLandroidx/compose/ui/graphics/Color;->access$getLightGray$cp()J
+HSPLandroidx/compose/ui/graphics/Color;->access$getRed$cp()J
+HSPLandroidx/compose/ui/graphics/Color;->access$getTransparent$cp()J
+HSPLandroidx/compose/ui/graphics/Color;->access$getUnspecified$cp()J
+HSPLandroidx/compose/ui/graphics/Color;->box-impl(J)Landroidx/compose/ui/graphics/Color;
+HSPLandroidx/compose/ui/graphics/Color;->constructor-impl(J)J
+HSPLandroidx/compose/ui/graphics/Color;->convert-vNxB06k(JLandroidx/compose/ui/graphics/colorspace/ColorSpace;)J
+HSPLandroidx/compose/ui/graphics/Color;->copy-wmQWz5c$default(JFFFFILjava/lang/Object;)J
+HSPLandroidx/compose/ui/graphics/Color;->copy-wmQWz5c(JFFFF)J
+HSPLandroidx/compose/ui/graphics/Color;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/graphics/Color;->equals-impl(JLjava/lang/Object;)Z
+HSPLandroidx/compose/ui/graphics/Color;->equals-impl0(JJ)Z
+HSPLandroidx/compose/ui/graphics/Color;->getAlpha-impl(J)F
+HSPLandroidx/compose/ui/graphics/Color;->getBlue-impl(J)F
+HSPLandroidx/compose/ui/graphics/Color;->getColorSpace-impl(J)Landroidx/compose/ui/graphics/colorspace/ColorSpace;
+HSPLandroidx/compose/ui/graphics/Color;->getGreen-impl(J)F
+HSPLandroidx/compose/ui/graphics/Color;->getRed-impl(J)F
+HSPLandroidx/compose/ui/graphics/Color;->unbox-impl()J
+HSPLandroidx/compose/ui/graphics/ColorFilter$Companion;-><init>()V
+HSPLandroidx/compose/ui/graphics/ColorFilter$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/ColorFilter$Companion;->tint-xETnrds$default(Landroidx/compose/ui/graphics/ColorFilter$Companion;JIILjava/lang/Object;)Landroidx/compose/ui/graphics/ColorFilter;
+HSPLandroidx/compose/ui/graphics/ColorFilter$Companion;->tint-xETnrds(JI)Landroidx/compose/ui/graphics/ColorFilter;
+HSPLandroidx/compose/ui/graphics/ColorFilter;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/ColorFilter;-><init>(Landroid/graphics/ColorFilter;)V
+HSPLandroidx/compose/ui/graphics/ColorFilter;->getNativeColorFilter$ui_graphics_release()Landroid/graphics/ColorFilter;
+HSPLandroidx/compose/ui/graphics/ColorKt;->Color$default(IIIIILjava/lang/Object;)J
+HSPLandroidx/compose/ui/graphics/ColorKt;->Color(FFFFLandroidx/compose/ui/graphics/colorspace/ColorSpace;)J
+HSPLandroidx/compose/ui/graphics/ColorKt;->Color(I)J
+HSPLandroidx/compose/ui/graphics/ColorKt;->Color(IIII)J
+HSPLandroidx/compose/ui/graphics/ColorKt;->Color(J)J
+HSPLandroidx/compose/ui/graphics/ColorKt;->compositeOver--OWjLjI(JJ)J
+HSPLandroidx/compose/ui/graphics/ColorKt;->toArgb-8_81llA(J)I
+HSPLandroidx/compose/ui/graphics/CompositingStrategy$Companion;-><init>()V
+HSPLandroidx/compose/ui/graphics/CompositingStrategy$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/CompositingStrategy$Companion;->getAuto--NrFUSI()I
+HSPLandroidx/compose/ui/graphics/CompositingStrategy$Companion;->getModulateAlpha--NrFUSI()I
+HSPLandroidx/compose/ui/graphics/CompositingStrategy$Companion;->getOffscreen--NrFUSI()I
+HSPLandroidx/compose/ui/graphics/CompositingStrategy;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/CompositingStrategy;->access$getAuto$cp()I
+HSPLandroidx/compose/ui/graphics/CompositingStrategy;->access$getModulateAlpha$cp()I
+HSPLandroidx/compose/ui/graphics/CompositingStrategy;->access$getOffscreen$cp()I
+HSPLandroidx/compose/ui/graphics/CompositingStrategy;->constructor-impl(I)I
+HSPLandroidx/compose/ui/graphics/CompositingStrategy;->equals-impl0(II)Z
+HSPLandroidx/compose/ui/graphics/FilterQuality$Companion;-><init>()V
+HSPLandroidx/compose/ui/graphics/FilterQuality$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/FilterQuality$Companion;->getLow-f-v9h1I()I
+HSPLandroidx/compose/ui/graphics/FilterQuality;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/FilterQuality;->access$getLow$cp()I
+HSPLandroidx/compose/ui/graphics/FilterQuality;->constructor-impl(I)I
+HSPLandroidx/compose/ui/graphics/FilterQuality;->equals-impl0(II)Z
+HSPLandroidx/compose/ui/graphics/Float16$Companion;-><init>()V
+HSPLandroidx/compose/ui/graphics/Float16$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/Float16$Companion;->access$floatToHalf(Landroidx/compose/ui/graphics/Float16$Companion;F)S
+HSPLandroidx/compose/ui/graphics/Float16$Companion;->floatToHalf(F)S
+HSPLandroidx/compose/ui/graphics/Float16;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/Float16;->constructor-impl(F)S
+HSPLandroidx/compose/ui/graphics/Float16;->constructor-impl(S)S
+HSPLandroidx/compose/ui/graphics/GraphicsLayerModifierKt;->graphicsLayer(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/graphics/GraphicsLayerModifierKt;->graphicsLayer-Ap8cVGQ$default(Landroidx/compose/ui/Modifier;FFFFFFFFFFJLandroidx/compose/ui/graphics/Shape;ZLandroidx/compose/ui/graphics/RenderEffect;JJIILjava/lang/Object;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/graphics/GraphicsLayerModifierKt;->graphicsLayer-Ap8cVGQ(Landroidx/compose/ui/Modifier;FFFFFFFFFFJLandroidx/compose/ui/graphics/Shape;ZLandroidx/compose/ui/graphics/RenderEffect;JJI)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/graphics/GraphicsLayerModifierKt;->toolingGraphicsLayer(Landroidx/compose/ui/Modifier;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/graphics/GraphicsLayerScopeKt;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/GraphicsLayerScopeKt;->getDefaultShadowColor()J
+HSPLandroidx/compose/ui/graphics/Matrix$Companion;-><init>()V
+HSPLandroidx/compose/ui/graphics/Matrix$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/Matrix;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/Matrix;->constructor-impl$default([FILkotlin/jvm/internal/DefaultConstructorMarker;)[F
+HSPLandroidx/compose/ui/graphics/Matrix;->constructor-impl([F)[F
+HSPLandroidx/compose/ui/graphics/Outline$Rounded;-><init>(Landroidx/compose/ui/geometry/RoundRect;)V
+HSPLandroidx/compose/ui/graphics/Outline$Rounded;->getRoundRect()Landroidx/compose/ui/geometry/RoundRect;
+HSPLandroidx/compose/ui/graphics/Outline$Rounded;->getRoundRectPath$ui_graphics_release()Landroidx/compose/ui/graphics/Path;
+HSPLandroidx/compose/ui/graphics/Outline;-><init>()V
+HSPLandroidx/compose/ui/graphics/Outline;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/OutlineKt;->access$hasSameCornerRadius(Landroidx/compose/ui/geometry/RoundRect;)Z
+HSPLandroidx/compose/ui/graphics/OutlineKt;->drawOutline-wDX37Ww$default(Landroidx/compose/ui/graphics/drawscope/DrawScope;Landroidx/compose/ui/graphics/Outline;JFLandroidx/compose/ui/graphics/drawscope/DrawStyle;Landroidx/compose/ui/graphics/ColorFilter;IILjava/lang/Object;)V
+HSPLandroidx/compose/ui/graphics/OutlineKt;->drawOutline-wDX37Ww(Landroidx/compose/ui/graphics/drawscope/DrawScope;Landroidx/compose/ui/graphics/Outline;JFLandroidx/compose/ui/graphics/drawscope/DrawStyle;Landroidx/compose/ui/graphics/ColorFilter;I)V
+HSPLandroidx/compose/ui/graphics/OutlineKt;->hasSameCornerRadius(Landroidx/compose/ui/geometry/RoundRect;)Z
+HSPLandroidx/compose/ui/graphics/OutlineKt;->size(Landroidx/compose/ui/geometry/RoundRect;)J
+HSPLandroidx/compose/ui/graphics/OutlineKt;->topLeft(Landroidx/compose/ui/geometry/RoundRect;)J
+HSPLandroidx/compose/ui/graphics/PaintingStyle$Companion;-><init>()V
+HSPLandroidx/compose/ui/graphics/PaintingStyle$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/PaintingStyle$Companion;->getFill-TiuSbCo()I
+HSPLandroidx/compose/ui/graphics/PaintingStyle$Companion;->getStroke-TiuSbCo()I
+HSPLandroidx/compose/ui/graphics/PaintingStyle;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/PaintingStyle;->access$getFill$cp()I
+HSPLandroidx/compose/ui/graphics/PaintingStyle;->access$getStroke$cp()I
+HSPLandroidx/compose/ui/graphics/PaintingStyle;->constructor-impl(I)I
+HSPLandroidx/compose/ui/graphics/PaintingStyle;->equals-impl0(II)Z
+HSPLandroidx/compose/ui/graphics/RectangleShapeKt$RectangleShape$1;-><init>()V
+HSPLandroidx/compose/ui/graphics/RectangleShapeKt;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/RectangleShapeKt;->getRectangleShape()Landroidx/compose/ui/graphics/Shape;
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;-><init>()V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->getAlpha()F
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->getAmbientShadowColor-0d7_KjU()J
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->getCameraDistance()F
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->getClip()Z
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->getCompositingStrategy--NrFUSI()I
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->getDensity()F
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->getRenderEffect()Landroidx/compose/ui/graphics/RenderEffect;
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->getRotationX()F
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->getRotationY()F
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->getRotationZ()F
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->getScaleX()F
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->getScaleY()F
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->getShadowElevation()F
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->getShape()Landroidx/compose/ui/graphics/Shape;
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->getSpotShadowColor-0d7_KjU()J
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->getTransformOrigin-SzJe1aQ()J
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->getTranslationX()F
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->getTranslationY()F
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->reset()V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setAlpha(F)V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setAmbientShadowColor-8_81llA(J)V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setCameraDistance(F)V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setClip(Z)V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setCompositingStrategy-aDBOjCE(I)V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setGraphicsDensity$ui_release(Landroidx/compose/ui/unit/Density;)V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setRenderEffect(Landroidx/compose/ui/graphics/RenderEffect;)V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setRotationX(F)V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setRotationY(F)V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setRotationZ(F)V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setScaleX(F)V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setScaleY(F)V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setShadowElevation(F)V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setShape(Landroidx/compose/ui/graphics/Shape;)V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setSize-uvyYCjk(J)V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setSpotShadowColor-8_81llA(J)V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setTransformOrigin-__ExYCQ(J)V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setTranslationX(F)V
+HSPLandroidx/compose/ui/graphics/ReusableGraphicsLayerScope;->setTranslationY(F)V
+HSPLandroidx/compose/ui/graphics/Shadow$Companion;-><init>()V
+HSPLandroidx/compose/ui/graphics/Shadow$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/Shadow$Companion;->getNone()Landroidx/compose/ui/graphics/Shadow;
+HSPLandroidx/compose/ui/graphics/Shadow;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/Shadow;-><init>(JJF)V
+HSPLandroidx/compose/ui/graphics/Shadow;-><init>(JJFILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/Shadow;-><init>(JJFLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/Shadow;->access$getNone$cp()Landroidx/compose/ui/graphics/Shadow;
+HSPLandroidx/compose/ui/graphics/Shadow;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier$layerBlock$1;-><init>(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)V
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier$layerBlock$1;->invoke(Landroidx/compose/ui/graphics/GraphicsLayerScope;)V
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier$layerBlock$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier$measure$1;-><init>(Landroidx/compose/ui/layout/Placeable;Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)V
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier$measure$1;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier$measure$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;-><init>(FFFFFFFFFFJLandroidx/compose/ui/graphics/Shape;ZLandroidx/compose/ui/graphics/RenderEffect;JJILkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;-><init>(FFFFFFFFFFJLandroidx/compose/ui/graphics/Shape;ZLandroidx/compose/ui/graphics/RenderEffect;JJILkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->access$getAlpha$p(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)F
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->access$getAmbientShadowColor$p(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)J
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->access$getCameraDistance$p(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)F
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->access$getClip$p(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)Z
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->access$getCompositingStrategy$p(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)I
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->access$getLayerBlock$p(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->access$getRenderEffect$p(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)Landroidx/compose/ui/graphics/RenderEffect;
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->access$getRotationX$p(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)F
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->access$getRotationY$p(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)F
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->access$getRotationZ$p(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)F
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->access$getScaleX$p(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)F
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->access$getScaleY$p(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)F
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->access$getShadowElevation$p(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)F
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->access$getShape$p(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)Landroidx/compose/ui/graphics/Shape;
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->access$getSpotShadowColor$p(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)J
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->access$getTransformOrigin$p(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)J
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->access$getTranslationX$p(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)F
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->access$getTranslationY$p(Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;)F
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/ui/graphics/TransformOrigin$Companion;-><init>()V
+HSPLandroidx/compose/ui/graphics/TransformOrigin$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/TransformOrigin$Companion;->getCenter-SzJe1aQ()J
+HSPLandroidx/compose/ui/graphics/TransformOrigin;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/TransformOrigin;->access$getCenter$cp()J
+HSPLandroidx/compose/ui/graphics/TransformOrigin;->constructor-impl(J)J
+HSPLandroidx/compose/ui/graphics/TransformOrigin;->equals-impl0(JJ)Z
+HSPLandroidx/compose/ui/graphics/TransformOrigin;->getPivotFractionX-impl(J)F
+HSPLandroidx/compose/ui/graphics/TransformOrigin;->getPivotFractionY-impl(J)F
+HSPLandroidx/compose/ui/graphics/TransformOriginKt;->TransformOrigin(FF)J
+HSPLandroidx/compose/ui/graphics/colorspace/Adaptation$Companion$Bradford$1;-><init>([F)V
+HSPLandroidx/compose/ui/graphics/colorspace/Adaptation$Companion$Ciecat02$1;-><init>([F)V
+HSPLandroidx/compose/ui/graphics/colorspace/Adaptation$Companion$VonKries$1;-><init>([F)V
+HSPLandroidx/compose/ui/graphics/colorspace/Adaptation$Companion;-><init>()V
+HSPLandroidx/compose/ui/graphics/colorspace/Adaptation$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/colorspace/Adaptation$Companion;->getBradford()Landroidx/compose/ui/graphics/colorspace/Adaptation;
+HSPLandroidx/compose/ui/graphics/colorspace/Adaptation;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/colorspace/Adaptation;-><init>([F)V
+HSPLandroidx/compose/ui/graphics/colorspace/Adaptation;-><init>([FLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/colorspace/Adaptation;->access$getBradford$cp()Landroidx/compose/ui/graphics/colorspace/Adaptation;
+HSPLandroidx/compose/ui/graphics/colorspace/Adaptation;->getTransform$ui_graphics_release()[F
+HSPLandroidx/compose/ui/graphics/colorspace/ColorModel$Companion;-><init>()V
+HSPLandroidx/compose/ui/graphics/colorspace/ColorModel$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/colorspace/ColorModel$Companion;->getLab-xdoWZVw()J
+HSPLandroidx/compose/ui/graphics/colorspace/ColorModel$Companion;->getRgb-xdoWZVw()J
+HSPLandroidx/compose/ui/graphics/colorspace/ColorModel$Companion;->getXyz-xdoWZVw()J
+HSPLandroidx/compose/ui/graphics/colorspace/ColorModel;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/colorspace/ColorModel;->access$getLab$cp()J
+HSPLandroidx/compose/ui/graphics/colorspace/ColorModel;->access$getRgb$cp()J
+HSPLandroidx/compose/ui/graphics/colorspace/ColorModel;->access$getXyz$cp()J
+HSPLandroidx/compose/ui/graphics/colorspace/ColorModel;->constructor-impl(J)J
+HSPLandroidx/compose/ui/graphics/colorspace/ColorModel;->getComponentCount-impl(J)I
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpace$Companion;-><init>()V
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpace$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpace;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpace;-><init>(Ljava/lang/String;JI)V
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpace;-><init>(Ljava/lang/String;JILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpace;->getComponentCount()I
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpace;->getId$ui_graphics_release()I
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaceKt;->chromaticAdaptation([F[F[F)[F
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaceKt;->compare(Landroidx/compose/ui/graphics/colorspace/WhitePoint;Landroidx/compose/ui/graphics/colorspace/WhitePoint;)Z
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaceKt;->compare([F[F)Z
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaceKt;->inverse3x3([F)[F
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaceKt;->mul3x3([F[F)[F
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaceKt;->mul3x3Diag([F[F)[F
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaceKt;->mul3x3Float3([F[F)[F
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaceKt;->rcpResponse(DDDDDD)D
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaceKt;->response(DDDDDD)D
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaces$ExtendedSrgb$1;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaces$ExtendedSrgb$1;-><init>()V
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaces$ExtendedSrgb$2;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaces$ExtendedSrgb$2;-><init>()V
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaces;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaces;-><init>()V
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaces;->getColorSpacesArray$ui_graphics_release()[Landroidx/compose/ui/graphics/colorspace/ColorSpace;
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaces;->getNtsc1953Primaries$ui_graphics_release()[F
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaces;->getSrgb()Landroidx/compose/ui/graphics/colorspace/Rgb;
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaces;->getSrgbPrimaries$ui_graphics_release()[F
+HSPLandroidx/compose/ui/graphics/colorspace/ColorSpaces;->getUnspecified$ui_graphics_release()Landroidx/compose/ui/graphics/colorspace/Rgb;
+HSPLandroidx/compose/ui/graphics/colorspace/Illuminant;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/colorspace/Illuminant;-><init>()V
+HSPLandroidx/compose/ui/graphics/colorspace/Illuminant;->getC()Landroidx/compose/ui/graphics/colorspace/WhitePoint;
+HSPLandroidx/compose/ui/graphics/colorspace/Illuminant;->getD50()Landroidx/compose/ui/graphics/colorspace/WhitePoint;
+HSPLandroidx/compose/ui/graphics/colorspace/Illuminant;->getD60()Landroidx/compose/ui/graphics/colorspace/WhitePoint;
+HSPLandroidx/compose/ui/graphics/colorspace/Illuminant;->getD65()Landroidx/compose/ui/graphics/colorspace/WhitePoint;
+HSPLandroidx/compose/ui/graphics/colorspace/Lab$Companion;-><init>()V
+HSPLandroidx/compose/ui/graphics/colorspace/Lab$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/colorspace/Lab;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/colorspace/Lab;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/ui/graphics/colorspace/Oklab$Companion;-><init>()V
+HSPLandroidx/compose/ui/graphics/colorspace/Oklab$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/colorspace/Oklab;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/colorspace/Oklab;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$1;-><init>(Landroidx/compose/ui/graphics/colorspace/TransferParameters;)V
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$1;->invoke(D)Ljava/lang/Double;
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$3;-><init>(Landroidx/compose/ui/graphics/colorspace/TransferParameters;)V
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$3;->invoke(D)Ljava/lang/Double;
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$3;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$5;-><init>(D)V
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$6;-><init>(D)V
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$Companion$DoubleIdentity$1;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$Companion$DoubleIdentity$1;-><init>()V
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$Companion$DoubleIdentity$1;->invoke(D)Ljava/lang/Double;
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$Companion$DoubleIdentity$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$Companion;-><init>()V
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$Companion;->access$computeXYZMatrix(Landroidx/compose/ui/graphics/colorspace/Rgb$Companion;[FLandroidx/compose/ui/graphics/colorspace/WhitePoint;)[F
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$Companion;->access$isSrgb(Landroidx/compose/ui/graphics/colorspace/Rgb$Companion;[FLandroidx/compose/ui/graphics/colorspace/WhitePoint;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;FFI)Z
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$Companion;->access$isWideGamut(Landroidx/compose/ui/graphics/colorspace/Rgb$Companion;[FFF)Z
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$Companion;->access$xyPrimaries(Landroidx/compose/ui/graphics/colorspace/Rgb$Companion;[F)[F
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$Companion;->area([F)F
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$Companion;->compare(DLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Z
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$Companion;->computeXYZMatrix([FLandroidx/compose/ui/graphics/colorspace/WhitePoint;)[F
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$Companion;->contains([F[F)Z
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$Companion;->cross(FFFF)F
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$Companion;->isSrgb([FLandroidx/compose/ui/graphics/colorspace/WhitePoint;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;FFI)Z
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$Companion;->isWideGamut([FFF)Z
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$Companion;->xyPrimaries([F)[F
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$eotf$1;-><init>(Landroidx/compose/ui/graphics/colorspace/Rgb;)V
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb$oetf$1;-><init>(Landroidx/compose/ui/graphics/colorspace/Rgb;)V
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb;-><init>(Ljava/lang/String;[FLandroidx/compose/ui/graphics/colorspace/WhitePoint;DFFI)V
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb;-><init>(Ljava/lang/String;[FLandroidx/compose/ui/graphics/colorspace/WhitePoint;Landroidx/compose/ui/graphics/colorspace/TransferParameters;I)V
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb;-><init>(Ljava/lang/String;[FLandroidx/compose/ui/graphics/colorspace/WhitePoint;[FLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;FFLandroidx/compose/ui/graphics/colorspace/TransferParameters;I)V
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb;->getEotfOrig$ui_graphics_release()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb;->getMaxValue(I)F
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb;->getMinValue(I)F
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb;->getOetfOrig$ui_graphics_release()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/ui/graphics/colorspace/Rgb;->isSrgb()Z
+HSPLandroidx/compose/ui/graphics/colorspace/TransferParameters;-><init>(DDDDDDD)V
+HSPLandroidx/compose/ui/graphics/colorspace/TransferParameters;-><init>(DDDDDDDILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/colorspace/TransferParameters;->getA()D
+HSPLandroidx/compose/ui/graphics/colorspace/TransferParameters;->getB()D
+HSPLandroidx/compose/ui/graphics/colorspace/TransferParameters;->getC()D
+HSPLandroidx/compose/ui/graphics/colorspace/TransferParameters;->getD()D
+HSPLandroidx/compose/ui/graphics/colorspace/TransferParameters;->getE()D
+HSPLandroidx/compose/ui/graphics/colorspace/TransferParameters;->getF()D
+HSPLandroidx/compose/ui/graphics/colorspace/TransferParameters;->getGamma()D
+HSPLandroidx/compose/ui/graphics/colorspace/WhitePoint;-><init>(FF)V
+HSPLandroidx/compose/ui/graphics/colorspace/WhitePoint;->getX()F
+HSPLandroidx/compose/ui/graphics/colorspace/WhitePoint;->getY()F
+HSPLandroidx/compose/ui/graphics/colorspace/WhitePoint;->toXyz$ui_graphics_release()[F
+HSPLandroidx/compose/ui/graphics/colorspace/Xyz;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$DrawParams;-><init>(Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/ui/graphics/Canvas;J)V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$DrawParams;-><init>(Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/ui/graphics/Canvas;JILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$DrawParams;-><init>(Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/ui/graphics/Canvas;JLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$DrawParams;->component1()Landroidx/compose/ui/unit/Density;
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$DrawParams;->component2()Landroidx/compose/ui/unit/LayoutDirection;
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$DrawParams;->component3()Landroidx/compose/ui/graphics/Canvas;
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$DrawParams;->component4-NH-jbRc()J
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$DrawParams;->getCanvas()Landroidx/compose/ui/graphics/Canvas;
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$DrawParams;->getDensity()Landroidx/compose/ui/unit/Density;
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$DrawParams;->getLayoutDirection()Landroidx/compose/ui/unit/LayoutDirection;
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$DrawParams;->getSize-NH-jbRc()J
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$DrawParams;->setCanvas(Landroidx/compose/ui/graphics/Canvas;)V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$DrawParams;->setDensity(Landroidx/compose/ui/unit/Density;)V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$DrawParams;->setLayoutDirection(Landroidx/compose/ui/unit/LayoutDirection;)V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$DrawParams;->setSize-uvyYCjk(J)V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$drawContext$1;-><init>(Landroidx/compose/ui/graphics/drawscope/CanvasDrawScope;)V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$drawContext$1;->getCanvas()Landroidx/compose/ui/graphics/Canvas;
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$drawContext$1;->getSize-NH-jbRc()J
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$drawContext$1;->getTransform()Landroidx/compose/ui/graphics/drawscope/DrawTransform;
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope$drawContext$1;->setSize-uvyYCjk(J)V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope;-><init>()V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope;->configurePaint-2qPWKa0$default(Landroidx/compose/ui/graphics/drawscope/CanvasDrawScope;JLandroidx/compose/ui/graphics/drawscope/DrawStyle;FLandroidx/compose/ui/graphics/ColorFilter;IIILjava/lang/Object;)Landroidx/compose/ui/graphics/Paint;
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope;->configurePaint-2qPWKa0(JLandroidx/compose/ui/graphics/drawscope/DrawStyle;FLandroidx/compose/ui/graphics/ColorFilter;II)Landroidx/compose/ui/graphics/Paint;
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope;->configurePaint-swdJneE(Landroidx/compose/ui/graphics/Brush;Landroidx/compose/ui/graphics/drawscope/DrawStyle;FLandroidx/compose/ui/graphics/ColorFilter;II)Landroidx/compose/ui/graphics/Paint;
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope;->drawImage-AZ2fEMs(Landroidx/compose/ui/graphics/ImageBitmap;JJJJFLandroidx/compose/ui/graphics/drawscope/DrawStyle;Landroidx/compose/ui/graphics/ColorFilter;II)V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope;->drawPath-LG529CI(Landroidx/compose/ui/graphics/Path;JFLandroidx/compose/ui/graphics/drawscope/DrawStyle;Landroidx/compose/ui/graphics/ColorFilter;I)V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope;->drawRect-n-J9OG0(JJJFLandroidx/compose/ui/graphics/drawscope/DrawStyle;Landroidx/compose/ui/graphics/ColorFilter;I)V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope;->drawRoundRect-u-Aw5IA(JJJJLandroidx/compose/ui/graphics/drawscope/DrawStyle;FLandroidx/compose/ui/graphics/ColorFilter;I)V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope;->getDensity()F
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope;->getDrawContext()Landroidx/compose/ui/graphics/drawscope/DrawContext;
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope;->getDrawParams()Landroidx/compose/ui/graphics/drawscope/CanvasDrawScope$DrawParams;
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope;->getLayoutDirection()Landroidx/compose/ui/unit/LayoutDirection;
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope;->modulate-5vOe2sY(JF)J
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope;->obtainFillPaint()Landroidx/compose/ui/graphics/Paint;
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope;->selectPaint(Landroidx/compose/ui/graphics/drawscope/DrawStyle;)Landroidx/compose/ui/graphics/Paint;
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScopeKt$asDrawTransform$1;-><init>(Landroidx/compose/ui/graphics/drawscope/DrawContext;)V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScopeKt$asDrawTransform$1;->getSize-NH-jbRc()J
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScopeKt$asDrawTransform$1;->inset(FFFF)V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScopeKt$asDrawTransform$1;->translate(FF)V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScopeKt;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScopeKt;->access$asDrawTransform(Landroidx/compose/ui/graphics/drawscope/DrawContext;)Landroidx/compose/ui/graphics/drawscope/DrawTransform;
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScopeKt;->access$getDefaultDensity$p()Landroidx/compose/ui/unit/Density;
+HSPLandroidx/compose/ui/graphics/drawscope/CanvasDrawScopeKt;->asDrawTransform(Landroidx/compose/ui/graphics/drawscope/DrawContext;)Landroidx/compose/ui/graphics/drawscope/DrawTransform;
+HSPLandroidx/compose/ui/graphics/drawscope/DrawScope$Companion;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/drawscope/DrawScope$Companion;-><init>()V
+HSPLandroidx/compose/ui/graphics/drawscope/DrawScope$Companion;->getDefaultBlendMode-0nO6VwU()I
+HSPLandroidx/compose/ui/graphics/drawscope/DrawScope$Companion;->getDefaultFilterQuality-f-v9h1I()I
+HSPLandroidx/compose/ui/graphics/drawscope/DrawScope;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/drawscope/DrawScope;->drawImage-AZ2fEMs$default(Landroidx/compose/ui/graphics/drawscope/DrawScope;Landroidx/compose/ui/graphics/ImageBitmap;JJJJFLandroidx/compose/ui/graphics/drawscope/DrawStyle;Landroidx/compose/ui/graphics/ColorFilter;IIILjava/lang/Object;)V
+HSPLandroidx/compose/ui/graphics/drawscope/DrawScope;->drawRect-n-J9OG0$default(Landroidx/compose/ui/graphics/drawscope/DrawScope;JJJFLandroidx/compose/ui/graphics/drawscope/DrawStyle;Landroidx/compose/ui/graphics/ColorFilter;IILjava/lang/Object;)V
+HSPLandroidx/compose/ui/graphics/drawscope/DrawScope;->getSize-NH-jbRc()J
+HSPLandroidx/compose/ui/graphics/drawscope/DrawScope;->offsetSize-PENXr5M(JJ)J
+HSPLandroidx/compose/ui/graphics/drawscope/DrawStyle;-><init>()V
+HSPLandroidx/compose/ui/graphics/drawscope/DrawStyle;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/drawscope/EmptyCanvas;-><init>()V
+HSPLandroidx/compose/ui/graphics/drawscope/Fill;-><clinit>()V
+HSPLandroidx/compose/ui/graphics/drawscope/Fill;-><init>()V
+HSPLandroidx/compose/ui/graphics/painter/BitmapPainter;-><init>(Landroidx/compose/ui/graphics/ImageBitmap;JJ)V
+HSPLandroidx/compose/ui/graphics/painter/BitmapPainter;-><init>(Landroidx/compose/ui/graphics/ImageBitmap;JJILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/painter/BitmapPainter;-><init>(Landroidx/compose/ui/graphics/ImageBitmap;JJLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/graphics/painter/BitmapPainter;->applyColorFilter(Landroidx/compose/ui/graphics/ColorFilter;)Z
+HSPLandroidx/compose/ui/graphics/painter/BitmapPainter;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/graphics/painter/BitmapPainter;->getIntrinsicSize-NH-jbRc()J
+HSPLandroidx/compose/ui/graphics/painter/BitmapPainter;->onDraw(Landroidx/compose/ui/graphics/drawscope/DrawScope;)V
+HSPLandroidx/compose/ui/graphics/painter/BitmapPainter;->validateSize-N5eqBDc(JJ)J
+HSPLandroidx/compose/ui/graphics/painter/Painter$drawLambda$1;-><init>(Landroidx/compose/ui/graphics/painter/Painter;)V
+HSPLandroidx/compose/ui/graphics/painter/Painter;-><init>()V
+HSPLandroidx/compose/ui/graphics/painter/Painter;->configureAlpha(F)V
+HSPLandroidx/compose/ui/graphics/painter/Painter;->configureColorFilter(Landroidx/compose/ui/graphics/ColorFilter;)V
+HSPLandroidx/compose/ui/graphics/painter/Painter;->configureLayoutDirection(Landroidx/compose/ui/unit/LayoutDirection;)V
+HSPLandroidx/compose/ui/graphics/painter/Painter;->draw-x_KDEd0(Landroidx/compose/ui/graphics/drawscope/DrawScope;JFLandroidx/compose/ui/graphics/ColorFilter;)V
+HSPLandroidx/compose/ui/hapticfeedback/PlatformHapticFeedback;-><init>(Landroid/view/View;)V
+HSPLandroidx/compose/ui/input/InputMode$Companion;-><init>()V
+HSPLandroidx/compose/ui/input/InputMode$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/input/InputMode$Companion;->getTouch-aOaMEAU()I
+HSPLandroidx/compose/ui/input/InputMode;-><clinit>()V
+HSPLandroidx/compose/ui/input/InputMode;-><init>(I)V
+HSPLandroidx/compose/ui/input/InputMode;->access$getTouch$cp()I
+HSPLandroidx/compose/ui/input/InputMode;->box-impl(I)Landroidx/compose/ui/input/InputMode;
+HSPLandroidx/compose/ui/input/InputMode;->constructor-impl(I)I
+HSPLandroidx/compose/ui/input/InputMode;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/input/InputMode;->equals-impl(ILjava/lang/Object;)Z
+HSPLandroidx/compose/ui/input/InputMode;->equals-impl0(II)Z
+HSPLandroidx/compose/ui/input/InputMode;->unbox-impl()I
+HSPLandroidx/compose/ui/input/InputModeManagerImpl;-><init>(ILkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/input/InputModeManagerImpl;-><init>(ILkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/input/InputModeManagerImpl;->getInputMode-aOaMEAU()I
+HSPLandroidx/compose/ui/input/InputModeManagerImpl;->setInputMode-iuPiT84(I)V
+HSPLandroidx/compose/ui/input/ScrollContainerInfoKt$ModifierLocalScrollContainerInfo$1;-><clinit>()V
+HSPLandroidx/compose/ui/input/ScrollContainerInfoKt$ModifierLocalScrollContainerInfo$1;-><init>()V
+HSPLandroidx/compose/ui/input/ScrollContainerInfoKt$ModifierLocalScrollContainerInfo$1;->invoke()Landroidx/compose/ui/input/ScrollContainerInfo;
+HSPLandroidx/compose/ui/input/ScrollContainerInfoKt$ModifierLocalScrollContainerInfo$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/input/ScrollContainerInfoKt$consumeScrollContainerInfo$1;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/input/ScrollContainerInfoKt$consumeScrollContainerInfo$1;->invoke(Landroidx/compose/ui/modifier/ModifierLocalReadScope;)V
+HSPLandroidx/compose/ui/input/ScrollContainerInfoKt$consumeScrollContainerInfo$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/input/ScrollContainerInfoKt;-><clinit>()V
+HSPLandroidx/compose/ui/input/ScrollContainerInfoKt;->consumeScrollContainerInfo(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/input/ScrollContainerInfoKt;->getModifierLocalScrollContainerInfo()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/input/focus/FocusAwareInputModifier;-><init>(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/modifier/ProvidableModifierLocal;)V
+HSPLandroidx/compose/ui/input/focus/FocusAwareInputModifier;->getKey()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/input/focus/FocusAwareInputModifier;->getValue()Landroidx/compose/ui/input/focus/FocusAwareInputModifier;
+HSPLandroidx/compose/ui/input/focus/FocusAwareInputModifier;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/ui/input/focus/FocusAwareInputModifier;->onModifierLocalsUpdated(Landroidx/compose/ui/modifier/ModifierLocalReadScope;)V
+HSPLandroidx/compose/ui/input/key/KeyInputModifier;-><init>(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/input/key/KeyInputModifier;->getKey()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/input/key/KeyInputModifier;->getValue()Landroidx/compose/ui/input/key/KeyInputModifier;
+HSPLandroidx/compose/ui/input/key/KeyInputModifier;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/ui/input/key/KeyInputModifier;->onModifierLocalsUpdated(Landroidx/compose/ui/modifier/ModifierLocalReadScope;)V
+HSPLandroidx/compose/ui/input/key/KeyInputModifier;->onPlaced(Landroidx/compose/ui/layout/LayoutCoordinates;)V
+HSPLandroidx/compose/ui/input/key/KeyInputModifierKt$ModifierLocalKeyInput$1;-><clinit>()V
+HSPLandroidx/compose/ui/input/key/KeyInputModifierKt$ModifierLocalKeyInput$1;-><init>()V
+HSPLandroidx/compose/ui/input/key/KeyInputModifierKt$ModifierLocalKeyInput$1;->invoke()Landroidx/compose/ui/input/key/KeyInputModifier;
+HSPLandroidx/compose/ui/input/key/KeyInputModifierKt$ModifierLocalKeyInput$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/input/key/KeyInputModifierKt;-><clinit>()V
+HSPLandroidx/compose/ui/input/key/KeyInputModifierKt;->getModifierLocalKeyInput()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/input/key/KeyInputModifierKt;->onKeyEvent(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher$calculateNestedScrollScope$1;-><init>(Landroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;)V
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;-><clinit>()V
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;-><init>()V
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;->setCalculateNestedScrollScope$ui_release(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;->setOriginNestedScrollScope$ui_release(Lkotlinx/coroutines/CoroutineScope;)V
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;->setParent$ui_release(Landroidx/compose/ui/input/nestedscroll/NestedScrollConnection;)V
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierKt$nestedScroll$2;-><init>(Landroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;Landroidx/compose/ui/input/nestedscroll/NestedScrollConnection;)V
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierKt$nestedScroll$2;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierKt$nestedScroll$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierKt;->nestedScroll$default(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/input/nestedscroll/NestedScrollConnection;Landroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;ILjava/lang/Object;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierKt;->nestedScroll(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/input/nestedscroll/NestedScrollConnection;Landroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal$1;-><init>(Landroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;)V
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;-><init>(Landroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;Landroidx/compose/ui/input/nestedscroll/NestedScrollConnection;)V
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;->getKey()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;->getParent()Landroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;->onModifierLocalsUpdated(Landroidx/compose/ui/modifier/ModifierLocalReadScope;)V
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;->setParent(Landroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;)V
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocalKt$ModifierLocalNestedScroll$1;-><clinit>()V
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocalKt$ModifierLocalNestedScroll$1;-><init>()V
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocalKt$ModifierLocalNestedScroll$1;->invoke()Landroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocalKt$ModifierLocalNestedScroll$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocalKt;-><clinit>()V
+HSPLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocalKt;->getModifierLocalNestedScroll()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/input/pointer/AwaitPointerEventScope;->awaitPointerEvent$default(Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;Landroidx/compose/ui/input/pointer/PointerEventPass;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/input/pointer/HitPathTracker;-><init>(Landroidx/compose/ui/layout/LayoutCoordinates;)V
+HSPLandroidx/compose/ui/input/pointer/MotionEventAdapter;-><init>()V
+HSPLandroidx/compose/ui/input/pointer/NodeParent;-><init>()V
+HSPLandroidx/compose/ui/input/pointer/PointerButtons;->constructor-impl(I)I
+HSPLandroidx/compose/ui/input/pointer/PointerEvent;-><clinit>()V
+HSPLandroidx/compose/ui/input/pointer/PointerEvent;-><init>(Ljava/util/List;)V
+HSPLandroidx/compose/ui/input/pointer/PointerEvent;-><init>(Ljava/util/List;Landroidx/compose/ui/input/pointer/InternalPointerEvent;)V
+HSPLandroidx/compose/ui/input/pointer/PointerEvent;->calculatePointerEventType-7fucELk()I
+HSPLandroidx/compose/ui/input/pointer/PointerEvent;->getMotionEvent$ui_release()Landroid/view/MotionEvent;
+HSPLandroidx/compose/ui/input/pointer/PointerEventPass;->$values()[Landroidx/compose/ui/input/pointer/PointerEventPass;
+HSPLandroidx/compose/ui/input/pointer/PointerEventPass;-><clinit>()V
+HSPLandroidx/compose/ui/input/pointer/PointerEventPass;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/ui/input/pointer/PointerEventType$Companion;-><init>()V
+HSPLandroidx/compose/ui/input/pointer/PointerEventType$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/input/pointer/PointerEventType$Companion;->getMove-7fucELk()I
+HSPLandroidx/compose/ui/input/pointer/PointerEventType;-><clinit>()V
+HSPLandroidx/compose/ui/input/pointer/PointerEventType;->access$getMove$cp()I
+HSPLandroidx/compose/ui/input/pointer/PointerEventType;->constructor-impl(I)I
+HSPLandroidx/compose/ui/input/pointer/PointerEvent_androidKt;->EmptyPointerKeyboardModifiers()I
+HSPLandroidx/compose/ui/input/pointer/PointerInputChangeEventProducer;-><init>()V
+HSPLandroidx/compose/ui/input/pointer/PointerInputEventProcessor;-><init>(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/input/pointer/PointerInputFilter;-><clinit>()V
+HSPLandroidx/compose/ui/input/pointer/PointerInputFilter;-><init>()V
+HSPLandroidx/compose/ui/input/pointer/PointerInputFilter;->getSize-YbymL2g()J
+HSPLandroidx/compose/ui/input/pointer/PointerInputFilter;->setLayoutCoordinates$ui_release(Landroidx/compose/ui/layout/LayoutCoordinates;)V
+HSPLandroidx/compose/ui/input/pointer/PointerKeyboardModifiers;-><init>(I)V
+HSPLandroidx/compose/ui/input/pointer/PointerKeyboardModifiers;->box-impl(I)Landroidx/compose/ui/input/pointer/PointerKeyboardModifiers;
+HSPLandroidx/compose/ui/input/pointer/PointerKeyboardModifiers;->constructor-impl(I)I
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;-><init>(Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;->access$setAwaitPass$p(Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;Landroidx/compose/ui/input/pointer/PointerEventPass;)V
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;->access$setPointerAwaiter$p(Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;Lkotlinx/coroutines/CancellableContinuation;)V
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;->awaitPointerEvent(Landroidx/compose/ui/input/pointer/PointerEventPass;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;->cancel(Ljava/lang/Throwable;)V
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;->getContext()Lkotlin/coroutines/CoroutineContext;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;->resumeWith(Ljava/lang/Object;)V
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$awaitPointerEventScope$2$2;-><init>(Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;)V
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$awaitPointerEventScope$2$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$awaitPointerEventScope$2$2;->invoke(Ljava/lang/Throwable;)V
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;-><init>(Landroidx/compose/ui/platform/ViewConfiguration;Landroidx/compose/ui/unit/Density;)V
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;->access$getPointerHandlers$p(Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;)Landroidx/compose/runtime/collection/MutableVector;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;->awaitPointerEventScope(Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;->getPointerInputFilter()Landroidx/compose/ui/input/pointer/PointerInputFilter;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;->setCoroutineScope(Lkotlinx/coroutines/CoroutineScope;)V
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$2$2$1;-><init>(Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$2$2$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$2$2$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$2;-><init>(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$2;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$4$2$1;-><init>(Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$4$2$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$4$2$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$4;-><init>(Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$4;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$4;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$6$2$1;-><init>(Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$6$2$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$6$2$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$6;-><init>([Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$6;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$6;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt;-><clinit>()V
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt;->access$getEmptyPointerEvent$p()Landroidx/compose/ui/input/pointer/PointerEvent;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt;->pointerInput(Landroidx/compose/ui/Modifier;Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt;->pointerInput(Landroidx/compose/ui/Modifier;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt;->pointerInput(Landroidx/compose/ui/Modifier;[Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/input/pointer/util/VelocityTracker;-><clinit>()V
+HSPLandroidx/compose/ui/input/pointer/util/VelocityTracker;-><init>()V
+HSPLandroidx/compose/ui/input/rotary/RotaryInputModifierKt$ModifierLocalRotaryScrollParent$1;-><clinit>()V
+HSPLandroidx/compose/ui/input/rotary/RotaryInputModifierKt$ModifierLocalRotaryScrollParent$1;-><init>()V
+HSPLandroidx/compose/ui/input/rotary/RotaryInputModifierKt$ModifierLocalRotaryScrollParent$1;->invoke()Landroidx/compose/ui/input/focus/FocusAwareInputModifier;
+HSPLandroidx/compose/ui/input/rotary/RotaryInputModifierKt$ModifierLocalRotaryScrollParent$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/input/rotary/RotaryInputModifierKt$focusAwareCallback$1;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/input/rotary/RotaryInputModifierKt;-><clinit>()V
+HSPLandroidx/compose/ui/input/rotary/RotaryInputModifierKt;->focusAwareCallback(Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/ui/input/rotary/RotaryInputModifierKt;->getModifierLocalRotaryScrollParent()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/input/rotary/RotaryInputModifierKt;->onRotaryScrollEvent(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/layout/AlignmentLine$Companion;-><init>()V
+HSPLandroidx/compose/ui/layout/AlignmentLine$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/layout/AlignmentLine;-><clinit>()V
+HSPLandroidx/compose/ui/layout/AlignmentLine;-><init>(Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/ui/layout/AlignmentLine;-><init>(Lkotlin/jvm/functions/Function2;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/layout/AlignmentLineKt$FirstBaseline$1;-><clinit>()V
+HSPLandroidx/compose/ui/layout/AlignmentLineKt$FirstBaseline$1;-><init>()V
+HSPLandroidx/compose/ui/layout/AlignmentLineKt$LastBaseline$1;-><clinit>()V
+HSPLandroidx/compose/ui/layout/AlignmentLineKt$LastBaseline$1;-><init>()V
+HSPLandroidx/compose/ui/layout/AlignmentLineKt;-><clinit>()V
+HSPLandroidx/compose/ui/layout/AlignmentLineKt;->getFirstBaseline()Landroidx/compose/ui/layout/HorizontalAlignmentLine;
+HSPLandroidx/compose/ui/layout/AlignmentLineKt;->getLastBaseline()Landroidx/compose/ui/layout/HorizontalAlignmentLine;
+HSPLandroidx/compose/ui/layout/BeyondBoundsLayoutKt$ModifierLocalBeyondBoundsLayout$1;-><clinit>()V
+HSPLandroidx/compose/ui/layout/BeyondBoundsLayoutKt$ModifierLocalBeyondBoundsLayout$1;-><init>()V
+HSPLandroidx/compose/ui/layout/BeyondBoundsLayoutKt$ModifierLocalBeyondBoundsLayout$1;->invoke()Landroidx/compose/ui/layout/BeyondBoundsLayout;
+HSPLandroidx/compose/ui/layout/BeyondBoundsLayoutKt$ModifierLocalBeyondBoundsLayout$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/layout/BeyondBoundsLayoutKt;-><clinit>()V
+HSPLandroidx/compose/ui/layout/BeyondBoundsLayoutKt;->getModifierLocalBeyondBoundsLayout()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/layout/ComposableSingletons$SubcomposeLayoutKt$lambda-1$1;-><clinit>()V
+HSPLandroidx/compose/ui/layout/ComposableSingletons$SubcomposeLayoutKt$lambda-1$1;-><init>()V
+HSPLandroidx/compose/ui/layout/ComposableSingletons$SubcomposeLayoutKt;-><clinit>()V
+HSPLandroidx/compose/ui/layout/ComposableSingletons$SubcomposeLayoutKt;-><init>()V
+HSPLandroidx/compose/ui/layout/ComposableSingletons$SubcomposeLayoutKt;->getLambda-1$ui_release()Lkotlin/jvm/functions/Function2;
+HSPLandroidx/compose/ui/layout/ContentScale$Companion$Crop$1;-><init>()V
+HSPLandroidx/compose/ui/layout/ContentScale$Companion$FillBounds$1;-><init>()V
+HSPLandroidx/compose/ui/layout/ContentScale$Companion$FillHeight$1;-><init>()V
+HSPLandroidx/compose/ui/layout/ContentScale$Companion$FillWidth$1;-><init>()V
+HSPLandroidx/compose/ui/layout/ContentScale$Companion$Fit$1;-><init>()V
+HSPLandroidx/compose/ui/layout/ContentScale$Companion$Fit$1;->computeScaleFactor-H7hwNQA(JJ)J
+HSPLandroidx/compose/ui/layout/ContentScale$Companion$Inside$1;-><init>()V
+HSPLandroidx/compose/ui/layout/ContentScale$Companion;-><clinit>()V
+HSPLandroidx/compose/ui/layout/ContentScale$Companion;-><init>()V
+HSPLandroidx/compose/ui/layout/ContentScale$Companion;->getFit()Landroidx/compose/ui/layout/ContentScale;
+HSPLandroidx/compose/ui/layout/ContentScale;-><clinit>()V
+HSPLandroidx/compose/ui/layout/ContentScaleKt;->access$computeFillMinDimension-iLBOSCw(JJ)F
+HSPLandroidx/compose/ui/layout/ContentScaleKt;->computeFillHeight-iLBOSCw(JJ)F
+HSPLandroidx/compose/ui/layout/ContentScaleKt;->computeFillMinDimension-iLBOSCw(JJ)F
+HSPLandroidx/compose/ui/layout/ContentScaleKt;->computeFillWidth-iLBOSCw(JJ)F
+HSPLandroidx/compose/ui/layout/FixedScale;-><init>(F)V
+HSPLandroidx/compose/ui/layout/HorizontalAlignmentLine;-><clinit>()V
+HSPLandroidx/compose/ui/layout/HorizontalAlignmentLine;-><init>(Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/ui/layout/LayoutKt$materializerOf$1;-><init>(Landroidx/compose/ui/Modifier;)V
+HSPLandroidx/compose/ui/layout/LayoutKt$materializerOf$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/layout/LayoutKt$materializerOf$1;->invoke-Deg8D_g(Landroidx/compose/runtime/Composer;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/ui/layout/LayoutKt;->materializerOf(Landroidx/compose/ui/Modifier;)Lkotlin/jvm/functions/Function3;
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$NodeState;-><init>(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composition;)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$NodeState;-><init>(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composition;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$NodeState;->getActive()Z
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$NodeState;->getComposition()Landroidx/compose/runtime/Composition;
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$NodeState;->getContent()Lkotlin/jvm/functions/Function2;
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$NodeState;->setComposition(Landroidx/compose/runtime/Composition;)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$NodeState;->setContent(Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$NodeState;->setForceRecompose(Z)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$Scope;-><init>(Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState;)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$Scope;->getLayoutDirection()Landroidx/compose/ui/unit/LayoutDirection;
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$Scope;->setDensity(F)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$Scope;->setFontScale(F)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$Scope;->setLayoutDirection(Landroidx/compose/ui/unit/LayoutDirection;)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$Scope;->subcompose(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/util/List;
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$createMeasurePolicy$1$measure$1;-><init>(Landroidx/compose/ui/layout/MeasureResult;Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState;I)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$createMeasurePolicy$1$measure$1;->getAlignmentLines()Ljava/util/Map;
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$createMeasurePolicy$1$measure$1;->getHeight()I
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$createMeasurePolicy$1$measure$1;->getWidth()I
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$createMeasurePolicy$1$measure$1;->placeChildren()V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$createMeasurePolicy$1;-><init>(Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState;Lkotlin/jvm/functions/Function2;Ljava/lang/String;)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$createMeasurePolicy$1;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Ljava/util/List;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$subcompose$2$1$1;-><init>(Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState$NodeState;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$subcompose$2$1$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$subcompose$2$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;-><init>(Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/ui/layout/SubcomposeSlotReusePolicy;)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->access$getCurrentIndex$p(Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState;)I
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->access$getScope$p(Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState;)Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState$Scope;
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->access$setCurrentIndex$p(Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState;I)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->createMeasurePolicy(Lkotlin/jvm/functions/Function2;)Landroidx/compose/ui/layout/MeasurePolicy;
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->createNodeAt(I)Landroidx/compose/ui/node/LayoutNode;
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->disposeOrReuseStartingFromIndex(I)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->forceRecomposeChildren()V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->makeSureStateIsConsistent()V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->setCompositionContext(Landroidx/compose/runtime/CompositionContext;)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->setSlotReusePolicy(Landroidx/compose/ui/layout/SubcomposeSlotReusePolicy;)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->subcompose(Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState$NodeState;)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->subcompose(Landroidx/compose/ui/node/LayoutNode;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->subcompose(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/util/List;
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->subcomposeInto(Landroidx/compose/runtime/Composition;Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/runtime/CompositionContext;Lkotlin/jvm/functions/Function2;)Landroidx/compose/runtime/Composition;
+HSPLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->takeNodeFromReusables(Ljava/lang/Object;)Landroidx/compose/ui/node/LayoutNode;
+HSPLandroidx/compose/ui/layout/MeasureScope$layout$1;-><init>(IILjava/util/Map;Landroidx/compose/ui/layout/MeasureScope;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/layout/MeasureScope$layout$1;->getAlignmentLines()Ljava/util/Map;
+HSPLandroidx/compose/ui/layout/MeasureScope$layout$1;->getHeight()I
+HSPLandroidx/compose/ui/layout/MeasureScope$layout$1;->getWidth()I
+HSPLandroidx/compose/ui/layout/MeasureScope$layout$1;->placeChildren()V
+HSPLandroidx/compose/ui/layout/MeasureScope;->layout$default(Landroidx/compose/ui/layout/MeasureScope;IILjava/util/Map;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/ui/layout/MeasureScope;->layout(IILjava/util/Map;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/ui/layout/NoOpSubcomposeSlotReusePolicy;-><clinit>()V
+HSPLandroidx/compose/ui/layout/NoOpSubcomposeSlotReusePolicy;-><init>()V
+HSPLandroidx/compose/ui/layout/OnGloballyPositionedModifierImpl;-><init>(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/layout/OnGloballyPositionedModifierImpl;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/layout/OnGloballyPositionedModifierImpl;->onGloballyPositioned(Landroidx/compose/ui/layout/LayoutCoordinates;)V
+HSPLandroidx/compose/ui/layout/OnGloballyPositionedModifierKt;->onGloballyPositioned(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope$Companion;-><init>()V
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope$Companion;->access$configureForPlacingForAlignment(Landroidx/compose/ui/layout/Placeable$PlacementScope$Companion;Landroidx/compose/ui/node/LookaheadCapablePlaceable;)Z
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope$Companion;->access$getParentLayoutDirection(Landroidx/compose/ui/layout/Placeable$PlacementScope$Companion;)Landroidx/compose/ui/unit/LayoutDirection;
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope$Companion;->access$getParentWidth(Landroidx/compose/ui/layout/Placeable$PlacementScope$Companion;)I
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope$Companion;->configureForPlacingForAlignment(Landroidx/compose/ui/node/LookaheadCapablePlaceable;)Z
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope$Companion;->getParentLayoutDirection()Landroidx/compose/ui/unit/LayoutDirection;
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope$Companion;->getParentWidth()I
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;-><clinit>()V
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;-><init>()V
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->access$getLayoutDelegate$cp()Landroidx/compose/ui/node/LayoutNodeLayoutDelegate;
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->access$getParentLayoutDirection$cp()Landroidx/compose/ui/unit/LayoutDirection;
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->access$getParentLayoutDirection(Landroidx/compose/ui/layout/Placeable$PlacementScope;)Landroidx/compose/ui/unit/LayoutDirection;
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->access$getParentWidth$cp()I
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->access$get_coordinates$cp()Landroidx/compose/ui/layout/LayoutCoordinates;
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->access$setLayoutDelegate$cp(Landroidx/compose/ui/node/LayoutNodeLayoutDelegate;)V
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->access$setParentLayoutDirection$cp(Landroidx/compose/ui/unit/LayoutDirection;)V
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->access$setParentWidth$cp(I)V
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->access$set_coordinates$cp(Landroidx/compose/ui/layout/LayoutCoordinates;)V
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->place$default(Landroidx/compose/ui/layout/Placeable$PlacementScope;Landroidx/compose/ui/layout/Placeable;IIFILjava/lang/Object;)V
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->place(Landroidx/compose/ui/layout/Placeable;IIF)V
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->place-70tqf50$default(Landroidx/compose/ui/layout/Placeable$PlacementScope;Landroidx/compose/ui/layout/Placeable;JFILjava/lang/Object;)V
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->place-70tqf50(Landroidx/compose/ui/layout/Placeable;JF)V
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->placeRelative$default(Landroidx/compose/ui/layout/Placeable$PlacementScope;Landroidx/compose/ui/layout/Placeable;IIFILjava/lang/Object;)V
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->placeRelative(Landroidx/compose/ui/layout/Placeable;IIF)V
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->placeRelativeWithLayer$default(Landroidx/compose/ui/layout/Placeable$PlacementScope;Landroidx/compose/ui/layout/Placeable;IIFLkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->placeRelativeWithLayer(Landroidx/compose/ui/layout/Placeable;IIFLkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->placeWithLayer$default(Landroidx/compose/ui/layout/Placeable$PlacementScope;Landroidx/compose/ui/layout/Placeable;IIFLkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->placeWithLayer(Landroidx/compose/ui/layout/Placeable;IIFLkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/layout/Placeable$PlacementScope;->placeWithLayer-aW-9-wM(Landroidx/compose/ui/layout/Placeable;JFLkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/layout/Placeable;-><clinit>()V
+HSPLandroidx/compose/ui/layout/Placeable;-><init>()V
+HSPLandroidx/compose/ui/layout/Placeable;->access$getApparentToRealOffset-nOcc-ac(Landroidx/compose/ui/layout/Placeable;)J
+HSPLandroidx/compose/ui/layout/Placeable;->access$placeAt-f8xVGno(Landroidx/compose/ui/layout/Placeable;JFLkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/layout/Placeable;->getApparentToRealOffset-nOcc-ac()J
+HSPLandroidx/compose/ui/layout/Placeable;->getHeight()I
+HSPLandroidx/compose/ui/layout/Placeable;->getMeasuredSize-YbymL2g()J
+HSPLandroidx/compose/ui/layout/Placeable;->getMeasuredWidth()I
+HSPLandroidx/compose/ui/layout/Placeable;->getMeasurementConstraints-msEJaDk()J
+HSPLandroidx/compose/ui/layout/Placeable;->getWidth()I
+HSPLandroidx/compose/ui/layout/Placeable;->recalculateWidthAndHeight()V
+HSPLandroidx/compose/ui/layout/Placeable;->setMeasuredSize-ozmzZPI(J)V
+HSPLandroidx/compose/ui/layout/Placeable;->setMeasurementConstraints-BRTryo0(J)V
+HSPLandroidx/compose/ui/layout/PlaceableKt$DefaultLayerBlock$1;-><clinit>()V
+HSPLandroidx/compose/ui/layout/PlaceableKt$DefaultLayerBlock$1;-><init>()V
+HSPLandroidx/compose/ui/layout/PlaceableKt$DefaultLayerBlock$1;->invoke(Landroidx/compose/ui/graphics/GraphicsLayerScope;)V
+HSPLandroidx/compose/ui/layout/PlaceableKt$DefaultLayerBlock$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/layout/PlaceableKt;-><clinit>()V
+HSPLandroidx/compose/ui/layout/PlaceableKt;->access$getDefaultConstraints$p()J
+HSPLandroidx/compose/ui/layout/PlaceableKt;->access$getDefaultLayerBlock$p()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/ui/layout/RootMeasurePolicy$measure$2;-><init>(Landroidx/compose/ui/layout/Placeable;)V
+HSPLandroidx/compose/ui/layout/RootMeasurePolicy$measure$2;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+HSPLandroidx/compose/ui/layout/RootMeasurePolicy$measure$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/layout/RootMeasurePolicy;-><clinit>()V
+HSPLandroidx/compose/ui/layout/RootMeasurePolicy;-><init>()V
+HSPLandroidx/compose/ui/layout/RootMeasurePolicy;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Ljava/util/List;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/ui/layout/ScaleFactor$Companion;-><init>()V
+HSPLandroidx/compose/ui/layout/ScaleFactor$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/layout/ScaleFactor;-><clinit>()V
+HSPLandroidx/compose/ui/layout/ScaleFactor;->constructor-impl(J)J
+HSPLandroidx/compose/ui/layout/ScaleFactor;->getScaleX-impl(J)F
+HSPLandroidx/compose/ui/layout/ScaleFactor;->getScaleY-impl(J)F
+HSPLandroidx/compose/ui/layout/ScaleFactorKt;->ScaleFactor(FF)J
+HSPLandroidx/compose/ui/layout/ScaleFactorKt;->times-UQTWf7w(JJ)J
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutKt$SubcomposeLayout$$inlined$ComposeNode$1;-><init>(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutKt$SubcomposeLayout$$inlined$ComposeNode$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutKt$SubcomposeLayout$4;-><init>(Landroidx/compose/ui/layout/SubcomposeLayoutState;)V
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutKt$SubcomposeLayout$4;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutKt$SubcomposeLayout$4;->invoke()V
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutKt$SubcomposeLayout$5$1$invoke$$inlined$onDispose$1;-><init>(Landroidx/compose/runtime/State;)V
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutKt$SubcomposeLayout$5$1;-><init>(Landroidx/compose/runtime/State;)V
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutKt$SubcomposeLayout$5$1;->invoke(Landroidx/compose/runtime/DisposableEffectScope;)Landroidx/compose/runtime/DisposableEffectResult;
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutKt$SubcomposeLayout$5$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutKt;->SubcomposeLayout(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutKt;->SubcomposeLayout(Landroidx/compose/ui/layout/SubcomposeLayoutState;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState$setCompositionContext$1;-><init>(Landroidx/compose/ui/layout/SubcomposeLayoutState;)V
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState$setCompositionContext$1;->invoke(Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/runtime/CompositionContext;)V
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState$setCompositionContext$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState$setMeasurePolicy$1;-><init>(Landroidx/compose/ui/layout/SubcomposeLayoutState;)V
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState$setMeasurePolicy$1;->invoke(Landroidx/compose/ui/node/LayoutNode;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState$setMeasurePolicy$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState$setRoot$1;-><init>(Landroidx/compose/ui/layout/SubcomposeLayoutState;)V
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState$setRoot$1;->invoke(Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/ui/layout/SubcomposeLayoutState;)V
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState$setRoot$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState;-><clinit>()V
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState;-><init>()V
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState;-><init>(Landroidx/compose/ui/layout/SubcomposeSlotReusePolicy;)V
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState;->access$getSlotReusePolicy$p(Landroidx/compose/ui/layout/SubcomposeLayoutState;)Landroidx/compose/ui/layout/SubcomposeSlotReusePolicy;
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState;->access$getState(Landroidx/compose/ui/layout/SubcomposeLayoutState;)Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState;
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState;->access$set_state$p(Landroidx/compose/ui/layout/SubcomposeLayoutState;Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState;)V
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState;->forceRecomposeChildren$ui_release()V
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState;->getSetCompositionContext$ui_release()Lkotlin/jvm/functions/Function2;
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState;->getSetMeasurePolicy$ui_release()Lkotlin/jvm/functions/Function2;
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState;->getSetRoot$ui_release()Lkotlin/jvm/functions/Function2;
+HSPLandroidx/compose/ui/layout/SubcomposeLayoutState;->getState()Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState;
+HSPLandroidx/compose/ui/layout/SubcomposeSlotReusePolicy$SlotIdsSet;-><clinit>()V
+HSPLandroidx/compose/ui/layout/SubcomposeSlotReusePolicy$SlotIdsSet;-><init>(Ljava/util/Set;)V
+HSPLandroidx/compose/ui/layout/SubcomposeSlotReusePolicy$SlotIdsSet;-><init>(Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/modifier/BackwardsCompatLocalMap;-><init>(Landroidx/compose/ui/modifier/ModifierLocalProvider;)V
+HSPLandroidx/compose/ui/modifier/BackwardsCompatLocalMap;->contains$ui_release(Landroidx/compose/ui/modifier/ModifierLocal;)Z
+HSPLandroidx/compose/ui/modifier/BackwardsCompatLocalMap;->get$ui_release(Landroidx/compose/ui/modifier/ModifierLocal;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/modifier/BackwardsCompatLocalMap;->setElement(Landroidx/compose/ui/modifier/ModifierLocalProvider;)V
+HSPLandroidx/compose/ui/modifier/EmptyMap;-><clinit>()V
+HSPLandroidx/compose/ui/modifier/EmptyMap;-><init>()V
+HSPLandroidx/compose/ui/modifier/EmptyMap;->contains$ui_release(Landroidx/compose/ui/modifier/ModifierLocal;)Z
+HSPLandroidx/compose/ui/modifier/ModifierLocal;-><init>(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/ui/modifier/ModifierLocal;-><init>(Lkotlin/jvm/functions/Function0;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/modifier/ModifierLocal;->getDefaultFactory$ui_release()Lkotlin/jvm/functions/Function0;
+HSPLandroidx/compose/ui/modifier/ModifierLocalConsumerImpl;-><init>(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/modifier/ModifierLocalConsumerImpl;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/modifier/ModifierLocalConsumerImpl;->onModifierLocalsUpdated(Landroidx/compose/ui/modifier/ModifierLocalReadScope;)V
+HSPLandroidx/compose/ui/modifier/ModifierLocalConsumerKt;->modifierLocalConsumer(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/modifier/ModifierLocalKt;->modifierLocalOf(Lkotlin/jvm/functions/Function0;)Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/modifier/ModifierLocalManager$invalidate$1;-><init>(Landroidx/compose/ui/modifier/ModifierLocalManager;)V
+HSPLandroidx/compose/ui/modifier/ModifierLocalManager$invalidate$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/modifier/ModifierLocalManager$invalidate$1;->invoke()V
+HSPLandroidx/compose/ui/modifier/ModifierLocalManager;-><init>(Landroidx/compose/ui/node/Owner;)V
+HSPLandroidx/compose/ui/modifier/ModifierLocalManager;->invalidate()V
+HSPLandroidx/compose/ui/modifier/ModifierLocalManager;->invalidateConsumersOfNodeForKey(Landroidx/compose/ui/Modifier$Node;Landroidx/compose/ui/modifier/ModifierLocal;Ljava/util/Set;)V
+HSPLandroidx/compose/ui/modifier/ModifierLocalManager;->removedProvider(Landroidx/compose/ui/node/BackwardsCompatNode;Landroidx/compose/ui/modifier/ModifierLocal;)V
+HSPLandroidx/compose/ui/modifier/ModifierLocalManager;->triggerUpdates()V
+HSPLandroidx/compose/ui/modifier/ModifierLocalManager;->updatedProvider(Landroidx/compose/ui/node/BackwardsCompatNode;Landroidx/compose/ui/modifier/ModifierLocal;)V
+HSPLandroidx/compose/ui/modifier/ModifierLocalMap;-><clinit>()V
+HSPLandroidx/compose/ui/modifier/ModifierLocalMap;-><init>()V
+HSPLandroidx/compose/ui/modifier/ModifierLocalMap;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/modifier/ModifierLocalNodeKt;->modifierLocalMapOf()Landroidx/compose/ui/modifier/ModifierLocalMap;
+HSPLandroidx/compose/ui/modifier/ProvidableModifierLocal;-><init>(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/ui/node/AlignmentLines;-><init>(Landroidx/compose/ui/node/AlignmentLinesOwner;)V
+HSPLandroidx/compose/ui/node/AlignmentLines;-><init>(Landroidx/compose/ui/node/AlignmentLinesOwner;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/node/AlignmentLines;->getDirty$ui_release()Z
+HSPLandroidx/compose/ui/node/AlignmentLines;->getQueried$ui_release()Z
+HSPLandroidx/compose/ui/node/AlignmentLines;->getRequired$ui_release()Z
+HSPLandroidx/compose/ui/node/AlignmentLines;->getUsedDuringParentLayout$ui_release()Z
+HSPLandroidx/compose/ui/node/AlignmentLines;->onAlignmentsChanged()V
+HSPLandroidx/compose/ui/node/AlignmentLines;->recalculateQueryOwner()V
+HSPLandroidx/compose/ui/node/AlignmentLines;->setPreviousUsedDuringParentLayout$ui_release(Z)V
+HSPLandroidx/compose/ui/node/AlignmentLines;->setUsedByModifierLayout$ui_release(Z)V
+HSPLandroidx/compose/ui/node/AlignmentLines;->setUsedByModifierMeasurement$ui_release(Z)V
+HSPLandroidx/compose/ui/node/AlignmentLines;->setUsedDuringParentMeasurement$ui_release(Z)V
+HSPLandroidx/compose/ui/node/BackwardsCompatNode$initializeModifier$1;-><init>(Landroidx/compose/ui/node/BackwardsCompatNode;)V
+HSPLandroidx/compose/ui/node/BackwardsCompatNode$initializeModifier$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/BackwardsCompatNode$initializeModifier$1;->invoke()V
+HSPLandroidx/compose/ui/node/BackwardsCompatNode$initializeModifier$4;-><init>(Landroidx/compose/ui/node/BackwardsCompatNode;)V
+HSPLandroidx/compose/ui/node/BackwardsCompatNode$initializeModifier$4;->onLayoutComplete()V
+HSPLandroidx/compose/ui/node/BackwardsCompatNode$updateModifierLocalConsumer$1;-><init>(Landroidx/compose/ui/node/BackwardsCompatNode;)V
+HSPLandroidx/compose/ui/node/BackwardsCompatNode$updateModifierLocalConsumer$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/BackwardsCompatNode$updateModifierLocalConsumer$1;->invoke()V
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;-><init>(Landroidx/compose/ui/Modifier$Element;)V
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->access$getLastOnPlacedCoordinates$p(Landroidx/compose/ui/node/BackwardsCompatNode;)Landroidx/compose/ui/layout/LayoutCoordinates;
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->draw(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;)V
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->getCurrent(Landroidx/compose/ui/modifier/ModifierLocal;)Ljava/lang/Object;+]Landroidx/compose/ui/modifier/ModifierLocal;Landroidx/compose/ui/modifier/ProvidableModifierLocal;]Landroidx/compose/ui/modifier/ModifierLocalMap;Landroidx/compose/ui/modifier/BackwardsCompatLocalMap;,Landroidx/compose/ui/modifier/EmptyMap;]Landroidx/compose/ui/Modifier$Node;Landroidx/compose/ui/node/BackwardsCompatNode;,Landroidx/compose/ui/node/InnerNodeCoordinator$tail$1;]Landroidx/compose/ui/node/NodeChain;Landroidx/compose/ui/node/NodeChain;]Landroidx/compose/ui/modifier/ModifierLocalNode;Landroidx/compose/ui/node/BackwardsCompatNode;]Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/ui/node/LayoutNode;]Lkotlin/jvm/functions/Function0;megamorphic_types]Landroidx/compose/ui/node/DelegatableNode;Landroidx/compose/ui/node/BackwardsCompatNode;
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->getElement()Landroidx/compose/ui/Modifier$Element;
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->getProvidedValues()Landroidx/compose/ui/modifier/ModifierLocalMap;
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->getReadValues()Ljava/util/HashSet;
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->getSemanticsConfiguration()Landroidx/compose/ui/semantics/SemanticsConfiguration;
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->initializeModifier(Z)V
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->modifyParentData(Landroidx/compose/ui/unit/Density;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->onAttach()V
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->onGloballyPositioned(Landroidx/compose/ui/layout/LayoutCoordinates;)V
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->onMeasureResultChanged()V
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->onPlaced(Landroidx/compose/ui/layout/LayoutCoordinates;)V
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->onRemeasured-ozmzZPI(J)V
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->setElement(Landroidx/compose/ui/Modifier$Element;)V
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->uninitializeModifier()V
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->updateModifierLocalConsumer()V
+HSPLandroidx/compose/ui/node/BackwardsCompatNode;->updateModifierLocalProvider(Landroidx/compose/ui/modifier/ModifierLocalProvider;)V
+HSPLandroidx/compose/ui/node/BackwardsCompatNodeKt$DetachedModifierLocalReadScope$1;-><init>()V
+HSPLandroidx/compose/ui/node/BackwardsCompatNodeKt$DetachedModifierLocalReadScope$1;->getCurrent(Landroidx/compose/ui/modifier/ModifierLocal;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/BackwardsCompatNodeKt$onDrawCacheReadsChanged$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/BackwardsCompatNodeKt$onDrawCacheReadsChanged$1;-><init>()V
+HSPLandroidx/compose/ui/node/BackwardsCompatNodeKt$updateFocusOrderModifierLocalConsumer$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/BackwardsCompatNodeKt$updateFocusOrderModifierLocalConsumer$1;-><init>()V
+HSPLandroidx/compose/ui/node/BackwardsCompatNodeKt$updateModifierLocalConsumer$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/BackwardsCompatNodeKt$updateModifierLocalConsumer$1;-><init>()V
+HSPLandroidx/compose/ui/node/BackwardsCompatNodeKt;-><clinit>()V
+HSPLandroidx/compose/ui/node/BackwardsCompatNodeKt;->access$getDetachedModifierLocalReadScope$p()Landroidx/compose/ui/node/BackwardsCompatNodeKt$DetachedModifierLocalReadScope$1;
+HSPLandroidx/compose/ui/node/BackwardsCompatNodeKt;->access$getUpdateModifierLocalConsumer$p()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/ui/node/CenteredArray;->constructor-impl([I)[I
+HSPLandroidx/compose/ui/node/CenteredArray;->get-impl([II)I
+HSPLandroidx/compose/ui/node/CenteredArray;->getMid-impl([I)I
+HSPLandroidx/compose/ui/node/CenteredArray;->set-impl([III)V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetDensity$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetDensity$1;-><init>()V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetDensity$1;->invoke(Landroidx/compose/ui/node/ComposeUiNode;Landroidx/compose/ui/unit/Density;)V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetDensity$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetLayoutDirection$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetLayoutDirection$1;-><init>()V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetLayoutDirection$1;->invoke(Landroidx/compose/ui/node/ComposeUiNode;Landroidx/compose/ui/unit/LayoutDirection;)V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetLayoutDirection$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetMeasurePolicy$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetMeasurePolicy$1;-><init>()V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetMeasurePolicy$1;->invoke(Landroidx/compose/ui/node/ComposeUiNode;Landroidx/compose/ui/layout/MeasurePolicy;)V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetMeasurePolicy$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetModifier$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetModifier$1;-><init>()V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetModifier$1;->invoke(Landroidx/compose/ui/node/ComposeUiNode;Landroidx/compose/ui/Modifier;)V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetModifier$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetViewConfiguration$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetViewConfiguration$1;-><init>()V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetViewConfiguration$1;->invoke(Landroidx/compose/ui/node/ComposeUiNode;Landroidx/compose/ui/platform/ViewConfiguration;)V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$SetViewConfiguration$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$VirtualConstructor$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion$VirtualConstructor$1;-><init>()V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion;-><clinit>()V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion;-><init>()V
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion;->getConstructor()Lkotlin/jvm/functions/Function0;
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion;->getSetDensity()Lkotlin/jvm/functions/Function2;
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion;->getSetLayoutDirection()Lkotlin/jvm/functions/Function2;
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion;->getSetMeasurePolicy()Lkotlin/jvm/functions/Function2;
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion;->getSetModifier()Lkotlin/jvm/functions/Function2;
+HSPLandroidx/compose/ui/node/ComposeUiNode$Companion;->getSetViewConfiguration()Lkotlin/jvm/functions/Function2;
+HSPLandroidx/compose/ui/node/ComposeUiNode;-><clinit>()V
+HSPLandroidx/compose/ui/node/DelegatableNodeKt;->access$addLayoutNodeChildren(Landroidx/compose/runtime/collection/MutableVector;Landroidx/compose/ui/Modifier$Node;)V
+HSPLandroidx/compose/ui/node/DelegatableNodeKt;->addLayoutNodeChildren(Landroidx/compose/runtime/collection/MutableVector;Landroidx/compose/ui/Modifier$Node;)V
+HSPLandroidx/compose/ui/node/DelegatableNodeKt;->has-64DMado(Landroidx/compose/ui/node/DelegatableNode;I)Z
+HSPLandroidx/compose/ui/node/DelegatableNodeKt;->localChild(Landroidx/compose/ui/node/DelegatableNode;I)Landroidx/compose/ui/Modifier$Node;
+HSPLandroidx/compose/ui/node/DelegatableNodeKt;->requireCoordinator-64DMado(Landroidx/compose/ui/node/DelegatableNode;I)Landroidx/compose/ui/node/NodeCoordinator;
+HSPLandroidx/compose/ui/node/DelegatableNodeKt;->requireLayoutNode(Landroidx/compose/ui/node/DelegatableNode;)Landroidx/compose/ui/node/LayoutNode;
+HSPLandroidx/compose/ui/node/DelegatableNodeKt;->requireOwner(Landroidx/compose/ui/node/DelegatableNode;)Landroidx/compose/ui/node/Owner;
+HSPLandroidx/compose/ui/node/DepthSortedSet$DepthComparator$1;-><init>()V
+HSPLandroidx/compose/ui/node/DepthSortedSet$DepthComparator$1;->compare(Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/ui/node/LayoutNode;)I
+HSPLandroidx/compose/ui/node/DepthSortedSet$DepthComparator$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
+HSPLandroidx/compose/ui/node/DepthSortedSet$mapOfOriginalDepth$2;-><clinit>()V
+HSPLandroidx/compose/ui/node/DepthSortedSet$mapOfOriginalDepth$2;-><init>()V
+HSPLandroidx/compose/ui/node/DepthSortedSet;-><init>(Z)V
+HSPLandroidx/compose/ui/node/DepthSortedSet;->add(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/DepthSortedSet;->isEmpty()Z
+HSPLandroidx/compose/ui/node/DepthSortedSet;->pop()Landroidx/compose/ui/node/LayoutNode;
+HSPLandroidx/compose/ui/node/DepthSortedSet;->remove(Landroidx/compose/ui/node/LayoutNode;)Z
+HSPLandroidx/compose/ui/node/DrawModifierNodeKt;->invalidateDraw(Landroidx/compose/ui/node/DrawModifierNode;)V
+HSPLandroidx/compose/ui/node/HitTestResult;-><init>()V
+HSPLandroidx/compose/ui/node/InnerNodeCoordinator$Companion;-><init>()V
+HSPLandroidx/compose/ui/node/InnerNodeCoordinator$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/node/InnerNodeCoordinator$tail$1;-><init>()V
+HSPLandroidx/compose/ui/node/InnerNodeCoordinator;-><clinit>()V
+HSPLandroidx/compose/ui/node/InnerNodeCoordinator;-><init>(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/InnerNodeCoordinator;->getTail()Landroidx/compose/ui/Modifier$Node;
+HSPLandroidx/compose/ui/node/InnerNodeCoordinator;->measure-BRTryo0(J)Landroidx/compose/ui/layout/Placeable;
+HSPLandroidx/compose/ui/node/InnerNodeCoordinator;->performDraw(Landroidx/compose/ui/graphics/Canvas;)V
+HSPLandroidx/compose/ui/node/InnerNodeCoordinator;->placeAt-f8xVGno(JFLkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/node/IntStack;-><init>(I)V
+HSPLandroidx/compose/ui/node/IntStack;->compareDiagonal(II)Z
+HSPLandroidx/compose/ui/node/IntStack;->isNotEmpty()Z
+HSPLandroidx/compose/ui/node/IntStack;->partition(III)I
+HSPLandroidx/compose/ui/node/IntStack;->pop()I
+HSPLandroidx/compose/ui/node/IntStack;->pushDiagonal(III)V
+HSPLandroidx/compose/ui/node/IntStack;->pushRange(IIII)V
+HSPLandroidx/compose/ui/node/IntStack;->quickSort(III)V
+HSPLandroidx/compose/ui/node/IntStack;->sortDiagonals()V
+HSPLandroidx/compose/ui/node/IntStack;->swapDiagonal(II)V
+HSPLandroidx/compose/ui/node/IntrinsicsPolicy$Companion;-><init>()V
+HSPLandroidx/compose/ui/node/IntrinsicsPolicy$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/node/IntrinsicsPolicy;-><clinit>()V
+HSPLandroidx/compose/ui/node/IntrinsicsPolicy;-><init>(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/IntrinsicsPolicy;->setMeasurePolicyState(Landroidx/compose/ui/layout/MeasurePolicy;)V
+HSPLandroidx/compose/ui/node/IntrinsicsPolicy;->updateFrom(Landroidx/compose/ui/layout/MeasurePolicy;)V
+HSPLandroidx/compose/ui/node/LayerPositionalProperties;-><init>()V
+HSPLandroidx/compose/ui/node/LayerPositionalProperties;->copyFrom(Landroidx/compose/ui/graphics/GraphicsLayerScope;)V
+HSPLandroidx/compose/ui/node/LayoutModifierNodeCoordinator$Companion;-><init>()V
+HSPLandroidx/compose/ui/node/LayoutModifierNodeCoordinator$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/node/LayoutModifierNodeCoordinator;-><clinit>()V
+HSPLandroidx/compose/ui/node/LayoutModifierNodeCoordinator;-><init>(Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/ui/node/LayoutModifierNode;)V
+HSPLandroidx/compose/ui/node/LayoutModifierNodeCoordinator;->getLayoutModifierNode()Landroidx/compose/ui/node/LayoutModifierNode;
+HSPLandroidx/compose/ui/node/LayoutModifierNodeCoordinator;->getTail()Landroidx/compose/ui/Modifier$Node;
+HSPLandroidx/compose/ui/node/LayoutModifierNodeCoordinator;->getWrappedNonNull()Landroidx/compose/ui/node/NodeCoordinator;
+HSPLandroidx/compose/ui/node/LayoutModifierNodeCoordinator;->measure-BRTryo0(J)Landroidx/compose/ui/layout/Placeable;
+HSPLandroidx/compose/ui/node/LayoutModifierNodeCoordinator;->onLayoutModifierNodeChanged()V
+HSPLandroidx/compose/ui/node/LayoutModifierNodeCoordinator;->performDraw(Landroidx/compose/ui/graphics/Canvas;)V
+HSPLandroidx/compose/ui/node/LayoutModifierNodeCoordinator;->placeAt-f8xVGno(JFLkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/node/LayoutModifierNodeCoordinator;->setLayoutModifierNode$ui_release(Landroidx/compose/ui/node/LayoutModifierNode;)V
+HSPLandroidx/compose/ui/node/LayoutModifierNodeKt;->invalidateLayer(Landroidx/compose/ui/node/LayoutModifierNode;)V
+HSPLandroidx/compose/ui/node/LayoutModifierNodeKt;->invalidateMeasurements(Landroidx/compose/ui/node/LayoutModifierNode;)V
+HSPLandroidx/compose/ui/node/LayoutNode$$ExternalSyntheticLambda0;-><init>()V
+HSPLandroidx/compose/ui/node/LayoutNode$$ExternalSyntheticLambda0;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
+HSPLandroidx/compose/ui/node/LayoutNode$Companion$Constructor$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/LayoutNode$Companion$Constructor$1;-><init>()V
+HSPLandroidx/compose/ui/node/LayoutNode$Companion$Constructor$1;->invoke()Landroidx/compose/ui/node/LayoutNode;
+HSPLandroidx/compose/ui/node/LayoutNode$Companion$Constructor$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/LayoutNode$Companion$DummyViewConfiguration$1;-><init>()V
+HSPLandroidx/compose/ui/node/LayoutNode$Companion$ErrorMeasurePolicy$1;-><init>()V
+HSPLandroidx/compose/ui/node/LayoutNode$Companion;-><init>()V
+HSPLandroidx/compose/ui/node/LayoutNode$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/node/LayoutNode$Companion;->getConstructor$ui_release()Lkotlin/jvm/functions/Function0;
+HSPLandroidx/compose/ui/node/LayoutNode$LayoutState;->$values()[Landroidx/compose/ui/node/LayoutNode$LayoutState;
+HSPLandroidx/compose/ui/node/LayoutNode$LayoutState;-><clinit>()V
+HSPLandroidx/compose/ui/node/LayoutNode$LayoutState;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/ui/node/LayoutNode$LayoutState;->values()[Landroidx/compose/ui/node/LayoutNode$LayoutState;
+HSPLandroidx/compose/ui/node/LayoutNode$NoIntrinsicsMeasurePolicy;-><init>(Ljava/lang/String;)V
+HSPLandroidx/compose/ui/node/LayoutNode$UsageByParent;->$values()[Landroidx/compose/ui/node/LayoutNode$UsageByParent;
+HSPLandroidx/compose/ui/node/LayoutNode$UsageByParent;-><clinit>()V
+HSPLandroidx/compose/ui/node/LayoutNode$UsageByParent;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/ui/node/LayoutNode$UsageByParent;->values()[Landroidx/compose/ui/node/LayoutNode$UsageByParent;
+HSPLandroidx/compose/ui/node/LayoutNode$_foldedChildren$1;-><init>(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/LayoutNode$_foldedChildren$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/LayoutNode$_foldedChildren$1;->invoke()V
+HSPLandroidx/compose/ui/node/LayoutNode;->$r8$lambda$7po1rmUuVs6tXeBa5BDq-nmH7XI(Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/ui/node/LayoutNode;)I
+HSPLandroidx/compose/ui/node/LayoutNode;-><clinit>()V
+HSPLandroidx/compose/ui/node/LayoutNode;-><init>(ZI)V
+HSPLandroidx/compose/ui/node/LayoutNode;-><init>(ZIILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/node/LayoutNode;->ZComparator$lambda$39(Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/ui/node/LayoutNode;)I
+HSPLandroidx/compose/ui/node/LayoutNode;->access$getConstructor$cp()Lkotlin/jvm/functions/Function0;
+HSPLandroidx/compose/ui/node/LayoutNode;->access$setIgnoreRemeasureRequests$p(Landroidx/compose/ui/node/LayoutNode;Z)V
+HSPLandroidx/compose/ui/node/LayoutNode;->attach$ui_release(Landroidx/compose/ui/node/Owner;)V
+HSPLandroidx/compose/ui/node/LayoutNode;->checkChildrenPlaceOrderForUpdates$ui_release()V
+HSPLandroidx/compose/ui/node/LayoutNode;->clearPlaceOrder$ui_release()V
+HSPLandroidx/compose/ui/node/LayoutNode;->clearSubtreeIntrinsicsUsage$ui_release()V
+HSPLandroidx/compose/ui/node/LayoutNode;->clearSubtreePlacementIntrinsicsUsage()V
+HSPLandroidx/compose/ui/node/LayoutNode;->dispatchOnPositionedCallbacks$ui_release()V+]Landroidx/compose/ui/node/GlobalPositionAwareModifierNode;Landroidx/compose/ui/node/BackwardsCompatNode;]Landroidx/compose/ui/Modifier$Node;Landroidx/compose/ui/node/BackwardsCompatNode;]Landroidx/compose/ui/node/NodeChain;Landroidx/compose/ui/node/NodeChain;]Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/ui/node/LayoutNode;
+HSPLandroidx/compose/ui/node/LayoutNode;->draw$ui_release(Landroidx/compose/ui/graphics/Canvas;)V
+HSPLandroidx/compose/ui/node/LayoutNode;->getCanMultiMeasure$ui_release()Z
+HSPLandroidx/compose/ui/node/LayoutNode;->getChildMeasurables$ui_release()Ljava/util/List;
+HSPLandroidx/compose/ui/node/LayoutNode;->getChildren$ui_release()Ljava/util/List;
+HSPLandroidx/compose/ui/node/LayoutNode;->getCoordinates()Landroidx/compose/ui/layout/LayoutCoordinates;
+HSPLandroidx/compose/ui/node/LayoutNode;->getDensity()Landroidx/compose/ui/unit/Density;
+HSPLandroidx/compose/ui/node/LayoutNode;->getDepth$ui_release()I
+HSPLandroidx/compose/ui/node/LayoutNode;->getFoldedChildren$ui_release()Ljava/util/List;
+HSPLandroidx/compose/ui/node/LayoutNode;->getHeight()I
+HSPLandroidx/compose/ui/node/LayoutNode;->getInnerCoordinator$ui_release()Landroidx/compose/ui/node/NodeCoordinator;
+HSPLandroidx/compose/ui/node/LayoutNode;->getInnerLayerCoordinator()Landroidx/compose/ui/node/NodeCoordinator;
+HSPLandroidx/compose/ui/node/LayoutNode;->getIntrinsicsUsageByParent$ui_release()Landroidx/compose/ui/node/LayoutNode$UsageByParent;
+HSPLandroidx/compose/ui/node/LayoutNode;->getLayoutDelegate$ui_release()Landroidx/compose/ui/node/LayoutNodeLayoutDelegate;
+HSPLandroidx/compose/ui/node/LayoutNode;->getLayoutDirection()Landroidx/compose/ui/unit/LayoutDirection;
+HSPLandroidx/compose/ui/node/LayoutNode;->getLayoutPending$ui_release()Z
+HSPLandroidx/compose/ui/node/LayoutNode;->getLayoutState$ui_release()Landroidx/compose/ui/node/LayoutNode$LayoutState;
+HSPLandroidx/compose/ui/node/LayoutNode;->getLookaheadLayoutPending$ui_release()Z
+HSPLandroidx/compose/ui/node/LayoutNode;->getLookaheadMeasurePending$ui_release()Z
+HSPLandroidx/compose/ui/node/LayoutNode;->getMDrawScope$ui_release()Landroidx/compose/ui/node/LayoutNodeDrawScope;
+HSPLandroidx/compose/ui/node/LayoutNode;->getMLookaheadScope$ui_release()Landroidx/compose/ui/layout/LookaheadScope;
+HSPLandroidx/compose/ui/node/LayoutNode;->getMeasurePassDelegate()Landroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;
+HSPLandroidx/compose/ui/node/LayoutNode;->getMeasurePending$ui_release()Z
+HSPLandroidx/compose/ui/node/LayoutNode;->getMeasurePolicy()Landroidx/compose/ui/layout/MeasurePolicy;
+HSPLandroidx/compose/ui/node/LayoutNode;->getMeasuredByParent$ui_release()Landroidx/compose/ui/node/LayoutNode$UsageByParent;
+HSPLandroidx/compose/ui/node/LayoutNode;->getNeedsOnPositionedDispatch$ui_release()Z
+HSPLandroidx/compose/ui/node/LayoutNode;->getNodes$ui_release()Landroidx/compose/ui/node/NodeChain;
+HSPLandroidx/compose/ui/node/LayoutNode;->getOuterCoordinator$ui_release()Landroidx/compose/ui/node/NodeCoordinator;
+HSPLandroidx/compose/ui/node/LayoutNode;->getOwner$ui_release()Landroidx/compose/ui/node/Owner;
+HSPLandroidx/compose/ui/node/LayoutNode;->getParent$ui_release()Landroidx/compose/ui/node/LayoutNode;+]Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/ui/node/LayoutNode;
+HSPLandroidx/compose/ui/node/LayoutNode;->getSemanticsId()I
+HSPLandroidx/compose/ui/node/LayoutNode;->getSubcompositionsState$ui_release()Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState;
+HSPLandroidx/compose/ui/node/LayoutNode;->getWidth()I
+HSPLandroidx/compose/ui/node/LayoutNode;->getZSortedChildren()Landroidx/compose/runtime/collection/MutableVector;
+HSPLandroidx/compose/ui/node/LayoutNode;->get_children$ui_release()Landroidx/compose/runtime/collection/MutableVector;
+HSPLandroidx/compose/ui/node/LayoutNode;->insertAt$ui_release(ILandroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/LayoutNode;->invalidateLayer$ui_release()V
+HSPLandroidx/compose/ui/node/LayoutNode;->invalidateLayers$ui_release()V
+HSPLandroidx/compose/ui/node/LayoutNode;->invalidateMeasurements$ui_release()V
+HSPLandroidx/compose/ui/node/LayoutNode;->invalidateUnfoldedVirtualChildren()V
+HSPLandroidx/compose/ui/node/LayoutNode;->isAttached()Z
+HSPLandroidx/compose/ui/node/LayoutNode;->isPlaced()Z
+HSPLandroidx/compose/ui/node/LayoutNode;->isValid()Z
+HSPLandroidx/compose/ui/node/LayoutNode;->markLayoutPending$ui_release()V
+HSPLandroidx/compose/ui/node/LayoutNode;->markMeasurePending$ui_release()V
+HSPLandroidx/compose/ui/node/LayoutNode;->markNodeAndSubtreeAsPlaced()V
+HSPLandroidx/compose/ui/node/LayoutNode;->onDensityOrLayoutDirectionChanged()V
+HSPLandroidx/compose/ui/node/LayoutNode;->onNodePlaced$ui_release()V
+HSPLandroidx/compose/ui/node/LayoutNode;->onZSortedChildrenInvalidated$ui_release()V
+HSPLandroidx/compose/ui/node/LayoutNode;->place$ui_release(II)V
+HSPLandroidx/compose/ui/node/LayoutNode;->recreateUnfoldedChildrenIfDirty()V
+HSPLandroidx/compose/ui/node/LayoutNode;->remeasure-_Sx5XlM$ui_release$default(Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/ui/unit/Constraints;ILjava/lang/Object;)Z
+HSPLandroidx/compose/ui/node/LayoutNode;->remeasure-_Sx5XlM$ui_release(Landroidx/compose/ui/unit/Constraints;)Z
+HSPLandroidx/compose/ui/node/LayoutNode;->replace$ui_release()V
+HSPLandroidx/compose/ui/node/LayoutNode;->requestRelayout$ui_release$default(Landroidx/compose/ui/node/LayoutNode;ZILjava/lang/Object;)V
+HSPLandroidx/compose/ui/node/LayoutNode;->requestRelayout$ui_release(Z)V
+HSPLandroidx/compose/ui/node/LayoutNode;->requestRemeasure$ui_release$default(Landroidx/compose/ui/node/LayoutNode;ZILjava/lang/Object;)V
+HSPLandroidx/compose/ui/node/LayoutNode;->requestRemeasure$ui_release(Z)V
+HSPLandroidx/compose/ui/node/LayoutNode;->resetSubtreeIntrinsicsUsage$ui_release()V
+HSPLandroidx/compose/ui/node/LayoutNode;->setCanMultiMeasure$ui_release(Z)V
+HSPLandroidx/compose/ui/node/LayoutNode;->setDensity(Landroidx/compose/ui/unit/Density;)V
+HSPLandroidx/compose/ui/node/LayoutNode;->setInnerLayerCoordinatorIsDirty$ui_release(Z)V
+HSPLandroidx/compose/ui/node/LayoutNode;->setLayoutDirection(Landroidx/compose/ui/unit/LayoutDirection;)V
+HSPLandroidx/compose/ui/node/LayoutNode;->setMLookaheadScope(Landroidx/compose/ui/layout/LookaheadScope;)V
+HSPLandroidx/compose/ui/node/LayoutNode;->setMeasurePolicy(Landroidx/compose/ui/layout/MeasurePolicy;)V
+HSPLandroidx/compose/ui/node/LayoutNode;->setMeasuredByParent$ui_release(Landroidx/compose/ui/node/LayoutNode$UsageByParent;)V
+HSPLandroidx/compose/ui/node/LayoutNode;->setModifier(Landroidx/compose/ui/Modifier;)V
+HSPLandroidx/compose/ui/node/LayoutNode;->setNeedsOnPositionedDispatch$ui_release(Z)V
+HSPLandroidx/compose/ui/node/LayoutNode;->setSubcompositionsState$ui_release(Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState;)V
+HSPLandroidx/compose/ui/node/LayoutNode;->setViewConfiguration(Landroidx/compose/ui/platform/ViewConfiguration;)V
+HSPLandroidx/compose/ui/node/LayoutNode;->updateChildrenIfDirty$ui_release()V
+HSPLandroidx/compose/ui/node/LayoutNodeAlignmentLines;-><init>(Landroidx/compose/ui/node/AlignmentLinesOwner;)V
+HSPLandroidx/compose/ui/node/LayoutNodeDrawScope;-><init>(Landroidx/compose/ui/graphics/drawscope/CanvasDrawScope;)V
+HSPLandroidx/compose/ui/node/LayoutNodeDrawScope;-><init>(Landroidx/compose/ui/graphics/drawscope/CanvasDrawScope;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/node/LayoutNodeDrawScope;->draw-x_KDEd0$ui_release(Landroidx/compose/ui/graphics/Canvas;JLandroidx/compose/ui/node/NodeCoordinator;Landroidx/compose/ui/node/DrawModifierNode;)V
+HSPLandroidx/compose/ui/node/LayoutNodeDrawScope;->drawContent()V
+HSPLandroidx/compose/ui/node/LayoutNodeDrawScope;->drawImage-AZ2fEMs(Landroidx/compose/ui/graphics/ImageBitmap;JJJJFLandroidx/compose/ui/graphics/drawscope/DrawStyle;Landroidx/compose/ui/graphics/ColorFilter;II)V
+HSPLandroidx/compose/ui/node/LayoutNodeDrawScope;->drawPath-LG529CI(Landroidx/compose/ui/graphics/Path;JFLandroidx/compose/ui/graphics/drawscope/DrawStyle;Landroidx/compose/ui/graphics/ColorFilter;I)V
+HSPLandroidx/compose/ui/node/LayoutNodeDrawScope;->drawRect-n-J9OG0(JJJFLandroidx/compose/ui/graphics/drawscope/DrawStyle;Landroidx/compose/ui/graphics/ColorFilter;I)V
+HSPLandroidx/compose/ui/node/LayoutNodeDrawScope;->drawRoundRect-u-Aw5IA(JJJJLandroidx/compose/ui/graphics/drawscope/DrawStyle;FLandroidx/compose/ui/graphics/ColorFilter;I)V
+HSPLandroidx/compose/ui/node/LayoutNodeDrawScope;->getDrawContext()Landroidx/compose/ui/graphics/drawscope/DrawContext;
+HSPLandroidx/compose/ui/node/LayoutNodeDrawScope;->getLayoutDirection()Landroidx/compose/ui/unit/LayoutDirection;
+HSPLandroidx/compose/ui/node/LayoutNodeDrawScope;->getSize-NH-jbRc()J
+HSPLandroidx/compose/ui/node/LayoutNodeDrawScope;->toPx-0680j_4(F)F
+HSPLandroidx/compose/ui/node/LayoutNodeDrawScopeKt;->access$nextDrawNode(Landroidx/compose/ui/node/DelegatableNode;)Landroidx/compose/ui/node/DrawModifierNode;
+HSPLandroidx/compose/ui/node/LayoutNodeDrawScopeKt;->nextDrawNode(Landroidx/compose/ui/node/DelegatableNode;)Landroidx/compose/ui/node/DrawModifierNode;
+HSPLandroidx/compose/ui/node/LayoutNodeKt;->requireOwner(Landroidx/compose/ui/node/LayoutNode;)Landroidx/compose/ui/node/Owner;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$WhenMappings;-><clinit>()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$childMeasurables$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$childMeasurables$1;-><init>()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$childMeasurables$1;->invoke(Landroidx/compose/ui/node/LayoutNode;)Landroidx/compose/ui/layout/Measurable;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$childMeasurables$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$layoutChildren$1$1$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$layoutChildren$1$1$1;-><init>()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$layoutChildren$1$1$1;->invoke(Landroidx/compose/ui/node/AlignmentLinesOwner;)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$layoutChildren$1$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$layoutChildren$1$1$2;-><clinit>()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$layoutChildren$1$1$2;-><init>()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$layoutChildren$1$1$2;->invoke(Landroidx/compose/ui/node/AlignmentLinesOwner;)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$layoutChildren$1$1$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$layoutChildren$1$1;-><init>(Landroidx/compose/ui/node/LayoutNodeLayoutDelegate;Landroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$layoutChildren$1$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$layoutChildren$1$1;->invoke()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$placeOuterCoordinator$1;-><init>(Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/node/LayoutNodeLayoutDelegate;JF)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$placeOuterCoordinator$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$placeOuterCoordinator$1;->invoke()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$remeasure$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$remeasure$1;-><init>()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$remeasure$1;->invoke(Landroidx/compose/ui/node/AlignmentLinesOwner;)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$remeasure$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;-><init>(Landroidx/compose/ui/node/LayoutNodeLayoutDelegate;)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->forEachChildAlignmentLinesOwner(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->getAlignmentLines()Landroidx/compose/ui/node/AlignmentLines;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->getChildMeasurables$ui_release()Ljava/util/List;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->getInnerCoordinator()Landroidx/compose/ui/node/NodeCoordinator;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->getLastConstraints-DWUhwKw()Landroidx/compose/ui/unit/Constraints;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->getMeasuredWidth()I
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->getParentAlignmentLinesOwner()Landroidx/compose/ui/node/AlignmentLinesOwner;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->getParentData()Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->invalidateIntrinsicsParent(Z)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->layoutChildren()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->measure-BRTryo0(J)Landroidx/compose/ui/layout/Placeable;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->notifyChildrenUsingCoordinatesWhilePlacing()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->onBeforeLayoutChildren()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->placeAt-f8xVGno(JFLkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->placeOuterCoordinator-f8xVGno(JFLkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->remeasure-BRTryo0(J)Z
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->replace()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->setChildMeasurablesDirty$ui_release(Z)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->trackMeasurementByParent(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->updateParentData()Z
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$performMeasure$2;-><init>(Landroidx/compose/ui/node/LayoutNodeLayoutDelegate;J)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$performMeasure$2;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$performMeasure$2;->invoke()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;-><init>(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->access$getLayoutNode$p(Landroidx/compose/ui/node/LayoutNodeLayoutDelegate;)Landroidx/compose/ui/node/LayoutNode;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->access$getLayoutPendingForAlignment$p(Landroidx/compose/ui/node/LayoutNodeLayoutDelegate;)Z
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->access$isOutMostLookaheadRoot(Landroidx/compose/ui/node/LayoutNodeLayoutDelegate;Landroidx/compose/ui/node/LayoutNode;)Z
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->access$performMeasure-BRTryo0(Landroidx/compose/ui/node/LayoutNodeLayoutDelegate;J)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->access$setLayoutPending$p(Landroidx/compose/ui/node/LayoutNodeLayoutDelegate;Z)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->access$setLayoutPendingForAlignment$p(Landroidx/compose/ui/node/LayoutNodeLayoutDelegate;Z)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->access$setLayoutState$p(Landroidx/compose/ui/node/LayoutNodeLayoutDelegate;Landroidx/compose/ui/node/LayoutNode$LayoutState;)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->getAlignmentLinesOwner$ui_release()Landroidx/compose/ui/node/AlignmentLinesOwner;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->getChildrenAccessingCoordinatesDuringPlacement()I
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->getHeight$ui_release()I
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->getLastConstraints-DWUhwKw()Landroidx/compose/ui/unit/Constraints;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->getLayoutPending$ui_release()Z
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->getLayoutState$ui_release()Landroidx/compose/ui/node/LayoutNode$LayoutState;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->getLookaheadLayoutPending$ui_release()Z
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->getLookaheadMeasurePending$ui_release()Z
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->getMeasurePassDelegate$ui_release()Landroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->getMeasurePending$ui_release()Z
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->getOuterCoordinator()Landroidx/compose/ui/node/NodeCoordinator;
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->getWidth$ui_release()I
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->isOutMostLookaheadRoot(Landroidx/compose/ui/node/LayoutNode;)Z
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->markChildrenDirty()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->markLayoutPending$ui_release()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->markMeasurePending$ui_release()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->performMeasure-BRTryo0(J)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->setCoordinatesAccessedDuringPlacement(Z)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->updateParentData()V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegateKt;->access$updateChildMeasurables(Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/runtime/collection/MutableVector;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/node/LayoutNodeLayoutDelegateKt;->updateChildMeasurables(Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/runtime/collection/MutableVector;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/node/LookaheadCapablePlaceable;-><init>()V
+HSPLandroidx/compose/ui/node/LookaheadCapablePlaceable;->invalidateAlignmentLinesFromPositionChange(Landroidx/compose/ui/node/NodeCoordinator;)V
+HSPLandroidx/compose/ui/node/LookaheadCapablePlaceable;->isPlacingForAlignment$ui_release()Z
+HSPLandroidx/compose/ui/node/LookaheadCapablePlaceable;->isShallowPlacing$ui_release()Z
+HSPLandroidx/compose/ui/node/LookaheadCapablePlaceable;->setPlacingForAlignment$ui_release(Z)V
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate$WhenMappings;-><clinit>()V
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;-><init>(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->access$getRoot$p(Landroidx/compose/ui/node/MeasureAndLayoutDelegate;)Landroidx/compose/ui/node/LayoutNode;
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->access$remeasureAndRelayoutIfNeeded(Landroidx/compose/ui/node/MeasureAndLayoutDelegate;Landroidx/compose/ui/node/LayoutNode;)Z
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->callOnLayoutCompletedListeners()V
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->dispatchOnPositionedCallbacks$default(Landroidx/compose/ui/node/MeasureAndLayoutDelegate;ZILjava/lang/Object;)V
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->dispatchOnPositionedCallbacks(Z)V
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->doRemeasure-sdFAvZA(Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/ui/unit/Constraints;)Z
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->forceMeasureTheSubtree(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->getCanAffectParent(Landroidx/compose/ui/node/LayoutNode;)Z
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->getMeasureAffectsParent(Landroidx/compose/ui/node/LayoutNode;)Z
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->measureAndLayout(Lkotlin/jvm/functions/Function0;)Z
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->measureOnly()V
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->recurseRemeasure(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->registerOnLayoutCompletedListener(Landroidx/compose/ui/node/Owner$OnLayoutCompletedListener;)V
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->remeasureAndRelayoutIfNeeded(Landroidx/compose/ui/node/LayoutNode;)Z
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->remeasureOnly(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->requestRelayout(Landroidx/compose/ui/node/LayoutNode;Z)Z
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->requestRemeasure$default(Landroidx/compose/ui/node/MeasureAndLayoutDelegate;Landroidx/compose/ui/node/LayoutNode;ZILjava/lang/Object;)Z
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->requestRemeasure(Landroidx/compose/ui/node/LayoutNode;Z)Z
+HSPLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->updateRootConstraints-BRTryo0(J)V
+HSPLandroidx/compose/ui/node/MutableVectorWithMutationTracking;-><init>(Landroidx/compose/runtime/collection/MutableVector;Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/ui/node/MutableVectorWithMutationTracking;->add(ILjava/lang/Object;)V
+HSPLandroidx/compose/ui/node/MutableVectorWithMutationTracking;->asList()Ljava/util/List;
+HSPLandroidx/compose/ui/node/MutableVectorWithMutationTracking;->getVector()Landroidx/compose/runtime/collection/MutableVector;
+HSPLandroidx/compose/ui/node/MyersDiffKt;->access$swap([III)V
+HSPLandroidx/compose/ui/node/MyersDiffKt;->applyDiff(IILandroidx/compose/ui/node/IntStack;Landroidx/compose/ui/node/DiffCallback;)V
+HSPLandroidx/compose/ui/node/MyersDiffKt;->backward-4l5_RBY(IIIILandroidx/compose/ui/node/DiffCallback;[I[II[I)Z
+HSPLandroidx/compose/ui/node/MyersDiffKt;->calculateDiff(IILandroidx/compose/ui/node/DiffCallback;)Landroidx/compose/ui/node/IntStack;
+HSPLandroidx/compose/ui/node/MyersDiffKt;->executeDiff(IILandroidx/compose/ui/node/DiffCallback;)V
+HSPLandroidx/compose/ui/node/MyersDiffKt;->fillSnake(IIIIZ[I)V
+HSPLandroidx/compose/ui/node/MyersDiffKt;->forward-4l5_RBY(IIIILandroidx/compose/ui/node/DiffCallback;[I[II[I)Z
+HSPLandroidx/compose/ui/node/MyersDiffKt;->midPoint-q5eDKzI(IIIILandroidx/compose/ui/node/DiffCallback;[I[I[I)Z
+HSPLandroidx/compose/ui/node/MyersDiffKt;->swap([III)V
+HSPLandroidx/compose/ui/node/NodeChain$Differ;-><init>(Landroidx/compose/ui/node/NodeChain;Landroidx/compose/ui/Modifier$Node;ILandroidx/compose/runtime/collection/MutableVector;Landroidx/compose/runtime/collection/MutableVector;)V
+HSPLandroidx/compose/ui/node/NodeChain$Differ;->areItemsTheSame(II)Z
+HSPLandroidx/compose/ui/node/NodeChain$Differ;->insert(II)V
+HSPLandroidx/compose/ui/node/NodeChain$Differ;->same(II)V
+HSPLandroidx/compose/ui/node/NodeChain;-><init>(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/NodeChain;->access$createAndInsertNodeAsParent(Landroidx/compose/ui/node/NodeChain;Landroidx/compose/ui/Modifier$Element;Landroidx/compose/ui/Modifier$Node;)Landroidx/compose/ui/Modifier$Node;
+HSPLandroidx/compose/ui/node/NodeChain;->access$getAggregateChildKindSet(Landroidx/compose/ui/node/NodeChain;)I
+HSPLandroidx/compose/ui/node/NodeChain;->access$getLogger$p(Landroidx/compose/ui/node/NodeChain;)Landroidx/compose/ui/node/NodeChain$Logger;
+HSPLandroidx/compose/ui/node/NodeChain;->access$updateNodeAndReplaceIfNeeded(Landroidx/compose/ui/node/NodeChain;Landroidx/compose/ui/Modifier$Element;Landroidx/compose/ui/Modifier$Element;Landroidx/compose/ui/Modifier$Node;)Landroidx/compose/ui/Modifier$Node;
+HSPLandroidx/compose/ui/node/NodeChain;->attach(Z)V
+HSPLandroidx/compose/ui/node/NodeChain;->createAndInsertNodeAsParent(Landroidx/compose/ui/Modifier$Element;Landroidx/compose/ui/Modifier$Node;)Landroidx/compose/ui/Modifier$Node;
+HSPLandroidx/compose/ui/node/NodeChain;->getAggregateChildKindSet()I
+HSPLandroidx/compose/ui/node/NodeChain;->getDiffer(Landroidx/compose/ui/Modifier$Node;Landroidx/compose/runtime/collection/MutableVector;Landroidx/compose/runtime/collection/MutableVector;)Landroidx/compose/ui/node/NodeChain$Differ;
+HSPLandroidx/compose/ui/node/NodeChain;->getHead$ui_release()Landroidx/compose/ui/Modifier$Node;
+HSPLandroidx/compose/ui/node/NodeChain;->getInnerCoordinator$ui_release()Landroidx/compose/ui/node/InnerNodeCoordinator;
+HSPLandroidx/compose/ui/node/NodeChain;->getOuterCoordinator$ui_release()Landroidx/compose/ui/node/NodeCoordinator;
+HSPLandroidx/compose/ui/node/NodeChain;->getTail$ui_release()Landroidx/compose/ui/Modifier$Node;
+HSPLandroidx/compose/ui/node/NodeChain;->has-H91voCI$ui_release(I)Z
+HSPLandroidx/compose/ui/node/NodeChain;->insertParent(Landroidx/compose/ui/Modifier$Node;Landroidx/compose/ui/Modifier$Node;)Landroidx/compose/ui/Modifier$Node;
+HSPLandroidx/compose/ui/node/NodeChain;->padChain()V
+HSPLandroidx/compose/ui/node/NodeChain;->structuralUpdate(Landroidx/compose/runtime/collection/MutableVector;ILandroidx/compose/runtime/collection/MutableVector;ILandroidx/compose/ui/Modifier$Node;)V
+HSPLandroidx/compose/ui/node/NodeChain;->syncCoordinators()V
+HSPLandroidx/compose/ui/node/NodeChain;->trimChain()V
+HSPLandroidx/compose/ui/node/NodeChain;->updateFrom$ui_release(Landroidx/compose/ui/Modifier;)V
+HSPLandroidx/compose/ui/node/NodeChain;->updateNodeAndReplaceIfNeeded(Landroidx/compose/ui/Modifier$Element;Landroidx/compose/ui/Modifier$Element;Landroidx/compose/ui/Modifier$Node;)Landroidx/compose/ui/Modifier$Node;
+HSPLandroidx/compose/ui/node/NodeChainKt$SentinelHead$1;-><init>()V
+HSPLandroidx/compose/ui/node/NodeChainKt;-><clinit>()V
+HSPLandroidx/compose/ui/node/NodeChainKt;->access$fillVector(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/collection/MutableVector;)Landroidx/compose/runtime/collection/MutableVector;
+HSPLandroidx/compose/ui/node/NodeChainKt;->access$getSentinelHead$p()Landroidx/compose/ui/node/NodeChainKt$SentinelHead$1;
+HSPLandroidx/compose/ui/node/NodeChainKt;->fillVector(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/collection/MutableVector;)Landroidx/compose/runtime/collection/MutableVector;
+HSPLandroidx/compose/ui/node/NodeChainKt;->reuseActionForModifiers(Landroidx/compose/ui/Modifier$Element;Landroidx/compose/ui/Modifier$Element;)I
+HSPLandroidx/compose/ui/node/NodeCoordinator$Companion$PointerInputSource$1;-><init>()V
+HSPLandroidx/compose/ui/node/NodeCoordinator$Companion$SemanticsSource$1;-><init>()V
+HSPLandroidx/compose/ui/node/NodeCoordinator$Companion$onCommitAffectingLayer$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/NodeCoordinator$Companion$onCommitAffectingLayer$1;-><init>()V
+HSPLandroidx/compose/ui/node/NodeCoordinator$Companion$onCommitAffectingLayer$1;->invoke(Landroidx/compose/ui/node/NodeCoordinator;)V
+HSPLandroidx/compose/ui/node/NodeCoordinator$Companion$onCommitAffectingLayer$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/NodeCoordinator$Companion$onCommitAffectingLayerParams$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/NodeCoordinator$Companion$onCommitAffectingLayerParams$1;-><init>()V
+HSPLandroidx/compose/ui/node/NodeCoordinator$Companion;-><init>()V
+HSPLandroidx/compose/ui/node/NodeCoordinator$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/node/NodeCoordinator$invalidateParentLayer$1;-><init>(Landroidx/compose/ui/node/NodeCoordinator;)V
+HSPLandroidx/compose/ui/node/NodeCoordinator$invalidateParentLayer$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/NodeCoordinator$invalidateParentLayer$1;->invoke()V
+HSPLandroidx/compose/ui/node/NodeCoordinator$invoke$1;-><init>(Landroidx/compose/ui/node/NodeCoordinator;Landroidx/compose/ui/graphics/Canvas;)V
+HSPLandroidx/compose/ui/node/NodeCoordinator$invoke$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/NodeCoordinator$invoke$1;->invoke()V
+HSPLandroidx/compose/ui/node/NodeCoordinator$updateLayerParameters$1;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/node/NodeCoordinator$updateLayerParameters$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/NodeCoordinator$updateLayerParameters$1;->invoke()V
+HSPLandroidx/compose/ui/node/NodeCoordinator;-><clinit>()V
+HSPLandroidx/compose/ui/node/NodeCoordinator;-><init>(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/NodeCoordinator;->access$drawContainedDrawModifiers(Landroidx/compose/ui/node/NodeCoordinator;Landroidx/compose/ui/graphics/Canvas;)V
+HSPLandroidx/compose/ui/node/NodeCoordinator;->access$getGraphicsLayerScope$cp()Landroidx/compose/ui/graphics/ReusableGraphicsLayerScope;
+HSPLandroidx/compose/ui/node/NodeCoordinator;->access$getMeasuredSize-YbymL2g(Landroidx/compose/ui/node/NodeCoordinator;)J
+HSPLandroidx/compose/ui/node/NodeCoordinator;->access$headNode(Landroidx/compose/ui/node/NodeCoordinator;Z)Landroidx/compose/ui/Modifier$Node;
+HSPLandroidx/compose/ui/node/NodeCoordinator;->access$setMeasurementConstraints-BRTryo0(Landroidx/compose/ui/node/NodeCoordinator;J)V
+HSPLandroidx/compose/ui/node/NodeCoordinator;->attach()V
+HSPLandroidx/compose/ui/node/NodeCoordinator;->draw(Landroidx/compose/ui/graphics/Canvas;)V
+HSPLandroidx/compose/ui/node/NodeCoordinator;->drawContainedDrawModifiers(Landroidx/compose/ui/graphics/Canvas;)V
+HSPLandroidx/compose/ui/node/NodeCoordinator;->getAlignmentLinesOwner()Landroidx/compose/ui/node/AlignmentLinesOwner;
+HSPLandroidx/compose/ui/node/NodeCoordinator;->getCoordinates()Landroidx/compose/ui/layout/LayoutCoordinates;
+HSPLandroidx/compose/ui/node/NodeCoordinator;->getDensity()F
+HSPLandroidx/compose/ui/node/NodeCoordinator;->getFontScale()F
+HSPLandroidx/compose/ui/node/NodeCoordinator;->getLastLayerDrawingWasSkipped$ui_release()Z
+HSPLandroidx/compose/ui/node/NodeCoordinator;->getLayer()Landroidx/compose/ui/node/OwnedLayer;
+HSPLandroidx/compose/ui/node/NodeCoordinator;->getLayoutDirection()Landroidx/compose/ui/unit/LayoutDirection;
+HSPLandroidx/compose/ui/node/NodeCoordinator;->getLayoutNode()Landroidx/compose/ui/node/LayoutNode;
+HSPLandroidx/compose/ui/node/NodeCoordinator;->getLookaheadDelegate$ui_release()Landroidx/compose/ui/node/LookaheadDelegate;
+HSPLandroidx/compose/ui/node/NodeCoordinator;->getMeasureResult$ui_release()Landroidx/compose/ui/layout/MeasureResult;
+HSPLandroidx/compose/ui/node/NodeCoordinator;->getParent()Landroidx/compose/ui/node/LookaheadCapablePlaceable;
+HSPLandroidx/compose/ui/node/NodeCoordinator;->getParentData()Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/NodeCoordinator;->getPosition-nOcc-ac()J
+HSPLandroidx/compose/ui/node/NodeCoordinator;->getSize-YbymL2g()J
+HSPLandroidx/compose/ui/node/NodeCoordinator;->getSnapshotObserver()Landroidx/compose/ui/node/OwnerSnapshotObserver;
+HSPLandroidx/compose/ui/node/NodeCoordinator;->getWrapped$ui_release()Landroidx/compose/ui/node/NodeCoordinator;
+HSPLandroidx/compose/ui/node/NodeCoordinator;->getWrappedBy$ui_release()Landroidx/compose/ui/node/NodeCoordinator;
+HSPLandroidx/compose/ui/node/NodeCoordinator;->getZIndex()F
+HSPLandroidx/compose/ui/node/NodeCoordinator;->hasNode-H91voCI(I)Z
+HSPLandroidx/compose/ui/node/NodeCoordinator;->headNode(Z)Landroidx/compose/ui/Modifier$Node;
+HSPLandroidx/compose/ui/node/NodeCoordinator;->invalidateLayer()V+]Landroidx/compose/ui/node/NodeCoordinator;Landroidx/compose/ui/node/InnerNodeCoordinator;,Landroidx/compose/ui/node/LayoutModifierNodeCoordinator;]Landroidx/compose/ui/node/OwnedLayer;Landroidx/compose/ui/platform/RenderNodeLayer;
+HSPLandroidx/compose/ui/node/NodeCoordinator;->invoke(Landroidx/compose/ui/graphics/Canvas;)V
+HSPLandroidx/compose/ui/node/NodeCoordinator;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/NodeCoordinator;->isAttached()Z
+HSPLandroidx/compose/ui/node/NodeCoordinator;->onLayerBlockUpdated(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/node/NodeCoordinator;->onLayoutModifierNodeChanged()V
+HSPLandroidx/compose/ui/node/NodeCoordinator;->onMeasureResultChanged(II)V
+HSPLandroidx/compose/ui/node/NodeCoordinator;->onMeasured()V
+HSPLandroidx/compose/ui/node/NodeCoordinator;->onPlaced()V
+HSPLandroidx/compose/ui/node/NodeCoordinator;->placeAt-f8xVGno(JFLkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/node/NodeCoordinator;->setMeasureResult$ui_release(Landroidx/compose/ui/layout/MeasureResult;)V
+HSPLandroidx/compose/ui/node/NodeCoordinator;->setPosition--gyyYBs(J)V
+HSPLandroidx/compose/ui/node/NodeCoordinator;->setWrapped$ui_release(Landroidx/compose/ui/node/NodeCoordinator;)V
+HSPLandroidx/compose/ui/node/NodeCoordinator;->setWrappedBy$ui_release(Landroidx/compose/ui/node/NodeCoordinator;)V
+HSPLandroidx/compose/ui/node/NodeCoordinator;->updateLayerParameters()V
+HSPLandroidx/compose/ui/node/NodeCoordinator;->updateLookaheadScope$ui_release(Landroidx/compose/ui/layout/LookaheadScope;)V
+HSPLandroidx/compose/ui/node/NodeKind;->constructor-impl(I)I
+HSPLandroidx/compose/ui/node/NodeKindKt;->autoInvalidateInsertedNode(Landroidx/compose/ui/Modifier$Node;)V
+HSPLandroidx/compose/ui/node/NodeKindKt;->autoInvalidateNode(Landroidx/compose/ui/Modifier$Node;I)V
+HSPLandroidx/compose/ui/node/NodeKindKt;->autoInvalidateUpdatedNode(Landroidx/compose/ui/Modifier$Node;)V
+HSPLandroidx/compose/ui/node/NodeKindKt;->calculateNodeKindSetFrom(Landroidx/compose/ui/Modifier$Element;)I
+HSPLandroidx/compose/ui/node/NodeKindKt;->getIncludeSelfInTraversal-H91voCI(I)Z
+HSPLandroidx/compose/ui/node/OnPositionedDispatcher$Companion$DepthComparator;-><clinit>()V
+HSPLandroidx/compose/ui/node/OnPositionedDispatcher$Companion$DepthComparator;-><init>()V
+HSPLandroidx/compose/ui/node/OnPositionedDispatcher$Companion$DepthComparator;->compare(Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/ui/node/LayoutNode;)I
+HSPLandroidx/compose/ui/node/OnPositionedDispatcher$Companion$DepthComparator;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
+HSPLandroidx/compose/ui/node/OnPositionedDispatcher$Companion;-><init>()V
+HSPLandroidx/compose/ui/node/OnPositionedDispatcher$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/node/OnPositionedDispatcher;-><clinit>()V
+HSPLandroidx/compose/ui/node/OnPositionedDispatcher;-><init>()V
+HSPLandroidx/compose/ui/node/OnPositionedDispatcher;->dispatch()V
+HSPLandroidx/compose/ui/node/OnPositionedDispatcher;->dispatchHierarchy(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/OnPositionedDispatcher;->onNodePositioned(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/Owner$Companion;-><clinit>()V
+HSPLandroidx/compose/ui/node/Owner$Companion;-><init>()V
+HSPLandroidx/compose/ui/node/Owner$Companion;->getEnableExtraAssertions()Z
+HSPLandroidx/compose/ui/node/Owner;-><clinit>()V
+HSPLandroidx/compose/ui/node/Owner;->measureAndLayout$default(Landroidx/compose/ui/node/Owner;ZILjava/lang/Object;)V
+HSPLandroidx/compose/ui/node/Owner;->onRequestMeasure$default(Landroidx/compose/ui/node/Owner;Landroidx/compose/ui/node/LayoutNode;ZZILjava/lang/Object;)V
+HSPLandroidx/compose/ui/node/Owner;->onRequestRelayout$default(Landroidx/compose/ui/node/Owner;Landroidx/compose/ui/node/LayoutNode;ZZILjava/lang/Object;)V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingLayout$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingLayout$1;-><init>()V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingLayoutModifier$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingLayoutModifier$1;-><init>()V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingLayoutModifier$1;->invoke(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingLayoutModifier$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingLayoutModifierInLookahead$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingLayoutModifierInLookahead$1;-><init>()V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingLookaheadLayout$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingLookaheadLayout$1;-><init>()V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingLookaheadMeasure$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingLookaheadMeasure$1;-><init>()V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingMeasure$1;-><clinit>()V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingMeasure$1;-><init>()V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingMeasure$1;->invoke(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingMeasure$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver;->observeLayoutModifierSnapshotReads$ui_release(Landroidx/compose/ui/node/LayoutNode;ZLkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver;->observeLayoutSnapshotReads$ui_release(Landroidx/compose/ui/node/LayoutNode;ZLkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver;->observeMeasureSnapshotReads$ui_release(Landroidx/compose/ui/node/LayoutNode;ZLkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver;->observeReads$ui_release(Landroidx/compose/ui/node/OwnerScope;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/ui/node/OwnerSnapshotObserver;->startObserving$ui_release()V
+HSPLandroidx/compose/ui/node/SemanticsModifierNodeKt;->collapsedSemanticsConfiguration(Landroidx/compose/ui/node/SemanticsModifierNode;)Landroidx/compose/ui/semantics/SemanticsConfiguration;
+HSPLandroidx/compose/ui/node/SemanticsModifierNodeKt;->invalidateSemantics(Landroidx/compose/ui/node/SemanticsModifierNode;)V
+HSPLandroidx/compose/ui/node/Snake;->addDiagonalToStack-impl([ILandroidx/compose/ui/node/IntStack;)V
+HSPLandroidx/compose/ui/node/Snake;->constructor-impl([I)[I
+HSPLandroidx/compose/ui/node/Snake;->getDiagonalSize-impl([I)I
+HSPLandroidx/compose/ui/node/Snake;->getEndX-impl([I)I
+HSPLandroidx/compose/ui/node/Snake;->getEndY-impl([I)I
+HSPLandroidx/compose/ui/node/Snake;->getHasAdditionOrRemoval-impl([I)Z
+HSPLandroidx/compose/ui/node/Snake;->getReverse-impl([I)Z
+HSPLandroidx/compose/ui/node/Snake;->getStartX-impl([I)I
+HSPLandroidx/compose/ui/node/Snake;->getStartY-impl([I)I
+HSPLandroidx/compose/ui/node/Snake;->isAddition-impl([I)Z
+HSPLandroidx/compose/ui/node/TreeSet;-><init>(Ljava/util/Comparator;)V
+HSPLandroidx/compose/ui/node/UiApplier;-><init>(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/UiApplier;->insertBottomUp(ILandroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/UiApplier;->insertBottomUp(ILjava/lang/Object;)V
+HSPLandroidx/compose/ui/node/UiApplier;->insertTopDown(ILandroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/node/UiApplier;->insertTopDown(ILjava/lang/Object;)V
+HSPLandroidx/compose/ui/node/UiApplier;->onEndChanges()V
+HSPLandroidx/compose/ui/platform/AbstractComposeView$ensureCompositionCreated$1;-><init>(Landroidx/compose/ui/platform/AbstractComposeView;)V
+HSPLandroidx/compose/ui/platform/AbstractComposeView$ensureCompositionCreated$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/ui/platform/AbstractComposeView$ensureCompositionCreated$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/AbstractComposeView;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AbstractComposeView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
+HSPLandroidx/compose/ui/platform/AbstractComposeView;->addView(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V
+HSPLandroidx/compose/ui/platform/AbstractComposeView;->addView(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
+HSPLandroidx/compose/ui/platform/AbstractComposeView;->cacheIfAlive(Landroidx/compose/runtime/CompositionContext;)Landroidx/compose/runtime/CompositionContext;
+HSPLandroidx/compose/ui/platform/AbstractComposeView;->checkAddView()V
+HSPLandroidx/compose/ui/platform/AbstractComposeView;->ensureCompositionCreated()V
+HSPLandroidx/compose/ui/platform/AbstractComposeView;->internalOnLayout$ui_release(ZIIII)V
+HSPLandroidx/compose/ui/platform/AbstractComposeView;->internalOnMeasure$ui_release(II)V
+HSPLandroidx/compose/ui/platform/AbstractComposeView;->isAlive(Landroidx/compose/runtime/CompositionContext;)Z
+HSPLandroidx/compose/ui/platform/AbstractComposeView;->onAttachedToWindow()V
+HSPLandroidx/compose/ui/platform/AbstractComposeView;->onLayout(ZIIII)V
+HSPLandroidx/compose/ui/platform/AbstractComposeView;->onMeasure(II)V
+HSPLandroidx/compose/ui/platform/AbstractComposeView;->onRtlPropertiesChanged(I)V
+HSPLandroidx/compose/ui/platform/AbstractComposeView;->resolveParentCompositionContext()Landroidx/compose/runtime/CompositionContext;
+HSPLandroidx/compose/ui/platform/AbstractComposeView;->setParentCompositionContext(Landroidx/compose/runtime/CompositionContext;)V
+HSPLandroidx/compose/ui/platform/AbstractComposeView;->setParentContext(Landroidx/compose/runtime/CompositionContext;)V
+HSPLandroidx/compose/ui/platform/AbstractComposeView;->setPreviousAttachedWindowToken(Landroid/os/IBinder;)V
+HSPLandroidx/compose/ui/platform/AndroidAccessibilityManager$Companion;-><init>()V
+HSPLandroidx/compose/ui/platform/AndroidAccessibilityManager$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/platform/AndroidAccessibilityManager;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidAccessibilityManager;-><init>(Landroid/content/Context;)V
+HSPLandroidx/compose/ui/platform/AndroidClipboardManager;-><init>(Landroid/content/ClipboardManager;)V
+HSPLandroidx/compose/ui/platform/AndroidClipboardManager;-><init>(Landroid/content/Context;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$$ExternalSyntheticLambda0;-><init>(Landroidx/compose/ui/platform/AndroidComposeView;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$$ExternalSyntheticLambda0;->onGlobalLayout()V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$$ExternalSyntheticLambda1;-><init>(Landroidx/compose/ui/platform/AndroidComposeView;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$$ExternalSyntheticLambda2;-><init>(Landroidx/compose/ui/platform/AndroidComposeView;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$$ExternalSyntheticLambda2;->onTouchModeChanged(Z)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$$ExternalSyntheticLambda3;-><init>(Landroidx/compose/ui/platform/AndroidComposeView;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$Companion;-><init>()V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$Companion;->access$getIsShowingLayoutBounds(Landroidx/compose/ui/platform/AndroidComposeView$Companion;)Z
+HSPLandroidx/compose/ui/platform/AndroidComposeView$Companion;->getIsShowingLayoutBounds()Z
+HSPLandroidx/compose/ui/platform/AndroidComposeView$ViewTreeOwners;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$ViewTreeOwners;-><init>(Landroidx/lifecycle/LifecycleOwner;Landroidx/savedstate/SavedStateRegistryOwner;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$ViewTreeOwners;->getLifecycleOwner()Landroidx/lifecycle/LifecycleOwner;
+HSPLandroidx/compose/ui/platform/AndroidComposeView$ViewTreeOwners;->getSavedStateRegistryOwner()Landroidx/savedstate/SavedStateRegistryOwner;
+HSPLandroidx/compose/ui/platform/AndroidComposeView$_inputModeManager$1;-><init>(Landroidx/compose/ui/platform/AndroidComposeView;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$configurationChangeObserver$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$configurationChangeObserver$1;-><init>()V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$keyInputModifier$1;-><init>(Landroidx/compose/ui/platform/AndroidComposeView;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$pointerIconService$1;-><init>(Landroidx/compose/ui/platform/AndroidComposeView;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$resendMotionEventOnLayout$1;-><init>(Landroidx/compose/ui/platform/AndroidComposeView;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$resendMotionEventOnLayout$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/AndroidComposeView$resendMotionEventOnLayout$1;->invoke()V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$resendMotionEventRunnable$1;-><init>(Landroidx/compose/ui/platform/AndroidComposeView;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$rotaryInputModifier$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$rotaryInputModifier$1;-><init>()V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$scrollContainerInfo$1$value$1;-><init>(Landroidx/compose/ui/platform/AndroidComposeView;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$scrollContainerInfo$1;-><init>(Landroidx/compose/ui/platform/AndroidComposeView;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$scrollContainerInfo$1;->getKey()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+HSPLandroidx/compose/ui/platform/AndroidComposeView$scrollContainerInfo$1;->getValue()Landroidx/compose/ui/platform/AndroidComposeView$scrollContainerInfo$1$value$1;
+HSPLandroidx/compose/ui/platform/AndroidComposeView$scrollContainerInfo$1;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/AndroidComposeView$semanticsModifier$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$semanticsModifier$1;-><init>()V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$semanticsModifier$1;->invoke(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$semanticsModifier$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/AndroidComposeView$snapshotObserver$1;-><init>(Landroidx/compose/ui/platform/AndroidComposeView;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView$snapshotObserver$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/AndroidComposeView$snapshotObserver$1;->invoke(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->$r8$lambda$6rnsioIDxAVR319ScBkOteeoeiE(Landroidx/compose/ui/platform/AndroidComposeView;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->$r8$lambda$TvhWqMihl4JwF42Odovn0ewO6fk(Landroidx/compose/ui/platform/AndroidComposeView;Z)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;-><init>(Landroid/content/Context;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->access$getGetBooleanMethod$cp()Ljava/lang/reflect/Method;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->access$getPreviousMotionEvent$p(Landroidx/compose/ui/platform/AndroidComposeView;)Landroid/view/MotionEvent;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->access$getSystemPropertiesClass$cp()Ljava/lang/Class;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->access$setGetBooleanMethod$cp(Ljava/lang/reflect/Method;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->access$setSystemPropertiesClass$cp(Ljava/lang/Class;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->autofillSupported()Z
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->boundsUpdatesEventLoop(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->convertMeasureSpec(I)Lkotlin/Pair;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->createLayer(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;)Landroidx/compose/ui/node/OwnedLayer;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->dispatchDraw(Landroid/graphics/Canvas;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->forceMeasureTheSubtree(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getAccessibilityManager()Landroidx/compose/ui/platform/AccessibilityManager;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getAccessibilityManager()Landroidx/compose/ui/platform/AndroidAccessibilityManager;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getAutofill()Landroidx/compose/ui/autofill/Autofill;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getAutofillTree()Landroidx/compose/ui/autofill/AutofillTree;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getClipboardManager()Landroidx/compose/ui/platform/AndroidClipboardManager;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getClipboardManager()Landroidx/compose/ui/platform/ClipboardManager;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getDensity()Landroidx/compose/ui/unit/Density;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getFocusManager()Landroidx/compose/ui/focus/FocusManager;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getFontFamilyResolver()Landroidx/compose/ui/text/font/FontFamily$Resolver;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getFontLoader()Landroidx/compose/ui/text/font/Font$ResourceLoader;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getFontWeightAdjustmentCompat(Landroid/content/res/Configuration;)I
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getHapticFeedBack()Landroidx/compose/ui/hapticfeedback/HapticFeedback;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getInputModeManager()Landroidx/compose/ui/input/InputModeManager;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getLayoutDirection()Landroidx/compose/ui/unit/LayoutDirection;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getModifierLocalManager()Landroidx/compose/ui/modifier/ModifierLocalManager;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getPointerIconService()Landroidx/compose/ui/input/pointer/PointerIconService;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getRoot()Landroidx/compose/ui/node/LayoutNode;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getSemanticsOwner()Landroidx/compose/ui/semantics/SemanticsOwner;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getSharedDrawScope()Landroidx/compose/ui/node/LayoutNodeDrawScope;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getShowLayoutBounds()Z
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getSnapshotObserver()Landroidx/compose/ui/node/OwnerSnapshotObserver;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getTextInputService()Landroidx/compose/ui/text/input/TextInputService;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getTextToolbar()Landroidx/compose/ui/platform/TextToolbar;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getView()Landroid/view/View;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getViewConfiguration()Landroidx/compose/ui/platform/ViewConfiguration;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getViewTreeOwners()Landroidx/compose/ui/platform/AndroidComposeView$ViewTreeOwners;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->getWindowInfo()Landroidx/compose/ui/platform/WindowInfo;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->globalLayoutListener$lambda$1(Landroidx/compose/ui/platform/AndroidComposeView;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->invalidateLayers(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->invalidateLayoutNodeMeasurement(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->keyboardVisibilityEventLoop(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->measureAndLayout(Z)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->notifyLayerIsDirty$ui_release(Landroidx/compose/ui/node/OwnedLayer;Z)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->onAttach(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->onAttachedToWindow()V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->onCheckIsTextEditor()Z
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->onDraw(Landroid/graphics/Canvas;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->onEndApplyChanges()V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->onLayout(ZIIII)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->onLayoutChange(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->onMeasure(II)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->onRequestMeasure(Landroidx/compose/ui/node/LayoutNode;ZZ)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->onRequestRelayout(Landroidx/compose/ui/node/LayoutNode;ZZ)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->onResume(Landroidx/lifecycle/LifecycleOwner;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->onRtlPropertiesChanged(I)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->onSemanticsChange()V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->onWindowFocusChanged(Z)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->registerOnEndApplyChangesListener(Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->registerOnLayoutCompletedListener(Landroidx/compose/ui/node/Owner$OnLayoutCompletedListener;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->scheduleMeasureAndLayout$default(Landroidx/compose/ui/platform/AndroidComposeView;Landroidx/compose/ui/node/LayoutNode;ILjava/lang/Object;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->scheduleMeasureAndLayout(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->setConfigurationChangeObserver(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->setLayoutDirection(Landroidx/compose/ui/unit/LayoutDirection;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->setOnViewTreeOwnersAvailable(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->setShowLayoutBounds(Z)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->setViewTreeOwners(Landroidx/compose/ui/platform/AndroidComposeView$ViewTreeOwners;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->touchModeChangeListener$lambda$3(Landroidx/compose/ui/platform/AndroidComposeView;Z)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView;->updatePositionCacheAndDispatch()V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$$ExternalSyntheticLambda0;-><init>(Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$$ExternalSyntheticLambda1;-><init>(Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$$ExternalSyntheticLambda2;-><init>(Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$1;-><init>(Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$1;->onViewAttachedToWindow(Landroid/view/View;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$Companion;-><init>()V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$MyNodeProvider;-><init>(Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$SemanticsNodeCopy;-><init>(Landroidx/compose/ui/semantics/SemanticsNode;Ljava/util/Map;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$boundsUpdatesEventLoop$1;-><init>(Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$sendScrollEventIfNeededLambda$1;-><init>(Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;-><init>(Landroidx/compose/ui/platform/AndroidComposeView;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;->boundsUpdatesEventLoop(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;->getAccessibilityManager$ui_release()Landroid/view/accessibility/AccessibilityManager;
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;->getEnabledStateListener$ui_release()Landroid/view/accessibility/AccessibilityManager$AccessibilityStateChangeListener;
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;->getTouchExplorationStateListener$ui_release()Landroid/view/accessibility/AccessibilityManager$TouchExplorationStateChangeListener;
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;->isEnabled$ui_release()Z
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;->onLayoutChange$ui_release(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;->onSemanticsChange$ui_release()V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewForceDarkModeQ;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewForceDarkModeQ;-><init>()V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewForceDarkModeQ;->disallowForceDark(Landroid/view/View;)V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewVerificationHelperMethodsO;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewVerificationHelperMethodsO;-><init>()V
+HSPLandroidx/compose/ui/platform/AndroidComposeViewVerificationHelperMethodsO;->focusable(Landroid/view/View;IZ)V
+HSPLandroidx/compose/ui/platform/AndroidComposeView_androidKt$textInputServiceFactory$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidComposeView_androidKt$textInputServiceFactory$1;-><init>()V
+HSPLandroidx/compose/ui/platform/AndroidComposeView_androidKt$textInputServiceFactory$1;->invoke(Landroidx/compose/ui/text/input/PlatformTextInputService;)Landroidx/compose/ui/text/input/TextInputService;
+HSPLandroidx/compose/ui/platform/AndroidComposeView_androidKt$textInputServiceFactory$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/AndroidComposeView_androidKt;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidComposeView_androidKt;->access$layoutDirectionFromInt(I)Landroidx/compose/ui/unit/LayoutDirection;
+HSPLandroidx/compose/ui/platform/AndroidComposeView_androidKt;->getLocaleLayoutDirection(Landroid/content/res/Configuration;)Landroidx/compose/ui/unit/LayoutDirection;
+HSPLandroidx/compose/ui/platform/AndroidComposeView_androidKt;->getTextInputServiceFactory()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/ui/platform/AndroidComposeView_androidKt;->layoutDirectionFromInt(I)Landroidx/compose/ui/unit/LayoutDirection;
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$LocalConfiguration$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$LocalConfiguration$1;-><init>()V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$LocalContext$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$LocalContext$1;-><init>()V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$LocalImageVectorCache$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$LocalImageVectorCache$1;-><init>()V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$LocalLifecycleOwner$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$LocalLifecycleOwner$1;-><init>()V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$LocalSavedStateRegistryOwner$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$LocalSavedStateRegistryOwner$1;-><init>()V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$LocalView$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$LocalView$1;-><init>()V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$1$1;-><init>(Landroidx/compose/runtime/MutableState;)V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$2$invoke$$inlined$onDispose$1;-><init>(Landroidx/compose/ui/platform/DisposableSaveableStateRegistry;)V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$2;-><init>(Landroidx/compose/ui/platform/DisposableSaveableStateRegistry;)V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$2;->invoke(Landroidx/compose/runtime/DisposableEffectScope;)Landroidx/compose/runtime/DisposableEffectResult;
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3;-><init>(Landroidx/compose/ui/platform/AndroidComposeView;Landroidx/compose/ui/platform/AndroidUriHandler;Lkotlin/jvm/functions/Function2;I)V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$4;-><init>(Landroidx/compose/ui/platform/AndroidComposeView;Lkotlin/jvm/functions/Function2;I)V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$4;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$4;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$obtainImageVectorCache$1$invoke$$inlined$onDispose$1;-><init>(Landroid/content/Context;Landroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$obtainImageVectorCache$callbacks$1$1;)V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$obtainImageVectorCache$1;-><init>(Landroid/content/Context;Landroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$obtainImageVectorCache$callbacks$1$1;)V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$obtainImageVectorCache$1;->invoke(Landroidx/compose/runtime/DisposableEffectScope;)Landroidx/compose/runtime/DisposableEffectResult;
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$obtainImageVectorCache$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$obtainImageVectorCache$callbacks$1$1;-><init>(Landroid/content/res/Configuration;Landroidx/compose/ui/res/ImageVectorCache;)V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt;->ProvideAndroidCompositionLocals$lambda$1(Landroidx/compose/runtime/MutableState;)Landroid/content/res/Configuration;
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt;->ProvideAndroidCompositionLocals(Landroidx/compose/ui/platform/AndroidComposeView;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt;->getLocalConfiguration()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt;->getLocalContext()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt;->getLocalView()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt;->obtainImageVectorCache(Landroid/content/Context;Landroid/content/res/Configuration;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/res/ImageVectorCache;
+HSPLandroidx/compose/ui/platform/AndroidFontResourceLoader;-><init>(Landroid/content/Context;)V
+HSPLandroidx/compose/ui/platform/AndroidTextToolbar$textActionModeCallback$1;-><init>(Landroidx/compose/ui/platform/AndroidTextToolbar;)V
+HSPLandroidx/compose/ui/platform/AndroidTextToolbar;-><init>(Landroid/view/View;)V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher$Companion$Main$2;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher$Companion$Main$2;-><init>()V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher$Companion$Main$2;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher$Companion$Main$2;->invoke()Lkotlin/coroutines/CoroutineContext;
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher$Companion$currentThread$1;-><init>()V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher$Companion;-><init>()V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher$Companion;->getCurrentThread()Lkotlin/coroutines/CoroutineContext;
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher$Companion;->getMain()Lkotlin/coroutines/CoroutineContext;
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher$dispatchCallback$1;-><init>(Landroidx/compose/ui/platform/AndroidUiDispatcher;)V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher$dispatchCallback$1;->doFrame(J)V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher$dispatchCallback$1;->run()V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher;-><init>(Landroid/view/Choreographer;Landroid/os/Handler;)V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher;-><init>(Landroid/view/Choreographer;Landroid/os/Handler;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher;->access$getHandler$p(Landroidx/compose/ui/platform/AndroidUiDispatcher;)Landroid/os/Handler;
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher;->access$getLock$p(Landroidx/compose/ui/platform/AndroidUiDispatcher;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher;->access$getMain$delegate$cp()Lkotlin/Lazy;
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher;->access$getToRunOnFrame$p(Landroidx/compose/ui/platform/AndroidUiDispatcher;)Ljava/util/List;
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher;->access$performFrameDispatch(Landroidx/compose/ui/platform/AndroidUiDispatcher;J)V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher;->access$performTrampolineDispatch(Landroidx/compose/ui/platform/AndroidUiDispatcher;)V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher;->access$setScheduledFrameDispatch$p(Landroidx/compose/ui/platform/AndroidUiDispatcher;Z)V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher;->dispatch(Lkotlin/coroutines/CoroutineContext;Ljava/lang/Runnable;)V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher;->getChoreographer()Landroid/view/Choreographer;
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher;->getFrameClock()Landroidx/compose/runtime/MonotonicFrameClock;
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher;->nextTask()Ljava/lang/Runnable;
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher;->performFrameDispatch(J)V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher;->performTrampolineDispatch()V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher;->postFrameCallback$ui_release(Landroid/view/Choreographer$FrameCallback;)V
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher_androidKt;->access$isMainThread()Z
+HSPLandroidx/compose/ui/platform/AndroidUiDispatcher_androidKt;->isMainThread()Z
+HSPLandroidx/compose/ui/platform/AndroidUiFrameClock$withFrameNanos$2$1;-><init>(Landroidx/compose/ui/platform/AndroidUiDispatcher;Landroid/view/Choreographer$FrameCallback;)V
+HSPLandroidx/compose/ui/platform/AndroidUiFrameClock$withFrameNanos$2$callback$1;-><init>(Lkotlinx/coroutines/CancellableContinuation;Landroidx/compose/ui/platform/AndroidUiFrameClock;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/platform/AndroidUiFrameClock$withFrameNanos$2$callback$1;->doFrame(J)V
+HSPLandroidx/compose/ui/platform/AndroidUiFrameClock;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidUiFrameClock;-><init>(Landroid/view/Choreographer;)V
+HSPLandroidx/compose/ui/platform/AndroidUiFrameClock;->fold(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/AndroidUiFrameClock;->get(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
+HSPLandroidx/compose/ui/platform/AndroidUiFrameClock;->getChoreographer()Landroid/view/Choreographer;
+HSPLandroidx/compose/ui/platform/AndroidUiFrameClock;->minusKey(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
+HSPLandroidx/compose/ui/platform/AndroidUiFrameClock;->withFrameNanos(Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/AndroidUriHandler;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidUriHandler;-><init>(Landroid/content/Context;)V
+HSPLandroidx/compose/ui/platform/AndroidViewConfiguration;-><clinit>()V
+HSPLandroidx/compose/ui/platform/AndroidViewConfiguration;-><init>(Landroid/view/ViewConfiguration;)V
+HSPLandroidx/compose/ui/platform/CalculateMatrixToWindowApi29;-><init>()V
+HSPLandroidx/compose/ui/platform/ComposableSingletons$Wrapper_androidKt$lambda-1$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/ComposableSingletons$Wrapper_androidKt$lambda-1$1;-><init>()V
+HSPLandroidx/compose/ui/platform/ComposableSingletons$Wrapper_androidKt;-><clinit>()V
+HSPLandroidx/compose/ui/platform/ComposableSingletons$Wrapper_androidKt;-><init>()V
+HSPLandroidx/compose/ui/platform/ComposableSingletons$Wrapper_androidKt;->getLambda-1$ui_release()Lkotlin/jvm/functions/Function2;
+HSPLandroidx/compose/ui/platform/ComposeView$Content$1;-><init>(Landroidx/compose/ui/platform/ComposeView;I)V
+HSPLandroidx/compose/ui/platform/ComposeView;-><clinit>()V
+HSPLandroidx/compose/ui/platform/ComposeView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
+HSPLandroidx/compose/ui/platform/ComposeView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;IILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/platform/ComposeView;->Content(Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/ui/platform/ComposeView;->getShouldCreateCompositionOnAttachedToWindow()Z
+HSPLandroidx/compose/ui/platform/ComposeView;->setContent(Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalAccessibilityManager$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalAccessibilityManager$1;-><init>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalAutofill$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalAutofill$1;-><init>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalAutofillTree$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalAutofillTree$1;-><init>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalClipboardManager$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalClipboardManager$1;-><init>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalDensity$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalDensity$1;-><init>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalFocusManager$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalFocusManager$1;-><init>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalFontFamilyResolver$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalFontFamilyResolver$1;-><init>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalFontLoader$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalFontLoader$1;-><init>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalHapticFeedback$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalHapticFeedback$1;-><init>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalInputModeManager$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalInputModeManager$1;-><init>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalLayoutDirection$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalLayoutDirection$1;-><init>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalPointerIconService$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalPointerIconService$1;-><init>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalTextInputService$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalTextInputService$1;-><init>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalTextToolbar$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalTextToolbar$1;-><init>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalUriHandler$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalUriHandler$1;-><init>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalViewConfiguration$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalViewConfiguration$1;-><init>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalWindowInfo$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$LocalWindowInfo$1;-><init>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt$ProvideCommonCompositionLocals$1;-><init>(Landroidx/compose/ui/node/Owner;Landroidx/compose/ui/platform/UriHandler;Lkotlin/jvm/functions/Function2;I)V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt;-><clinit>()V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt;->ProvideCommonCompositionLocals(Landroidx/compose/ui/node/Owner;Landroidx/compose/ui/platform/UriHandler;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt;->getLocalDensity()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt;->getLocalFontFamilyResolver()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt;->getLocalInputModeManager()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt;->getLocalLayoutDirection()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/ui/platform/CompositionLocalsKt;->getLocalViewConfiguration()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLandroidx/compose/ui/platform/DisposableSaveableStateRegistry;-><init>(Landroidx/compose/runtime/saveable/SaveableStateRegistry;Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/ui/platform/DisposableSaveableStateRegistry;->canBeSaved(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/platform/DisposableSaveableStateRegistry;->consumeRestored(Ljava/lang/String;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/DisposableSaveableStateRegistry;->registerProvider(Ljava/lang/String;Lkotlin/jvm/functions/Function0;)Landroidx/compose/runtime/saveable/SaveableStateRegistry$Entry;
+HSPLandroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt$DisposableSaveableStateRegistry$1;-><init>(ZLandroidx/savedstate/SavedStateRegistry;Ljava/lang/String;)V
+HSPLandroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt$DisposableSaveableStateRegistry$registered$1;-><init>(Landroidx/compose/runtime/saveable/SaveableStateRegistry;)V
+HSPLandroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt$DisposableSaveableStateRegistry$saveableStateRegistry$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt$DisposableSaveableStateRegistry$saveableStateRegistry$1;-><init>()V
+HSPLandroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt$DisposableSaveableStateRegistry$saveableStateRegistry$1;->invoke(Ljava/lang/Object;)Ljava/lang/Boolean;
+HSPLandroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt$DisposableSaveableStateRegistry$saveableStateRegistry$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt;-><clinit>()V
+HSPLandroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt;->DisposableSaveableStateRegistry(Landroid/view/View;Landroidx/savedstate/SavedStateRegistryOwner;)Landroidx/compose/ui/platform/DisposableSaveableStateRegistry;
+HSPLandroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt;->DisposableSaveableStateRegistry(Ljava/lang/String;Landroidx/savedstate/SavedStateRegistryOwner;)Landroidx/compose/ui/platform/DisposableSaveableStateRegistry;
+HSPLandroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt;->access$canBeSavedToBundle(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt;->canBeSavedToBundle(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/platform/GlobalSnapshotManager$ensureStarted$1;-><init>(Lkotlinx/coroutines/channels/Channel;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/ui/platform/GlobalSnapshotManager$ensureStarted$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/ui/platform/GlobalSnapshotManager$ensureStarted$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/GlobalSnapshotManager$ensureStarted$2;-><init>(Lkotlinx/coroutines/channels/Channel;)V
+HSPLandroidx/compose/ui/platform/GlobalSnapshotManager$ensureStarted$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/GlobalSnapshotManager$ensureStarted$2;->invoke(Ljava/lang/Object;)V
+HSPLandroidx/compose/ui/platform/GlobalSnapshotManager;-><clinit>()V
+HSPLandroidx/compose/ui/platform/GlobalSnapshotManager;-><init>()V
+HSPLandroidx/compose/ui/platform/GlobalSnapshotManager;->ensureStarted()V
+HSPLandroidx/compose/ui/platform/InspectableModifier$End;-><init>(Landroidx/compose/ui/platform/InspectableModifier;)V
+HSPLandroidx/compose/ui/platform/InspectableModifier;-><clinit>()V
+HSPLandroidx/compose/ui/platform/InspectableModifier;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/platform/InspectableModifier;->getEnd()Landroidx/compose/ui/platform/InspectableModifier$End;
+HSPLandroidx/compose/ui/platform/InspectableValueKt$NoInspectorInfo$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/InspectableValueKt$NoInspectorInfo$1;-><init>()V
+HSPLandroidx/compose/ui/platform/InspectableValueKt;-><clinit>()V
+HSPLandroidx/compose/ui/platform/InspectableValueKt;->getNoInspectorInfo()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/ui/platform/InspectableValueKt;->inspectableWrapper(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/platform/InspectableValueKt;->isDebugInspectorInfoEnabled()Z
+HSPLandroidx/compose/ui/platform/InspectorValueInfo;-><clinit>()V
+HSPLandroidx/compose/ui/platform/InspectorValueInfo;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/platform/LayerMatrixCache;-><init>(Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/ui/platform/LayerMatrixCache;->invalidate()V
+HSPLandroidx/compose/ui/platform/MotionDurationScaleImpl;-><init>()V
+HSPLandroidx/compose/ui/platform/MotionDurationScaleImpl;->fold(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/MotionDurationScaleImpl;->get(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
+HSPLandroidx/compose/ui/platform/MotionDurationScaleImpl;->getScaleFactor()F
+HSPLandroidx/compose/ui/platform/MotionDurationScaleImpl;->minusKey(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
+HSPLandroidx/compose/ui/platform/MotionDurationScaleImpl;->setScaleFactor(F)V
+HSPLandroidx/compose/ui/platform/OutlineResolver;-><init>(Landroidx/compose/ui/unit/Density;)V
+HSPLandroidx/compose/ui/platform/OutlineResolver;->getOutline()Landroid/graphics/Outline;
+HSPLandroidx/compose/ui/platform/OutlineResolver;->getOutlineClipSupported()Z
+HSPLandroidx/compose/ui/platform/OutlineResolver;->update(Landroidx/compose/ui/graphics/Shape;FZFLandroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/ui/unit/Density;)Z
+HSPLandroidx/compose/ui/platform/OutlineResolver;->update-uvyYCjk(J)V
+HSPLandroidx/compose/ui/platform/OutlineResolver;->updateCache()V
+HSPLandroidx/compose/ui/platform/OutlineResolver;->updateCacheWithPath(Landroidx/compose/ui/graphics/Path;)V
+HSPLandroidx/compose/ui/platform/OutlineResolver;->updateCacheWithRoundRect(Landroidx/compose/ui/geometry/RoundRect;)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;-><init>(Landroidx/compose/ui/platform/AndroidComposeView;)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->drawInto(Landroid/graphics/Canvas;)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->getAlpha()F
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->getClipToOutline()Z
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->getElevation()F
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->getHasDisplayList()Z
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->getHeight()I
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->getLeft()I
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->getTop()I
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->getWidth()I
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->offsetLeftAndRight(I)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->offsetTopAndBottom(I)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->record(Landroidx/compose/ui/graphics/CanvasHolder;Landroidx/compose/ui/graphics/Path;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setAlpha(F)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setAmbientShadowColor(I)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setCameraDistance(F)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setClipToBounds(Z)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setClipToOutline(Z)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setCompositingStrategy-aDBOjCE(I)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setElevation(F)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setHasOverlappingRendering(Z)Z
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setOutline(Landroid/graphics/Outline;)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setPivotX(F)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setPivotY(F)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setPosition(IIII)Z
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setRenderEffect(Landroidx/compose/ui/graphics/RenderEffect;)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setRotationX(F)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setRotationY(F)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setRotationZ(F)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setScaleX(F)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setScaleY(F)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setSpotShadowColor(I)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setTranslationX(F)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29;->setTranslationY(F)V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29VerificationHelper;-><clinit>()V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29VerificationHelper;-><init>()V
+HSPLandroidx/compose/ui/platform/RenderNodeApi29VerificationHelper;->setRenderEffect(Landroid/graphics/RenderNode;Landroidx/compose/ui/graphics/RenderEffect;)V
+HSPLandroidx/compose/ui/platform/RenderNodeLayer$Companion$getMatrix$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/RenderNodeLayer$Companion$getMatrix$1;-><init>()V
+HSPLandroidx/compose/ui/platform/RenderNodeLayer$Companion;-><init>()V
+HSPLandroidx/compose/ui/platform/RenderNodeLayer$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/platform/RenderNodeLayer;-><clinit>()V
+HSPLandroidx/compose/ui/platform/RenderNodeLayer;-><init>(Landroidx/compose/ui/platform/AndroidComposeView;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/ui/platform/RenderNodeLayer;->drawLayer(Landroidx/compose/ui/graphics/Canvas;)V
+HSPLandroidx/compose/ui/platform/RenderNodeLayer;->invalidate()V
+HSPLandroidx/compose/ui/platform/RenderNodeLayer;->move--gyyYBs(J)V
+HSPLandroidx/compose/ui/platform/RenderNodeLayer;->resize-ozmzZPI(J)V
+HSPLandroidx/compose/ui/platform/RenderNodeLayer;->setDirty(Z)V
+HSPLandroidx/compose/ui/platform/RenderNodeLayer;->triggerRepaint()V
+HSPLandroidx/compose/ui/platform/RenderNodeLayer;->updateDisplayList()V
+HSPLandroidx/compose/ui/platform/RenderNodeLayer;->updateLayerProperties-dDxr-wY(FFFFFFFFFFJLandroidx/compose/ui/graphics/Shape;ZLandroidx/compose/ui/graphics/RenderEffect;JJILandroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/ui/unit/Density;)V
+HSPLandroidx/compose/ui/platform/TextToolbarStatus;->$values()[Landroidx/compose/ui/platform/TextToolbarStatus;
+HSPLandroidx/compose/ui/platform/TextToolbarStatus;-><clinit>()V
+HSPLandroidx/compose/ui/platform/TextToolbarStatus;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/ui/platform/ViewCompositionStrategy$Companion;-><clinit>()V
+HSPLandroidx/compose/ui/platform/ViewCompositionStrategy$Companion;-><init>()V
+HSPLandroidx/compose/ui/platform/ViewCompositionStrategy$Companion;->getDefault()Landroidx/compose/ui/platform/ViewCompositionStrategy;
+HSPLandroidx/compose/ui/platform/ViewCompositionStrategy$DisposeOnDetachedFromWindowOrReleasedFromPool$installFor$1;-><init>(Landroidx/compose/ui/platform/AbstractComposeView;Landroidx/compose/ui/platform/ViewCompositionStrategy$DisposeOnDetachedFromWindowOrReleasedFromPool$installFor$listener$1;Landroidx/customview/poolingcontainer/PoolingContainerListener;)V
+HSPLandroidx/compose/ui/platform/ViewCompositionStrategy$DisposeOnDetachedFromWindowOrReleasedFromPool$installFor$listener$1;-><init>(Landroidx/compose/ui/platform/AbstractComposeView;)V
+HSPLandroidx/compose/ui/platform/ViewCompositionStrategy$DisposeOnDetachedFromWindowOrReleasedFromPool$installFor$listener$1;->onViewAttachedToWindow(Landroid/view/View;)V
+HSPLandroidx/compose/ui/platform/ViewCompositionStrategy$DisposeOnDetachedFromWindowOrReleasedFromPool$installFor$poolingContainerListener$1;-><init>(Landroidx/compose/ui/platform/AbstractComposeView;)V
+HSPLandroidx/compose/ui/platform/ViewCompositionStrategy$DisposeOnDetachedFromWindowOrReleasedFromPool;-><clinit>()V
+HSPLandroidx/compose/ui/platform/ViewCompositionStrategy$DisposeOnDetachedFromWindowOrReleasedFromPool;-><init>()V
+HSPLandroidx/compose/ui/platform/ViewCompositionStrategy$DisposeOnDetachedFromWindowOrReleasedFromPool;->installFor(Landroidx/compose/ui/platform/AbstractComposeView;)Lkotlin/jvm/functions/Function0;
+HSPLandroidx/compose/ui/platform/ViewCompositionStrategy;-><clinit>()V
+HSPLandroidx/compose/ui/platform/ViewConfiguration;->getMinimumTouchTargetSize-MYxV2XQ()J
+HSPLandroidx/compose/ui/platform/ViewLayer$Companion$OutlineProvider$1;-><init>()V
+HSPLandroidx/compose/ui/platform/ViewLayer$Companion$getMatrix$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/ViewLayer$Companion$getMatrix$1;-><init>()V
+HSPLandroidx/compose/ui/platform/ViewLayer$Companion;-><init>()V
+HSPLandroidx/compose/ui/platform/ViewLayer$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/platform/ViewLayer$Companion;->getShouldUseDispatchDraw()Z
+HSPLandroidx/compose/ui/platform/ViewLayer;-><clinit>()V
+HSPLandroidx/compose/ui/platform/ViewLayer;->access$getShouldUseDispatchDraw$cp()Z
+HSPLandroidx/compose/ui/platform/ViewRootForTest$Companion;-><clinit>()V
+HSPLandroidx/compose/ui/platform/ViewRootForTest$Companion;-><init>()V
+HSPLandroidx/compose/ui/platform/ViewRootForTest$Companion;->getOnViewCreatedCallback()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/ui/platform/ViewRootForTest;-><clinit>()V
+HSPLandroidx/compose/ui/platform/WeakCache;-><init>()V
+HSPLandroidx/compose/ui/platform/WeakCache;->clearWeakReferences()V
+HSPLandroidx/compose/ui/platform/WeakCache;->pop()Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/WindowInfoImpl$Companion;-><init>()V
+HSPLandroidx/compose/ui/platform/WindowInfoImpl$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/platform/WindowInfoImpl;-><clinit>()V
+HSPLandroidx/compose/ui/platform/WindowInfoImpl;-><init>()V
+HSPLandroidx/compose/ui/platform/WindowInfoImpl;->setWindowFocused(Z)V
+HSPLandroidx/compose/ui/platform/WindowRecomposerFactory$Companion$LifecycleAware$1;-><clinit>()V
+HSPLandroidx/compose/ui/platform/WindowRecomposerFactory$Companion$LifecycleAware$1;-><init>()V
+HSPLandroidx/compose/ui/platform/WindowRecomposerFactory$Companion$LifecycleAware$1;->createRecomposer(Landroid/view/View;)Landroidx/compose/runtime/Recomposer;
+HSPLandroidx/compose/ui/platform/WindowRecomposerFactory$Companion;-><clinit>()V
+HSPLandroidx/compose/ui/platform/WindowRecomposerFactory$Companion;-><init>()V
+HSPLandroidx/compose/ui/platform/WindowRecomposerFactory$Companion;->getLifecycleAware()Landroidx/compose/ui/platform/WindowRecomposerFactory;
+HSPLandroidx/compose/ui/platform/WindowRecomposerFactory;-><clinit>()V
+HSPLandroidx/compose/ui/platform/WindowRecomposerPolicy$createAndInstallWindowRecomposer$1;-><init>(Lkotlinx/coroutines/Job;)V
+HSPLandroidx/compose/ui/platform/WindowRecomposerPolicy$createAndInstallWindowRecomposer$1;->onViewAttachedToWindow(Landroid/view/View;)V
+HSPLandroidx/compose/ui/platform/WindowRecomposerPolicy$createAndInstallWindowRecomposer$unsetJob$1;-><init>(Landroidx/compose/runtime/Recomposer;Landroid/view/View;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/ui/platform/WindowRecomposerPolicy$createAndInstallWindowRecomposer$unsetJob$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/ui/platform/WindowRecomposerPolicy$createAndInstallWindowRecomposer$unsetJob$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/WindowRecomposerPolicy;-><clinit>()V
+HSPLandroidx/compose/ui/platform/WindowRecomposerPolicy;-><init>()V
+HSPLandroidx/compose/ui/platform/WindowRecomposerPolicy;->createAndInstallWindowRecomposer$ui_release(Landroid/view/View;)Landroidx/compose/runtime/Recomposer;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$1;-><init>(Landroid/view/View;Landroidx/compose/runtime/Recomposer;)V
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$1;->onViewAttachedToWindow(Landroid/view/View;)V
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2$WhenMappings;-><clinit>()V
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2$onStateChanged$1$1$1$1;-><init>(Landroidx/compose/ui/platform/MotionDurationScaleImpl;)V
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2$onStateChanged$1$1$1$1;->emit(FLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2$onStateChanged$1$1$1$1;->emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2$onStateChanged$1$1$1;-><init>(Lkotlinx/coroutines/flow/StateFlow;Landroidx/compose/ui/platform/MotionDurationScaleImpl;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2$onStateChanged$1$1$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2$onStateChanged$1$1$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2$onStateChanged$1;-><init>(Lkotlin/jvm/internal/Ref$ObjectRef;Landroidx/compose/runtime/Recomposer;Landroidx/lifecycle/LifecycleOwner;Landroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2;Landroid/view/View;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2$onStateChanged$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2$onStateChanged$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2$onStateChanged$1;->invoke(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2$onStateChanged$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2;-><init>(Lkotlinx/coroutines/CoroutineScope;Landroidx/compose/runtime/PausableMonotonicFrameClock;Landroidx/compose/runtime/Recomposer;Lkotlin/jvm/internal/Ref$ObjectRef;Landroid/view/View;)V
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$getAnimationScaleFlowFor$1$1$1;-><init>(Landroid/content/ContentResolver;Landroid/net/Uri;Landroidx/compose/ui/platform/WindowRecomposer_androidKt$getAnimationScaleFlowFor$1$1$contentObserver$1;Lkotlinx/coroutines/channels/Channel;Landroid/content/Context;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$getAnimationScaleFlowFor$1$1$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$getAnimationScaleFlowFor$1$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$getAnimationScaleFlowFor$1$1$1;->invoke(Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$getAnimationScaleFlowFor$1$1$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt$getAnimationScaleFlowFor$1$1$contentObserver$1;-><init>(Lkotlinx/coroutines/channels/Channel;Landroid/os/Handler;)V
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt;-><clinit>()V
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt;->access$getAnimationScaleFlowFor(Landroid/content/Context;)Lkotlinx/coroutines/flow/StateFlow;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt;->createLifecycleAwareWindowRecomposer$default(Landroid/view/View;Lkotlin/coroutines/CoroutineContext;Landroidx/lifecycle/Lifecycle;ILjava/lang/Object;)Landroidx/compose/runtime/Recomposer;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt;->createLifecycleAwareWindowRecomposer(Landroid/view/View;Lkotlin/coroutines/CoroutineContext;Landroidx/lifecycle/Lifecycle;)Landroidx/compose/runtime/Recomposer;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt;->findViewTreeCompositionContext(Landroid/view/View;)Landroidx/compose/runtime/CompositionContext;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt;->getAnimationScaleFlowFor(Landroid/content/Context;)Lkotlinx/coroutines/flow/StateFlow;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt;->getCompositionContext(Landroid/view/View;)Landroidx/compose/runtime/CompositionContext;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt;->getContentChild(Landroid/view/View;)Landroid/view/View;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt;->getWindowRecomposer(Landroid/view/View;)Landroidx/compose/runtime/Recomposer;
+HSPLandroidx/compose/ui/platform/WindowRecomposer_androidKt;->setCompositionContext(Landroid/view/View;Landroidx/compose/runtime/CompositionContext;)V
+HSPLandroidx/compose/ui/platform/WrappedComposition$setContent$1$1$1;-><init>(Landroidx/compose/ui/platform/WrappedComposition;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/ui/platform/WrappedComposition$setContent$1$1$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/ui/platform/WrappedComposition$setContent$1$1$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/WrappedComposition$setContent$1$1$2;-><init>(Landroidx/compose/ui/platform/WrappedComposition;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/ui/platform/WrappedComposition$setContent$1$1$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLandroidx/compose/ui/platform/WrappedComposition$setContent$1$1$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/WrappedComposition$setContent$1$1$3;-><init>(Landroidx/compose/ui/platform/WrappedComposition;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/ui/platform/WrappedComposition$setContent$1$1$3;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/ui/platform/WrappedComposition$setContent$1$1$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/WrappedComposition$setContent$1$1;-><init>(Landroidx/compose/ui/platform/WrappedComposition;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/ui/platform/WrappedComposition$setContent$1$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLandroidx/compose/ui/platform/WrappedComposition$setContent$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/WrappedComposition$setContent$1;-><init>(Landroidx/compose/ui/platform/WrappedComposition;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/ui/platform/WrappedComposition$setContent$1;->invoke(Landroidx/compose/ui/platform/AndroidComposeView$ViewTreeOwners;)V
+HSPLandroidx/compose/ui/platform/WrappedComposition$setContent$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/platform/WrappedComposition;-><init>(Landroidx/compose/ui/platform/AndroidComposeView;Landroidx/compose/runtime/Composition;)V
+HSPLandroidx/compose/ui/platform/WrappedComposition;->access$getAddedToLifecycle$p(Landroidx/compose/ui/platform/WrappedComposition;)Landroidx/lifecycle/Lifecycle;
+HSPLandroidx/compose/ui/platform/WrappedComposition;->access$getDisposed$p(Landroidx/compose/ui/platform/WrappedComposition;)Z
+HSPLandroidx/compose/ui/platform/WrappedComposition;->access$setAddedToLifecycle$p(Landroidx/compose/ui/platform/WrappedComposition;Landroidx/lifecycle/Lifecycle;)V
+HSPLandroidx/compose/ui/platform/WrappedComposition;->access$setLastContent$p(Landroidx/compose/ui/platform/WrappedComposition;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/ui/platform/WrappedComposition;->getOriginal()Landroidx/compose/runtime/Composition;
+HSPLandroidx/compose/ui/platform/WrappedComposition;->getOwner()Landroidx/compose/ui/platform/AndroidComposeView;
+HSPLandroidx/compose/ui/platform/WrappedComposition;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
+HSPLandroidx/compose/ui/platform/WrappedComposition;->setContent(Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/ui/platform/WrapperRenderNodeLayerHelperMethods;-><clinit>()V
+HSPLandroidx/compose/ui/platform/WrapperRenderNodeLayerHelperMethods;-><init>()V
+HSPLandroidx/compose/ui/platform/WrapperRenderNodeLayerHelperMethods;->onDescendantInvalidated(Landroidx/compose/ui/platform/AndroidComposeView;)V
+HSPLandroidx/compose/ui/platform/WrapperVerificationHelperMethods;-><clinit>()V
+HSPLandroidx/compose/ui/platform/WrapperVerificationHelperMethods;-><init>()V
+HSPLandroidx/compose/ui/platform/WrapperVerificationHelperMethods;->attributeSourceResourceMap(Landroid/view/View;)Ljava/util/Map;
+HSPLandroidx/compose/ui/platform/Wrapper_androidKt;-><clinit>()V
+HSPLandroidx/compose/ui/platform/Wrapper_androidKt;->createSubcomposition(Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/runtime/CompositionContext;)Landroidx/compose/runtime/Composition;
+HSPLandroidx/compose/ui/platform/Wrapper_androidKt;->doSetContent(Landroidx/compose/ui/platform/AndroidComposeView;Landroidx/compose/runtime/CompositionContext;Lkotlin/jvm/functions/Function2;)Landroidx/compose/runtime/Composition;
+HSPLandroidx/compose/ui/platform/Wrapper_androidKt;->inspectionWanted(Landroidx/compose/ui/platform/AndroidComposeView;)Z
+HSPLandroidx/compose/ui/platform/Wrapper_androidKt;->setContent(Landroidx/compose/ui/platform/AbstractComposeView;Landroidx/compose/runtime/CompositionContext;Lkotlin/jvm/functions/Function2;)Landroidx/compose/runtime/Composition;
+HSPLandroidx/compose/ui/platform/actionmodecallback/TextActionModeCallback;-><init>(Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/geometry/Rect;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/ui/platform/actionmodecallback/TextActionModeCallback;-><init>(Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/geometry/Rect;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/res/ImageVectorCache;-><init>()V
+HSPLandroidx/compose/ui/res/Resources_androidKt;->resources(Landroidx/compose/runtime/Composer;I)Landroid/content/res/Resources;
+HSPLandroidx/compose/ui/res/StringResources_androidKt;->stringResource(ILandroidx/compose/runtime/Composer;I)Ljava/lang/String;
+HSPLandroidx/compose/ui/res/StringResources_androidKt;->stringResource(I[Ljava/lang/Object;Landroidx/compose/runtime/Composer;I)Ljava/lang/String;
+HSPLandroidx/compose/ui/semantics/AccessibilityAction;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/AccessibilityAction;-><init>(Ljava/lang/String;Lkotlin/Function;)V
+HSPLandroidx/compose/ui/semantics/AccessibilityAction;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/semantics/Role$Companion;-><init>()V
+HSPLandroidx/compose/ui/semantics/Role$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/semantics/Role$Companion;->getButton-o7Vup1c()I
+HSPLandroidx/compose/ui/semantics/Role;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/Role;-><init>(I)V
+HSPLandroidx/compose/ui/semantics/Role;->access$getButton$cp()I
+HSPLandroidx/compose/ui/semantics/Role;->box-impl(I)Landroidx/compose/ui/semantics/Role;
+HSPLandroidx/compose/ui/semantics/Role;->constructor-impl(I)I
+HSPLandroidx/compose/ui/semantics/Role;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/semantics/Role;->equals-impl(ILjava/lang/Object;)Z
+HSPLandroidx/compose/ui/semantics/Role;->unbox-impl()I
+HSPLandroidx/compose/ui/semantics/SemanticsActions;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsActions;-><init>()V
+HSPLandroidx/compose/ui/semantics/SemanticsActions;->getCustomActions()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsActions;->getDismiss()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsActions;->getGetTextLayoutResult()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsActions;->getOnClick()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsActions;->getRequestFocus()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsConfiguration;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsConfiguration;-><init>()V
+HSPLandroidx/compose/ui/semantics/SemanticsConfiguration;->contains(Landroidx/compose/ui/semantics/SemanticsPropertyKey;)Z
+HSPLandroidx/compose/ui/semantics/SemanticsConfiguration;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/semantics/SemanticsConfiguration;->getOrElseNullable(Landroidx/compose/ui/semantics/SemanticsPropertyKey;Lkotlin/jvm/functions/Function0;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/semantics/SemanticsConfiguration;->isClearingSemantics()Z
+HSPLandroidx/compose/ui/semantics/SemanticsConfiguration;->set(Landroidx/compose/ui/semantics/SemanticsPropertyKey;Ljava/lang/Object;)V
+HSPLandroidx/compose/ui/semantics/SemanticsConfiguration;->setClearingSemantics(Z)V
+HSPLandroidx/compose/ui/semantics/SemanticsConfiguration;->setMergingSemanticsOfDescendants(Z)V
+HSPLandroidx/compose/ui/semantics/SemanticsConfigurationKt$getOrNull$1;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsConfigurationKt$getOrNull$1;-><init>()V
+HSPLandroidx/compose/ui/semantics/SemanticsConfigurationKt$getOrNull$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/semantics/SemanticsConfigurationKt;->getOrNull(Landroidx/compose/ui/semantics/SemanticsConfiguration;Landroidx/compose/ui/semantics/SemanticsPropertyKey;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/semantics/SemanticsModifierCore$Companion;-><init>()V
+HSPLandroidx/compose/ui/semantics/SemanticsModifierCore$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/semantics/SemanticsModifierCore$Companion;->generateSemanticsId()I
+HSPLandroidx/compose/ui/semantics/SemanticsModifierCore;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsModifierCore;-><init>(ZZLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/semantics/SemanticsModifierCore;-><init>(ZZLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/semantics/SemanticsModifierCore;->access$getLastIdentifier$cp()Ljava/util/concurrent/atomic/AtomicInteger;
+HSPLandroidx/compose/ui/semantics/SemanticsModifierCore;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/semantics/SemanticsModifierCore;->getSemanticsConfiguration()Landroidx/compose/ui/semantics/SemanticsConfiguration;
+HSPLandroidx/compose/ui/semantics/SemanticsModifierKt;->semantics$default(Landroidx/compose/ui/Modifier;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/semantics/SemanticsModifierKt;->semantics(Landroidx/compose/ui/Modifier;ZLkotlin/jvm/functions/Function1;)Landroidx/compose/ui/Modifier;
+HSPLandroidx/compose/ui/semantics/SemanticsNode;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsNode;-><init>(Landroidx/compose/ui/node/SemanticsModifierNode;ZLandroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/semantics/SemanticsNode;-><init>(Landroidx/compose/ui/node/SemanticsModifierNode;ZLandroidx/compose/ui/node/LayoutNode;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/semantics/SemanticsNode;->emitFakeNodes(Ljava/util/List;)V
+HSPLandroidx/compose/ui/semantics/SemanticsNode;->getChildren(ZZZ)Ljava/util/List;
+HSPLandroidx/compose/ui/semantics/SemanticsNode;->getReplacedChildren$ui_release()Ljava/util/List;
+HSPLandroidx/compose/ui/semantics/SemanticsNode;->getUnmergedConfig$ui_release()Landroidx/compose/ui/semantics/SemanticsConfiguration;
+HSPLandroidx/compose/ui/semantics/SemanticsNode;->isMergingSemanticsOfDescendants()Z
+HSPLandroidx/compose/ui/semantics/SemanticsNode;->unmergedChildren$ui_release(ZZ)Ljava/util/List;
+HSPLandroidx/compose/ui/semantics/SemanticsNodeKt;->access$getRole(Landroidx/compose/ui/semantics/SemanticsNode;)Landroidx/compose/ui/semantics/Role;
+HSPLandroidx/compose/ui/semantics/SemanticsNodeKt;->findOneLayerOfSemanticsWrappers$default(Landroidx/compose/ui/node/LayoutNode;Ljava/util/List;ILjava/lang/Object;)Ljava/util/List;
+HSPLandroidx/compose/ui/semantics/SemanticsNodeKt;->findOneLayerOfSemanticsWrappers(Landroidx/compose/ui/node/LayoutNode;Ljava/util/List;)Ljava/util/List;
+HSPLandroidx/compose/ui/semantics/SemanticsNodeKt;->getOuterSemantics(Landroidx/compose/ui/node/LayoutNode;)Landroidx/compose/ui/node/SemanticsModifierNode;
+HSPLandroidx/compose/ui/semantics/SemanticsNodeKt;->getRole(Landroidx/compose/ui/semantics/SemanticsNode;)Landroidx/compose/ui/semantics/Role;
+HSPLandroidx/compose/ui/semantics/SemanticsOwner;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsOwner;-><init>(Landroidx/compose/ui/node/LayoutNode;)V
+HSPLandroidx/compose/ui/semantics/SemanticsOwner;->getUnmergedRootSemanticsNode()Landroidx/compose/ui/semantics/SemanticsNode;
+HSPLandroidx/compose/ui/semantics/SemanticsProperties$ContentDescription$1;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsProperties$ContentDescription$1;-><init>()V
+HSPLandroidx/compose/ui/semantics/SemanticsProperties$InvisibleToUser$1;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsProperties$InvisibleToUser$1;-><init>()V
+HSPLandroidx/compose/ui/semantics/SemanticsProperties$IsDialog$1;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsProperties$IsDialog$1;-><init>()V
+HSPLandroidx/compose/ui/semantics/SemanticsProperties$IsPopup$1;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsProperties$IsPopup$1;-><init>()V
+HSPLandroidx/compose/ui/semantics/SemanticsProperties$PaneTitle$1;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsProperties$PaneTitle$1;-><init>()V
+HSPLandroidx/compose/ui/semantics/SemanticsProperties$Role$1;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsProperties$Role$1;-><init>()V
+HSPLandroidx/compose/ui/semantics/SemanticsProperties$TestTag$1;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsProperties$TestTag$1;-><init>()V
+HSPLandroidx/compose/ui/semantics/SemanticsProperties$Text$1;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsProperties$Text$1;-><init>()V
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;-><init>()V
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;->getCollectionInfo()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;->getCollectionItemInfo()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;->getContentDescription()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;->getEditableText()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;->getFocused()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;->getHorizontalScrollAxisRange()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;->getImeAction()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;->getLiveRegion()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;->getPaneTitle()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;->getProgressBarRangeInfo()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;->getRole()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;->getSelected()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;->getStateDescription()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;->getTestTag()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;->getText()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;->getTextSelectionRange()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;->getToggleableState()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsProperties;->getVerticalScrollAxisRange()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+HSPLandroidx/compose/ui/semantics/SemanticsPropertiesKt$ActionPropertyKey$1;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertiesKt$ActionPropertyKey$1;-><init>()V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertiesKt;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->dismiss$default(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->dismiss(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->getTextLayoutResult$default(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->getTextLayoutResult(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->onClick$default(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->onClick(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->requestFocus$default(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->requestFocus(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->setContentDescription(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Ljava/lang/String;)V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->setFocused(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Z)V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->setRole-kuIjeqM(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;I)V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->setText(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Landroidx/compose/ui/text/AnnotatedString;)V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertyKey$1;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertyKey$1;-><init>()V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertyKey;-><clinit>()V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertyKey;-><init>(Ljava/lang/String;Lkotlin/jvm/functions/Function2;)V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertyKey;-><init>(Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/semantics/SemanticsPropertyKey;->setValue(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Lkotlin/reflect/KProperty;Ljava/lang/Object;)V
+HSPLandroidx/compose/ui/text/AndroidParagraph$wordBoundary$2;-><init>(Landroidx/compose/ui/text/AndroidParagraph;)V
+HSPLandroidx/compose/ui/text/AndroidParagraph;-><init>(Landroidx/compose/ui/text/platform/AndroidParagraphIntrinsics;IZJ)V
+HSPLandroidx/compose/ui/text/AndroidParagraph;-><init>(Landroidx/compose/ui/text/platform/AndroidParagraphIntrinsics;IZJLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/AndroidParagraph;->constructTextLayout(IILandroid/text/TextUtils$TruncateAt;IIIII)Landroidx/compose/ui/text/android/TextLayout;
+HSPLandroidx/compose/ui/text/AndroidParagraph;->getDidExceedMaxLines()Z
+HSPLandroidx/compose/ui/text/AndroidParagraph;->getFirstBaseline()F
+HSPLandroidx/compose/ui/text/AndroidParagraph;->getHeight()F
+HSPLandroidx/compose/ui/text/AndroidParagraph;->getLastBaseline()F
+HSPLandroidx/compose/ui/text/AndroidParagraph;->getLineBaseline$ui_text_release(I)F
+HSPLandroidx/compose/ui/text/AndroidParagraph;->getLineCount()I
+HSPLandroidx/compose/ui/text/AndroidParagraph;->getPlaceholderRects()Ljava/util/List;
+HSPLandroidx/compose/ui/text/AndroidParagraph;->getShaderBrushSpans(Landroidx/compose/ui/text/android/TextLayout;)[Landroidx/compose/ui/text/platform/style/ShaderBrushSpan;
+HSPLandroidx/compose/ui/text/AndroidParagraph;->getTextPaint$ui_text_release()Landroidx/compose/ui/text/platform/AndroidTextPaint;
+HSPLandroidx/compose/ui/text/AndroidParagraph;->getWidth()F
+HSPLandroidx/compose/ui/text/AndroidParagraph;->paint(Landroidx/compose/ui/graphics/Canvas;)V
+HSPLandroidx/compose/ui/text/AndroidParagraph;->paint-iJQMabo(Landroidx/compose/ui/graphics/Canvas;JLandroidx/compose/ui/graphics/Shadow;Landroidx/compose/ui/text/style/TextDecoration;Landroidx/compose/ui/graphics/drawscope/DrawStyle;)V
+HSPLandroidx/compose/ui/text/AndroidParagraph_androidKt;->access$shouldAttachIndentationFixSpan(Landroidx/compose/ui/text/TextStyle;Z)Z
+HSPLandroidx/compose/ui/text/AndroidParagraph_androidKt;->access$toLayoutAlign-AMY3VfE(Landroidx/compose/ui/text/style/TextAlign;)I
+HSPLandroidx/compose/ui/text/AndroidParagraph_androidKt;->access$toLayoutBreakStrategy-u6PBz3U(Landroidx/compose/ui/text/style/LineBreak$Strategy;)I
+HSPLandroidx/compose/ui/text/AndroidParagraph_androidKt;->access$toLayoutHyphenationFrequency(Landroidx/compose/ui/text/style/Hyphens;)I
+HSPLandroidx/compose/ui/text/AndroidParagraph_androidKt;->access$toLayoutLineBreakStyle-4a2g8L8(Landroidx/compose/ui/text/style/LineBreak$Strictness;)I
+HSPLandroidx/compose/ui/text/AndroidParagraph_androidKt;->access$toLayoutLineBreakWordStyle-gvcdTPQ(Landroidx/compose/ui/text/style/LineBreak$WordBreak;)I
+HSPLandroidx/compose/ui/text/AndroidParagraph_androidKt;->shouldAttachIndentationFixSpan(Landroidx/compose/ui/text/TextStyle;Z)Z
+HSPLandroidx/compose/ui/text/AndroidParagraph_androidKt;->toLayoutAlign-AMY3VfE(Landroidx/compose/ui/text/style/TextAlign;)I
+HSPLandroidx/compose/ui/text/AndroidParagraph_androidKt;->toLayoutBreakStrategy-u6PBz3U(Landroidx/compose/ui/text/style/LineBreak$Strategy;)I
+HSPLandroidx/compose/ui/text/AndroidParagraph_androidKt;->toLayoutHyphenationFrequency(Landroidx/compose/ui/text/style/Hyphens;)I
+HSPLandroidx/compose/ui/text/AndroidParagraph_androidKt;->toLayoutLineBreakStyle-4a2g8L8(Landroidx/compose/ui/text/style/LineBreak$Strictness;)I
+HSPLandroidx/compose/ui/text/AndroidParagraph_androidKt;->toLayoutLineBreakWordStyle-gvcdTPQ(Landroidx/compose/ui/text/style/LineBreak$WordBreak;)I
+HSPLandroidx/compose/ui/text/AnnotatedString$Range;-><init>(Ljava/lang/Object;II)V
+HSPLandroidx/compose/ui/text/AnnotatedString$Range;-><init>(Ljava/lang/Object;IILjava/lang/String;)V
+HSPLandroidx/compose/ui/text/AnnotatedString$Range;->getEnd()I
+HSPLandroidx/compose/ui/text/AnnotatedString$Range;->getItem()Ljava/lang/Object;
+HSPLandroidx/compose/ui/text/AnnotatedString$Range;->getStart()I
+HSPLandroidx/compose/ui/text/AnnotatedString$special$$inlined$sortedBy$1;-><init>()V
+HSPLandroidx/compose/ui/text/AnnotatedString;-><init>(Ljava/lang/String;Ljava/util/List;Ljava/util/List;)V
+HSPLandroidx/compose/ui/text/AnnotatedString;-><init>(Ljava/lang/String;Ljava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/AnnotatedString;-><init>(Ljava/lang/String;Ljava/util/List;Ljava/util/List;Ljava/util/List;)V
+HSPLandroidx/compose/ui/text/AnnotatedString;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/text/AnnotatedString;->getParagraphStyles()Ljava/util/List;
+HSPLandroidx/compose/ui/text/AnnotatedString;->getSpanStyles()Ljava/util/List;
+HSPLandroidx/compose/ui/text/AnnotatedString;->getText()Ljava/lang/String;
+HSPLandroidx/compose/ui/text/AnnotatedStringKt;-><clinit>()V
+HSPLandroidx/compose/ui/text/AnnotatedStringKt;->access$substringWithoutParagraphStyles(Landroidx/compose/ui/text/AnnotatedString;II)Landroidx/compose/ui/text/AnnotatedString;
+HSPLandroidx/compose/ui/text/AnnotatedStringKt;->getLocalSpanStyles(Landroidx/compose/ui/text/AnnotatedString;II)Ljava/util/List;
+HSPLandroidx/compose/ui/text/AnnotatedStringKt;->normalizedParagraphStyles(Landroidx/compose/ui/text/AnnotatedString;Landroidx/compose/ui/text/ParagraphStyle;)Ljava/util/List;
+HSPLandroidx/compose/ui/text/AnnotatedStringKt;->substringWithoutParagraphStyles(Landroidx/compose/ui/text/AnnotatedString;II)Landroidx/compose/ui/text/AnnotatedString;
+HSPLandroidx/compose/ui/text/MultiParagraph;-><clinit>()V
+HSPLandroidx/compose/ui/text/MultiParagraph;-><init>(Landroidx/compose/ui/text/MultiParagraphIntrinsics;JIZ)V
+HSPLandroidx/compose/ui/text/MultiParagraph;-><init>(Landroidx/compose/ui/text/MultiParagraphIntrinsics;JIZLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/MultiParagraph;->getDidExceedMaxLines()Z
+HSPLandroidx/compose/ui/text/MultiParagraph;->getFirstBaseline()F
+HSPLandroidx/compose/ui/text/MultiParagraph;->getHeight()F
+HSPLandroidx/compose/ui/text/MultiParagraph;->getIntrinsics()Landroidx/compose/ui/text/MultiParagraphIntrinsics;
+HSPLandroidx/compose/ui/text/MultiParagraph;->getLastBaseline()F
+HSPLandroidx/compose/ui/text/MultiParagraph;->getPlaceholderRects()Ljava/util/List;
+HSPLandroidx/compose/ui/text/MultiParagraph;->getWidth()F
+HSPLandroidx/compose/ui/text/MultiParagraph;->paint-iJQMabo(Landroidx/compose/ui/graphics/Canvas;JLandroidx/compose/ui/graphics/Shadow;Landroidx/compose/ui/text/style/TextDecoration;Landroidx/compose/ui/graphics/drawscope/DrawStyle;)V
+HSPLandroidx/compose/ui/text/MultiParagraphIntrinsics$maxIntrinsicWidth$2;-><init>(Landroidx/compose/ui/text/MultiParagraphIntrinsics;)V
+HSPLandroidx/compose/ui/text/MultiParagraphIntrinsics$maxIntrinsicWidth$2;->invoke()Ljava/lang/Float;
+HSPLandroidx/compose/ui/text/MultiParagraphIntrinsics$maxIntrinsicWidth$2;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/text/MultiParagraphIntrinsics$minIntrinsicWidth$2;-><init>(Landroidx/compose/ui/text/MultiParagraphIntrinsics;)V
+HSPLandroidx/compose/ui/text/MultiParagraphIntrinsics;-><clinit>()V
+HSPLandroidx/compose/ui/text/MultiParagraphIntrinsics;-><init>(Landroidx/compose/ui/text/AnnotatedString;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;)V
+HSPLandroidx/compose/ui/text/MultiParagraphIntrinsics;->access$resolveTextDirection(Landroidx/compose/ui/text/MultiParagraphIntrinsics;Landroidx/compose/ui/text/ParagraphStyle;Landroidx/compose/ui/text/ParagraphStyle;)Landroidx/compose/ui/text/ParagraphStyle;
+HSPLandroidx/compose/ui/text/MultiParagraphIntrinsics;->getHasStaleResolvedFonts()Z
+HSPLandroidx/compose/ui/text/MultiParagraphIntrinsics;->getInfoList$ui_text_release()Ljava/util/List;
+HSPLandroidx/compose/ui/text/MultiParagraphIntrinsics;->getMaxIntrinsicWidth()F
+HSPLandroidx/compose/ui/text/MultiParagraphIntrinsics;->getPlaceholders()Ljava/util/List;
+HSPLandroidx/compose/ui/text/MultiParagraphIntrinsics;->resolveTextDirection(Landroidx/compose/ui/text/ParagraphStyle;Landroidx/compose/ui/text/ParagraphStyle;)Landroidx/compose/ui/text/ParagraphStyle;
+HSPLandroidx/compose/ui/text/MultiParagraphIntrinsicsKt;->access$getLocalPlaceholders(Ljava/util/List;II)Ljava/util/List;
+HSPLandroidx/compose/ui/text/MultiParagraphIntrinsicsKt;->getLocalPlaceholders(Ljava/util/List;II)Ljava/util/List;
+HSPLandroidx/compose/ui/text/ParagraphInfo;-><init>(Landroidx/compose/ui/text/Paragraph;IIIIFF)V
+HSPLandroidx/compose/ui/text/ParagraphInfo;->getParagraph()Landroidx/compose/ui/text/Paragraph;
+HSPLandroidx/compose/ui/text/ParagraphInfo;->toGlobalYPosition(F)F
+HSPLandroidx/compose/ui/text/ParagraphIntrinsicInfo;-><init>(Landroidx/compose/ui/text/ParagraphIntrinsics;II)V
+HSPLandroidx/compose/ui/text/ParagraphIntrinsicInfo;->getEndIndex()I
+HSPLandroidx/compose/ui/text/ParagraphIntrinsicInfo;->getIntrinsics()Landroidx/compose/ui/text/ParagraphIntrinsics;
+HSPLandroidx/compose/ui/text/ParagraphIntrinsicInfo;->getStartIndex()I
+HSPLandroidx/compose/ui/text/ParagraphIntrinsicsKt;->ParagraphIntrinsics(Ljava/lang/String;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Ljava/util/List;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;)Landroidx/compose/ui/text/ParagraphIntrinsics;
+HSPLandroidx/compose/ui/text/ParagraphKt;->Paragraph-_EkL_-Y(Landroidx/compose/ui/text/ParagraphIntrinsics;JIZ)Landroidx/compose/ui/text/Paragraph;
+HSPLandroidx/compose/ui/text/ParagraphKt;->ceilToInt(F)I
+HSPLandroidx/compose/ui/text/ParagraphStyle;-><init>(Landroidx/compose/ui/text/style/TextAlign;Landroidx/compose/ui/text/style/TextDirection;JLandroidx/compose/ui/text/style/TextIndent;Landroidx/compose/ui/text/PlatformParagraphStyle;Landroidx/compose/ui/text/style/LineHeightStyle;Landroidx/compose/ui/text/style/LineBreak;Landroidx/compose/ui/text/style/Hyphens;)V
+HSPLandroidx/compose/ui/text/ParagraphStyle;-><init>(Landroidx/compose/ui/text/style/TextAlign;Landroidx/compose/ui/text/style/TextDirection;JLandroidx/compose/ui/text/style/TextIndent;Landroidx/compose/ui/text/PlatformParagraphStyle;Landroidx/compose/ui/text/style/LineHeightStyle;Landroidx/compose/ui/text/style/LineBreak;Landroidx/compose/ui/text/style/Hyphens;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/ParagraphStyle;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/text/ParagraphStyle;->getHyphens()Landroidx/compose/ui/text/style/Hyphens;
+HSPLandroidx/compose/ui/text/ParagraphStyle;->getLineBreak()Landroidx/compose/ui/text/style/LineBreak;
+HSPLandroidx/compose/ui/text/ParagraphStyle;->getLineHeight-XSAIIZE()J
+HSPLandroidx/compose/ui/text/ParagraphStyle;->getLineHeightStyle()Landroidx/compose/ui/text/style/LineHeightStyle;
+HSPLandroidx/compose/ui/text/ParagraphStyle;->getPlatformStyle()Landroidx/compose/ui/text/PlatformParagraphStyle;
+HSPLandroidx/compose/ui/text/ParagraphStyle;->getTextAlign-buA522U()Landroidx/compose/ui/text/style/TextAlign;
+HSPLandroidx/compose/ui/text/ParagraphStyle;->getTextDirection-mmuk1to()Landroidx/compose/ui/text/style/TextDirection;
+HSPLandroidx/compose/ui/text/ParagraphStyle;->getTextIndent()Landroidx/compose/ui/text/style/TextIndent;
+HSPLandroidx/compose/ui/text/ParagraphStyle;->merge(Landroidx/compose/ui/text/ParagraphStyle;)Landroidx/compose/ui/text/ParagraphStyle;
+HSPLandroidx/compose/ui/text/ParagraphStyle;->mergePlatformStyle(Landroidx/compose/ui/text/PlatformParagraphStyle;)Landroidx/compose/ui/text/PlatformParagraphStyle;
+HSPLandroidx/compose/ui/text/ParagraphStyleKt;-><clinit>()V
+HSPLandroidx/compose/ui/text/ParagraphStyleKt;->resolveParagraphStyleDefaults(Landroidx/compose/ui/text/ParagraphStyle;Landroidx/compose/ui/unit/LayoutDirection;)Landroidx/compose/ui/text/ParagraphStyle;
+HSPLandroidx/compose/ui/text/SpanStyle;-><init>(JJLandroidx/compose/ui/text/font/FontWeight;Landroidx/compose/ui/text/font/FontStyle;Landroidx/compose/ui/text/font/FontSynthesis;Landroidx/compose/ui/text/font/FontFamily;Ljava/lang/String;JLandroidx/compose/ui/text/style/BaselineShift;Landroidx/compose/ui/text/style/TextGeometricTransform;Landroidx/compose/ui/text/intl/LocaleList;JLandroidx/compose/ui/text/style/TextDecoration;Landroidx/compose/ui/graphics/Shadow;)V
+HSPLandroidx/compose/ui/text/SpanStyle;-><init>(JJLandroidx/compose/ui/text/font/FontWeight;Landroidx/compose/ui/text/font/FontStyle;Landroidx/compose/ui/text/font/FontSynthesis;Landroidx/compose/ui/text/font/FontFamily;Ljava/lang/String;JLandroidx/compose/ui/text/style/BaselineShift;Landroidx/compose/ui/text/style/TextGeometricTransform;Landroidx/compose/ui/text/intl/LocaleList;JLandroidx/compose/ui/text/style/TextDecoration;Landroidx/compose/ui/graphics/Shadow;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/SpanStyle;-><init>(JJLandroidx/compose/ui/text/font/FontWeight;Landroidx/compose/ui/text/font/FontStyle;Landroidx/compose/ui/text/font/FontSynthesis;Landroidx/compose/ui/text/font/FontFamily;Ljava/lang/String;JLandroidx/compose/ui/text/style/BaselineShift;Landroidx/compose/ui/text/style/TextGeometricTransform;Landroidx/compose/ui/text/intl/LocaleList;JLandroidx/compose/ui/text/style/TextDecoration;Landroidx/compose/ui/graphics/Shadow;Landroidx/compose/ui/text/PlatformSpanStyle;)V
+HSPLandroidx/compose/ui/text/SpanStyle;-><init>(JJLandroidx/compose/ui/text/font/FontWeight;Landroidx/compose/ui/text/font/FontStyle;Landroidx/compose/ui/text/font/FontSynthesis;Landroidx/compose/ui/text/font/FontFamily;Ljava/lang/String;JLandroidx/compose/ui/text/style/BaselineShift;Landroidx/compose/ui/text/style/TextGeometricTransform;Landroidx/compose/ui/text/intl/LocaleList;JLandroidx/compose/ui/text/style/TextDecoration;Landroidx/compose/ui/graphics/Shadow;Landroidx/compose/ui/text/PlatformSpanStyle;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/SpanStyle;-><init>(JJLandroidx/compose/ui/text/font/FontWeight;Landroidx/compose/ui/text/font/FontStyle;Landroidx/compose/ui/text/font/FontSynthesis;Landroidx/compose/ui/text/font/FontFamily;Ljava/lang/String;JLandroidx/compose/ui/text/style/BaselineShift;Landroidx/compose/ui/text/style/TextGeometricTransform;Landroidx/compose/ui/text/intl/LocaleList;JLandroidx/compose/ui/text/style/TextDecoration;Landroidx/compose/ui/graphics/Shadow;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/SpanStyle;-><init>(Landroidx/compose/ui/text/style/TextForegroundStyle;JLandroidx/compose/ui/text/font/FontWeight;Landroidx/compose/ui/text/font/FontStyle;Landroidx/compose/ui/text/font/FontSynthesis;Landroidx/compose/ui/text/font/FontFamily;Ljava/lang/String;JLandroidx/compose/ui/text/style/BaselineShift;Landroidx/compose/ui/text/style/TextGeometricTransform;Landroidx/compose/ui/text/intl/LocaleList;JLandroidx/compose/ui/text/style/TextDecoration;Landroidx/compose/ui/graphics/Shadow;Landroidx/compose/ui/text/PlatformSpanStyle;Landroidx/compose/ui/graphics/drawscope/DrawStyle;)V
+HSPLandroidx/compose/ui/text/SpanStyle;-><init>(Landroidx/compose/ui/text/style/TextForegroundStyle;JLandroidx/compose/ui/text/font/FontWeight;Landroidx/compose/ui/text/font/FontStyle;Landroidx/compose/ui/text/font/FontSynthesis;Landroidx/compose/ui/text/font/FontFamily;Ljava/lang/String;JLandroidx/compose/ui/text/style/BaselineShift;Landroidx/compose/ui/text/style/TextGeometricTransform;Landroidx/compose/ui/text/intl/LocaleList;JLandroidx/compose/ui/text/style/TextDecoration;Landroidx/compose/ui/graphics/Shadow;Landroidx/compose/ui/text/PlatformSpanStyle;Landroidx/compose/ui/graphics/drawscope/DrawStyle;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/SpanStyle;-><init>(Landroidx/compose/ui/text/style/TextForegroundStyle;JLandroidx/compose/ui/text/font/FontWeight;Landroidx/compose/ui/text/font/FontStyle;Landroidx/compose/ui/text/font/FontSynthesis;Landroidx/compose/ui/text/font/FontFamily;Ljava/lang/String;JLandroidx/compose/ui/text/style/BaselineShift;Landroidx/compose/ui/text/style/TextGeometricTransform;Landroidx/compose/ui/text/intl/LocaleList;JLandroidx/compose/ui/text/style/TextDecoration;Landroidx/compose/ui/graphics/Shadow;Landroidx/compose/ui/text/PlatformSpanStyle;Landroidx/compose/ui/graphics/drawscope/DrawStyle;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/SpanStyle;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/text/SpanStyle;->getAlpha()F
+HSPLandroidx/compose/ui/text/SpanStyle;->getBackground-0d7_KjU()J
+HSPLandroidx/compose/ui/text/SpanStyle;->getBaselineShift-5SSeXJ0()Landroidx/compose/ui/text/style/BaselineShift;
+HSPLandroidx/compose/ui/text/SpanStyle;->getBrush()Landroidx/compose/ui/graphics/Brush;
+HSPLandroidx/compose/ui/text/SpanStyle;->getColor-0d7_KjU()J
+HSPLandroidx/compose/ui/text/SpanStyle;->getDrawStyle()Landroidx/compose/ui/graphics/drawscope/DrawStyle;
+HSPLandroidx/compose/ui/text/SpanStyle;->getFontFamily()Landroidx/compose/ui/text/font/FontFamily;
+HSPLandroidx/compose/ui/text/SpanStyle;->getFontFeatureSettings()Ljava/lang/String;
+HSPLandroidx/compose/ui/text/SpanStyle;->getFontSize-XSAIIZE()J
+HSPLandroidx/compose/ui/text/SpanStyle;->getFontStyle-4Lr2A7w()Landroidx/compose/ui/text/font/FontStyle;
+HSPLandroidx/compose/ui/text/SpanStyle;->getFontSynthesis-ZQGJjVo()Landroidx/compose/ui/text/font/FontSynthesis;
+HSPLandroidx/compose/ui/text/SpanStyle;->getFontWeight()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/ui/text/SpanStyle;->getLetterSpacing-XSAIIZE()J
+HSPLandroidx/compose/ui/text/SpanStyle;->getLocaleList()Landroidx/compose/ui/text/intl/LocaleList;
+HSPLandroidx/compose/ui/text/SpanStyle;->getPlatformStyle()Landroidx/compose/ui/text/PlatformSpanStyle;
+HSPLandroidx/compose/ui/text/SpanStyle;->getShadow()Landroidx/compose/ui/graphics/Shadow;
+HSPLandroidx/compose/ui/text/SpanStyle;->getTextDecoration()Landroidx/compose/ui/text/style/TextDecoration;
+HSPLandroidx/compose/ui/text/SpanStyle;->getTextForegroundStyle$ui_text_release()Landroidx/compose/ui/text/style/TextForegroundStyle;
+HSPLandroidx/compose/ui/text/SpanStyle;->getTextGeometricTransform()Landroidx/compose/ui/text/style/TextGeometricTransform;
+HSPLandroidx/compose/ui/text/SpanStyle;->hasSameLayoutAffectingAttributes$ui_text_release(Landroidx/compose/ui/text/SpanStyle;)Z
+HSPLandroidx/compose/ui/text/SpanStyle;->hasSameNonLayoutAttributes(Landroidx/compose/ui/text/SpanStyle;)Z
+HSPLandroidx/compose/ui/text/SpanStyle;->merge(Landroidx/compose/ui/text/SpanStyle;)Landroidx/compose/ui/text/SpanStyle;
+HSPLandroidx/compose/ui/text/SpanStyle;->mergePlatformStyle(Landroidx/compose/ui/text/PlatformSpanStyle;)Landroidx/compose/ui/text/PlatformSpanStyle;
+HSPLandroidx/compose/ui/text/SpanStyleKt$resolveSpanStyleDefaults$1;-><clinit>()V
+HSPLandroidx/compose/ui/text/SpanStyleKt$resolveSpanStyleDefaults$1;-><init>()V
+HSPLandroidx/compose/ui/text/SpanStyleKt;-><clinit>()V
+HSPLandroidx/compose/ui/text/SpanStyleKt;->resolveSpanStyleDefaults(Landroidx/compose/ui/text/SpanStyle;)Landroidx/compose/ui/text/SpanStyle;
+HSPLandroidx/compose/ui/text/TextLayoutInput;-><clinit>()V
+HSPLandroidx/compose/ui/text/TextLayoutInput;-><init>(Landroidx/compose/ui/text/AnnotatedString;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;IZILandroidx/compose/ui/unit/Density;Landroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/ui/text/font/Font$ResourceLoader;Landroidx/compose/ui/text/font/FontFamily$Resolver;J)V
+HSPLandroidx/compose/ui/text/TextLayoutInput;-><init>(Landroidx/compose/ui/text/AnnotatedString;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;IZILandroidx/compose/ui/unit/Density;Landroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/ui/text/font/FontFamily$Resolver;J)V
+HSPLandroidx/compose/ui/text/TextLayoutInput;-><init>(Landroidx/compose/ui/text/AnnotatedString;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;IZILandroidx/compose/ui/unit/Density;Landroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/ui/text/font/FontFamily$Resolver;JLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/TextLayoutInput;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/text/TextLayoutInput;->getStyle()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/ui/text/TextLayoutInput;->getText()Landroidx/compose/ui/text/AnnotatedString;
+HSPLandroidx/compose/ui/text/TextLayoutResult;-><clinit>()V
+HSPLandroidx/compose/ui/text/TextLayoutResult;-><init>(Landroidx/compose/ui/text/TextLayoutInput;Landroidx/compose/ui/text/MultiParagraph;J)V
+HSPLandroidx/compose/ui/text/TextLayoutResult;-><init>(Landroidx/compose/ui/text/TextLayoutInput;Landroidx/compose/ui/text/MultiParagraph;JLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/TextLayoutResult;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/text/TextLayoutResult;->getDidOverflowHeight()Z
+HSPLandroidx/compose/ui/text/TextLayoutResult;->getDidOverflowWidth()Z
+HSPLandroidx/compose/ui/text/TextLayoutResult;->getFirstBaseline()F
+HSPLandroidx/compose/ui/text/TextLayoutResult;->getHasVisualOverflow()Z
+HSPLandroidx/compose/ui/text/TextLayoutResult;->getLastBaseline()F
+HSPLandroidx/compose/ui/text/TextLayoutResult;->getLayoutInput()Landroidx/compose/ui/text/TextLayoutInput;
+HSPLandroidx/compose/ui/text/TextLayoutResult;->getMultiParagraph()Landroidx/compose/ui/text/MultiParagraph;
+HSPLandroidx/compose/ui/text/TextLayoutResult;->getPlaceholderRects()Ljava/util/List;
+HSPLandroidx/compose/ui/text/TextLayoutResult;->getSize-YbymL2g()J
+HSPLandroidx/compose/ui/text/TextPainter;-><clinit>()V
+HSPLandroidx/compose/ui/text/TextPainter;-><init>()V
+HSPLandroidx/compose/ui/text/TextPainter;->paint(Landroidx/compose/ui/graphics/Canvas;Landroidx/compose/ui/text/TextLayoutResult;)V
+HSPLandroidx/compose/ui/text/TextRange$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/TextRange$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/TextRange$Companion;->getZero-d9O1mEE()J
+HSPLandroidx/compose/ui/text/TextRange;-><clinit>()V
+HSPLandroidx/compose/ui/text/TextRange;->access$getZero$cp()J
+HSPLandroidx/compose/ui/text/TextRange;->constructor-impl(J)J
+HSPLandroidx/compose/ui/text/TextRange;->getEnd-impl(J)I
+HSPLandroidx/compose/ui/text/TextRange;->getStart-impl(J)I
+HSPLandroidx/compose/ui/text/TextRangeKt;->TextRange(I)J
+HSPLandroidx/compose/ui/text/TextRangeKt;->TextRange(II)J
+HSPLandroidx/compose/ui/text/TextRangeKt;->constrain-8ffj60Q(JII)J
+HSPLandroidx/compose/ui/text/TextRangeKt;->packWithCheck(II)J
+HSPLandroidx/compose/ui/text/TextStyle$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/TextStyle$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/TextStyle$Companion;->getDefault()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/ui/text/TextStyle;-><clinit>()V
+HSPLandroidx/compose/ui/text/TextStyle;-><init>(JJLandroidx/compose/ui/text/font/FontWeight;Landroidx/compose/ui/text/font/FontStyle;Landroidx/compose/ui/text/font/FontSynthesis;Landroidx/compose/ui/text/font/FontFamily;Ljava/lang/String;JLandroidx/compose/ui/text/style/BaselineShift;Landroidx/compose/ui/text/style/TextGeometricTransform;Landroidx/compose/ui/text/intl/LocaleList;JLandroidx/compose/ui/text/style/TextDecoration;Landroidx/compose/ui/graphics/Shadow;Landroidx/compose/ui/text/style/TextAlign;Landroidx/compose/ui/text/style/TextDirection;JLandroidx/compose/ui/text/style/TextIndent;)V
+HSPLandroidx/compose/ui/text/TextStyle;-><init>(JJLandroidx/compose/ui/text/font/FontWeight;Landroidx/compose/ui/text/font/FontStyle;Landroidx/compose/ui/text/font/FontSynthesis;Landroidx/compose/ui/text/font/FontFamily;Ljava/lang/String;JLandroidx/compose/ui/text/style/BaselineShift;Landroidx/compose/ui/text/style/TextGeometricTransform;Landroidx/compose/ui/text/intl/LocaleList;JLandroidx/compose/ui/text/style/TextDecoration;Landroidx/compose/ui/graphics/Shadow;Landroidx/compose/ui/text/style/TextAlign;Landroidx/compose/ui/text/style/TextDirection;JLandroidx/compose/ui/text/style/TextIndent;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/TextStyle;-><init>(JJLandroidx/compose/ui/text/font/FontWeight;Landroidx/compose/ui/text/font/FontStyle;Landroidx/compose/ui/text/font/FontSynthesis;Landroidx/compose/ui/text/font/FontFamily;Ljava/lang/String;JLandroidx/compose/ui/text/style/BaselineShift;Landroidx/compose/ui/text/style/TextGeometricTransform;Landroidx/compose/ui/text/intl/LocaleList;JLandroidx/compose/ui/text/style/TextDecoration;Landroidx/compose/ui/graphics/Shadow;Landroidx/compose/ui/text/style/TextAlign;Landroidx/compose/ui/text/style/TextDirection;JLandroidx/compose/ui/text/style/TextIndent;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/TextStyle;-><init>(Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/ParagraphStyle;)V
+HSPLandroidx/compose/ui/text/TextStyle;-><init>(Landroidx/compose/ui/text/SpanStyle;Landroidx/compose/ui/text/ParagraphStyle;Landroidx/compose/ui/text/PlatformTextStyle;)V
+HSPLandroidx/compose/ui/text/TextStyle;->access$getDefault$cp()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/ui/text/TextStyle;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/text/TextStyle;->getAlpha()F
+HSPLandroidx/compose/ui/text/TextStyle;->getBrush()Landroidx/compose/ui/graphics/Brush;
+HSPLandroidx/compose/ui/text/TextStyle;->getColor-0d7_KjU()J
+HSPLandroidx/compose/ui/text/TextStyle;->getFontFamily()Landroidx/compose/ui/text/font/FontFamily;
+HSPLandroidx/compose/ui/text/TextStyle;->getFontStyle-4Lr2A7w()Landroidx/compose/ui/text/font/FontStyle;
+HSPLandroidx/compose/ui/text/TextStyle;->getFontSynthesis-ZQGJjVo()Landroidx/compose/ui/text/font/FontSynthesis;
+HSPLandroidx/compose/ui/text/TextStyle;->getFontWeight()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/ui/text/TextStyle;->getLineBreak()Landroidx/compose/ui/text/style/LineBreak;
+HSPLandroidx/compose/ui/text/TextStyle;->getLineHeight-XSAIIZE()J
+HSPLandroidx/compose/ui/text/TextStyle;->getLineHeightStyle()Landroidx/compose/ui/text/style/LineHeightStyle;
+HSPLandroidx/compose/ui/text/TextStyle;->getLocaleList()Landroidx/compose/ui/text/intl/LocaleList;
+HSPLandroidx/compose/ui/text/TextStyle;->getParagraphStyle$ui_text_release()Landroidx/compose/ui/text/ParagraphStyle;
+HSPLandroidx/compose/ui/text/TextStyle;->getPlatformStyle()Landroidx/compose/ui/text/PlatformTextStyle;
+HSPLandroidx/compose/ui/text/TextStyle;->getSpanStyle$ui_text_release()Landroidx/compose/ui/text/SpanStyle;
+HSPLandroidx/compose/ui/text/TextStyle;->getTextAlign-buA522U()Landroidx/compose/ui/text/style/TextAlign;
+HSPLandroidx/compose/ui/text/TextStyle;->getTextDecoration()Landroidx/compose/ui/text/style/TextDecoration;
+HSPLandroidx/compose/ui/text/TextStyle;->getTextDirection-mmuk1to()Landroidx/compose/ui/text/style/TextDirection;
+HSPLandroidx/compose/ui/text/TextStyle;->getTextIndent()Landroidx/compose/ui/text/style/TextIndent;
+HSPLandroidx/compose/ui/text/TextStyle;->merge(Landroidx/compose/ui/text/ParagraphStyle;)Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/ui/text/TextStyle;->merge(Landroidx/compose/ui/text/TextStyle;)Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/ui/text/TextStyle;->toParagraphStyle()Landroidx/compose/ui/text/ParagraphStyle;
+HSPLandroidx/compose/ui/text/TextStyle;->toSpanStyle()Landroidx/compose/ui/text/SpanStyle;
+HSPLandroidx/compose/ui/text/TextStyleKt$WhenMappings;-><clinit>()V
+HSPLandroidx/compose/ui/text/TextStyleKt;->access$createPlatformTextStyleInternal(Landroidx/compose/ui/text/PlatformSpanStyle;Landroidx/compose/ui/text/PlatformParagraphStyle;)Landroidx/compose/ui/text/PlatformTextStyle;
+HSPLandroidx/compose/ui/text/TextStyleKt;->createPlatformTextStyleInternal(Landroidx/compose/ui/text/PlatformSpanStyle;Landroidx/compose/ui/text/PlatformParagraphStyle;)Landroidx/compose/ui/text/PlatformTextStyle;
+HSPLandroidx/compose/ui/text/TextStyleKt;->resolveDefaults(Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/unit/LayoutDirection;)Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/ui/text/TextStyleKt;->resolveTextDirection-Yj3eThk(Landroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/ui/text/style/TextDirection;)I
+HSPLandroidx/compose/ui/text/android/BoringLayoutFactory33;-><clinit>()V
+HSPLandroidx/compose/ui/text/android/BoringLayoutFactory33;-><init>()V
+HSPLandroidx/compose/ui/text/android/BoringLayoutFactory33;->isBoring(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/TextDirectionHeuristic;)Landroid/text/BoringLayout$Metrics;
+HSPLandroidx/compose/ui/text/android/BoringLayoutFactory;-><clinit>()V
+HSPLandroidx/compose/ui/text/android/BoringLayoutFactory;-><init>()V
+HSPLandroidx/compose/ui/text/android/BoringLayoutFactory;->measure(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/TextDirectionHeuristic;)Landroid/text/BoringLayout$Metrics;
+HSPLandroidx/compose/ui/text/android/LayoutIntrinsics$boringMetrics$2;-><init>(ILjava/lang/CharSequence;Landroid/text/TextPaint;)V
+HSPLandroidx/compose/ui/text/android/LayoutIntrinsics$boringMetrics$2;->invoke()Landroid/text/BoringLayout$Metrics;
+HSPLandroidx/compose/ui/text/android/LayoutIntrinsics$boringMetrics$2;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/text/android/LayoutIntrinsics$maxIntrinsicWidth$2;-><init>(Landroidx/compose/ui/text/android/LayoutIntrinsics;Ljava/lang/CharSequence;Landroid/text/TextPaint;)V
+HSPLandroidx/compose/ui/text/android/LayoutIntrinsics$maxIntrinsicWidth$2;->invoke()Ljava/lang/Float;
+HSPLandroidx/compose/ui/text/android/LayoutIntrinsics$maxIntrinsicWidth$2;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/text/android/LayoutIntrinsics$minIntrinsicWidth$2;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;)V
+HSPLandroidx/compose/ui/text/android/LayoutIntrinsics;-><clinit>()V
+HSPLandroidx/compose/ui/text/android/LayoutIntrinsics;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;I)V
+HSPLandroidx/compose/ui/text/android/LayoutIntrinsics;->getBoringMetrics()Landroid/text/BoringLayout$Metrics;
+HSPLandroidx/compose/ui/text/android/LayoutIntrinsics;->getMaxIntrinsicWidth()F
+HSPLandroidx/compose/ui/text/android/LayoutIntrinsicsKt;->access$shouldIncreaseMaxIntrinsic(FLjava/lang/CharSequence;Landroid/text/TextPaint;)Z
+HSPLandroidx/compose/ui/text/android/LayoutIntrinsicsKt;->shouldIncreaseMaxIntrinsic(FLjava/lang/CharSequence;Landroid/text/TextPaint;)Z
+HSPLandroidx/compose/ui/text/android/SpannedExtensionsKt;->hasSpan(Landroid/text/Spanned;Ljava/lang/Class;)Z
+HSPLandroidx/compose/ui/text/android/StaticLayoutFactory23;-><init>()V
+HSPLandroidx/compose/ui/text/android/StaticLayoutFactory23;->create(Landroidx/compose/ui/text/android/StaticLayoutParams;)Landroid/text/StaticLayout;
+HSPLandroidx/compose/ui/text/android/StaticLayoutFactory26;-><clinit>()V
+HSPLandroidx/compose/ui/text/android/StaticLayoutFactory26;-><init>()V
+HSPLandroidx/compose/ui/text/android/StaticLayoutFactory26;->setJustificationMode(Landroid/text/StaticLayout$Builder;I)V
+HSPLandroidx/compose/ui/text/android/StaticLayoutFactory28;-><clinit>()V
+HSPLandroidx/compose/ui/text/android/StaticLayoutFactory28;-><init>()V
+HSPLandroidx/compose/ui/text/android/StaticLayoutFactory28;->setUseLineSpacingFromFallbacks(Landroid/text/StaticLayout$Builder;Z)V
+HSPLandroidx/compose/ui/text/android/StaticLayoutFactory33;-><clinit>()V
+HSPLandroidx/compose/ui/text/android/StaticLayoutFactory33;-><init>()V
+HSPLandroidx/compose/ui/text/android/StaticLayoutFactory33;->setLineBreakConfig(Landroid/text/StaticLayout$Builder;II)V
+HSPLandroidx/compose/ui/text/android/StaticLayoutFactory;-><clinit>()V
+HSPLandroidx/compose/ui/text/android/StaticLayoutFactory;-><init>()V
+HSPLandroidx/compose/ui/text/android/StaticLayoutFactory;->create(Ljava/lang/CharSequence;IILandroid/text/TextPaint;ILandroid/text/TextDirectionHeuristic;Landroid/text/Layout$Alignment;ILandroid/text/TextUtils$TruncateAt;IFFIZZIIII[I[I)Landroid/text/StaticLayout;
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;-><init>(Ljava/lang/CharSequence;IILandroid/text/TextPaint;ILandroid/text/TextDirectionHeuristic;Landroid/text/Layout$Alignment;ILandroid/text/TextUtils$TruncateAt;IFFIZZIIII[I[I)V
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getAlignment()Landroid/text/Layout$Alignment;
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getBreakStrategy()I
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getEllipsize()Landroid/text/TextUtils$TruncateAt;
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getEllipsizedWidth()I
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getEnd()I
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getHyphenationFrequency()I
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getIncludePadding()Z
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getJustificationMode()I
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getLeftIndents()[I
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getLineBreakStyle()I
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getLineBreakWordStyle()I
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getLineSpacingExtra()F
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getLineSpacingMultiplier()F
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getMaxLines()I
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getPaint()Landroid/text/TextPaint;
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getRightIndents()[I
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getStart()I
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getText()Ljava/lang/CharSequence;
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getTextDir()Landroid/text/TextDirectionHeuristic;
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getUseFallbackLineSpacing()Z
+HSPLandroidx/compose/ui/text/android/StaticLayoutParams;->getWidth()I
+HSPLandroidx/compose/ui/text/android/TextAlignmentAdapter;-><clinit>()V
+HSPLandroidx/compose/ui/text/android/TextAlignmentAdapter;-><init>()V
+HSPLandroidx/compose/ui/text/android/TextAlignmentAdapter;->get(I)Landroid/text/Layout$Alignment;
+HSPLandroidx/compose/ui/text/android/TextAndroidCanvas;-><init>()V
+HSPLandroidx/compose/ui/text/android/TextAndroidCanvas;->drawTextRun(Ljava/lang/CharSequence;IIIIFFZLandroid/graphics/Paint;)V
+HSPLandroidx/compose/ui/text/android/TextAndroidCanvas;->getClipBounds(Landroid/graphics/Rect;)Z
+HSPLandroidx/compose/ui/text/android/TextAndroidCanvas;->setCanvas(Landroid/graphics/Canvas;)V
+HSPLandroidx/compose/ui/text/android/TextLayout$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/android/TextLayout$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/android/TextLayout$layoutHelper$2;-><init>(Landroidx/compose/ui/text/android/TextLayout;)V
+HSPLandroidx/compose/ui/text/android/TextLayout;-><clinit>()V
+HSPLandroidx/compose/ui/text/android/TextLayout;-><init>(Ljava/lang/CharSequence;FLandroid/text/TextPaint;ILandroid/text/TextUtils$TruncateAt;IFFZZIIIIII[I[ILandroidx/compose/ui/text/android/LayoutIntrinsics;)V
+HSPLandroidx/compose/ui/text/android/TextLayout;-><init>(Ljava/lang/CharSequence;FLandroid/text/TextPaint;ILandroid/text/TextUtils$TruncateAt;IFFZZIIIIII[I[ILandroidx/compose/ui/text/android/LayoutIntrinsics;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/android/TextLayout;->getDidExceedMaxLines()Z
+HSPLandroidx/compose/ui/text/android/TextLayout;->getHeight()I
+HSPLandroidx/compose/ui/text/android/TextLayout;->getIncludePadding()Z
+HSPLandroidx/compose/ui/text/android/TextLayout;->getLayout()Landroid/text/Layout;
+HSPLandroidx/compose/ui/text/android/TextLayout;->getLineBaseline(I)F
+HSPLandroidx/compose/ui/text/android/TextLayout;->getLineCount()I
+HSPLandroidx/compose/ui/text/android/TextLayout;->getText()Ljava/lang/CharSequence;
+HSPLandroidx/compose/ui/text/android/TextLayout;->paint(Landroid/graphics/Canvas;)V
+HSPLandroidx/compose/ui/text/android/TextLayoutKt;-><clinit>()V
+HSPLandroidx/compose/ui/text/android/TextLayoutKt;->access$getLastLineMetrics(Landroidx/compose/ui/text/android/TextLayout;Landroid/text/TextPaint;Landroid/text/TextDirectionHeuristic;[Landroidx/compose/ui/text/android/style/LineHeightStyleSpan;)Lkotlin/Pair;
+HSPLandroidx/compose/ui/text/android/TextLayoutKt;->access$getLineHeightPaddings(Landroidx/compose/ui/text/android/TextLayout;[Landroidx/compose/ui/text/android/style/LineHeightStyleSpan;)Lkotlin/Pair;
+HSPLandroidx/compose/ui/text/android/TextLayoutKt;->access$getLineHeightSpans(Landroidx/compose/ui/text/android/TextLayout;)[Landroidx/compose/ui/text/android/style/LineHeightStyleSpan;
+HSPLandroidx/compose/ui/text/android/TextLayoutKt;->access$getVerticalPaddings(Landroidx/compose/ui/text/android/TextLayout;)Lkotlin/Pair;
+HSPLandroidx/compose/ui/text/android/TextLayoutKt;->getLastLineMetrics(Landroidx/compose/ui/text/android/TextLayout;Landroid/text/TextPaint;Landroid/text/TextDirectionHeuristic;[Landroidx/compose/ui/text/android/style/LineHeightStyleSpan;)Lkotlin/Pair;
+HSPLandroidx/compose/ui/text/android/TextLayoutKt;->getLineHeightPaddings(Landroidx/compose/ui/text/android/TextLayout;[Landroidx/compose/ui/text/android/style/LineHeightStyleSpan;)Lkotlin/Pair;
+HSPLandroidx/compose/ui/text/android/TextLayoutKt;->getLineHeightSpans(Landroidx/compose/ui/text/android/TextLayout;)[Landroidx/compose/ui/text/android/style/LineHeightStyleSpan;
+HSPLandroidx/compose/ui/text/android/TextLayoutKt;->getTextDirectionHeuristic(I)Landroid/text/TextDirectionHeuristic;
+HSPLandroidx/compose/ui/text/android/TextLayoutKt;->getVerticalPaddings(Landroidx/compose/ui/text/android/TextLayout;)Lkotlin/Pair;
+HSPLandroidx/compose/ui/text/android/TextLayoutKt;->isLineEllipsized(Landroid/text/Layout;I)Z
+HSPLandroidx/compose/ui/text/android/style/IndentationFixSpanKt;->getEllipsizedLeftPadding$default(Landroid/text/Layout;ILandroid/graphics/Paint;ILjava/lang/Object;)F
+HSPLandroidx/compose/ui/text/android/style/IndentationFixSpanKt;->getEllipsizedLeftPadding(Landroid/text/Layout;ILandroid/graphics/Paint;)F
+HSPLandroidx/compose/ui/text/android/style/IndentationFixSpanKt;->getEllipsizedRightPadding$default(Landroid/text/Layout;ILandroid/graphics/Paint;ILjava/lang/Object;)F
+HSPLandroidx/compose/ui/text/android/style/IndentationFixSpanKt;->getEllipsizedRightPadding(Landroid/text/Layout;ILandroid/graphics/Paint;)F
+HSPLandroidx/compose/ui/text/android/style/LineHeightSpan;-><clinit>()V
+HSPLandroidx/compose/ui/text/android/style/LineHeightSpan;-><init>(F)V
+HSPLandroidx/compose/ui/text/android/style/LineHeightSpan;->chooseHeight(Ljava/lang/CharSequence;IIIILandroid/graphics/Paint$FontMetricsInt;)V
+HSPLandroidx/compose/ui/text/android/style/LineHeightStyleSpanKt;->lineHeight(Landroid/graphics/Paint$FontMetricsInt;)I
+HSPLandroidx/compose/ui/text/caches/ContainerHelpersKt;-><clinit>()V
+HSPLandroidx/compose/ui/text/caches/LruCache;-><init>(I)V
+HSPLandroidx/compose/ui/text/caches/LruCache;->access$getMonitor$p(Landroidx/compose/ui/text/caches/LruCache;)Landroidx/compose/ui/text/platform/SynchronizedObject;
+HSPLandroidx/compose/ui/text/caches/LruCache;->create(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/text/caches/LruCache;->get(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/text/caches/LruCache;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/text/caches/LruCache;->safeSizeOf(Ljava/lang/Object;Ljava/lang/Object;)I
+HSPLandroidx/compose/ui/text/caches/LruCache;->size()I
+HSPLandroidx/compose/ui/text/caches/LruCache;->sizeOf(Ljava/lang/Object;Ljava/lang/Object;)I
+HSPLandroidx/compose/ui/text/caches/LruCache;->trimToSize(I)V
+HSPLandroidx/compose/ui/text/caches/SimpleArrayMap;-><init>(I)V
+HSPLandroidx/compose/ui/text/caches/SimpleArrayMap;-><init>(IILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/font/AndroidFontLoader;-><init>(Landroid/content/Context;)V
+HSPLandroidx/compose/ui/text/font/AndroidFontLoader;->getCacheKey()Ljava/lang/Object;
+HSPLandroidx/compose/ui/text/font/AndroidFontResolveInterceptor;-><init>(I)V
+HSPLandroidx/compose/ui/text/font/AndroidFontResolveInterceptor;->interceptFontWeight(Landroidx/compose/ui/text/font/FontWeight;)Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/ui/text/font/AndroidFontResolveInterceptor_androidKt;->AndroidFontResolveInterceptor(Landroid/content/Context;)Landroidx/compose/ui/text/font/AndroidFontResolveInterceptor;
+HSPLandroidx/compose/ui/text/font/AsyncTypefaceCache$AsyncTypefaceResult;->constructor-impl(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/text/font/AsyncTypefaceCache;-><init>()V
+HSPLandroidx/compose/ui/text/font/DefaultFontFamily;-><init>()V
+HSPLandroidx/compose/ui/text/font/FontFamily$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/font/FontFamily$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/font/FontFamily$Companion;->getDefault()Landroidx/compose/ui/text/font/SystemFontFamily;
+HSPLandroidx/compose/ui/text/font/FontFamily$Companion;->getSansSerif()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/ui/text/font/FontFamily;-><clinit>()V
+HSPLandroidx/compose/ui/text/font/FontFamily;-><init>(Z)V
+HSPLandroidx/compose/ui/text/font/FontFamily;-><init>(ZLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/font/FontFamily;->access$getDefault$cp()Landroidx/compose/ui/text/font/SystemFontFamily;
+HSPLandroidx/compose/ui/text/font/FontFamily;->access$getSansSerif$cp()Landroidx/compose/ui/text/font/GenericFontFamily;
+HSPLandroidx/compose/ui/text/font/FontFamilyResolverImpl$createDefaultTypeface$1;-><init>(Landroidx/compose/ui/text/font/FontFamilyResolverImpl;)V
+HSPLandroidx/compose/ui/text/font/FontFamilyResolverImpl$resolve$result$1;-><init>(Landroidx/compose/ui/text/font/FontFamilyResolverImpl;Landroidx/compose/ui/text/font/TypefaceRequest;)V
+HSPLandroidx/compose/ui/text/font/FontFamilyResolverImpl$resolve$result$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/text/font/FontFamilyResolverImpl$resolve$result$1;->invoke(Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/text/font/TypefaceResult;
+HSPLandroidx/compose/ui/text/font/FontFamilyResolverImpl;-><init>(Landroidx/compose/ui/text/font/PlatformFontLoader;Landroidx/compose/ui/text/font/PlatformResolveInterceptor;Landroidx/compose/ui/text/font/TypefaceRequestCache;Landroidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter;Landroidx/compose/ui/text/font/PlatformFontFamilyTypefaceAdapter;)V
+HSPLandroidx/compose/ui/text/font/FontFamilyResolverImpl;-><init>(Landroidx/compose/ui/text/font/PlatformFontLoader;Landroidx/compose/ui/text/font/PlatformResolveInterceptor;Landroidx/compose/ui/text/font/TypefaceRequestCache;Landroidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter;Landroidx/compose/ui/text/font/PlatformFontFamilyTypefaceAdapter;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/font/FontFamilyResolverImpl;->access$getCreateDefaultTypeface$p(Landroidx/compose/ui/text/font/FontFamilyResolverImpl;)Lkotlin/jvm/functions/Function1;
+HSPLandroidx/compose/ui/text/font/FontFamilyResolverImpl;->access$getFontListFontFamilyTypefaceAdapter$p(Landroidx/compose/ui/text/font/FontFamilyResolverImpl;)Landroidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter;
+HSPLandroidx/compose/ui/text/font/FontFamilyResolverImpl;->access$getPlatformFamilyTypefaceAdapter$p(Landroidx/compose/ui/text/font/FontFamilyResolverImpl;)Landroidx/compose/ui/text/font/PlatformFontFamilyTypefaceAdapter;
+HSPLandroidx/compose/ui/text/font/FontFamilyResolverImpl;->getPlatformFontLoader$ui_text_release()Landroidx/compose/ui/text/font/PlatformFontLoader;
+HSPLandroidx/compose/ui/text/font/FontFamilyResolverImpl;->resolve(Landroidx/compose/ui/text/font/TypefaceRequest;)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/ui/text/font/FontFamilyResolverImpl;->resolve-DPcqOEQ(Landroidx/compose/ui/text/font/FontFamily;Landroidx/compose/ui/text/font/FontWeight;II)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/ui/text/font/FontFamilyResolverKt;-><clinit>()V
+HSPLandroidx/compose/ui/text/font/FontFamilyResolverKt;->getGlobalAsyncTypefaceCache()Landroidx/compose/ui/text/font/AsyncTypefaceCache;
+HSPLandroidx/compose/ui/text/font/FontFamilyResolverKt;->getGlobalTypefaceRequestCache()Landroidx/compose/ui/text/font/TypefaceRequestCache;
+HSPLandroidx/compose/ui/text/font/FontFamilyResolver_androidKt;->createFontFamilyResolver(Landroid/content/Context;)Landroidx/compose/ui/text/font/FontFamily$Resolver;
+HSPLandroidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter$special$$inlined$CoroutineExceptionHandler$1;-><init>(Lkotlinx/coroutines/CoroutineExceptionHandler$Key;)V
+HSPLandroidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter;-><clinit>()V
+HSPLandroidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter;-><init>(Landroidx/compose/ui/text/font/AsyncTypefaceCache;Lkotlin/coroutines/CoroutineContext;)V
+HSPLandroidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter;-><init>(Landroidx/compose/ui/text/font/AsyncTypefaceCache;Lkotlin/coroutines/CoroutineContext;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter;->resolve(Landroidx/compose/ui/text/font/TypefaceRequest;Landroidx/compose/ui/text/font/PlatformFontLoader;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/text/font/TypefaceResult;
+HSPLandroidx/compose/ui/text/font/FontMatcher;-><init>()V
+HSPLandroidx/compose/ui/text/font/FontStyle$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/font/FontStyle$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/font/FontStyle$Companion;->getItalic-_-LCdwA()I
+HSPLandroidx/compose/ui/text/font/FontStyle$Companion;->getNormal-_-LCdwA()I
+HSPLandroidx/compose/ui/text/font/FontStyle;-><clinit>()V
+HSPLandroidx/compose/ui/text/font/FontStyle;-><init>(I)V
+HSPLandroidx/compose/ui/text/font/FontStyle;->access$getItalic$cp()I
+HSPLandroidx/compose/ui/text/font/FontStyle;->access$getNormal$cp()I
+HSPLandroidx/compose/ui/text/font/FontStyle;->box-impl(I)Landroidx/compose/ui/text/font/FontStyle;
+HSPLandroidx/compose/ui/text/font/FontStyle;->constructor-impl(I)I
+HSPLandroidx/compose/ui/text/font/FontStyle;->equals-impl0(II)Z
+HSPLandroidx/compose/ui/text/font/FontStyle;->hashCode-impl(I)I
+HSPLandroidx/compose/ui/text/font/FontStyle;->unbox-impl()I
+HSPLandroidx/compose/ui/text/font/FontSynthesis$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/font/FontSynthesis$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/font/FontSynthesis$Companion;->getAll-GVVA2EU()I
+HSPLandroidx/compose/ui/text/font/FontSynthesis;-><clinit>()V
+HSPLandroidx/compose/ui/text/font/FontSynthesis;-><init>(I)V
+HSPLandroidx/compose/ui/text/font/FontSynthesis;->access$getAll$cp()I
+HSPLandroidx/compose/ui/text/font/FontSynthesis;->box-impl(I)Landroidx/compose/ui/text/font/FontSynthesis;
+HSPLandroidx/compose/ui/text/font/FontSynthesis;->constructor-impl(I)I
+HSPLandroidx/compose/ui/text/font/FontSynthesis;->equals-impl0(II)Z
+HSPLandroidx/compose/ui/text/font/FontSynthesis;->hashCode-impl(I)I
+HSPLandroidx/compose/ui/text/font/FontSynthesis;->unbox-impl()I
+HSPLandroidx/compose/ui/text/font/FontWeight$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/font/FontWeight$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/font/FontWeight$Companion;->getBold()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/ui/text/font/FontWeight$Companion;->getMedium()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/ui/text/font/FontWeight$Companion;->getNormal()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/ui/text/font/FontWeight;-><clinit>()V
+HSPLandroidx/compose/ui/text/font/FontWeight;-><init>(I)V
+HSPLandroidx/compose/ui/text/font/FontWeight;->access$getBold$cp()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/ui/text/font/FontWeight;->access$getMedium$cp()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/ui/text/font/FontWeight;->access$getNormal$cp()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/ui/text/font/FontWeight;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/text/font/FontWeight;->getWeight()I
+HSPLandroidx/compose/ui/text/font/FontWeight;->hashCode()I
+HSPLandroidx/compose/ui/text/font/GenericFontFamily;-><init>(Ljava/lang/String;Ljava/lang/String;)V
+HSPLandroidx/compose/ui/text/font/PlatformFontFamilyTypefaceAdapter;-><init>()V
+HSPLandroidx/compose/ui/text/font/PlatformFontFamilyTypefaceAdapter;->resolve(Landroidx/compose/ui/text/font/TypefaceRequest;Landroidx/compose/ui/text/font/PlatformFontLoader;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/text/font/TypefaceResult;
+HSPLandroidx/compose/ui/text/font/PlatformResolveInterceptor$Companion$Default$1;-><init>()V
+HSPLandroidx/compose/ui/text/font/PlatformResolveInterceptor$Companion;-><clinit>()V
+HSPLandroidx/compose/ui/text/font/PlatformResolveInterceptor$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/font/PlatformResolveInterceptor;-><clinit>()V
+HSPLandroidx/compose/ui/text/font/PlatformResolveInterceptor;->interceptFontFamily(Landroidx/compose/ui/text/font/FontFamily;)Landroidx/compose/ui/text/font/FontFamily;
+HSPLandroidx/compose/ui/text/font/PlatformResolveInterceptor;->interceptFontStyle-T2F_aPo(I)I
+HSPLandroidx/compose/ui/text/font/PlatformResolveInterceptor;->interceptFontSynthesis-Mscr08Y(I)I
+HSPLandroidx/compose/ui/text/font/PlatformTypefacesApi28;-><init>()V
+HSPLandroidx/compose/ui/text/font/PlatformTypefacesApi28;->createAndroidTypefaceApi28-RetOiIg(Ljava/lang/String;Landroidx/compose/ui/text/font/FontWeight;I)Landroid/graphics/Typeface;
+HSPLandroidx/compose/ui/text/font/PlatformTypefacesApi28;->createDefault-FO1MlWM(Landroidx/compose/ui/text/font/FontWeight;I)Landroid/graphics/Typeface;
+HSPLandroidx/compose/ui/text/font/PlatformTypefacesKt;->PlatformTypefaces()Landroidx/compose/ui/text/font/PlatformTypefaces;
+HSPLandroidx/compose/ui/text/font/SystemFontFamily;-><clinit>()V
+HSPLandroidx/compose/ui/text/font/SystemFontFamily;-><init>()V
+HSPLandroidx/compose/ui/text/font/SystemFontFamily;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/font/TypefaceRequest;-><init>(Landroidx/compose/ui/text/font/FontFamily;Landroidx/compose/ui/text/font/FontWeight;IILjava/lang/Object;)V
+HSPLandroidx/compose/ui/text/font/TypefaceRequest;-><init>(Landroidx/compose/ui/text/font/FontFamily;Landroidx/compose/ui/text/font/FontWeight;IILjava/lang/Object;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/font/TypefaceRequest;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/text/font/TypefaceRequest;->getFontFamily()Landroidx/compose/ui/text/font/FontFamily;
+HSPLandroidx/compose/ui/text/font/TypefaceRequest;->getFontStyle-_-LCdwA()I
+HSPLandroidx/compose/ui/text/font/TypefaceRequest;->getFontWeight()Landroidx/compose/ui/text/font/FontWeight;
+HSPLandroidx/compose/ui/text/font/TypefaceRequest;->hashCode()I
+HSPLandroidx/compose/ui/text/font/TypefaceRequestCache$runCached$currentTypefaceResult$1;-><init>(Landroidx/compose/ui/text/font/TypefaceRequestCache;Landroidx/compose/ui/text/font/TypefaceRequest;)V
+HSPLandroidx/compose/ui/text/font/TypefaceRequestCache;-><init>()V
+HSPLandroidx/compose/ui/text/font/TypefaceRequestCache;->runCached(Landroidx/compose/ui/text/font/TypefaceRequest;Lkotlin/jvm/functions/Function1;)Landroidx/compose/runtime/State;
+HSPLandroidx/compose/ui/text/font/TypefaceResult$Immutable;-><clinit>()V
+HSPLandroidx/compose/ui/text/font/TypefaceResult$Immutable;-><init>(Ljava/lang/Object;Z)V
+HSPLandroidx/compose/ui/text/font/TypefaceResult$Immutable;-><init>(Ljava/lang/Object;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/font/TypefaceResult$Immutable;->getCacheable()Z
+HSPLandroidx/compose/ui/text/font/TypefaceResult$Immutable;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/ui/text/input/ImeAction$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/input/ImeAction$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/input/ImeAction$Companion;->getDefault-eUduSuo()I
+HSPLandroidx/compose/ui/text/input/ImeAction;-><clinit>()V
+HSPLandroidx/compose/ui/text/input/ImeAction;->access$getDefault$cp()I
+HSPLandroidx/compose/ui/text/input/ImeAction;->constructor-impl(I)I
+HSPLandroidx/compose/ui/text/input/ImeOptions$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/input/ImeOptions$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/input/ImeOptions$Companion;->getDefault()Landroidx/compose/ui/text/input/ImeOptions;
+HSPLandroidx/compose/ui/text/input/ImeOptions;-><clinit>()V
+HSPLandroidx/compose/ui/text/input/ImeOptions;-><init>(ZIZII)V
+HSPLandroidx/compose/ui/text/input/ImeOptions;-><init>(ZIZIIILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/input/ImeOptions;-><init>(ZIZIILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/input/ImeOptions;->access$getDefault$cp()Landroidx/compose/ui/text/input/ImeOptions;
+HSPLandroidx/compose/ui/text/input/ImmHelper30;-><init>(Landroid/view/View;)V
+HSPLandroidx/compose/ui/text/input/InputMethodManagerImpl$imm$2;-><init>(Landroidx/compose/ui/text/input/InputMethodManagerImpl;)V
+HSPLandroidx/compose/ui/text/input/InputMethodManagerImpl;-><init>(Landroid/view/View;)V
+HSPLandroidx/compose/ui/text/input/KeyboardCapitalization$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/input/KeyboardCapitalization$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/input/KeyboardCapitalization$Companion;->getNone-IUNYP9k()I
+HSPLandroidx/compose/ui/text/input/KeyboardCapitalization;-><clinit>()V
+HSPLandroidx/compose/ui/text/input/KeyboardCapitalization;->access$getNone$cp()I
+HSPLandroidx/compose/ui/text/input/KeyboardCapitalization;->constructor-impl(I)I
+HSPLandroidx/compose/ui/text/input/KeyboardType$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/input/KeyboardType$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/input/KeyboardType$Companion;->getText-PjHm6EE()I
+HSPLandroidx/compose/ui/text/input/KeyboardType;-><clinit>()V
+HSPLandroidx/compose/ui/text/input/KeyboardType;->access$getText$cp()I
+HSPLandroidx/compose/ui/text/input/KeyboardType;->constructor-impl(I)I
+HSPLandroidx/compose/ui/text/input/TextFieldValue$Companion$Saver$1;-><clinit>()V
+HSPLandroidx/compose/ui/text/input/TextFieldValue$Companion$Saver$1;-><init>()V
+HSPLandroidx/compose/ui/text/input/TextFieldValue$Companion$Saver$2;-><clinit>()V
+HSPLandroidx/compose/ui/text/input/TextFieldValue$Companion$Saver$2;-><init>()V
+HSPLandroidx/compose/ui/text/input/TextFieldValue$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/input/TextFieldValue$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/input/TextFieldValue;-><clinit>()V
+HSPLandroidx/compose/ui/text/input/TextFieldValue;-><init>(Landroidx/compose/ui/text/AnnotatedString;JLandroidx/compose/ui/text/TextRange;)V
+HSPLandroidx/compose/ui/text/input/TextFieldValue;-><init>(Landroidx/compose/ui/text/AnnotatedString;JLandroidx/compose/ui/text/TextRange;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/input/TextFieldValue;-><init>(Ljava/lang/String;JLandroidx/compose/ui/text/TextRange;)V
+HSPLandroidx/compose/ui/text/input/TextFieldValue;-><init>(Ljava/lang/String;JLandroidx/compose/ui/text/TextRange;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/input/TextFieldValue;-><init>(Ljava/lang/String;JLandroidx/compose/ui/text/TextRange;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/input/TextFieldValue;->getText()Ljava/lang/String;
+HSPLandroidx/compose/ui/text/input/TextInputService;-><clinit>()V
+HSPLandroidx/compose/ui/text/input/TextInputService;-><init>(Landroidx/compose/ui/text/input/PlatformTextInputService;)V
+HSPLandroidx/compose/ui/text/input/TextInputServiceAndroid$baseInputConnection$2;-><init>(Landroidx/compose/ui/text/input/TextInputServiceAndroid;)V
+HSPLandroidx/compose/ui/text/input/TextInputServiceAndroid$onEditCommand$1;-><clinit>()V
+HSPLandroidx/compose/ui/text/input/TextInputServiceAndroid$onEditCommand$1;-><init>()V
+HSPLandroidx/compose/ui/text/input/TextInputServiceAndroid$onImeActionPerformed$1;-><clinit>()V
+HSPLandroidx/compose/ui/text/input/TextInputServiceAndroid$onImeActionPerformed$1;-><init>()V
+HSPLandroidx/compose/ui/text/input/TextInputServiceAndroid$textInputCommandEventLoop$1;-><init>(Landroidx/compose/ui/text/input/TextInputServiceAndroid;Lkotlin/coroutines/Continuation;)V
+HSPLandroidx/compose/ui/text/input/TextInputServiceAndroid;-><init>(Landroid/view/View;)V
+HSPLandroidx/compose/ui/text/input/TextInputServiceAndroid;-><init>(Landroid/view/View;Landroidx/compose/ui/text/input/InputMethodManager;)V
+HSPLandroidx/compose/ui/text/input/TextInputServiceAndroid;->isEditorFocused()Z
+HSPLandroidx/compose/ui/text/input/TextInputServiceAndroid;->textInputCommandEventLoop(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/text/intl/AndroidLocale;-><init>(Ljava/util/Locale;)V
+HSPLandroidx/compose/ui/text/intl/AndroidLocale;->toLanguageTag()Ljava/lang/String;
+HSPLandroidx/compose/ui/text/intl/AndroidLocaleDelegateAPI24;-><init>()V
+HSPLandroidx/compose/ui/text/intl/AndroidLocaleDelegateAPI24;->getCurrent()Ljava/util/List;
+HSPLandroidx/compose/ui/text/intl/AndroidPlatformLocale_androidKt;->createPlatformLocaleDelegate()Landroidx/compose/ui/text/intl/PlatformLocaleDelegate;
+HSPLandroidx/compose/ui/text/intl/Locale$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/intl/Locale$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/intl/Locale;-><clinit>()V
+HSPLandroidx/compose/ui/text/intl/Locale;-><init>(Landroidx/compose/ui/text/intl/PlatformLocale;)V
+HSPLandroidx/compose/ui/text/intl/Locale;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/text/intl/Locale;->toLanguageTag()Ljava/lang/String;
+HSPLandroidx/compose/ui/text/intl/LocaleList$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/intl/LocaleList$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/intl/LocaleList$Companion;->getCurrent()Landroidx/compose/ui/text/intl/LocaleList;
+HSPLandroidx/compose/ui/text/intl/LocaleList;-><clinit>()V
+HSPLandroidx/compose/ui/text/intl/LocaleList;-><init>(Ljava/util/List;)V
+HSPLandroidx/compose/ui/text/intl/LocaleList;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/text/intl/PlatformLocaleKt;-><clinit>()V
+HSPLandroidx/compose/ui/text/intl/PlatformLocaleKt;->getPlatformLocaleDelegate()Landroidx/compose/ui/text/intl/PlatformLocaleDelegate;
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphHelper_androidKt$NoopSpan$1;-><init>()V
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphHelper_androidKt;-><clinit>()V
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphHelper_androidKt;->createCharSequence(Ljava/lang/String;FLandroidx/compose/ui/text/TextStyle;Ljava/util/List;Ljava/util/List;Landroidx/compose/ui/unit/Density;Lkotlin/jvm/functions/Function4;Z)Ljava/lang/CharSequence;
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphHelper_androidKt;->isIncludeFontPaddingEnabled(Landroidx/compose/ui/text/TextStyle;)Z
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphIntrinsics$resolveTypeface$1;-><init>(Landroidx/compose/ui/text/platform/AndroidParagraphIntrinsics;)V
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphIntrinsics$resolveTypeface$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphIntrinsics$resolveTypeface$1;->invoke-DPcqOEQ(Landroidx/compose/ui/text/font/FontFamily;Landroidx/compose/ui/text/font/FontWeight;II)Landroid/graphics/Typeface;
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphIntrinsics;-><init>(Ljava/lang/String;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Ljava/util/List;Landroidx/compose/ui/text/font/FontFamily$Resolver;Landroidx/compose/ui/unit/Density;)V
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphIntrinsics;->access$getResolvedTypefaces$p(Landroidx/compose/ui/text/platform/AndroidParagraphIntrinsics;)Ljava/util/List;
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphIntrinsics;->getCharSequence$ui_text_release()Ljava/lang/CharSequence;
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphIntrinsics;->getFontFamilyResolver()Landroidx/compose/ui/text/font/FontFamily$Resolver;
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphIntrinsics;->getHasStaleResolvedFonts()Z
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphIntrinsics;->getLayoutIntrinsics$ui_text_release()Landroidx/compose/ui/text/android/LayoutIntrinsics;
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphIntrinsics;->getMaxIntrinsicWidth()F
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphIntrinsics;->getStyle()Landroidx/compose/ui/text/TextStyle;
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphIntrinsics;->getTextDirectionHeuristic$ui_text_release()I
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphIntrinsics;->getTextPaint$ui_text_release()Landroidx/compose/ui/text/platform/AndroidTextPaint;
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphIntrinsics_androidKt;->ActualParagraphIntrinsics(Ljava/lang/String;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Ljava/util/List;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;)Landroidx/compose/ui/text/ParagraphIntrinsics;
+HSPLandroidx/compose/ui/text/platform/AndroidParagraphIntrinsics_androidKt;->resolveTextDirectionHeuristics-9GRLPo0(Landroidx/compose/ui/text/style/TextDirection;Landroidx/compose/ui/text/intl/LocaleList;)I
+HSPLandroidx/compose/ui/text/platform/AndroidParagraph_androidKt;->ActualParagraph--hBUhpc(Landroidx/compose/ui/text/ParagraphIntrinsics;IZJ)Landroidx/compose/ui/text/Paragraph;
+HSPLandroidx/compose/ui/text/platform/AndroidTextPaint;-><init>(IF)V
+HSPLandroidx/compose/ui/text/platform/AndroidTextPaint;->setBrush-12SF9DM(Landroidx/compose/ui/graphics/Brush;JF)V
+HSPLandroidx/compose/ui/text/platform/AndroidTextPaint;->setColor-8_81llA(J)V
+HSPLandroidx/compose/ui/text/platform/AndroidTextPaint;->setDrawStyle(Landroidx/compose/ui/graphics/drawscope/DrawStyle;)V
+HSPLandroidx/compose/ui/text/platform/AndroidTextPaint;->setShadow(Landroidx/compose/ui/graphics/Shadow;)V
+HSPLandroidx/compose/ui/text/platform/AndroidTextPaint;->setTextDecoration(Landroidx/compose/ui/text/style/TextDecoration;)V
+HSPLandroidx/compose/ui/text/platform/DefaultImpl$getFontLoadState$initCallback$1;-><init>(Landroidx/compose/runtime/MutableState;Landroidx/compose/ui/text/platform/DefaultImpl;)V
+HSPLandroidx/compose/ui/text/platform/DefaultImpl$getFontLoadState$initCallback$1;->onInitialized()V
+HSPLandroidx/compose/ui/text/platform/DefaultImpl;-><init>()V
+HSPLandroidx/compose/ui/text/platform/DefaultImpl;->access$setLoadState$p(Landroidx/compose/ui/text/platform/DefaultImpl;Landroidx/compose/runtime/State;)V
+HSPLandroidx/compose/ui/text/platform/DefaultImpl;->getFontLoadState()Landroidx/compose/runtime/State;
+HSPLandroidx/compose/ui/text/platform/DefaultImpl;->getFontLoaded()Landroidx/compose/runtime/State;
+HSPLandroidx/compose/ui/text/platform/EmojiCompatStatus;-><clinit>()V
+HSPLandroidx/compose/ui/text/platform/EmojiCompatStatus;-><init>()V
+HSPLandroidx/compose/ui/text/platform/EmojiCompatStatus;->getFontLoaded()Landroidx/compose/runtime/State;
+HSPLandroidx/compose/ui/text/platform/ImmutableBool;-><init>(Z)V
+HSPLandroidx/compose/ui/text/platform/ImmutableBool;->getValue()Ljava/lang/Boolean;
+HSPLandroidx/compose/ui/text/platform/ImmutableBool;->getValue()Ljava/lang/Object;
+HSPLandroidx/compose/ui/text/platform/Synchronization_jvmKt;->createSynchronizedObject()Landroidx/compose/ui/text/platform/SynchronizedObject;
+HSPLandroidx/compose/ui/text/platform/SynchronizedObject;-><init>()V
+HSPLandroidx/compose/ui/text/platform/TypefaceDirtyTracker;-><init>(Landroidx/compose/runtime/State;)V
+HSPLandroidx/compose/ui/text/platform/TypefaceDirtyTracker;->getTypeface()Landroid/graphics/Typeface;
+HSPLandroidx/compose/ui/text/platform/TypefaceDirtyTracker;->isStaleResolvedFont()Z
+HSPLandroidx/compose/ui/text/platform/extensions/PlaceholderExtensions_androidKt;->setPlaceholders(Landroid/text/Spannable;Ljava/util/List;Landroidx/compose/ui/unit/Density;)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt$setFontAttributes$1;-><init>(Landroid/text/Spannable;Lkotlin/jvm/functions/Function4;)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->createLetterSpacingSpan-eAf_CNQ(JLandroidx/compose/ui/unit/Density;)Landroid/text/style/MetricAffectingSpan;
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->flattenFontStylesAndApply(Landroidx/compose/ui/text/SpanStyle;Ljava/util/List;Lkotlin/jvm/functions/Function3;)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->hasFontAttributes(Landroidx/compose/ui/text/TextStyle;)Z
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->resolveLineHeightInPx-o2QH7mI(JFLandroidx/compose/ui/unit/Density;)F
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->setBackground-RPmYEkk(Landroid/text/Spannable;JII)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->setBaselineShift-0ocSgnM(Landroid/text/Spannable;Landroidx/compose/ui/text/style/BaselineShift;II)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->setBrush(Landroid/text/Spannable;Landroidx/compose/ui/graphics/Brush;FII)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->setColor-RPmYEkk(Landroid/text/Spannable;JII)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->setDrawStyle(Landroid/text/Spannable;Landroidx/compose/ui/graphics/drawscope/DrawStyle;II)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->setFontAttributes(Landroid/text/Spannable;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Lkotlin/jvm/functions/Function4;)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->setFontFeatureSettings(Landroid/text/Spannable;Ljava/lang/String;II)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->setFontSize-KmRG4DE(Landroid/text/Spannable;JLandroidx/compose/ui/unit/Density;II)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->setGeometricTransform(Landroid/text/Spannable;Landroidx/compose/ui/text/style/TextGeometricTransform;II)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->setLineHeight-r9BaKPg(Landroid/text/Spannable;JFLandroidx/compose/ui/unit/Density;)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->setLocaleList(Landroid/text/Spannable;Landroidx/compose/ui/text/intl/LocaleList;II)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->setShadow(Landroid/text/Spannable;Landroidx/compose/ui/graphics/Shadow;II)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->setSpan(Landroid/text/Spannable;Ljava/lang/Object;II)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->setSpanStyle(Landroid/text/Spannable;Landroidx/compose/ui/text/AnnotatedString$Range;Landroidx/compose/ui/unit/Density;Ljava/util/ArrayList;)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->setSpanStyles(Landroid/text/Spannable;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Landroidx/compose/ui/unit/Density;Lkotlin/jvm/functions/Function4;)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->setTextDecoration(Landroid/text/Spannable;Landroidx/compose/ui/text/style/TextDecoration;II)V
+HSPLandroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;->setTextIndent(Landroid/text/Spannable;Landroidx/compose/ui/text/style/TextIndent;FLandroidx/compose/ui/unit/Density;)V
+HSPLandroidx/compose/ui/text/platform/extensions/TextPaintExtensions_androidKt;->applySpanStyle(Landroidx/compose/ui/text/platform/AndroidTextPaint;Landroidx/compose/ui/text/SpanStyle;Lkotlin/jvm/functions/Function4;Landroidx/compose/ui/unit/Density;)Landroidx/compose/ui/text/SpanStyle;
+HSPLandroidx/compose/ui/text/platform/extensions/TextPaintExtensions_androidKt;->hasFontAttributes(Landroidx/compose/ui/text/SpanStyle;)Z
+HSPLandroidx/compose/ui/text/style/BaselineShift$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/style/BaselineShift$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/style/BaselineShift$Companion;->getNone-y9eOQZs()F
+HSPLandroidx/compose/ui/text/style/BaselineShift;-><clinit>()V
+HSPLandroidx/compose/ui/text/style/BaselineShift;-><init>(F)V
+HSPLandroidx/compose/ui/text/style/BaselineShift;->access$getNone$cp()F
+HSPLandroidx/compose/ui/text/style/BaselineShift;->box-impl(F)Landroidx/compose/ui/text/style/BaselineShift;
+HSPLandroidx/compose/ui/text/style/BaselineShift;->constructor-impl(F)F
+HSPLandroidx/compose/ui/text/style/BaselineShift;->equals-impl0(FF)Z
+HSPLandroidx/compose/ui/text/style/BaselineShift;->unbox-impl()F
+HSPLandroidx/compose/ui/text/style/ColorStyle;-><init>(J)V
+HSPLandroidx/compose/ui/text/style/ColorStyle;-><init>(JLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/style/ColorStyle;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/text/style/ColorStyle;->getAlpha()F
+HSPLandroidx/compose/ui/text/style/ColorStyle;->getBrush()Landroidx/compose/ui/graphics/Brush;
+HSPLandroidx/compose/ui/text/style/ColorStyle;->getColor-0d7_KjU()J
+HSPLandroidx/compose/ui/text/style/Hyphens$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/style/Hyphens$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/style/Hyphens$Companion;->getAuto()Landroidx/compose/ui/text/style/Hyphens;
+HSPLandroidx/compose/ui/text/style/Hyphens$Companion;->getNone()Landroidx/compose/ui/text/style/Hyphens;
+HSPLandroidx/compose/ui/text/style/Hyphens;-><clinit>()V
+HSPLandroidx/compose/ui/text/style/Hyphens;-><init>()V
+HSPLandroidx/compose/ui/text/style/Hyphens;->access$getAuto$cp()Landroidx/compose/ui/text/style/Hyphens;
+HSPLandroidx/compose/ui/text/style/Hyphens;->access$getNone$cp()Landroidx/compose/ui/text/style/Hyphens;
+HSPLandroidx/compose/ui/text/style/LineBreak$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/style/LineBreak$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/style/LineBreak$Companion;->getSimple()Landroidx/compose/ui/text/style/LineBreak;
+HSPLandroidx/compose/ui/text/style/LineBreak$Strategy$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/style/LineBreak$Strategy$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/style/LineBreak$Strategy$Companion;->getBalanced-fcGXIks()I
+HSPLandroidx/compose/ui/text/style/LineBreak$Strategy$Companion;->getHighQuality-fcGXIks()I
+HSPLandroidx/compose/ui/text/style/LineBreak$Strategy$Companion;->getSimple-fcGXIks()I
+HSPLandroidx/compose/ui/text/style/LineBreak$Strategy;-><clinit>()V
+HSPLandroidx/compose/ui/text/style/LineBreak$Strategy;-><init>(I)V
+HSPLandroidx/compose/ui/text/style/LineBreak$Strategy;->access$getBalanced$cp()I
+HSPLandroidx/compose/ui/text/style/LineBreak$Strategy;->access$getHighQuality$cp()I
+HSPLandroidx/compose/ui/text/style/LineBreak$Strategy;->access$getSimple$cp()I
+HSPLandroidx/compose/ui/text/style/LineBreak$Strategy;->box-impl(I)Landroidx/compose/ui/text/style/LineBreak$Strategy;
+HSPLandroidx/compose/ui/text/style/LineBreak$Strategy;->constructor-impl(I)I
+HSPLandroidx/compose/ui/text/style/LineBreak$Strategy;->equals-impl0(II)Z
+HSPLandroidx/compose/ui/text/style/LineBreak$Strategy;->unbox-impl()I
+HSPLandroidx/compose/ui/text/style/LineBreak$Strictness$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/style/LineBreak$Strictness$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/style/LineBreak$Strictness$Companion;->getDefault-usljTpc()I
+HSPLandroidx/compose/ui/text/style/LineBreak$Strictness$Companion;->getLoose-usljTpc()I
+HSPLandroidx/compose/ui/text/style/LineBreak$Strictness$Companion;->getNormal-usljTpc()I
+HSPLandroidx/compose/ui/text/style/LineBreak$Strictness$Companion;->getStrict-usljTpc()I
+HSPLandroidx/compose/ui/text/style/LineBreak$Strictness;-><clinit>()V
+HSPLandroidx/compose/ui/text/style/LineBreak$Strictness;-><init>(I)V
+HSPLandroidx/compose/ui/text/style/LineBreak$Strictness;->access$getDefault$cp()I
+HSPLandroidx/compose/ui/text/style/LineBreak$Strictness;->access$getLoose$cp()I
+HSPLandroidx/compose/ui/text/style/LineBreak$Strictness;->access$getNormal$cp()I
+HSPLandroidx/compose/ui/text/style/LineBreak$Strictness;->access$getStrict$cp()I
+HSPLandroidx/compose/ui/text/style/LineBreak$Strictness;->box-impl(I)Landroidx/compose/ui/text/style/LineBreak$Strictness;
+HSPLandroidx/compose/ui/text/style/LineBreak$Strictness;->constructor-impl(I)I
+HSPLandroidx/compose/ui/text/style/LineBreak$Strictness;->equals-impl0(II)Z
+HSPLandroidx/compose/ui/text/style/LineBreak$Strictness;->unbox-impl()I
+HSPLandroidx/compose/ui/text/style/LineBreak$WordBreak$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/style/LineBreak$WordBreak$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/style/LineBreak$WordBreak$Companion;->getDefault-jp8hJ3c()I
+HSPLandroidx/compose/ui/text/style/LineBreak$WordBreak$Companion;->getPhrase-jp8hJ3c()I
+HSPLandroidx/compose/ui/text/style/LineBreak$WordBreak;-><clinit>()V
+HSPLandroidx/compose/ui/text/style/LineBreak$WordBreak;-><init>(I)V
+HSPLandroidx/compose/ui/text/style/LineBreak$WordBreak;->access$getDefault$cp()I
+HSPLandroidx/compose/ui/text/style/LineBreak$WordBreak;->access$getPhrase$cp()I
+HSPLandroidx/compose/ui/text/style/LineBreak$WordBreak;->box-impl(I)Landroidx/compose/ui/text/style/LineBreak$WordBreak;
+HSPLandroidx/compose/ui/text/style/LineBreak$WordBreak;->constructor-impl(I)I
+HSPLandroidx/compose/ui/text/style/LineBreak$WordBreak;->equals-impl0(II)Z
+HSPLandroidx/compose/ui/text/style/LineBreak$WordBreak;->unbox-impl()I
+HSPLandroidx/compose/ui/text/style/LineBreak;-><clinit>()V
+HSPLandroidx/compose/ui/text/style/LineBreak;-><init>(III)V
+HSPLandroidx/compose/ui/text/style/LineBreak;-><init>(IIILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/style/LineBreak;->access$getSimple$cp()Landroidx/compose/ui/text/style/LineBreak;
+HSPLandroidx/compose/ui/text/style/LineBreak;->getStrategy-fcGXIks()I
+HSPLandroidx/compose/ui/text/style/LineBreak;->getStrictness-usljTpc()I
+HSPLandroidx/compose/ui/text/style/LineBreak;->getWordBreak-jp8hJ3c()I
+HSPLandroidx/compose/ui/text/style/TextAlign$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/style/TextAlign$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/style/TextAlign$Companion;->getCenter-e0LSkKk()I
+HSPLandroidx/compose/ui/text/style/TextAlign$Companion;->getJustify-e0LSkKk()I
+HSPLandroidx/compose/ui/text/style/TextAlign$Companion;->getLeft-e0LSkKk()I
+HSPLandroidx/compose/ui/text/style/TextAlign$Companion;->getRight-e0LSkKk()I
+HSPLandroidx/compose/ui/text/style/TextAlign$Companion;->getStart-e0LSkKk()I
+HSPLandroidx/compose/ui/text/style/TextAlign;-><clinit>()V
+HSPLandroidx/compose/ui/text/style/TextAlign;-><init>(I)V
+HSPLandroidx/compose/ui/text/style/TextAlign;->access$getCenter$cp()I
+HSPLandroidx/compose/ui/text/style/TextAlign;->access$getJustify$cp()I
+HSPLandroidx/compose/ui/text/style/TextAlign;->access$getLeft$cp()I
+HSPLandroidx/compose/ui/text/style/TextAlign;->access$getRight$cp()I
+HSPLandroidx/compose/ui/text/style/TextAlign;->access$getStart$cp()I
+HSPLandroidx/compose/ui/text/style/TextAlign;->box-impl(I)Landroidx/compose/ui/text/style/TextAlign;
+HSPLandroidx/compose/ui/text/style/TextAlign;->constructor-impl(I)I
+HSPLandroidx/compose/ui/text/style/TextAlign;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/text/style/TextAlign;->equals-impl(ILjava/lang/Object;)Z
+HSPLandroidx/compose/ui/text/style/TextAlign;->equals-impl0(II)Z
+HSPLandroidx/compose/ui/text/style/TextAlign;->unbox-impl()I
+HSPLandroidx/compose/ui/text/style/TextDecoration$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/style/TextDecoration$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/style/TextDecoration$Companion;->getNone()Landroidx/compose/ui/text/style/TextDecoration;
+HSPLandroidx/compose/ui/text/style/TextDecoration$Companion;->getUnderline()Landroidx/compose/ui/text/style/TextDecoration;
+HSPLandroidx/compose/ui/text/style/TextDecoration;-><clinit>()V
+HSPLandroidx/compose/ui/text/style/TextDecoration;-><init>(I)V
+HSPLandroidx/compose/ui/text/style/TextDecoration;->access$getNone$cp()Landroidx/compose/ui/text/style/TextDecoration;
+HSPLandroidx/compose/ui/text/style/TextDecoration;->access$getUnderline$cp()Landroidx/compose/ui/text/style/TextDecoration;
+HSPLandroidx/compose/ui/text/style/TextDecoration;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/text/style/TextDirection$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/style/TextDirection$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/style/TextDirection$Companion;->getContent-s_7X-co()I
+HSPLandroidx/compose/ui/text/style/TextDirection$Companion;->getContentOrLtr-s_7X-co()I
+HSPLandroidx/compose/ui/text/style/TextDirection$Companion;->getContentOrRtl-s_7X-co()I
+HSPLandroidx/compose/ui/text/style/TextDirection$Companion;->getLtr-s_7X-co()I
+HSPLandroidx/compose/ui/text/style/TextDirection;-><clinit>()V
+HSPLandroidx/compose/ui/text/style/TextDirection;-><init>(I)V
+HSPLandroidx/compose/ui/text/style/TextDirection;->access$getContent$cp()I
+HSPLandroidx/compose/ui/text/style/TextDirection;->access$getContentOrLtr$cp()I
+HSPLandroidx/compose/ui/text/style/TextDirection;->access$getContentOrRtl$cp()I
+HSPLandroidx/compose/ui/text/style/TextDirection;->access$getLtr$cp()I
+HSPLandroidx/compose/ui/text/style/TextDirection;->box-impl(I)Landroidx/compose/ui/text/style/TextDirection;
+HSPLandroidx/compose/ui/text/style/TextDirection;->constructor-impl(I)I
+HSPLandroidx/compose/ui/text/style/TextDirection;->equals-impl0(II)Z
+HSPLandroidx/compose/ui/text/style/TextDirection;->unbox-impl()I
+HSPLandroidx/compose/ui/text/style/TextForegroundStyle$Companion;-><clinit>()V
+HSPLandroidx/compose/ui/text/style/TextForegroundStyle$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/style/TextForegroundStyle$Companion;->from-8_81llA(J)Landroidx/compose/ui/text/style/TextForegroundStyle;
+HSPLandroidx/compose/ui/text/style/TextForegroundStyle$Unspecified;-><clinit>()V
+HSPLandroidx/compose/ui/text/style/TextForegroundStyle$Unspecified;-><init>()V
+HSPLandroidx/compose/ui/text/style/TextForegroundStyle$Unspecified;->getAlpha()F
+HSPLandroidx/compose/ui/text/style/TextForegroundStyle$Unspecified;->getBrush()Landroidx/compose/ui/graphics/Brush;
+HSPLandroidx/compose/ui/text/style/TextForegroundStyle$Unspecified;->getColor-0d7_KjU()J
+HSPLandroidx/compose/ui/text/style/TextForegroundStyle$merge$2;-><init>(Landroidx/compose/ui/text/style/TextForegroundStyle;)V
+HSPLandroidx/compose/ui/text/style/TextForegroundStyle$merge$2;->invoke()Landroidx/compose/ui/text/style/TextForegroundStyle;
+HSPLandroidx/compose/ui/text/style/TextForegroundStyle$merge$2;->invoke()Ljava/lang/Object;
+HSPLandroidx/compose/ui/text/style/TextForegroundStyle;-><clinit>()V
+HSPLandroidx/compose/ui/text/style/TextForegroundStyle;->merge(Landroidx/compose/ui/text/style/TextForegroundStyle;)Landroidx/compose/ui/text/style/TextForegroundStyle;
+HSPLandroidx/compose/ui/text/style/TextForegroundStyle;->takeOrElse(Lkotlin/jvm/functions/Function0;)Landroidx/compose/ui/text/style/TextForegroundStyle;
+HSPLandroidx/compose/ui/text/style/TextGeometricTransform$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/style/TextGeometricTransform$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/style/TextGeometricTransform$Companion;->getNone$ui_text_release()Landroidx/compose/ui/text/style/TextGeometricTransform;
+HSPLandroidx/compose/ui/text/style/TextGeometricTransform;-><clinit>()V
+HSPLandroidx/compose/ui/text/style/TextGeometricTransform;-><init>(FF)V
+HSPLandroidx/compose/ui/text/style/TextGeometricTransform;->access$getNone$cp()Landroidx/compose/ui/text/style/TextGeometricTransform;
+HSPLandroidx/compose/ui/text/style/TextGeometricTransform;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/text/style/TextIndent$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/style/TextIndent$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/style/TextIndent$Companion;->getNone()Landroidx/compose/ui/text/style/TextIndent;
+HSPLandroidx/compose/ui/text/style/TextIndent;-><clinit>()V
+HSPLandroidx/compose/ui/text/style/TextIndent;-><init>(JJ)V
+HSPLandroidx/compose/ui/text/style/TextIndent;-><init>(JJILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/style/TextIndent;-><init>(JJLkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/style/TextIndent;->access$getNone$cp()Landroidx/compose/ui/text/style/TextIndent;
+HSPLandroidx/compose/ui/text/style/TextIndent;->getFirstLine-XSAIIZE()J
+HSPLandroidx/compose/ui/text/style/TextIndent;->getRestLine-XSAIIZE()J
+HSPLandroidx/compose/ui/text/style/TextOverflow$Companion;-><init>()V
+HSPLandroidx/compose/ui/text/style/TextOverflow$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/text/style/TextOverflow$Companion;->getClip-gIe3tQ8()I
+HSPLandroidx/compose/ui/text/style/TextOverflow$Companion;->getEllipsis-gIe3tQ8()I
+HSPLandroidx/compose/ui/text/style/TextOverflow;-><clinit>()V
+HSPLandroidx/compose/ui/text/style/TextOverflow;->access$getClip$cp()I
+HSPLandroidx/compose/ui/text/style/TextOverflow;->access$getEllipsis$cp()I
+HSPLandroidx/compose/ui/text/style/TextOverflow;->constructor-impl(I)I
+HSPLandroidx/compose/ui/text/style/TextOverflow;->equals-impl0(II)Z
+HSPLandroidx/compose/ui/unit/AndroidDensity_androidKt;->Density(Landroid/content/Context;)Landroidx/compose/ui/unit/Density;
+HSPLandroidx/compose/ui/unit/Constraints$Companion;-><init>()V
+HSPLandroidx/compose/ui/unit/Constraints$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/unit/Constraints$Companion;->bitsNeedForSize(I)I
+HSPLandroidx/compose/ui/unit/Constraints$Companion;->createConstraints-Zbe2FdA$ui_unit_release(IIII)J
+HSPLandroidx/compose/ui/unit/Constraints;-><clinit>()V
+HSPLandroidx/compose/ui/unit/Constraints;-><init>(J)V
+HSPLandroidx/compose/ui/unit/Constraints;->access$getMinHeightOffsets$cp()[I
+HSPLandroidx/compose/ui/unit/Constraints;->box-impl(J)Landroidx/compose/ui/unit/Constraints;
+HSPLandroidx/compose/ui/unit/Constraints;->constructor-impl(J)J
+HSPLandroidx/compose/ui/unit/Constraints;->copy-Zbe2FdA$default(JIIIIILjava/lang/Object;)J
+HSPLandroidx/compose/ui/unit/Constraints;->copy-Zbe2FdA(JIIII)J
+HSPLandroidx/compose/ui/unit/Constraints;->equals-impl0(JJ)Z
+HSPLandroidx/compose/ui/unit/Constraints;->getFocusIndex-impl(J)I
+HSPLandroidx/compose/ui/unit/Constraints;->getHasBoundedHeight-impl(J)Z
+HSPLandroidx/compose/ui/unit/Constraints;->getHasBoundedWidth-impl(J)Z
+HSPLandroidx/compose/ui/unit/Constraints;->getHasFixedHeight-impl(J)Z
+HSPLandroidx/compose/ui/unit/Constraints;->getHasFixedWidth-impl(J)Z
+HSPLandroidx/compose/ui/unit/Constraints;->getMaxHeight-impl(J)I
+HSPLandroidx/compose/ui/unit/Constraints;->getMaxWidth-impl(J)I
+HSPLandroidx/compose/ui/unit/Constraints;->getMinHeight-impl(J)I
+HSPLandroidx/compose/ui/unit/Constraints;->getMinWidth-impl(J)I
+HSPLandroidx/compose/ui/unit/Constraints;->unbox-impl()J
+HSPLandroidx/compose/ui/unit/ConstraintsKt;->Constraints$default(IIIIILjava/lang/Object;)J
+HSPLandroidx/compose/ui/unit/ConstraintsKt;->Constraints(IIII)J
+HSPLandroidx/compose/ui/unit/ConstraintsKt;->addMaxWithMinimum(II)I
+HSPLandroidx/compose/ui/unit/ConstraintsKt;->constrain-4WqzIAM(JJ)J
+HSPLandroidx/compose/ui/unit/ConstraintsKt;->constrain-N9IONVI(JJ)J
+HSPLandroidx/compose/ui/unit/ConstraintsKt;->constrainHeight-K40F9xA(JI)I
+HSPLandroidx/compose/ui/unit/ConstraintsKt;->constrainWidth-K40F9xA(JI)I
+HSPLandroidx/compose/ui/unit/ConstraintsKt;->offset-NN6Ew-U(JII)J
+HSPLandroidx/compose/ui/unit/Density;->roundToPx-0680j_4(F)I
+HSPLandroidx/compose/ui/unit/Density;->toPx--R2X_6o(J)F
+HSPLandroidx/compose/ui/unit/Density;->toPx-0680j_4(F)F
+HSPLandroidx/compose/ui/unit/DensityImpl;-><init>(FF)V
+HSPLandroidx/compose/ui/unit/DensityImpl;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/unit/DensityImpl;->getDensity()F
+HSPLandroidx/compose/ui/unit/DensityImpl;->getFontScale()F
+HSPLandroidx/compose/ui/unit/DensityKt;->Density$default(FFILjava/lang/Object;)Landroidx/compose/ui/unit/Density;
+HSPLandroidx/compose/ui/unit/DensityKt;->Density(FF)Landroidx/compose/ui/unit/Density;
+HSPLandroidx/compose/ui/unit/Dp$Companion;-><init>()V
+HSPLandroidx/compose/ui/unit/Dp$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/unit/Dp$Companion;->getHairline-D9Ej5fM()F
+HSPLandroidx/compose/ui/unit/Dp$Companion;->getUnspecified-D9Ej5fM()F
+HSPLandroidx/compose/ui/unit/Dp;-><clinit>()V
+HSPLandroidx/compose/ui/unit/Dp;-><init>(F)V
+HSPLandroidx/compose/ui/unit/Dp;->access$getHairline$cp()F
+HSPLandroidx/compose/ui/unit/Dp;->access$getUnspecified$cp()F
+HSPLandroidx/compose/ui/unit/Dp;->box-impl(F)Landroidx/compose/ui/unit/Dp;
+HSPLandroidx/compose/ui/unit/Dp;->compareTo(Ljava/lang/Object;)I
+HSPLandroidx/compose/ui/unit/Dp;->compareTo-0680j_4(F)I
+HSPLandroidx/compose/ui/unit/Dp;->compareTo-0680j_4(FF)I
+HSPLandroidx/compose/ui/unit/Dp;->constructor-impl(F)F
+HSPLandroidx/compose/ui/unit/Dp;->equals(Ljava/lang/Object;)Z
+HSPLandroidx/compose/ui/unit/Dp;->equals-impl(FLjava/lang/Object;)Z
+HSPLandroidx/compose/ui/unit/Dp;->equals-impl0(FF)Z
+HSPLandroidx/compose/ui/unit/Dp;->unbox-impl()F
+HSPLandroidx/compose/ui/unit/DpKt;->DpOffset-YgX7TsA(FF)J
+HSPLandroidx/compose/ui/unit/DpKt;->DpSize-YgX7TsA(FF)J
+HSPLandroidx/compose/ui/unit/DpOffset$Companion;-><init>()V
+HSPLandroidx/compose/ui/unit/DpOffset$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/unit/DpOffset;-><clinit>()V
+HSPLandroidx/compose/ui/unit/DpOffset;->constructor-impl(J)J
+HSPLandroidx/compose/ui/unit/DpSize$Companion;-><init>()V
+HSPLandroidx/compose/ui/unit/DpSize$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/unit/DpSize;-><clinit>()V
+HSPLandroidx/compose/ui/unit/DpSize;->constructor-impl(J)J
+HSPLandroidx/compose/ui/unit/DpSize;->equals-impl0(JJ)Z
+HSPLandroidx/compose/ui/unit/DpSize;->getHeight-D9Ej5fM(J)F
+HSPLandroidx/compose/ui/unit/DpSize;->getWidth-D9Ej5fM(J)F
+HSPLandroidx/compose/ui/unit/IntOffset$Companion;-><init>()V
+HSPLandroidx/compose/ui/unit/IntOffset$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/unit/IntOffset$Companion;->getZero-nOcc-ac()J
+HSPLandroidx/compose/ui/unit/IntOffset;-><clinit>()V
+HSPLandroidx/compose/ui/unit/IntOffset;-><init>(J)V
+HSPLandroidx/compose/ui/unit/IntOffset;->access$getZero$cp()J
+HSPLandroidx/compose/ui/unit/IntOffset;->box-impl(J)Landroidx/compose/ui/unit/IntOffset;
+HSPLandroidx/compose/ui/unit/IntOffset;->component1-impl(J)I
+HSPLandroidx/compose/ui/unit/IntOffset;->component2-impl(J)I
+HSPLandroidx/compose/ui/unit/IntOffset;->constructor-impl(J)J
+HSPLandroidx/compose/ui/unit/IntOffset;->equals-impl0(JJ)Z
+HSPLandroidx/compose/ui/unit/IntOffset;->getX-impl(J)I
+HSPLandroidx/compose/ui/unit/IntOffset;->getY-impl(J)I
+HSPLandroidx/compose/ui/unit/IntOffset;->unbox-impl()J
+HSPLandroidx/compose/ui/unit/IntOffsetKt;->IntOffset(II)J
+HSPLandroidx/compose/ui/unit/IntSize$Companion;-><init>()V
+HSPLandroidx/compose/ui/unit/IntSize$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/unit/IntSize$Companion;->getZero-YbymL2g()J
+HSPLandroidx/compose/ui/unit/IntSize;-><clinit>()V
+HSPLandroidx/compose/ui/unit/IntSize;-><init>(J)V
+HSPLandroidx/compose/ui/unit/IntSize;->access$getZero$cp()J
+HSPLandroidx/compose/ui/unit/IntSize;->box-impl(J)Landroidx/compose/ui/unit/IntSize;
+HSPLandroidx/compose/ui/unit/IntSize;->constructor-impl(J)J
+HSPLandroidx/compose/ui/unit/IntSize;->equals-impl0(JJ)Z
+HSPLandroidx/compose/ui/unit/IntSize;->getHeight-impl(J)I
+HSPLandroidx/compose/ui/unit/IntSize;->getWidth-impl(J)I
+HSPLandroidx/compose/ui/unit/IntSizeKt;->IntSize(II)J
+HSPLandroidx/compose/ui/unit/IntSizeKt;->getCenter-ozmzZPI(J)J
+HSPLandroidx/compose/ui/unit/IntSizeKt;->toSize-ozmzZPI(J)J
+HSPLandroidx/compose/ui/unit/LayoutDirection;->$values()[Landroidx/compose/ui/unit/LayoutDirection;
+HSPLandroidx/compose/ui/unit/LayoutDirection;-><clinit>()V
+HSPLandroidx/compose/ui/unit/LayoutDirection;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/compose/ui/unit/LayoutDirection;->values()[Landroidx/compose/ui/unit/LayoutDirection;
+HSPLandroidx/compose/ui/unit/TextUnit$Companion;-><init>()V
+HSPLandroidx/compose/ui/unit/TextUnit$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/unit/TextUnit$Companion;->getUnspecified-XSAIIZE()J
+HSPLandroidx/compose/ui/unit/TextUnit;-><clinit>()V
+HSPLandroidx/compose/ui/unit/TextUnit;->access$getUnspecified$cp()J
+HSPLandroidx/compose/ui/unit/TextUnit;->constructor-impl(J)J
+HSPLandroidx/compose/ui/unit/TextUnit;->equals-impl0(JJ)Z
+HSPLandroidx/compose/ui/unit/TextUnit;->getRawType-impl(J)J
+HSPLandroidx/compose/ui/unit/TextUnit;->getType-UIouoOA(J)J
+HSPLandroidx/compose/ui/unit/TextUnit;->getValue-impl(J)F
+HSPLandroidx/compose/ui/unit/TextUnitKt;->checkArithmetic--R2X_6o(J)V
+HSPLandroidx/compose/ui/unit/TextUnitKt;->getSp(D)J
+HSPLandroidx/compose/ui/unit/TextUnitKt;->getSp(I)J
+HSPLandroidx/compose/ui/unit/TextUnitKt;->isUnspecified--R2X_6o(J)Z
+HSPLandroidx/compose/ui/unit/TextUnitKt;->pack(JF)J
+HSPLandroidx/compose/ui/unit/TextUnitType$Companion;-><init>()V
+HSPLandroidx/compose/ui/unit/TextUnitType$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/compose/ui/unit/TextUnitType$Companion;->getEm-UIouoOA()J
+HSPLandroidx/compose/ui/unit/TextUnitType$Companion;->getSp-UIouoOA()J
+HSPLandroidx/compose/ui/unit/TextUnitType$Companion;->getUnspecified-UIouoOA()J
+HSPLandroidx/compose/ui/unit/TextUnitType;-><clinit>()V
+HSPLandroidx/compose/ui/unit/TextUnitType;-><init>(J)V
+HSPLandroidx/compose/ui/unit/TextUnitType;->access$getEm$cp()J
+HSPLandroidx/compose/ui/unit/TextUnitType;->access$getSp$cp()J
+HSPLandroidx/compose/ui/unit/TextUnitType;->access$getUnspecified$cp()J
+HSPLandroidx/compose/ui/unit/TextUnitType;->box-impl(J)Landroidx/compose/ui/unit/TextUnitType;
+HSPLandroidx/compose/ui/unit/TextUnitType;->constructor-impl(J)J
+HSPLandroidx/compose/ui/unit/TextUnitType;->equals-impl0(JJ)Z
+HSPLandroidx/compose/ui/unit/TextUnitType;->unbox-impl()J
+HSPLandroidx/core/app/ComponentActivity;-><init>()V
+HSPLandroidx/core/app/ComponentActivity;->onCreate(Landroid/os/Bundle;)V
+HSPLandroidx/core/app/CoreComponentFactory;-><init>()V
+HSPLandroidx/core/app/CoreComponentFactory;->checkCompatWrapper(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/core/app/CoreComponentFactory;->instantiateActivity(Ljava/lang/ClassLoader;Ljava/lang/String;Landroid/content/Intent;)Landroid/app/Activity;
+HSPLandroidx/core/app/CoreComponentFactory;->instantiateApplication(Ljava/lang/ClassLoader;Ljava/lang/String;)Landroid/app/Application;
+HSPLandroidx/core/app/CoreComponentFactory;->instantiateProvider(Ljava/lang/ClassLoader;Ljava/lang/String;)Landroid/content/ContentProvider;
+HSPLandroidx/core/graphics/TypefaceCompat;-><clinit>()V
+HSPLandroidx/core/graphics/TypefaceCompat;->createFromFontInfo(Landroid/content/Context;Landroid/os/CancellationSignal;[Landroidx/core/provider/FontsContractCompat$FontInfo;I)Landroid/graphics/Typeface;
+HSPLandroidx/core/graphics/TypefaceCompatApi29Impl;-><init>()V
+HSPLandroidx/core/graphics/TypefaceCompatApi29Impl;->createFromFontInfo(Landroid/content/Context;Landroid/os/CancellationSignal;[Landroidx/core/provider/FontsContractCompat$FontInfo;I)Landroid/graphics/Typeface;
+HSPLandroidx/core/graphics/TypefaceCompatApi29Impl;->findBaseFont(Landroid/graphics/fonts/FontFamily;I)Landroid/graphics/fonts/Font;
+HSPLandroidx/core/graphics/TypefaceCompatApi29Impl;->getMatchScore(Landroid/graphics/fonts/FontStyle;Landroid/graphics/fonts/FontStyle;)I
+HSPLandroidx/core/graphics/TypefaceCompatBaseImpl;-><init>()V
+HSPLandroidx/core/graphics/TypefaceCompatUtil$Api19Impl;->openFileDescriptor(Landroid/content/ContentResolver;Landroid/net/Uri;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/os/ParcelFileDescriptor;
+HSPLandroidx/core/graphics/TypefaceCompatUtil;->mmap(Landroid/content/Context;Landroid/os/CancellationSignal;Landroid/net/Uri;)Ljava/nio/ByteBuffer;
+HSPLandroidx/core/graphics/drawable/DrawableKt;->toBitmap$default(Landroid/graphics/drawable/Drawable;IILandroid/graphics/Bitmap$Config;ILjava/lang/Object;)Landroid/graphics/Bitmap;
+HSPLandroidx/core/graphics/drawable/DrawableKt;->toBitmap(Landroid/graphics/drawable/Drawable;IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;
+HSPLandroidx/core/os/BuildCompat;->isAtLeastT()Z
+HSPLandroidx/core/os/HandlerCompat$Api28Impl;->createAsync(Landroid/os/Looper;)Landroid/os/Handler;
+HSPLandroidx/core/os/HandlerCompat;->createAsync(Landroid/os/Looper;)Landroid/os/Handler;
+HSPLandroidx/core/os/TraceCompat$Api18Impl;->beginSection(Ljava/lang/String;)V
+HSPLandroidx/core/os/TraceCompat$Api18Impl;->endSection()V
+HSPLandroidx/core/os/TraceCompat;-><clinit>()V
+HSPLandroidx/core/os/TraceCompat;->beginSection(Ljava/lang/String;)V
+HSPLandroidx/core/os/TraceCompat;->endSection()V
+HSPLandroidx/core/provider/FontProvider$$ExternalSyntheticLambda0;-><init>()V
+HSPLandroidx/core/provider/FontProvider$Api16Impl;->query(Landroid/content/ContentResolver;Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)Landroid/database/Cursor;
+HSPLandroidx/core/provider/FontProvider;-><clinit>()V
+HSPLandroidx/core/provider/FontProvider;->convertToByteArrayList([Landroid/content/pm/Signature;)Ljava/util/List;
+HSPLandroidx/core/provider/FontProvider;->equalsByteArrayList(Ljava/util/List;Ljava/util/List;)Z
+HSPLandroidx/core/provider/FontProvider;->getCertificates(Landroidx/core/provider/FontRequest;Landroid/content/res/Resources;)Ljava/util/List;
+HSPLandroidx/core/provider/FontProvider;->getFontFamilyResult(Landroid/content/Context;Landroidx/core/provider/FontRequest;Landroid/os/CancellationSignal;)Landroidx/core/provider/FontsContractCompat$FontFamilyResult;
+HSPLandroidx/core/provider/FontProvider;->getProvider(Landroid/content/pm/PackageManager;Landroidx/core/provider/FontRequest;Landroid/content/res/Resources;)Landroid/content/pm/ProviderInfo;
+HSPLandroidx/core/provider/FontProvider;->query(Landroid/content/Context;Landroidx/core/provider/FontRequest;Ljava/lang/String;Landroid/os/CancellationSignal;)[Landroidx/core/provider/FontsContractCompat$FontInfo;
+HSPLandroidx/core/provider/FontRequest;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)V
+HSPLandroidx/core/provider/FontRequest;->createIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroidx/core/provider/FontRequest;->getCertificates()Ljava/util/List;
+HSPLandroidx/core/provider/FontRequest;->getProviderAuthority()Ljava/lang/String;
+HSPLandroidx/core/provider/FontRequest;->getProviderPackage()Ljava/lang/String;
+HSPLandroidx/core/provider/FontRequest;->getQuery()Ljava/lang/String;
+HSPLandroidx/core/provider/FontsContractCompat$FontFamilyResult;-><init>(I[Landroidx/core/provider/FontsContractCompat$FontInfo;)V
+HSPLandroidx/core/provider/FontsContractCompat$FontFamilyResult;->create(I[Landroidx/core/provider/FontsContractCompat$FontInfo;)Landroidx/core/provider/FontsContractCompat$FontFamilyResult;
+HSPLandroidx/core/provider/FontsContractCompat$FontFamilyResult;->getFonts()[Landroidx/core/provider/FontsContractCompat$FontInfo;
+HSPLandroidx/core/provider/FontsContractCompat$FontFamilyResult;->getStatusCode()I
+HSPLandroidx/core/provider/FontsContractCompat$FontInfo;-><init>(Landroid/net/Uri;IIZI)V
+HSPLandroidx/core/provider/FontsContractCompat$FontInfo;->create(Landroid/net/Uri;IIZI)Landroidx/core/provider/FontsContractCompat$FontInfo;
+HSPLandroidx/core/provider/FontsContractCompat$FontInfo;->getResultCode()I
+HSPLandroidx/core/provider/FontsContractCompat$FontInfo;->getTtcIndex()I
+HSPLandroidx/core/provider/FontsContractCompat$FontInfo;->getUri()Landroid/net/Uri;
+HSPLandroidx/core/provider/FontsContractCompat$FontInfo;->getWeight()I
+HSPLandroidx/core/provider/FontsContractCompat$FontInfo;->isItalic()Z
+HSPLandroidx/core/provider/FontsContractCompat;->buildTypeface(Landroid/content/Context;Landroid/os/CancellationSignal;[Landroidx/core/provider/FontsContractCompat$FontInfo;)Landroid/graphics/Typeface;
+HSPLandroidx/core/provider/FontsContractCompat;->fetchFonts(Landroid/content/Context;Landroid/os/CancellationSignal;Landroidx/core/provider/FontRequest;)Landroidx/core/provider/FontsContractCompat$FontFamilyResult;
+HSPLandroidx/core/util/Preconditions;->checkArgument(ZLjava/lang/Object;)V
+HSPLandroidx/core/util/Preconditions;->checkArgumentNonnegative(ILjava/lang/String;)I
+HSPLandroidx/core/util/Preconditions;->checkNotNull(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/core/util/Preconditions;->checkNotNull(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/core/util/Preconditions;->checkState(ZLjava/lang/String;)V
+HSPLandroidx/core/view/AccessibilityDelegateCompat$AccessibilityDelegateAdapter;-><init>(Landroidx/core/view/AccessibilityDelegateCompat;)V
+HSPLandroidx/core/view/AccessibilityDelegateCompat;-><clinit>()V
+HSPLandroidx/core/view/AccessibilityDelegateCompat;-><init>()V
+HSPLandroidx/core/view/AccessibilityDelegateCompat;-><init>(Landroid/view/View$AccessibilityDelegate;)V
+HSPLandroidx/core/view/AccessibilityDelegateCompat;->getBridge()Landroid/view/View$AccessibilityDelegate;
+HSPLandroidx/core/view/MenuHostHelper;-><init>(Ljava/lang/Runnable;)V
+HSPLandroidx/core/view/ViewCompat$$ExternalSyntheticLambda0;-><init>()V
+HSPLandroidx/core/view/ViewCompat$AccessibilityPaneVisibilityManager;-><init>()V
+HSPLandroidx/core/view/ViewCompat;-><clinit>()V
+HSPLandroidx/core/view/ViewCompat;->setAccessibilityDelegate(Landroid/view/View;Landroidx/core/view/AccessibilityDelegateCompat;)V
+HSPLandroidx/core/view/accessibility/AccessibilityNodeProviderCompat;-><init>(Ljava/lang/Object;)V
+HSPLandroidx/customview/poolingcontainer/PoolingContainer;-><clinit>()V
+HSPLandroidx/customview/poolingcontainer/PoolingContainer;->addPoolingContainerListener(Landroid/view/View;Landroidx/customview/poolingcontainer/PoolingContainerListener;)V
+HSPLandroidx/customview/poolingcontainer/PoolingContainer;->getPoolingContainerListenerHolder(Landroid/view/View;)Landroidx/customview/poolingcontainer/PoolingContainerListenerHolder;
+HSPLandroidx/customview/poolingcontainer/PoolingContainerListenerHolder;-><init>()V
+HSPLandroidx/customview/poolingcontainer/PoolingContainerListenerHolder;->addListener(Landroidx/customview/poolingcontainer/PoolingContainerListener;)V
+HSPLandroidx/emoji2/text/ConcurrencyHelpers$$ExternalSyntheticLambda0;-><init>(Ljava/lang/String;)V
+HSPLandroidx/emoji2/text/ConcurrencyHelpers$$ExternalSyntheticLambda0;->newThread(Ljava/lang/Runnable;)Ljava/lang/Thread;
+HSPLandroidx/emoji2/text/ConcurrencyHelpers$Handler28Impl;->createAsync(Landroid/os/Looper;)Landroid/os/Handler;
+HSPLandroidx/emoji2/text/ConcurrencyHelpers;->$r8$lambda$rm7NN8F9tEuy2Vr8i0fl8_hnx_A(Ljava/lang/String;Ljava/lang/Runnable;)Ljava/lang/Thread;
+HSPLandroidx/emoji2/text/ConcurrencyHelpers;->createBackgroundPriorityExecutor(Ljava/lang/String;)Ljava/util/concurrent/ThreadPoolExecutor;
+HSPLandroidx/emoji2/text/ConcurrencyHelpers;->lambda$createBackgroundPriorityExecutor$0(Ljava/lang/String;Ljava/lang/Runnable;)Ljava/lang/Thread;
+HSPLandroidx/emoji2/text/ConcurrencyHelpers;->mainHandlerAsync()Landroid/os/Handler;
+HSPLandroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigFactory;-><init>(Landroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigHelper;)V
+HSPLandroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigFactory;->configOrNull(Landroid/content/Context;Landroidx/core/provider/FontRequest;)Landroidx/emoji2/text/EmojiCompat$Config;
+HSPLandroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigFactory;->convertToByteArray([Landroid/content/pm/Signature;)Ljava/util/List;
+HSPLandroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigFactory;->create(Landroid/content/Context;)Landroidx/emoji2/text/EmojiCompat$Config;
+HSPLandroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigFactory;->generateFontRequestFrom(Landroid/content/pm/ProviderInfo;Landroid/content/pm/PackageManager;)Landroidx/core/provider/FontRequest;
+HSPLandroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigFactory;->getHelperForApi()Landroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigHelper;
+HSPLandroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigFactory;->hasFlagSystem(Landroid/content/pm/ProviderInfo;)Z
+HSPLandroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigFactory;->queryDefaultInstalledContentProvider(Landroid/content/pm/PackageManager;)Landroid/content/pm/ProviderInfo;
+HSPLandroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigFactory;->queryForDefaultFontRequest(Landroid/content/Context;)Landroidx/core/provider/FontRequest;
+HSPLandroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigHelper;-><init>()V
+HSPLandroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigHelper_API19;-><init>()V
+HSPLandroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigHelper_API19;->getProviderInfo(Landroid/content/pm/ResolveInfo;)Landroid/content/pm/ProviderInfo;
+HSPLandroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigHelper_API19;->queryIntentContentProviders(Landroid/content/pm/PackageManager;Landroid/content/Intent;I)Ljava/util/List;
+HSPLandroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigHelper_API28;-><init>()V
+HSPLandroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigHelper_API28;->getSigningSignatures(Landroid/content/pm/PackageManager;Ljava/lang/String;)[Landroid/content/pm/Signature;
+HSPLandroidx/emoji2/text/DefaultEmojiCompatConfig;->create(Landroid/content/Context;)Landroidx/emoji2/text/FontRequestEmojiCompatConfig;
+HSPLandroidx/emoji2/text/DefaultGlyphChecker;-><clinit>()V
+HSPLandroidx/emoji2/text/DefaultGlyphChecker;-><init>()V
+HSPLandroidx/emoji2/text/EmojiCompat$CompatInternal19$1;-><init>(Landroidx/emoji2/text/EmojiCompat$CompatInternal19;)V
+HSPLandroidx/emoji2/text/EmojiCompat$CompatInternal19$1;->onLoaded(Landroidx/emoji2/text/MetadataRepo;)V
+HSPLandroidx/emoji2/text/EmojiCompat$CompatInternal19;-><init>(Landroidx/emoji2/text/EmojiCompat;)V
+HSPLandroidx/emoji2/text/EmojiCompat$CompatInternal19;->loadMetadata()V
+HSPLandroidx/emoji2/text/EmojiCompat$CompatInternal19;->onMetadataLoadSuccess(Landroidx/emoji2/text/MetadataRepo;)V
+HSPLandroidx/emoji2/text/EmojiCompat$CompatInternal19;->process(Ljava/lang/CharSequence;IIIZ)Ljava/lang/CharSequence;
+HSPLandroidx/emoji2/text/EmojiCompat$CompatInternal;-><init>(Landroidx/emoji2/text/EmojiCompat;)V
+HSPLandroidx/emoji2/text/EmojiCompat$Config;-><init>(Landroidx/emoji2/text/EmojiCompat$MetadataRepoLoader;)V
+HSPLandroidx/emoji2/text/EmojiCompat$Config;->getMetadataRepoLoader()Landroidx/emoji2/text/EmojiCompat$MetadataRepoLoader;
+HSPLandroidx/emoji2/text/EmojiCompat$Config;->setMetadataLoadStrategy(I)Landroidx/emoji2/text/EmojiCompat$Config;
+HSPLandroidx/emoji2/text/EmojiCompat$InitCallback;-><init>()V
+HSPLandroidx/emoji2/text/EmojiCompat$ListenerDispatcher;-><init>(Ljava/util/Collection;I)V
+HSPLandroidx/emoji2/text/EmojiCompat$ListenerDispatcher;-><init>(Ljava/util/Collection;ILjava/lang/Throwable;)V
+HSPLandroidx/emoji2/text/EmojiCompat$ListenerDispatcher;->run()V
+HSPLandroidx/emoji2/text/EmojiCompat$MetadataRepoLoaderCallback;-><init>()V
+HSPLandroidx/emoji2/text/EmojiCompat$SpanFactory;-><init>()V
+HSPLandroidx/emoji2/text/EmojiCompat;-><clinit>()V
+HSPLandroidx/emoji2/text/EmojiCompat;-><init>(Landroidx/emoji2/text/EmojiCompat$Config;)V
+HSPLandroidx/emoji2/text/EmojiCompat;->access$000(Landroidx/emoji2/text/EmojiCompat;)Landroidx/emoji2/text/EmojiCompat$GlyphChecker;
+HSPLandroidx/emoji2/text/EmojiCompat;->get()Landroidx/emoji2/text/EmojiCompat;
+HSPLandroidx/emoji2/text/EmojiCompat;->getLoadState()I
+HSPLandroidx/emoji2/text/EmojiCompat;->init(Landroidx/emoji2/text/EmojiCompat$Config;)Landroidx/emoji2/text/EmojiCompat;
+HSPLandroidx/emoji2/text/EmojiCompat;->isConfigured()Z
+HSPLandroidx/emoji2/text/EmojiCompat;->isInitialized()Z
+HSPLandroidx/emoji2/text/EmojiCompat;->load()V
+HSPLandroidx/emoji2/text/EmojiCompat;->loadMetadata()V
+HSPLandroidx/emoji2/text/EmojiCompat;->onMetadataLoadSuccess()V
+HSPLandroidx/emoji2/text/EmojiCompat;->process(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
+HSPLandroidx/emoji2/text/EmojiCompat;->process(Ljava/lang/CharSequence;II)Ljava/lang/CharSequence;
+HSPLandroidx/emoji2/text/EmojiCompat;->process(Ljava/lang/CharSequence;III)Ljava/lang/CharSequence;
+HSPLandroidx/emoji2/text/EmojiCompat;->process(Ljava/lang/CharSequence;IIII)Ljava/lang/CharSequence;
+HSPLandroidx/emoji2/text/EmojiCompat;->registerInitCallback(Landroidx/emoji2/text/EmojiCompat$InitCallback;)V
+HSPLandroidx/emoji2/text/EmojiCompatInitializer$1;-><init>(Landroidx/emoji2/text/EmojiCompatInitializer;Landroidx/lifecycle/Lifecycle;)V
+HSPLandroidx/emoji2/text/EmojiCompatInitializer$1;->onResume(Landroidx/lifecycle/LifecycleOwner;)V
+HSPLandroidx/emoji2/text/EmojiCompatInitializer$BackgroundDefaultConfig;-><init>(Landroid/content/Context;)V
+HSPLandroidx/emoji2/text/EmojiCompatInitializer$BackgroundDefaultLoader$$ExternalSyntheticLambda0;-><init>(Landroidx/emoji2/text/EmojiCompatInitializer$BackgroundDefaultLoader;Landroidx/emoji2/text/EmojiCompat$MetadataRepoLoaderCallback;Ljava/util/concurrent/ThreadPoolExecutor;)V
+HSPLandroidx/emoji2/text/EmojiCompatInitializer$BackgroundDefaultLoader$$ExternalSyntheticLambda0;->run()V
+HSPLandroidx/emoji2/text/EmojiCompatInitializer$BackgroundDefaultLoader$1;-><init>(Landroidx/emoji2/text/EmojiCompatInitializer$BackgroundDefaultLoader;Landroidx/emoji2/text/EmojiCompat$MetadataRepoLoaderCallback;Ljava/util/concurrent/ThreadPoolExecutor;)V
+HSPLandroidx/emoji2/text/EmojiCompatInitializer$BackgroundDefaultLoader$1;->onLoaded(Landroidx/emoji2/text/MetadataRepo;)V
+HSPLandroidx/emoji2/text/EmojiCompatInitializer$BackgroundDefaultLoader;->$r8$lambda$2V1iWTiAwNxOBlVvz73bbuEdzIw(Landroidx/emoji2/text/EmojiCompatInitializer$BackgroundDefaultLoader;Landroidx/emoji2/text/EmojiCompat$MetadataRepoLoaderCallback;Ljava/util/concurrent/ThreadPoolExecutor;)V
+HSPLandroidx/emoji2/text/EmojiCompatInitializer$BackgroundDefaultLoader;-><init>(Landroid/content/Context;)V
+HSPLandroidx/emoji2/text/EmojiCompatInitializer$BackgroundDefaultLoader;->doLoad(Landroidx/emoji2/text/EmojiCompat$MetadataRepoLoaderCallback;Ljava/util/concurrent/ThreadPoolExecutor;)V
+HSPLandroidx/emoji2/text/EmojiCompatInitializer$BackgroundDefaultLoader;->lambda$load$0(Landroidx/emoji2/text/EmojiCompat$MetadataRepoLoaderCallback;Ljava/util/concurrent/ThreadPoolExecutor;)V
+HSPLandroidx/emoji2/text/EmojiCompatInitializer$BackgroundDefaultLoader;->load(Landroidx/emoji2/text/EmojiCompat$MetadataRepoLoaderCallback;)V
+HSPLandroidx/emoji2/text/EmojiCompatInitializer$LoadEmojiCompatRunnable;-><init>()V
+HSPLandroidx/emoji2/text/EmojiCompatInitializer$LoadEmojiCompatRunnable;->run()V
+HSPLandroidx/emoji2/text/EmojiCompatInitializer;-><init>()V
+HSPLandroidx/emoji2/text/EmojiCompatInitializer;->create(Landroid/content/Context;)Ljava/lang/Boolean;
+HSPLandroidx/emoji2/text/EmojiCompatInitializer;->create(Landroid/content/Context;)Ljava/lang/Object;
+HSPLandroidx/emoji2/text/EmojiCompatInitializer;->delayUntilFirstResume(Landroid/content/Context;)V
+HSPLandroidx/emoji2/text/EmojiCompatInitializer;->dependencies()Ljava/util/List;
+HSPLandroidx/emoji2/text/EmojiCompatInitializer;->loadEmojiCompatAfterDelay()V
+HSPLandroidx/emoji2/text/EmojiMetadata;-><clinit>()V
+HSPLandroidx/emoji2/text/EmojiMetadata;-><init>(Landroidx/emoji2/text/MetadataRepo;I)V
+HSPLandroidx/emoji2/text/EmojiMetadata;->getCodepointAt(I)I
+HSPLandroidx/emoji2/text/EmojiMetadata;->getCodepointsLength()I
+HSPLandroidx/emoji2/text/EmojiMetadata;->getId()I
+HSPLandroidx/emoji2/text/EmojiMetadata;->getMetadataItem()Landroidx/emoji2/text/flatbuffer/MetadataItem;+]Landroidx/emoji2/text/flatbuffer/MetadataList;Landroidx/emoji2/text/flatbuffer/MetadataList;]Landroidx/emoji2/text/MetadataRepo;Landroidx/emoji2/text/MetadataRepo;
+HSPLandroidx/emoji2/text/EmojiProcessor$ProcessorSm;-><init>(Landroidx/emoji2/text/MetadataRepo$Node;Z[I)V
+HSPLandroidx/emoji2/text/EmojiProcessor$ProcessorSm;->check(I)I
+HSPLandroidx/emoji2/text/EmojiProcessor$ProcessorSm;->isInFlushableState()Z
+HSPLandroidx/emoji2/text/EmojiProcessor$ProcessorSm;->reset()I
+HSPLandroidx/emoji2/text/EmojiProcessor;-><init>(Landroidx/emoji2/text/MetadataRepo;Landroidx/emoji2/text/EmojiCompat$SpanFactory;Landroidx/emoji2/text/EmojiCompat$GlyphChecker;Z[I)V
+HSPLandroidx/emoji2/text/EmojiProcessor;->process(Ljava/lang/CharSequence;IIIZ)Ljava/lang/CharSequence;
+HSPLandroidx/emoji2/text/FontRequestEmojiCompatConfig$FontProviderHelper;-><init>()V
+HSPLandroidx/emoji2/text/FontRequestEmojiCompatConfig$FontProviderHelper;->buildTypeface(Landroid/content/Context;Landroidx/core/provider/FontsContractCompat$FontInfo;)Landroid/graphics/Typeface;
+HSPLandroidx/emoji2/text/FontRequestEmojiCompatConfig$FontProviderHelper;->fetchFonts(Landroid/content/Context;Landroidx/core/provider/FontRequest;)Landroidx/core/provider/FontsContractCompat$FontFamilyResult;
+HSPLandroidx/emoji2/text/FontRequestEmojiCompatConfig$FontRequestMetadataLoader$$ExternalSyntheticLambda0;-><init>(Landroidx/emoji2/text/FontRequestEmojiCompatConfig$FontRequestMetadataLoader;)V
+HSPLandroidx/emoji2/text/FontRequestEmojiCompatConfig$FontRequestMetadataLoader$$ExternalSyntheticLambda0;->run()V
+HSPLandroidx/emoji2/text/FontRequestEmojiCompatConfig$FontRequestMetadataLoader;-><init>(Landroid/content/Context;Landroidx/core/provider/FontRequest;Landroidx/emoji2/text/FontRequestEmojiCompatConfig$FontProviderHelper;)V
+HSPLandroidx/emoji2/text/FontRequestEmojiCompatConfig$FontRequestMetadataLoader;->cleanUp()V
+HSPLandroidx/emoji2/text/FontRequestEmojiCompatConfig$FontRequestMetadataLoader;->createMetadata()V
+HSPLandroidx/emoji2/text/FontRequestEmojiCompatConfig$FontRequestMetadataLoader;->load(Landroidx/emoji2/text/EmojiCompat$MetadataRepoLoaderCallback;)V
+HSPLandroidx/emoji2/text/FontRequestEmojiCompatConfig$FontRequestMetadataLoader;->loadInternal()V
+HSPLandroidx/emoji2/text/FontRequestEmojiCompatConfig$FontRequestMetadataLoader;->retrieveFontInfo()Landroidx/core/provider/FontsContractCompat$FontInfo;
+HSPLandroidx/emoji2/text/FontRequestEmojiCompatConfig$FontRequestMetadataLoader;->setExecutor(Ljava/util/concurrent/Executor;)V
+HSPLandroidx/emoji2/text/FontRequestEmojiCompatConfig;-><clinit>()V
+HSPLandroidx/emoji2/text/FontRequestEmojiCompatConfig;-><init>(Landroid/content/Context;Landroidx/core/provider/FontRequest;)V
+HSPLandroidx/emoji2/text/FontRequestEmojiCompatConfig;->setLoadingExecutor(Ljava/util/concurrent/Executor;)Landroidx/emoji2/text/FontRequestEmojiCompatConfig;
+HSPLandroidx/emoji2/text/MetadataListReader$ByteBufferReader;-><init>(Ljava/nio/ByteBuffer;)V
+HSPLandroidx/emoji2/text/MetadataListReader$ByteBufferReader;->getPosition()J
+HSPLandroidx/emoji2/text/MetadataListReader$ByteBufferReader;->readTag()I
+HSPLandroidx/emoji2/text/MetadataListReader$ByteBufferReader;->readUnsignedInt()J
+HSPLandroidx/emoji2/text/MetadataListReader$ByteBufferReader;->readUnsignedShort()I
+HSPLandroidx/emoji2/text/MetadataListReader$ByteBufferReader;->skip(I)V
+HSPLandroidx/emoji2/text/MetadataListReader$OffsetInfo;-><init>(JJ)V
+HSPLandroidx/emoji2/text/MetadataListReader$OffsetInfo;->getStartOffset()J
+HSPLandroidx/emoji2/text/MetadataListReader;->findOffsetInfo(Landroidx/emoji2/text/MetadataListReader$OpenTypeReader;)Landroidx/emoji2/text/MetadataListReader$OffsetInfo;
+HSPLandroidx/emoji2/text/MetadataListReader;->read(Ljava/nio/ByteBuffer;)Landroidx/emoji2/text/flatbuffer/MetadataList;
+HSPLandroidx/emoji2/text/MetadataListReader;->toUnsignedInt(I)J
+HSPLandroidx/emoji2/text/MetadataListReader;->toUnsignedShort(S)I
+HSPLandroidx/emoji2/text/MetadataRepo$Node;-><init>()V
+HSPLandroidx/emoji2/text/MetadataRepo$Node;-><init>(I)V
+HSPLandroidx/emoji2/text/MetadataRepo$Node;->get(I)Landroidx/emoji2/text/MetadataRepo$Node;
+HSPLandroidx/emoji2/text/MetadataRepo$Node;->put(Landroidx/emoji2/text/EmojiMetadata;II)V
+HSPLandroidx/emoji2/text/MetadataRepo;-><init>(Landroid/graphics/Typeface;Landroidx/emoji2/text/flatbuffer/MetadataList;)V
+HSPLandroidx/emoji2/text/MetadataRepo;->constructIndex(Landroidx/emoji2/text/flatbuffer/MetadataList;)V
+HSPLandroidx/emoji2/text/MetadataRepo;->create(Landroid/graphics/Typeface;Ljava/nio/ByteBuffer;)Landroidx/emoji2/text/MetadataRepo;
+HSPLandroidx/emoji2/text/MetadataRepo;->getMetadataList()Landroidx/emoji2/text/flatbuffer/MetadataList;
+HSPLandroidx/emoji2/text/MetadataRepo;->getRootNode()Landroidx/emoji2/text/MetadataRepo$Node;
+HSPLandroidx/emoji2/text/MetadataRepo;->put(Landroidx/emoji2/text/EmojiMetadata;)V
+HSPLandroidx/emoji2/text/flatbuffer/MetadataItem;-><init>()V
+HSPLandroidx/emoji2/text/flatbuffer/MetadataItem;->__assign(ILjava/nio/ByteBuffer;)Landroidx/emoji2/text/flatbuffer/MetadataItem;
+HSPLandroidx/emoji2/text/flatbuffer/MetadataItem;->__init(ILjava/nio/ByteBuffer;)V
+HSPLandroidx/emoji2/text/flatbuffer/MetadataItem;->codepoints(I)I
+HSPLandroidx/emoji2/text/flatbuffer/MetadataItem;->codepointsLength()I
+HSPLandroidx/emoji2/text/flatbuffer/MetadataItem;->id()I
+HSPLandroidx/emoji2/text/flatbuffer/MetadataList;-><init>()V
+HSPLandroidx/emoji2/text/flatbuffer/MetadataList;->__assign(ILjava/nio/ByteBuffer;)Landroidx/emoji2/text/flatbuffer/MetadataList;
+HSPLandroidx/emoji2/text/flatbuffer/MetadataList;->__init(ILjava/nio/ByteBuffer;)V
+HSPLandroidx/emoji2/text/flatbuffer/MetadataList;->getRootAsMetadataList(Ljava/nio/ByteBuffer;)Landroidx/emoji2/text/flatbuffer/MetadataList;
+HSPLandroidx/emoji2/text/flatbuffer/MetadataList;->getRootAsMetadataList(Ljava/nio/ByteBuffer;Landroidx/emoji2/text/flatbuffer/MetadataList;)Landroidx/emoji2/text/flatbuffer/MetadataList;
+HSPLandroidx/emoji2/text/flatbuffer/MetadataList;->list(Landroidx/emoji2/text/flatbuffer/MetadataItem;I)Landroidx/emoji2/text/flatbuffer/MetadataItem;+]Landroidx/emoji2/text/flatbuffer/MetadataItem;Landroidx/emoji2/text/flatbuffer/MetadataItem;]Landroidx/emoji2/text/flatbuffer/Table;Landroidx/emoji2/text/flatbuffer/MetadataList;
+HSPLandroidx/emoji2/text/flatbuffer/MetadataList;->listLength()I
+HSPLandroidx/emoji2/text/flatbuffer/Table;-><init>()V
+HSPLandroidx/emoji2/text/flatbuffer/Table;->__indirect(I)I
+HSPLandroidx/emoji2/text/flatbuffer/Table;->__offset(I)I
+HSPLandroidx/emoji2/text/flatbuffer/Table;->__reset(ILjava/nio/ByteBuffer;)V
+HSPLandroidx/emoji2/text/flatbuffer/Table;->__vector(I)I
+HSPLandroidx/emoji2/text/flatbuffer/Table;->__vector_len(I)I
+HSPLandroidx/emoji2/text/flatbuffer/Utf8;-><init>()V
+HSPLandroidx/emoji2/text/flatbuffer/Utf8;->getDefault()Landroidx/emoji2/text/flatbuffer/Utf8;
+HSPLandroidx/emoji2/text/flatbuffer/Utf8Safe;-><init>()V
+HSPLandroidx/lifecycle/DefaultLifecycleObserver;->onCreate(Landroidx/lifecycle/LifecycleOwner;)V
+HSPLandroidx/lifecycle/DefaultLifecycleObserver;->onStart(Landroidx/lifecycle/LifecycleOwner;)V
+HSPLandroidx/lifecycle/EmptyActivityLifecycleCallbacks;-><init>()V
+HSPLandroidx/lifecycle/EmptyActivityLifecycleCallbacks;->onActivityCreated(Landroid/app/Activity;Landroid/os/Bundle;)V
+HSPLandroidx/lifecycle/EmptyActivityLifecycleCallbacks;->onActivityResumed(Landroid/app/Activity;)V
+HSPLandroidx/lifecycle/EmptyActivityLifecycleCallbacks;->onActivityStarted(Landroid/app/Activity;)V
+HSPLandroidx/lifecycle/FullLifecycleObserverAdapter$1;-><clinit>()V
+HSPLandroidx/lifecycle/FullLifecycleObserverAdapter;-><init>(Landroidx/lifecycle/FullLifecycleObserver;Landroidx/lifecycle/LifecycleEventObserver;)V
+HSPLandroidx/lifecycle/FullLifecycleObserverAdapter;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
+HSPLandroidx/lifecycle/LegacySavedStateHandleController;->attachHandleIfNeeded(Landroidx/lifecycle/ViewModel;Landroidx/savedstate/SavedStateRegistry;Landroidx/lifecycle/Lifecycle;)V
+HSPLandroidx/lifecycle/Lifecycle$1;-><clinit>()V
+HSPLandroidx/lifecycle/Lifecycle$Event;->$values()[Landroidx/lifecycle/Lifecycle$Event;
+HSPLandroidx/lifecycle/Lifecycle$Event;-><clinit>()V
+HSPLandroidx/lifecycle/Lifecycle$Event;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/lifecycle/Lifecycle$Event;->getTargetState()Landroidx/lifecycle/Lifecycle$State;
+HSPLandroidx/lifecycle/Lifecycle$Event;->upFrom(Landroidx/lifecycle/Lifecycle$State;)Landroidx/lifecycle/Lifecycle$Event;
+HSPLandroidx/lifecycle/Lifecycle$Event;->values()[Landroidx/lifecycle/Lifecycle$Event;
+HSPLandroidx/lifecycle/Lifecycle$State;->$values()[Landroidx/lifecycle/Lifecycle$State;
+HSPLandroidx/lifecycle/Lifecycle$State;-><clinit>()V
+HSPLandroidx/lifecycle/Lifecycle$State;-><init>(Ljava/lang/String;I)V
+HSPLandroidx/lifecycle/Lifecycle$State;->isAtLeast(Landroidx/lifecycle/Lifecycle$State;)Z
+HSPLandroidx/lifecycle/Lifecycle$State;->values()[Landroidx/lifecycle/Lifecycle$State;
+HSPLandroidx/lifecycle/Lifecycle;-><init>()V
+HSPLandroidx/lifecycle/LifecycleDispatcher$DispatcherActivityCallback;-><init>()V
+HSPLandroidx/lifecycle/LifecycleDispatcher$DispatcherActivityCallback;->onActivityCreated(Landroid/app/Activity;Landroid/os/Bundle;)V
+HSPLandroidx/lifecycle/LifecycleDispatcher;-><clinit>()V
+HSPLandroidx/lifecycle/LifecycleDispatcher;->init(Landroid/content/Context;)V
+HSPLandroidx/lifecycle/LifecycleRegistry$ObserverWithState;-><init>(Landroidx/lifecycle/LifecycleObserver;Landroidx/lifecycle/Lifecycle$State;)V
+HSPLandroidx/lifecycle/LifecycleRegistry$ObserverWithState;->dispatchEvent(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
+HSPLandroidx/lifecycle/LifecycleRegistry;-><init>(Landroidx/lifecycle/LifecycleOwner;)V
+HSPLandroidx/lifecycle/LifecycleRegistry;-><init>(Landroidx/lifecycle/LifecycleOwner;Z)V
+HSPLandroidx/lifecycle/LifecycleRegistry;->addObserver(Landroidx/lifecycle/LifecycleObserver;)V
+HSPLandroidx/lifecycle/LifecycleRegistry;->calculateTargetState(Landroidx/lifecycle/LifecycleObserver;)Landroidx/lifecycle/Lifecycle$State;
+HSPLandroidx/lifecycle/LifecycleRegistry;->enforceMainThreadIfNeeded(Ljava/lang/String;)V
+HSPLandroidx/lifecycle/LifecycleRegistry;->forwardPass(Landroidx/lifecycle/LifecycleOwner;)V
+HSPLandroidx/lifecycle/LifecycleRegistry;->getCurrentState()Landroidx/lifecycle/Lifecycle$State;
+HSPLandroidx/lifecycle/LifecycleRegistry;->handleLifecycleEvent(Landroidx/lifecycle/Lifecycle$Event;)V
+HSPLandroidx/lifecycle/LifecycleRegistry;->isSynced()Z
+HSPLandroidx/lifecycle/LifecycleRegistry;->min(Landroidx/lifecycle/Lifecycle$State;Landroidx/lifecycle/Lifecycle$State;)Landroidx/lifecycle/Lifecycle$State;
+HSPLandroidx/lifecycle/LifecycleRegistry;->moveToState(Landroidx/lifecycle/Lifecycle$State;)V
+HSPLandroidx/lifecycle/LifecycleRegistry;->popParentState()V
+HSPLandroidx/lifecycle/LifecycleRegistry;->pushParentState(Landroidx/lifecycle/Lifecycle$State;)V
+HSPLandroidx/lifecycle/LifecycleRegistry;->removeObserver(Landroidx/lifecycle/LifecycleObserver;)V
+HSPLandroidx/lifecycle/LifecycleRegistry;->sync()V
+HSPLandroidx/lifecycle/Lifecycling;-><clinit>()V
+HSPLandroidx/lifecycle/Lifecycling;->lifecycleEventObserver(Ljava/lang/Object;)Landroidx/lifecycle/LifecycleEventObserver;
+HSPLandroidx/lifecycle/LiveData$1;-><init>(Landroidx/lifecycle/LiveData;)V
+HSPLandroidx/lifecycle/LiveData$LifecycleBoundObserver;-><init>(Landroidx/lifecycle/LiveData;Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Observer;)V
+HSPLandroidx/lifecycle/LiveData$LifecycleBoundObserver;->isAttachedTo(Landroidx/lifecycle/LifecycleOwner;)Z
+HSPLandroidx/lifecycle/LiveData$LifecycleBoundObserver;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
+HSPLandroidx/lifecycle/LiveData$LifecycleBoundObserver;->shouldBeActive()Z
+HSPLandroidx/lifecycle/LiveData$ObserverWrapper;-><init>(Landroidx/lifecycle/LiveData;Landroidx/lifecycle/Observer;)V
+HSPLandroidx/lifecycle/LiveData$ObserverWrapper;->activeStateChanged(Z)V
+HSPLandroidx/lifecycle/LiveData;-><clinit>()V
+HSPLandroidx/lifecycle/LiveData;-><init>()V
+HSPLandroidx/lifecycle/LiveData;->assertMainThread(Ljava/lang/String;)V
+HSPLandroidx/lifecycle/LiveData;->changeActiveCounter(I)V
+HSPLandroidx/lifecycle/LiveData;->considerNotify(Landroidx/lifecycle/LiveData$ObserverWrapper;)V
+HSPLandroidx/lifecycle/LiveData;->dispatchingValue(Landroidx/lifecycle/LiveData$ObserverWrapper;)V
+HSPLandroidx/lifecycle/LiveData;->observe(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Observer;)V
+HSPLandroidx/lifecycle/LiveData;->onActive()V
+HSPLandroidx/lifecycle/MutableLiveData;-><init>()V
+HSPLandroidx/lifecycle/ProcessLifecycleInitializer;-><init>()V
+HSPLandroidx/lifecycle/ProcessLifecycleInitializer;->create(Landroid/content/Context;)Landroidx/lifecycle/LifecycleOwner;
+HSPLandroidx/lifecycle/ProcessLifecycleInitializer;->create(Landroid/content/Context;)Ljava/lang/Object;
+HSPLandroidx/lifecycle/ProcessLifecycleInitializer;->dependencies()Ljava/util/List;
+HSPLandroidx/lifecycle/ProcessLifecycleOwner$1;-><init>(Landroidx/lifecycle/ProcessLifecycleOwner;)V
+HSPLandroidx/lifecycle/ProcessLifecycleOwner$2;-><init>(Landroidx/lifecycle/ProcessLifecycleOwner;)V
+HSPLandroidx/lifecycle/ProcessLifecycleOwner$3$1;-><init>(Landroidx/lifecycle/ProcessLifecycleOwner$3;)V
+HSPLandroidx/lifecycle/ProcessLifecycleOwner$3$1;->onActivityPostResumed(Landroid/app/Activity;)V
+HSPLandroidx/lifecycle/ProcessLifecycleOwner$3$1;->onActivityPostStarted(Landroid/app/Activity;)V
+HSPLandroidx/lifecycle/ProcessLifecycleOwner$3;-><init>(Landroidx/lifecycle/ProcessLifecycleOwner;)V
+HSPLandroidx/lifecycle/ProcessLifecycleOwner$3;->onActivityCreated(Landroid/app/Activity;Landroid/os/Bundle;)V
+HSPLandroidx/lifecycle/ProcessLifecycleOwner$3;->onActivityPreCreated(Landroid/app/Activity;Landroid/os/Bundle;)V
+HSPLandroidx/lifecycle/ProcessLifecycleOwner$Api29Impl;->registerActivityLifecycleCallbacks(Landroid/app/Activity;Landroid/app/Application$ActivityLifecycleCallbacks;)V
+HSPLandroidx/lifecycle/ProcessLifecycleOwner;-><clinit>()V
+HSPLandroidx/lifecycle/ProcessLifecycleOwner;-><init>()V
+HSPLandroidx/lifecycle/ProcessLifecycleOwner;->activityResumed()V
+HSPLandroidx/lifecycle/ProcessLifecycleOwner;->activityStarted()V
+HSPLandroidx/lifecycle/ProcessLifecycleOwner;->attach(Landroid/content/Context;)V
+HSPLandroidx/lifecycle/ProcessLifecycleOwner;->get()Landroidx/lifecycle/LifecycleOwner;
+HSPLandroidx/lifecycle/ProcessLifecycleOwner;->getLifecycle()Landroidx/lifecycle/Lifecycle;
+HSPLandroidx/lifecycle/ProcessLifecycleOwner;->init(Landroid/content/Context;)V
+HSPLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;-><init>()V
+HSPLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityCreated(Landroid/app/Activity;Landroid/os/Bundle;)V
+HSPLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityPostCreated(Landroid/app/Activity;Landroid/os/Bundle;)V
+HSPLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityPostResumed(Landroid/app/Activity;)V
+HSPLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityPostStarted(Landroid/app/Activity;)V
+HSPLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityResumed(Landroid/app/Activity;)V
+HSPLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityStarted(Landroid/app/Activity;)V
+HSPLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->registerIn(Landroid/app/Activity;)V
+HSPLandroidx/lifecycle/ReportFragment;-><init>()V
+HSPLandroidx/lifecycle/ReportFragment;->dispatch(Landroid/app/Activity;Landroidx/lifecycle/Lifecycle$Event;)V
+HSPLandroidx/lifecycle/ReportFragment;->dispatch(Landroidx/lifecycle/Lifecycle$Event;)V
+HSPLandroidx/lifecycle/ReportFragment;->dispatchCreate(Landroidx/lifecycle/ReportFragment$ActivityInitializationListener;)V
+HSPLandroidx/lifecycle/ReportFragment;->dispatchResume(Landroidx/lifecycle/ReportFragment$ActivityInitializationListener;)V
+HSPLandroidx/lifecycle/ReportFragment;->dispatchStart(Landroidx/lifecycle/ReportFragment$ActivityInitializationListener;)V
+HSPLandroidx/lifecycle/ReportFragment;->injectIfNeededIn(Landroid/app/Activity;)V
+HSPLandroidx/lifecycle/ReportFragment;->onActivityCreated(Landroid/os/Bundle;)V
+HSPLandroidx/lifecycle/ReportFragment;->onResume()V
+HSPLandroidx/lifecycle/ReportFragment;->onStart()V
+HSPLandroidx/lifecycle/SavedStateHandleAttacher;-><init>(Landroidx/lifecycle/SavedStateHandlesProvider;)V
+HSPLandroidx/lifecycle/SavedStateHandleAttacher;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
+HSPLandroidx/lifecycle/SavedStateHandleSupport$DEFAULT_ARGS_KEY$1;-><init>()V
+HSPLandroidx/lifecycle/SavedStateHandleSupport$SAVED_STATE_REGISTRY_OWNER_KEY$1;-><init>()V
+HSPLandroidx/lifecycle/SavedStateHandleSupport$VIEW_MODEL_STORE_OWNER_KEY$1;-><init>()V
+HSPLandroidx/lifecycle/SavedStateHandleSupport$savedStateHandlesVM$1$1;-><clinit>()V
+HSPLandroidx/lifecycle/SavedStateHandleSupport$savedStateHandlesVM$1$1;-><init>()V
+HSPLandroidx/lifecycle/SavedStateHandleSupport$savedStateHandlesVM$1$1;->invoke(Landroidx/lifecycle/viewmodel/CreationExtras;)Landroidx/lifecycle/SavedStateHandlesVM;
+HSPLandroidx/lifecycle/SavedStateHandleSupport$savedStateHandlesVM$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/lifecycle/SavedStateHandleSupport;-><clinit>()V
+HSPLandroidx/lifecycle/SavedStateHandleSupport;->enableSavedStateHandles(Landroidx/savedstate/SavedStateRegistryOwner;)V
+HSPLandroidx/lifecycle/SavedStateHandleSupport;->getSavedStateHandlesVM(Landroidx/lifecycle/ViewModelStoreOwner;)Landroidx/lifecycle/SavedStateHandlesVM;
+HSPLandroidx/lifecycle/SavedStateHandlesProvider$viewModel$2;-><init>(Landroidx/lifecycle/ViewModelStoreOwner;)V
+HSPLandroidx/lifecycle/SavedStateHandlesProvider$viewModel$2;->invoke()Landroidx/lifecycle/SavedStateHandlesVM;
+HSPLandroidx/lifecycle/SavedStateHandlesProvider$viewModel$2;->invoke()Ljava/lang/Object;
+HSPLandroidx/lifecycle/SavedStateHandlesProvider;-><init>(Landroidx/savedstate/SavedStateRegistry;Landroidx/lifecycle/ViewModelStoreOwner;)V
+HSPLandroidx/lifecycle/SavedStateHandlesProvider;->getViewModel()Landroidx/lifecycle/SavedStateHandlesVM;
+HSPLandroidx/lifecycle/SavedStateHandlesProvider;->performRestore()V
+HSPLandroidx/lifecycle/SavedStateHandlesVM;-><init>()V
+HSPLandroidx/lifecycle/SavedStateViewModelFactory;-><init>(Landroid/app/Application;Landroidx/savedstate/SavedStateRegistryOwner;Landroid/os/Bundle;)V
+HSPLandroidx/lifecycle/SavedStateViewModelFactory;->create(Ljava/lang/Class;Landroidx/lifecycle/viewmodel/CreationExtras;)Landroidx/lifecycle/ViewModel;
+HSPLandroidx/lifecycle/SavedStateViewModelFactory;->onRequery(Landroidx/lifecycle/ViewModel;)V
+HSPLandroidx/lifecycle/SavedStateViewModelFactoryKt;-><clinit>()V
+HSPLandroidx/lifecycle/SavedStateViewModelFactoryKt;->access$getVIEWMODEL_SIGNATURE$p()Ljava/util/List;
+HSPLandroidx/lifecycle/SavedStateViewModelFactoryKt;->findMatchingConstructor(Ljava/lang/Class;Ljava/util/List;)Ljava/lang/reflect/Constructor;
+HSPLandroidx/lifecycle/ViewModel;-><init>()V
+HSPLandroidx/lifecycle/ViewModel;->getTag(Ljava/lang/String;)Ljava/lang/Object;
+HSPLandroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory$Companion$ApplicationKeyImpl;-><clinit>()V
+HSPLandroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory$Companion$ApplicationKeyImpl;-><init>()V
+HSPLandroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory$Companion;-><init>()V
+HSPLandroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory$Companion;->getInstance(Landroid/app/Application;)Landroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory;
+HSPLandroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory;-><clinit>()V
+HSPLandroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory;-><init>(Landroid/app/Application;)V
+HSPLandroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory;-><init>(Landroid/app/Application;I)V
+HSPLandroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory;->access$getSInstance$cp()Landroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory;
+HSPLandroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory;->access$setSInstance$cp(Landroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory;)V
+HSPLandroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory;->create(Ljava/lang/Class;)Landroidx/lifecycle/ViewModel;
+HSPLandroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory;->create(Ljava/lang/Class;Landroid/app/Application;)Landroidx/lifecycle/ViewModel;
+HSPLandroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory;->create(Ljava/lang/Class;Landroidx/lifecycle/viewmodel/CreationExtras;)Landroidx/lifecycle/ViewModel;
+HSPLandroidx/lifecycle/ViewModelProvider$Factory$Companion;-><clinit>()V
+HSPLandroidx/lifecycle/ViewModelProvider$Factory$Companion;-><init>()V
+HSPLandroidx/lifecycle/ViewModelProvider$Factory;-><clinit>()V
+HSPLandroidx/lifecycle/ViewModelProvider$NewInstanceFactory$Companion$ViewModelKeyImpl;-><clinit>()V
+HSPLandroidx/lifecycle/ViewModelProvider$NewInstanceFactory$Companion$ViewModelKeyImpl;-><init>()V
+HSPLandroidx/lifecycle/ViewModelProvider$NewInstanceFactory$Companion;-><init>()V
+HSPLandroidx/lifecycle/ViewModelProvider$NewInstanceFactory$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/lifecycle/ViewModelProvider$NewInstanceFactory;-><clinit>()V
+HSPLandroidx/lifecycle/ViewModelProvider$NewInstanceFactory;-><init>()V
+HSPLandroidx/lifecycle/ViewModelProvider$NewInstanceFactory;->create(Ljava/lang/Class;)Landroidx/lifecycle/ViewModel;
+HSPLandroidx/lifecycle/ViewModelProvider$OnRequeryFactory;-><init>()V
+HSPLandroidx/lifecycle/ViewModelProvider;-><init>(Landroidx/lifecycle/ViewModelStore;Landroidx/lifecycle/ViewModelProvider$Factory;Landroidx/lifecycle/viewmodel/CreationExtras;)V
+HSPLandroidx/lifecycle/ViewModelProvider;-><init>(Landroidx/lifecycle/ViewModelStoreOwner;Landroidx/lifecycle/ViewModelProvider$Factory;)V
+HSPLandroidx/lifecycle/ViewModelProvider;->get(Ljava/lang/Class;)Landroidx/lifecycle/ViewModel;
+HSPLandroidx/lifecycle/ViewModelProvider;->get(Ljava/lang/String;Ljava/lang/Class;)Landroidx/lifecycle/ViewModel;
+HSPLandroidx/lifecycle/ViewModelProviderGetKt;->defaultCreationExtras(Landroidx/lifecycle/ViewModelStoreOwner;)Landroidx/lifecycle/viewmodel/CreationExtras;
+HSPLandroidx/lifecycle/ViewModelStore;-><init>()V
+HSPLandroidx/lifecycle/ViewModelStore;->get(Ljava/lang/String;)Landroidx/lifecycle/ViewModel;
+HSPLandroidx/lifecycle/ViewModelStore;->put(Ljava/lang/String;Landroidx/lifecycle/ViewModel;)V
+HSPLandroidx/lifecycle/ViewTreeLifecycleOwner;->get(Landroid/view/View;)Landroidx/lifecycle/LifecycleOwner;
+HSPLandroidx/lifecycle/ViewTreeLifecycleOwner;->set(Landroid/view/View;Landroidx/lifecycle/LifecycleOwner;)V
+HSPLandroidx/lifecycle/ViewTreeViewModelStoreOwner;->get(Landroid/view/View;)Landroidx/lifecycle/ViewModelStoreOwner;
+HSPLandroidx/lifecycle/ViewTreeViewModelStoreOwner;->set(Landroid/view/View;Landroidx/lifecycle/ViewModelStoreOwner;)V
+HSPLandroidx/lifecycle/viewmodel/CreationExtras$Empty;-><clinit>()V
+HSPLandroidx/lifecycle/viewmodel/CreationExtras$Empty;-><init>()V
+HSPLandroidx/lifecycle/viewmodel/CreationExtras;-><init>()V
+HSPLandroidx/lifecycle/viewmodel/CreationExtras;->getMap$lifecycle_viewmodel_release()Ljava/util/Map;
+HSPLandroidx/lifecycle/viewmodel/InitializerViewModelFactory;-><init>([Landroidx/lifecycle/viewmodel/ViewModelInitializer;)V
+HSPLandroidx/lifecycle/viewmodel/InitializerViewModelFactory;->create(Ljava/lang/Class;Landroidx/lifecycle/viewmodel/CreationExtras;)Landroidx/lifecycle/ViewModel;
+HSPLandroidx/lifecycle/viewmodel/InitializerViewModelFactoryBuilder;-><init>()V
+HSPLandroidx/lifecycle/viewmodel/InitializerViewModelFactoryBuilder;->addInitializer(Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/lifecycle/viewmodel/InitializerViewModelFactoryBuilder;->build()Landroidx/lifecycle/ViewModelProvider$Factory;
+HSPLandroidx/lifecycle/viewmodel/MutableCreationExtras;-><init>()V
+HSPLandroidx/lifecycle/viewmodel/MutableCreationExtras;-><init>(Landroidx/lifecycle/viewmodel/CreationExtras;)V
+HSPLandroidx/lifecycle/viewmodel/MutableCreationExtras;-><init>(Landroidx/lifecycle/viewmodel/CreationExtras;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/lifecycle/viewmodel/MutableCreationExtras;->get(Landroidx/lifecycle/viewmodel/CreationExtras$Key;)Ljava/lang/Object;
+HSPLandroidx/lifecycle/viewmodel/MutableCreationExtras;->set(Landroidx/lifecycle/viewmodel/CreationExtras$Key;Ljava/lang/Object;)V
+HSPLandroidx/lifecycle/viewmodel/ViewModelInitializer;-><init>(Ljava/lang/Class;Lkotlin/jvm/functions/Function1;)V
+HSPLandroidx/lifecycle/viewmodel/ViewModelInitializer;->getClazz$lifecycle_viewmodel_release()Ljava/lang/Class;
+HSPLandroidx/lifecycle/viewmodel/ViewModelInitializer;->getInitializer$lifecycle_viewmodel_release()Lkotlin/jvm/functions/Function1;
+HSPLandroidx/lifecycle/viewmodel/compose/LocalViewModelStoreOwner$LocalViewModelStoreOwner$1;-><clinit>()V
+HSPLandroidx/lifecycle/viewmodel/compose/LocalViewModelStoreOwner$LocalViewModelStoreOwner$1;-><init>()V
+HSPLandroidx/lifecycle/viewmodel/compose/LocalViewModelStoreOwner$LocalViewModelStoreOwner$1;->invoke()Landroidx/lifecycle/ViewModelStoreOwner;
+HSPLandroidx/lifecycle/viewmodel/compose/LocalViewModelStoreOwner$LocalViewModelStoreOwner$1;->invoke()Ljava/lang/Object;
+HSPLandroidx/lifecycle/viewmodel/compose/LocalViewModelStoreOwner;-><clinit>()V
+HSPLandroidx/lifecycle/viewmodel/compose/LocalViewModelStoreOwner;-><init>()V
+HSPLandroidx/lifecycle/viewmodel/compose/LocalViewModelStoreOwner;->getCurrent(Landroidx/compose/runtime/Composer;I)Landroidx/lifecycle/ViewModelStoreOwner;
+HSPLandroidx/lifecycle/viewmodel/compose/ViewModelKt;->get(Landroidx/lifecycle/ViewModelStoreOwner;Ljava/lang/Class;Ljava/lang/String;Landroidx/lifecycle/ViewModelProvider$Factory;Landroidx/lifecycle/viewmodel/CreationExtras;)Landroidx/lifecycle/ViewModel;
+HSPLandroidx/lifecycle/viewmodel/compose/ViewModelKt;->viewModel(Ljava/lang/Class;Landroidx/lifecycle/ViewModelStoreOwner;Ljava/lang/String;Landroidx/lifecycle/ViewModelProvider$Factory;Landroidx/lifecycle/viewmodel/CreationExtras;Landroidx/compose/runtime/Composer;II)Landroidx/lifecycle/ViewModel;
+HSPLandroidx/profileinstaller/ProfileInstallerInitializer$$ExternalSyntheticLambda0;-><init>(Landroidx/profileinstaller/ProfileInstallerInitializer;Landroid/content/Context;)V
+HSPLandroidx/profileinstaller/ProfileInstallerInitializer$$ExternalSyntheticLambda0;->run()V
+HSPLandroidx/profileinstaller/ProfileInstallerInitializer$$ExternalSyntheticLambda1;-><init>(Landroid/content/Context;)V
+HSPLandroidx/profileinstaller/ProfileInstallerInitializer$Choreographer16Impl$$ExternalSyntheticLambda0;-><init>(Ljava/lang/Runnable;)V
+HSPLandroidx/profileinstaller/ProfileInstallerInitializer$Choreographer16Impl$$ExternalSyntheticLambda0;->doFrame(J)V
+HSPLandroidx/profileinstaller/ProfileInstallerInitializer$Choreographer16Impl;->$r8$lambda$DSwPKNQiVu4DdgIKQZrSpqkWM-A(Ljava/lang/Runnable;J)V
+HSPLandroidx/profileinstaller/ProfileInstallerInitializer$Choreographer16Impl;->lambda$postFrameCallback$0(Ljava/lang/Runnable;J)V
+HSPLandroidx/profileinstaller/ProfileInstallerInitializer$Choreographer16Impl;->postFrameCallback(Ljava/lang/Runnable;)V
+HSPLandroidx/profileinstaller/ProfileInstallerInitializer$Handler28Impl;->createAsync(Landroid/os/Looper;)Landroid/os/Handler;
+HSPLandroidx/profileinstaller/ProfileInstallerInitializer$Result;-><init>()V
+HSPLandroidx/profileinstaller/ProfileInstallerInitializer;->$r8$lambda$QGpANLTF0YGY0pXfe2eje4OKwkc(Landroidx/profileinstaller/ProfileInstallerInitializer;Landroid/content/Context;)V
+HSPLandroidx/profileinstaller/ProfileInstallerInitializer;-><init>()V
+HSPLandroidx/profileinstaller/ProfileInstallerInitializer;->create(Landroid/content/Context;)Landroidx/profileinstaller/ProfileInstallerInitializer$Result;
+HSPLandroidx/profileinstaller/ProfileInstallerInitializer;->create(Landroid/content/Context;)Ljava/lang/Object;
+HSPLandroidx/profileinstaller/ProfileInstallerInitializer;->delayAfterFirstFrame(Landroid/content/Context;)V
+HSPLandroidx/profileinstaller/ProfileInstallerInitializer;->dependencies()Ljava/util/List;
+HSPLandroidx/profileinstaller/ProfileInstallerInitializer;->installAfterDelay(Landroid/content/Context;)V
+HSPLandroidx/profileinstaller/ProfileInstallerInitializer;->lambda$delayAfterFirstFrame$0(Landroid/content/Context;)V
+HSPLandroidx/savedstate/Recreator$Companion;-><init>()V
+HSPLandroidx/savedstate/Recreator$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/savedstate/Recreator;-><clinit>()V
+HSPLandroidx/savedstate/Recreator;-><init>(Landroidx/savedstate/SavedStateRegistryOwner;)V
+HSPLandroidx/savedstate/Recreator;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
+HSPLandroidx/savedstate/SavedStateRegistry$$ExternalSyntheticLambda0;-><init>(Landroidx/savedstate/SavedStateRegistry;)V
+HSPLandroidx/savedstate/SavedStateRegistry$$ExternalSyntheticLambda0;->onStateChanged(Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
+HSPLandroidx/savedstate/SavedStateRegistry$Companion;-><init>()V
+HSPLandroidx/savedstate/SavedStateRegistry$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/savedstate/SavedStateRegistry;->$r8$lambda$AUDDdpkzZrJMhBj0r-_9pI-j6hA(Landroidx/savedstate/SavedStateRegistry;Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
+HSPLandroidx/savedstate/SavedStateRegistry;-><clinit>()V
+HSPLandroidx/savedstate/SavedStateRegistry;-><init>()V
+HSPLandroidx/savedstate/SavedStateRegistry;->consumeRestoredStateForKey(Ljava/lang/String;)Landroid/os/Bundle;
+HSPLandroidx/savedstate/SavedStateRegistry;->getSavedStateProvider(Ljava/lang/String;)Landroidx/savedstate/SavedStateRegistry$SavedStateProvider;
+HSPLandroidx/savedstate/SavedStateRegistry;->performAttach$lambda$4(Landroidx/savedstate/SavedStateRegistry;Landroidx/lifecycle/LifecycleOwner;Landroidx/lifecycle/Lifecycle$Event;)V
+HSPLandroidx/savedstate/SavedStateRegistry;->performAttach$savedstate_release(Landroidx/lifecycle/Lifecycle;)V
+HSPLandroidx/savedstate/SavedStateRegistry;->performRestore$savedstate_release(Landroid/os/Bundle;)V
+HSPLandroidx/savedstate/SavedStateRegistry;->registerSavedStateProvider(Ljava/lang/String;Landroidx/savedstate/SavedStateRegistry$SavedStateProvider;)V
+HSPLandroidx/savedstate/SavedStateRegistryController$Companion;-><init>()V
+HSPLandroidx/savedstate/SavedStateRegistryController$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/savedstate/SavedStateRegistryController$Companion;->create(Landroidx/savedstate/SavedStateRegistryOwner;)Landroidx/savedstate/SavedStateRegistryController;
+HSPLandroidx/savedstate/SavedStateRegistryController;-><clinit>()V
+HSPLandroidx/savedstate/SavedStateRegistryController;-><init>(Landroidx/savedstate/SavedStateRegistryOwner;)V
+HSPLandroidx/savedstate/SavedStateRegistryController;-><init>(Landroidx/savedstate/SavedStateRegistryOwner;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLandroidx/savedstate/SavedStateRegistryController;->create(Landroidx/savedstate/SavedStateRegistryOwner;)Landroidx/savedstate/SavedStateRegistryController;
+HSPLandroidx/savedstate/SavedStateRegistryController;->getSavedStateRegistry()Landroidx/savedstate/SavedStateRegistry;
+HSPLandroidx/savedstate/SavedStateRegistryController;->performAttach()V
+HSPLandroidx/savedstate/SavedStateRegistryController;->performRestore(Landroid/os/Bundle;)V
+HSPLandroidx/savedstate/ViewTreeSavedStateRegistryOwner$findViewTreeSavedStateRegistryOwner$1;-><clinit>()V
+HSPLandroidx/savedstate/ViewTreeSavedStateRegistryOwner$findViewTreeSavedStateRegistryOwner$1;-><init>()V
+HSPLandroidx/savedstate/ViewTreeSavedStateRegistryOwner$findViewTreeSavedStateRegistryOwner$1;->invoke(Landroid/view/View;)Landroid/view/View;
+HSPLandroidx/savedstate/ViewTreeSavedStateRegistryOwner$findViewTreeSavedStateRegistryOwner$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/savedstate/ViewTreeSavedStateRegistryOwner$findViewTreeSavedStateRegistryOwner$2;-><clinit>()V
+HSPLandroidx/savedstate/ViewTreeSavedStateRegistryOwner$findViewTreeSavedStateRegistryOwner$2;-><init>()V
+HSPLandroidx/savedstate/ViewTreeSavedStateRegistryOwner$findViewTreeSavedStateRegistryOwner$2;->invoke(Landroid/view/View;)Landroidx/savedstate/SavedStateRegistryOwner;
+HSPLandroidx/savedstate/ViewTreeSavedStateRegistryOwner$findViewTreeSavedStateRegistryOwner$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroidx/savedstate/ViewTreeSavedStateRegistryOwner;->get(Landroid/view/View;)Landroidx/savedstate/SavedStateRegistryOwner;
+HSPLandroidx/savedstate/ViewTreeSavedStateRegistryOwner;->set(Landroid/view/View;Landroidx/savedstate/SavedStateRegistryOwner;)V
+HSPLandroidx/startup/AppInitializer;-><clinit>()V
+HSPLandroidx/startup/AppInitializer;-><init>(Landroid/content/Context;)V
+HSPLandroidx/startup/AppInitializer;->discoverAndInitialize(Landroid/os/Bundle;)V
+HSPLandroidx/startup/AppInitializer;->discoverAndInitialize(Ljava/lang/Class;)V
+HSPLandroidx/startup/AppInitializer;->doInitialize(Ljava/lang/Class;)Ljava/lang/Object;
+HSPLandroidx/startup/AppInitializer;->doInitialize(Ljava/lang/Class;Ljava/util/Set;)Ljava/lang/Object;
+HSPLandroidx/startup/AppInitializer;->getInstance(Landroid/content/Context;)Landroidx/startup/AppInitializer;
+HSPLandroidx/startup/AppInitializer;->initializeComponent(Ljava/lang/Class;)Ljava/lang/Object;
+HSPLandroidx/startup/AppInitializer;->isEagerlyInitialized(Ljava/lang/Class;)Z
+HSPLandroidx/startup/InitializationProvider;-><init>()V
+HSPLandroidx/startup/InitializationProvider;->onCreate()Z
+HSPLandroidx/tracing/Trace;->beginSection(Ljava/lang/String;)V
+HSPLandroidx/tracing/Trace;->endSection()V
+HSPLandroidx/tracing/Trace;->isEnabled()Z
+HSPLandroidx/tracing/TraceApi18Impl;->beginSection(Ljava/lang/String;)V
+HSPLandroidx/tracing/TraceApi18Impl;->endSection()V
+HSPLandroidx/tracing/TraceApi29Impl;->isEnabled()Z
+HSPLcom/android/credentialmanager/CreateFlowUtils$Companion$toCreateCredentialUiState$$inlined$compareByDescending$1;-><init>()V
+HSPLcom/android/credentialmanager/CreateFlowUtils$Companion$toCreateCredentialUiState$$inlined$compareByDescending$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
+HSPLcom/android/credentialmanager/CreateFlowUtils$Companion;-><init>()V
+HSPLcom/android/credentialmanager/CreateFlowUtils$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLcom/android/credentialmanager/CreateFlowUtils$Companion;->toActiveEntry(Lcom/android/credentialmanager/createflow/EnabledProviderInfo;ILcom/android/credentialmanager/createflow/EnabledProviderInfo;Lcom/android/credentialmanager/createflow/RemoteInfo;)Lcom/android/credentialmanager/createflow/ActiveEntry;
+HSPLcom/android/credentialmanager/CreateFlowUtils$Companion;->toCreateCredentialUiState(Ljava/util/List;Ljava/util/List;Ljava/lang/String;Lcom/android/credentialmanager/createflow/RequestDisplayInfo;ZZ)Lcom/android/credentialmanager/createflow/CreateCredentialUiState;
+HSPLcom/android/credentialmanager/CreateFlowUtils$Companion;->toCreateScreenState(IZLcom/android/credentialmanager/createflow/RequestDisplayInfo;Lcom/android/credentialmanager/createflow/EnabledProviderInfo;Lcom/android/credentialmanager/createflow/RemoteInfo;Z)Lcom/android/credentialmanager/createflow/CreateScreenState;
+HSPLcom/android/credentialmanager/CreateFlowUtils$Companion;->toCreationOptionInfoList(Ljava/lang/String;Ljava/util/List;Landroid/content/Context;)Ljava/util/List;
+HSPLcom/android/credentialmanager/CreateFlowUtils$Companion;->toDisabledProviderList(Ljava/util/List;Landroid/content/Context;)Ljava/util/List;
+HSPLcom/android/credentialmanager/CreateFlowUtils$Companion;->toEnabledProviderList(Ljava/util/List;Landroid/content/Context;)Ljava/util/List;
+HSPLcom/android/credentialmanager/CreateFlowUtils$Companion;->toRemoteInfo(Ljava/lang/String;Landroid/credentials/ui/Entry;)Lcom/android/credentialmanager/createflow/RemoteInfo;
+HSPLcom/android/credentialmanager/CreateFlowUtils$Companion;->toRequestDisplayInfo(Landroid/credentials/ui/RequestInfo;Landroid/content/Context;)Lcom/android/credentialmanager/createflow/RequestDisplayInfo;
+HSPLcom/android/credentialmanager/CreateFlowUtils;-><clinit>()V
+HSPLcom/android/credentialmanager/CredentialManagerRepo$Companion;-><init>()V
+HSPLcom/android/credentialmanager/CredentialManagerRepo$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLcom/android/credentialmanager/CredentialManagerRepo$Companion;->getInstance()Lcom/android/credentialmanager/CredentialManagerRepo;
+HSPLcom/android/credentialmanager/CredentialManagerRepo$Companion;->getRepo()Lcom/android/credentialmanager/CredentialManagerRepo;
+HSPLcom/android/credentialmanager/CredentialManagerRepo$Companion;->setRepo(Lcom/android/credentialmanager/CredentialManagerRepo;)V
+HSPLcom/android/credentialmanager/CredentialManagerRepo$Companion;->setup(Landroid/content/Context;Landroid/content/Intent;)V
+HSPLcom/android/credentialmanager/CredentialManagerRepo;-><clinit>()V
+HSPLcom/android/credentialmanager/CredentialManagerRepo;-><init>(Landroid/content/Context;Landroid/content/Intent;)V
+HSPLcom/android/credentialmanager/CredentialManagerRepo;->getCreateProviderDisableListInitialUiState()Ljava/util/List;
+HSPLcom/android/credentialmanager/CredentialManagerRepo;->getCreateProviderEnableListInitialUiState()Ljava/util/List;
+HSPLcom/android/credentialmanager/CredentialManagerRepo;->getCreateRequestDisplayInfoInitialUiState()Lcom/android/credentialmanager/createflow/RequestDisplayInfo;
+HSPLcom/android/credentialmanager/CredentialManagerRepo;->getRequestInfo()Landroid/credentials/ui/RequestInfo;
+HSPLcom/android/credentialmanager/CredentialSelectorActivity$CredentialManagerBottomSheet$3;-><init>(Lcom/android/credentialmanager/CredentialSelectorActivity;Lcom/android/credentialmanager/common/DialogType;I)V
+HSPLcom/android/credentialmanager/CredentialSelectorActivity$CredentialManagerBottomSheet$launcher$1$1;-><init>(Landroidx/compose/runtime/MutableState;)V
+HSPLcom/android/credentialmanager/CredentialSelectorActivity$WhenMappings;-><clinit>()V
+HSPLcom/android/credentialmanager/CredentialSelectorActivity$onCancel$1;-><init>(Lcom/android/credentialmanager/CredentialSelectorActivity;)V
+HSPLcom/android/credentialmanager/CredentialSelectorActivity$onCreate$1$1;-><init>(Lcom/android/credentialmanager/CredentialSelectorActivity;Landroid/credentials/ui/RequestInfo;)V
+HSPLcom/android/credentialmanager/CredentialSelectorActivity$onCreate$1$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/CredentialSelectorActivity$onCreate$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/CredentialSelectorActivity$onCreate$1;-><init>(Lcom/android/credentialmanager/CredentialSelectorActivity;Landroid/credentials/ui/RequestInfo;)V
+HSPLcom/android/credentialmanager/CredentialSelectorActivity$onCreate$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/CredentialSelectorActivity$onCreate$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/CredentialSelectorActivity;-><clinit>()V
+HSPLcom/android/credentialmanager/CredentialSelectorActivity;-><init>()V
+HSPLcom/android/credentialmanager/CredentialSelectorActivity;->CredentialManagerBottomSheet(Lcom/android/credentialmanager/common/DialogType;Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/CredentialSelectorActivity;->onCreate(Landroid/os/Bundle;)V
+HSPLcom/android/credentialmanager/UserConfigRepo$Companion;-><init>()V
+HSPLcom/android/credentialmanager/UserConfigRepo$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLcom/android/credentialmanager/UserConfigRepo$Companion;->getInstance()Lcom/android/credentialmanager/UserConfigRepo;
+HSPLcom/android/credentialmanager/UserConfigRepo$Companion;->getRepo()Lcom/android/credentialmanager/UserConfigRepo;
+HSPLcom/android/credentialmanager/UserConfigRepo$Companion;->setRepo(Lcom/android/credentialmanager/UserConfigRepo;)V
+HSPLcom/android/credentialmanager/UserConfigRepo$Companion;->setup(Landroid/content/Context;)V
+HSPLcom/android/credentialmanager/UserConfigRepo;-><clinit>()V
+HSPLcom/android/credentialmanager/UserConfigRepo;-><init>(Landroid/content/Context;)V
+HSPLcom/android/credentialmanager/UserConfigRepo;->getDefaultProviderId()Ljava/lang/String;
+HSPLcom/android/credentialmanager/UserConfigRepo;->getIsPasskeyFirstUse()Z
+HSPLcom/android/credentialmanager/common/DialogType$Companion;-><init>()V
+HSPLcom/android/credentialmanager/common/DialogType$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLcom/android/credentialmanager/common/DialogType$Companion;->toDialogType(Ljava/lang/String;)Lcom/android/credentialmanager/common/DialogType;
+HSPLcom/android/credentialmanager/common/DialogType;->$values()[Lcom/android/credentialmanager/common/DialogType;
+HSPLcom/android/credentialmanager/common/DialogType;-><clinit>()V
+HSPLcom/android/credentialmanager/common/DialogType;-><init>(Ljava/lang/String;I)V
+HSPLcom/android/credentialmanager/common/DialogType;->values()[Lcom/android/credentialmanager/common/DialogType;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetDefaults;-><clinit>()V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetDefaults;-><init>()V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetDefaults;->getElevation-D9Ej5fM()F
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$1$1;-><init>(Lcom/android/credentialmanager/common/material/ModalBottomSheetState;Lkotlinx/coroutines/CoroutineScope;)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$2$1;-><init>(Lcom/android/credentialmanager/common/material/ModalBottomSheetState;F)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$2$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$2$1;->invoke-Bjo55l4(Landroidx/compose/ui/unit/Density;)J
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$3$1;-><init>(Landroidx/compose/runtime/MutableState;)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$3$1;->invoke(Landroidx/compose/ui/layout/LayoutCoordinates;)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$3$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$4$1;-><init>(Lcom/android/credentialmanager/common/material/ModalBottomSheetState;Lkotlinx/coroutines/CoroutineScope;)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$4;-><init>(Lcom/android/credentialmanager/common/material/ModalBottomSheetState;Lkotlinx/coroutines/CoroutineScope;)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$4;->invoke(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$4;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$5;-><init>(Lkotlin/jvm/functions/Function3;I)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$5;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$5;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1;-><init>(Lcom/android/credentialmanager/common/material/ModalBottomSheetState;ILandroidx/compose/ui/graphics/Shape;JJFLkotlin/jvm/functions/Function2;JLkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function3;)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1;->invoke(Landroidx/compose/foundation/layout/BoxWithConstraintsScope;Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$2;-><init>(Lkotlin/jvm/functions/Function3;Landroidx/compose/ui/Modifier;Lcom/android/credentialmanager/common/material/ModalBottomSheetState;Landroidx/compose/ui/graphics/Shape;FJJJLkotlin/jvm/functions/Function2;II)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$1$1;-><init>(JLandroidx/compose/runtime/State;)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$1$1;->invoke(Landroidx/compose/ui/graphics/drawscope/DrawScope;)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$2;-><init>(JLkotlin/jvm/functions/Function0;ZI)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$dismissModifier$1$1$1;-><init>(Lkotlin/jvm/functions/Function0;)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$dismissModifier$1$1;-><init>(Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$dismissModifier$1$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$dismissModifier$1$1;->invoke(Landroidx/compose/ui/input/pointer/PointerInputScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$dismissModifier$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$dismissModifier$1$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$dismissModifier$2$1$1;-><init>(Lkotlin/jvm/functions/Function0;)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$dismissModifier$2$1;-><init>(Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$dismissModifier$2$1;->invoke(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$dismissModifier$2$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$rememberModalBottomSheetState$1;-><clinit>()V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$rememberModalBottomSheetState$1;-><init>()V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$rememberModalBottomSheetState$2;-><init>(Lcom/android/credentialmanager/common/material/ModalBottomSheetValue;Landroidx/compose/animation/core/AnimationSpec;ZLkotlin/jvm/functions/Function1;)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$rememberModalBottomSheetState$2;->invoke()Lcom/android/credentialmanager/common/material/ModalBottomSheetState;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt$rememberModalBottomSheetState$2;->invoke()Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt;->ModalBottomSheetLayout-BzaUkTc(Lkotlin/jvm/functions/Function3;Landroidx/compose/ui/Modifier;Lcom/android/credentialmanager/common/material/ModalBottomSheetState;Landroidx/compose/ui/graphics/Shape;FJJJLkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt;->Scrim-3J-VO9M(JLkotlin/jvm/functions/Function0;ZLandroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt;->Scrim_3J_VO9M$lambda$0(Landroidx/compose/runtime/State;)F
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt;->access$Scrim-3J-VO9M(JLkotlin/jvm/functions/Function0;ZLandroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt;->access$Scrim_3J_VO9M$lambda$0(Landroidx/compose/runtime/State;)F
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt;->access$bottomSheetSwipeable(Landroidx/compose/ui/Modifier;Lcom/android/credentialmanager/common/material/ModalBottomSheetState;FLandroidx/compose/runtime/State;)Landroidx/compose/ui/Modifier;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt;->bottomSheetSwipeable(Landroidx/compose/ui/Modifier;Lcom/android/credentialmanager/common/material/ModalBottomSheetState;FLandroidx/compose/runtime/State;)Landroidx/compose/ui/Modifier;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetKt;->rememberModalBottomSheetState(Lcom/android/credentialmanager/common/material/ModalBottomSheetValue;Landroidx/compose/animation/core/AnimationSpec;ZLkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)Lcom/android/credentialmanager/common/material/ModalBottomSheetState;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetState$Companion$Saver$1;-><clinit>()V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetState$Companion$Saver$1;-><init>()V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetState$Companion$Saver$1;->invoke(Landroidx/compose/runtime/saveable/SaverScope;Lcom/android/credentialmanager/common/material/ModalBottomSheetState;)Lcom/android/credentialmanager/common/material/ModalBottomSheetValue;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetState$Companion$Saver$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetState$Companion$Saver$2;-><init>(Landroidx/compose/animation/core/AnimationSpec;ZLkotlin/jvm/functions/Function1;)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetState$Companion;-><init>()V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetState$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetState$Companion;->Saver(Landroidx/compose/animation/core/AnimationSpec;ZLkotlin/jvm/functions/Function1;)Landroidx/compose/runtime/saveable/Saver;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetState;-><clinit>()V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetState;-><init>(Lcom/android/credentialmanager/common/material/ModalBottomSheetValue;Landroidx/compose/animation/core/AnimationSpec;ZLkotlin/jvm/functions/Function1;)V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetState;->getHasHalfExpandedState$frameworks__base__packages__CredentialManager__android_common__CredentialManager()Z
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetState;->getNestedScrollConnection$frameworks__base__packages__CredentialManager__android_common__CredentialManager()Landroidx/compose/ui/input/nestedscroll/NestedScrollConnection;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetState;->isSkipHalfExpanded$frameworks__base__packages__CredentialManager__android_common__CredentialManager()Z
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetState;->isVisible()Z
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetValue;->$values()[Lcom/android/credentialmanager/common/material/ModalBottomSheetValue;
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetValue;-><clinit>()V
+HSPLcom/android/credentialmanager/common/material/ModalBottomSheetValue;-><init>(Ljava/lang/String;I)V
+HSPLcom/android/credentialmanager/common/material/SwipeableDefaults;-><clinit>()V
+HSPLcom/android/credentialmanager/common/material/SwipeableDefaults;-><init>()V
+HSPLcom/android/credentialmanager/common/material/SwipeableDefaults;->getAnimationSpec()Landroidx/compose/animation/core/SpringSpec;
+HSPLcom/android/credentialmanager/common/material/SwipeableDefaults;->getVelocityThreshold-D9Ej5fM()F
+HSPLcom/android/credentialmanager/common/material/SwipeableKt$PreUpPostDownNestedScrollConnection$1;-><init>(Lcom/android/credentialmanager/common/material/SwipeableState;)V
+HSPLcom/android/credentialmanager/common/material/SwipeableKt$swipeable$1;-><clinit>()V
+HSPLcom/android/credentialmanager/common/material/SwipeableKt$swipeable$1;-><init>()V
+HSPLcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3$3$1;-><init>(Ljava/util/Map;Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/unit/Density;)V
+HSPLcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3$3;-><init>(Lcom/android/credentialmanager/common/material/SwipeableState;Ljava/util/Map;Lcom/android/credentialmanager/common/material/ResistanceConfig;Landroidx/compose/ui/unit/Density;Lkotlin/jvm/functions/Function2;FLkotlin/coroutines/Continuation;)V
+HSPLcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3$3;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3$3;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3$4$1;-><init>(Lcom/android/credentialmanager/common/material/SwipeableState;Lkotlin/coroutines/Continuation;)V
+HSPLcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3;-><init>(Ljava/util/Map;Lcom/android/credentialmanager/common/material/SwipeableState;Landroidx/compose/foundation/gestures/Orientation;ZLandroidx/compose/foundation/interaction/MutableInteractionSource;ZLcom/android/credentialmanager/common/material/ResistanceConfig;Lkotlin/jvm/functions/Function2;F)V
+HSPLcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+HSPLcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/SwipeableKt;->access$computeTarget(FFLjava/util/Set;Lkotlin/jvm/functions/Function2;FF)F
+HSPLcom/android/credentialmanager/common/material/SwipeableKt;->access$getOffset(Ljava/util/Map;Ljava/lang/Object;)Ljava/lang/Float;
+HSPLcom/android/credentialmanager/common/material/SwipeableKt;->computeTarget(FFLjava/util/Set;Lkotlin/jvm/functions/Function2;FF)F
+HSPLcom/android/credentialmanager/common/material/SwipeableKt;->findBounds(FLjava/util/Set;)Ljava/util/List;
+HSPLcom/android/credentialmanager/common/material/SwipeableKt;->getOffset(Ljava/util/Map;Ljava/lang/Object;)Ljava/lang/Float;
+HSPLcom/android/credentialmanager/common/material/SwipeableKt;->getPreUpPostDownNestedScrollConnection(Lcom/android/credentialmanager/common/material/SwipeableState;)Landroidx/compose/ui/input/nestedscroll/NestedScrollConnection;
+HSPLcom/android/credentialmanager/common/material/SwipeableKt;->swipeable-pPrIpRY$default(Landroidx/compose/ui/Modifier;Lcom/android/credentialmanager/common/material/SwipeableState;Ljava/util/Map;Landroidx/compose/foundation/gestures/Orientation;ZZLandroidx/compose/foundation/interaction/MutableInteractionSource;Lkotlin/jvm/functions/Function2;Lcom/android/credentialmanager/common/material/ResistanceConfig;FILjava/lang/Object;)Landroidx/compose/ui/Modifier;
+HSPLcom/android/credentialmanager/common/material/SwipeableKt;->swipeable-pPrIpRY(Landroidx/compose/ui/Modifier;Lcom/android/credentialmanager/common/material/SwipeableState;Ljava/util/Map;Landroidx/compose/foundation/gestures/Orientation;ZZLandroidx/compose/foundation/interaction/MutableInteractionSource;Lkotlin/jvm/functions/Function2;Lcom/android/credentialmanager/common/material/ResistanceConfig;F)Landroidx/compose/ui/Modifier;
+HSPLcom/android/credentialmanager/common/material/SwipeableState$Companion;-><init>()V
+HSPLcom/android/credentialmanager/common/material/SwipeableState$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLcom/android/credentialmanager/common/material/SwipeableState$draggableState$1;-><init>(Lcom/android/credentialmanager/common/material/SwipeableState;)V
+HSPLcom/android/credentialmanager/common/material/SwipeableState$draggableState$1;->invoke(F)V
+HSPLcom/android/credentialmanager/common/material/SwipeableState$draggableState$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/SwipeableState$latestNonEmptyAnchorsFlow$1;-><init>(Lcom/android/credentialmanager/common/material/SwipeableState;)V
+HSPLcom/android/credentialmanager/common/material/SwipeableState$processNewAnchors$1;-><init>(Lcom/android/credentialmanager/common/material/SwipeableState;Lkotlin/coroutines/Continuation;)V
+HSPLcom/android/credentialmanager/common/material/SwipeableState$snapInternalToOffset$2;-><init>(FLcom/android/credentialmanager/common/material/SwipeableState;Lkotlin/coroutines/Continuation;)V
+HSPLcom/android/credentialmanager/common/material/SwipeableState$snapInternalToOffset$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLcom/android/credentialmanager/common/material/SwipeableState$snapInternalToOffset$2;->invoke(Landroidx/compose/foundation/gestures/DragScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/SwipeableState$snapInternalToOffset$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/SwipeableState$snapInternalToOffset$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/SwipeableState$special$$inlined$filter$1;-><init>(Lkotlinx/coroutines/flow/Flow;)V
+HSPLcom/android/credentialmanager/common/material/SwipeableState$thresholds$2;-><clinit>()V
+HSPLcom/android/credentialmanager/common/material/SwipeableState$thresholds$2;-><init>()V
+HSPLcom/android/credentialmanager/common/material/SwipeableState;-><clinit>()V
+HSPLcom/android/credentialmanager/common/material/SwipeableState;-><init>(Ljava/lang/Object;Landroidx/compose/animation/core/AnimationSpec;Lkotlin/jvm/functions/Function1;)V
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->access$getAbsoluteOffset$p(Lcom/android/credentialmanager/common/material/SwipeableState;)Landroidx/compose/runtime/MutableState;
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->access$getOffsetState$p(Lcom/android/credentialmanager/common/material/SwipeableState;)Landroidx/compose/runtime/MutableState;
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->access$getOverflowState$p(Lcom/android/credentialmanager/common/material/SwipeableState;)Landroidx/compose/runtime/MutableState;
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->ensureInit$frameworks__base__packages__CredentialManager__android_common__CredentialManager(Ljava/util/Map;)V
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->getAnchors$frameworks__base__packages__CredentialManager__android_common__CredentialManager()Ljava/util/Map;
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->getCurrentValue()Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->getDraggableState$frameworks__base__packages__CredentialManager__android_common__CredentialManager()Landroidx/compose/foundation/gestures/DraggableState;
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->getMaxBound$frameworks__base__packages__CredentialManager__android_common__CredentialManager()F
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->getMinBound$frameworks__base__packages__CredentialManager__android_common__CredentialManager()F
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->getOffset()Landroidx/compose/runtime/State;
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->getResistance$frameworks__base__packages__CredentialManager__android_common__CredentialManager()Lcom/android/credentialmanager/common/material/ResistanceConfig;
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->getTargetValue()Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->getThresholds$frameworks__base__packages__CredentialManager__android_common__CredentialManager()Lkotlin/jvm/functions/Function2;
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->isAnimationRunning()Z
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->processNewAnchors$frameworks__base__packages__CredentialManager__android_common__CredentialManager(Ljava/util/Map;Ljava/util/Map;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->setAnchors$frameworks__base__packages__CredentialManager__android_common__CredentialManager(Ljava/util/Map;)V
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->setResistance$frameworks__base__packages__CredentialManager__android_common__CredentialManager(Lcom/android/credentialmanager/common/material/ResistanceConfig;)V
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->setThresholds$frameworks__base__packages__CredentialManager__android_common__CredentialManager(Lkotlin/jvm/functions/Function2;)V
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->setVelocityThreshold$frameworks__base__packages__CredentialManager__android_common__CredentialManager(F)V
+HSPLcom/android/credentialmanager/common/material/SwipeableState;->snapInternalToOffset(FLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/ui/ActionButtonKt$ActionButton$1;-><init>(Ljava/lang/String;I)V
+HSPLcom/android/credentialmanager/common/ui/ActionButtonKt$ActionButton$1;->invoke(Landroidx/compose/foundation/layout/RowScope;Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/common/ui/ActionButtonKt$ActionButton$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/ui/ActionButtonKt$ActionButton$2;-><init>(Ljava/lang/String;Lkotlin/jvm/functions/Function0;I)V
+HSPLcom/android/credentialmanager/common/ui/ActionButtonKt;->ActionButton(Ljava/lang/String;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/common/ui/CardsKt$ContainerCard$1;-><init>(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/graphics/Shape;Landroidx/compose/foundation/BorderStroke;Lkotlin/jvm/functions/Function3;II)V
+HSPLcom/android/credentialmanager/common/ui/CardsKt;->ContainerCard(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/graphics/Shape;Landroidx/compose/foundation/BorderStroke;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V
+HSPLcom/android/credentialmanager/common/ui/ConfirmButtonKt$ConfirmButton$1;-><init>(Ljava/lang/String;I)V
+HSPLcom/android/credentialmanager/common/ui/ConfirmButtonKt$ConfirmButton$1;->invoke(Landroidx/compose/foundation/layout/RowScope;Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/common/ui/ConfirmButtonKt$ConfirmButton$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/common/ui/ConfirmButtonKt$ConfirmButton$2;-><init>(Ljava/lang/String;Lkotlin/jvm/functions/Function0;I)V
+HSPLcom/android/credentialmanager/common/ui/ConfirmButtonKt;->ConfirmButton(Ljava/lang/String;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/common/ui/EntryKt$Entry$1;-><init>(Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function2;II)V
+HSPLcom/android/credentialmanager/common/ui/EntryKt;->Entry(Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V
+HSPLcom/android/credentialmanager/common/ui/TextsKt$TextOnSurface$1;-><init>(Ljava/lang/String;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/text/style/TextAlign;Landroidx/compose/ui/text/TextStyle;II)V
+HSPLcom/android/credentialmanager/common/ui/TextsKt$TextOnSurfaceVariant$1;-><init>(Ljava/lang/String;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/text/style/TextAlign;Landroidx/compose/ui/text/TextStyle;II)V
+HSPLcom/android/credentialmanager/common/ui/TextsKt$TextSecondary$1;-><init>(Ljava/lang/String;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/text/style/TextAlign;Landroidx/compose/ui/text/TextStyle;II)V
+HSPLcom/android/credentialmanager/common/ui/TextsKt;->TextInternal-2rk-Xng(Ljava/lang/String;JLandroidx/compose/ui/Modifier;Landroidx/compose/ui/text/style/TextAlign;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/common/ui/TextsKt;->TextOnSurface-B9Ufvwk(Ljava/lang/String;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/text/style/TextAlign;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/runtime/Composer;II)V
+HSPLcom/android/credentialmanager/common/ui/TextsKt;->TextOnSurfaceVariant-B9Ufvwk(Ljava/lang/String;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/text/style/TextAlign;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/runtime/Composer;II)V
+HSPLcom/android/credentialmanager/common/ui/TextsKt;->TextSecondary-B9Ufvwk(Ljava/lang/String;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/text/style/TextAlign;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/runtime/Composer;II)V
+HSPLcom/android/credentialmanager/createflow/ActiveEntry;-><clinit>()V
+HSPLcom/android/credentialmanager/createflow/ActiveEntry;-><init>(Lcom/android/credentialmanager/createflow/EnabledProviderInfo;Lcom/android/credentialmanager/createflow/EntryInfo;)V
+HSPLcom/android/credentialmanager/createflow/ActiveEntry;->getActiveEntryInfo()Lcom/android/credentialmanager/createflow/EntryInfo;
+HSPLcom/android/credentialmanager/createflow/ActiveEntry;->getActiveProvider()Lcom/android/credentialmanager/createflow/EnabledProviderInfo;
+HSPLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-1$1;-><clinit>()V
+HSPLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-1$1;-><init>()V
+HSPLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-1$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-2$1;-><clinit>()V
+HSPLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-2$1;-><init>()V
+HSPLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-3$1;-><clinit>()V
+HSPLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-3$1;-><init>()V
+HSPLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-4$1;-><clinit>()V
+HSPLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-4$1;-><init>()V
+HSPLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-5$1;-><clinit>()V
+HSPLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-5$1;-><init>()V
+HSPLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt;-><clinit>()V
+HSPLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt;-><init>()V
+HSPLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt;->getLambda-1$frameworks__base__packages__CredentialManager__android_common__CredentialManager()Lkotlin/jvm/functions/Function2;
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$6;-><init>(Ljava/lang/Object;)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$7;-><init>(Ljava/lang/Object;)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$8;-><init>(Ljava/lang/Object;)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$WhenMappings;-><clinit>()V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1;-><init>(Lcom/android/credentialmanager/createflow/CreateCredentialViewModel;Landroidx/activity/compose/ManagedActivityResultLauncher;)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1;->invoke(Landroidx/compose/foundation/layout/ColumnScope;Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$2;-><init>(Lcom/android/credentialmanager/common/material/ModalBottomSheetState;Lcom/android/credentialmanager/createflow/CreateCredentialViewModel;Lkotlin/coroutines/Continuation;)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$3;-><init>(Lcom/android/credentialmanager/createflow/CreateCredentialViewModel;Landroidx/activity/compose/ManagedActivityResultLauncher;I)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreationSelectionCard$1$1$1;-><init>(Lcom/android/credentialmanager/createflow/RequestDisplayInfo;Lcom/android/credentialmanager/createflow/CreateOptionInfo;Lkotlin/jvm/functions/Function1;I)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreationSelectionCard$1$1$1;->invoke(Landroidx/compose/foundation/layout/ColumnScope;Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreationSelectionCard$1$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreationSelectionCard$1;-><init>(Lcom/android/credentialmanager/createflow/EnabledProviderInfo;Lcom/android/credentialmanager/createflow/RequestDisplayInfo;Ljava/util/List;Lcom/android/credentialmanager/createflow/CreateOptionInfo;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreationSelectionCard$1;->invoke(Landroidx/compose/foundation/layout/ColumnScope;Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreationSelectionCard$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$PrimaryCreateOptionRow$1;-><init>(Lkotlin/jvm/functions/Function1;Lcom/android/credentialmanager/createflow/EntryInfo;)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$PrimaryCreateOptionRow$2;-><init>(Lcom/android/credentialmanager/createflow/RequestDisplayInfo;)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$PrimaryCreateOptionRow$2;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$PrimaryCreateOptionRow$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$PrimaryCreateOptionRow$3;-><init>(Lcom/android/credentialmanager/createflow/EntryInfo;Lcom/android/credentialmanager/createflow/RequestDisplayInfo;)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$PrimaryCreateOptionRow$3;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$PrimaryCreateOptionRow$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt;->CreateCredentialScreen(Lcom/android/credentialmanager/createflow/CreateCredentialViewModel;Landroidx/activity/compose/ManagedActivityResultLauncher;Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt;->CreationSelectionCard(Lcom/android/credentialmanager/createflow/RequestDisplayInfo;Ljava/util/List;Lcom/android/credentialmanager/createflow/EnabledProviderInfo;Lcom/android/credentialmanager/createflow/CreateOptionInfo;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt;->PrimaryCreateOptionRow(Lcom/android/credentialmanager/createflow/RequestDisplayInfo;Lcom/android/credentialmanager/createflow/EntryInfo;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialUiState;-><clinit>()V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialUiState;-><init>(Ljava/util/List;Ljava/util/List;Lcom/android/credentialmanager/createflow/CreateScreenState;Lcom/android/credentialmanager/createflow/RequestDisplayInfo;Ljava/util/List;ZLcom/android/credentialmanager/createflow/ActiveEntry;Lcom/android/credentialmanager/createflow/EntryInfo;ZZLjava/lang/Boolean;)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialUiState;-><init>(Ljava/util/List;Ljava/util/List;Lcom/android/credentialmanager/createflow/CreateScreenState;Lcom/android/credentialmanager/createflow/RequestDisplayInfo;Ljava/util/List;ZLcom/android/credentialmanager/createflow/ActiveEntry;Lcom/android/credentialmanager/createflow/EntryInfo;ZZLjava/lang/Boolean;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialUiState;->getActiveEntry()Lcom/android/credentialmanager/createflow/ActiveEntry;
+HSPLcom/android/credentialmanager/createflow/CreateCredentialUiState;->getCurrentScreenState()Lcom/android/credentialmanager/createflow/CreateScreenState;
+HSPLcom/android/credentialmanager/createflow/CreateCredentialUiState;->getEnabledProviders()Ljava/util/List;
+HSPLcom/android/credentialmanager/createflow/CreateCredentialUiState;->getHidden()Z
+HSPLcom/android/credentialmanager/createflow/CreateCredentialUiState;->getRequestDisplayInfo()Lcom/android/credentialmanager/createflow/RequestDisplayInfo;
+HSPLcom/android/credentialmanager/createflow/CreateCredentialViewModel$dialogResult$2;-><clinit>()V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialViewModel$dialogResult$2;-><init>()V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialViewModel$dialogResult$2;->invoke()Landroidx/lifecycle/MutableLiveData;
+HSPLcom/android/credentialmanager/createflow/CreateCredentialViewModel$dialogResult$2;->invoke()Ljava/lang/Object;
+HSPLcom/android/credentialmanager/createflow/CreateCredentialViewModel;-><clinit>()V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialViewModel;-><init>()V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialViewModel;-><init>(Lcom/android/credentialmanager/CredentialManagerRepo;Lcom/android/credentialmanager/UserConfigRepo;)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialViewModel;-><init>(Lcom/android/credentialmanager/CredentialManagerRepo;Lcom/android/credentialmanager/UserConfigRepo;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLcom/android/credentialmanager/createflow/CreateCredentialViewModel;->getDialogResult()Landroidx/lifecycle/MutableLiveData;
+HSPLcom/android/credentialmanager/createflow/CreateCredentialViewModel;->getUiState()Lcom/android/credentialmanager/createflow/CreateCredentialUiState;
+HSPLcom/android/credentialmanager/createflow/CreateCredentialViewModel;->observeDialogResult()Landroidx/lifecycle/LiveData;
+HSPLcom/android/credentialmanager/createflow/CreateOptionInfo;-><clinit>()V
+HSPLcom/android/credentialmanager/createflow/CreateOptionInfo;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/content/Intent;Ljava/lang/String;Landroid/graphics/drawable/Drawable;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Long;)V
+HSPLcom/android/credentialmanager/createflow/CreateOptionInfo;->getLastUsedTimeMillis()Ljava/lang/Long;
+HSPLcom/android/credentialmanager/createflow/CreateOptionInfo;->getProfileIcon()Landroid/graphics/drawable/Drawable;
+HSPLcom/android/credentialmanager/createflow/CreateOptionInfo;->getUserProviderDisplayName()Ljava/lang/String;
+HSPLcom/android/credentialmanager/createflow/CreateScreenState;->$values()[Lcom/android/credentialmanager/createflow/CreateScreenState;
+HSPLcom/android/credentialmanager/createflow/CreateScreenState;-><clinit>()V
+HSPLcom/android/credentialmanager/createflow/CreateScreenState;-><init>(Ljava/lang/String;I)V
+HSPLcom/android/credentialmanager/createflow/CreateScreenState;->values()[Lcom/android/credentialmanager/createflow/CreateScreenState;
+HSPLcom/android/credentialmanager/createflow/DisabledProviderInfo;-><clinit>()V
+HSPLcom/android/credentialmanager/createflow/DisabledProviderInfo;-><init>(Landroid/graphics/drawable/Drawable;Ljava/lang/String;Ljava/lang/String;)V
+HSPLcom/android/credentialmanager/createflow/EnabledProviderInfo;-><clinit>()V
+HSPLcom/android/credentialmanager/createflow/EnabledProviderInfo;-><init>(Landroid/graphics/drawable/Drawable;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Lcom/android/credentialmanager/createflow/RemoteInfo;)V
+HSPLcom/android/credentialmanager/createflow/EnabledProviderInfo;->getCreateOptions()Ljava/util/List;
+HSPLcom/android/credentialmanager/createflow/EnabledProviderInfo;->getRemoteEntry()Lcom/android/credentialmanager/createflow/RemoteInfo;
+HSPLcom/android/credentialmanager/createflow/EntryInfo;-><clinit>()V
+HSPLcom/android/credentialmanager/createflow/EntryInfo;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/content/Intent;)V
+HSPLcom/android/credentialmanager/createflow/ProviderInfo;-><clinit>()V
+HSPLcom/android/credentialmanager/createflow/ProviderInfo;-><init>(Landroid/graphics/drawable/Drawable;Ljava/lang/String;Ljava/lang/String;)V
+HSPLcom/android/credentialmanager/createflow/ProviderInfo;->getDisplayName()Ljava/lang/String;
+HSPLcom/android/credentialmanager/createflow/ProviderInfo;->getIcon()Landroid/graphics/drawable/Drawable;
+HSPLcom/android/credentialmanager/createflow/ProviderInfo;->getId()Ljava/lang/String;
+HSPLcom/android/credentialmanager/createflow/RequestDisplayInfo;-><clinit>()V
+HSPLcom/android/credentialmanager/createflow/RequestDisplayInfo;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/graphics/drawable/Drawable;)V
+HSPLcom/android/credentialmanager/createflow/RequestDisplayInfo;->getAppName()Ljava/lang/String;
+HSPLcom/android/credentialmanager/createflow/RequestDisplayInfo;->getSubtitle()Ljava/lang/String;
+HSPLcom/android/credentialmanager/createflow/RequestDisplayInfo;->getTitle()Ljava/lang/String;
+HSPLcom/android/credentialmanager/createflow/RequestDisplayInfo;->getType()Ljava/lang/String;
+HSPLcom/android/credentialmanager/createflow/RequestDisplayInfo;->getTypeIcon()Landroid/graphics/drawable/Drawable;
+HSPLcom/android/credentialmanager/jetpack/developer/CreateCredentialRequest$Companion;-><init>()V
+HSPLcom/android/credentialmanager/jetpack/developer/CreateCredentialRequest$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLcom/android/credentialmanager/jetpack/developer/CreateCredentialRequest$Companion;->createFrom(Ljava/lang/String;Landroid/os/Bundle;Landroid/os/Bundle;Z)Lcom/android/credentialmanager/jetpack/developer/CreateCredentialRequest;
+HSPLcom/android/credentialmanager/jetpack/developer/CreateCredentialRequest;-><clinit>()V
+HSPLcom/android/credentialmanager/jetpack/developer/CreateCredentialRequest;-><init>(Ljava/lang/String;Landroid/os/Bundle;Landroid/os/Bundle;Z)V
+HSPLcom/android/credentialmanager/jetpack/developer/CreateCredentialRequest;->getType()Ljava/lang/String;
+HSPLcom/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest$Companion;-><init>()V
+HSPLcom/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLcom/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest$Companion;->createFrom$frameworks__base__packages__CredentialManager__android_common__CredentialManager(Landroid/os/Bundle;)Lcom/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest;
+HSPLcom/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest$Companion;->toCredentialDataBundle$frameworks__base__packages__CredentialManager__android_common__CredentialManager(Ljava/lang/String;Z)Landroid/os/Bundle;
+HSPLcom/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest;-><clinit>()V
+HSPLcom/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest;-><init>(Ljava/lang/String;Z)V
+HSPLcom/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest;->getRequestJson()Ljava/lang/String;
+HSPLcom/android/credentialmanager/jetpack/provider/CreateEntry$Companion;-><init>()V
+HSPLcom/android/credentialmanager/jetpack/provider/CreateEntry$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLcom/android/credentialmanager/jetpack/provider/CreateEntry$Companion;->fromSlice(Landroid/app/slice/Slice;)Lcom/android/credentialmanager/jetpack/provider/CreateEntry;
+HSPLcom/android/credentialmanager/jetpack/provider/CreateEntry;-><clinit>()V
+HSPLcom/android/credentialmanager/jetpack/provider/CreateEntry;-><init>(Ljava/lang/CharSequence;Landroid/app/PendingIntent;Landroid/graphics/drawable/Icon;JLjava/util/List;)V
+HSPLcom/android/credentialmanager/jetpack/provider/CreateEntry;->getAccountName()Ljava/lang/CharSequence;
+HSPLcom/android/credentialmanager/jetpack/provider/CreateEntry;->getCredentialCountInformationList()Ljava/util/List;
+HSPLcom/android/credentialmanager/jetpack/provider/CreateEntry;->getIcon()Landroid/graphics/drawable/Icon;
+HSPLcom/android/credentialmanager/jetpack/provider/CreateEntry;->getLastUsedTimeMillis()J
+HSPLcom/android/credentialmanager/jetpack/provider/CreateEntry;->getPendingIntent()Landroid/app/PendingIntent;
+HSPLcom/android/credentialmanager/jetpack/provider/CredentialCountInformation$Companion;-><init>()V
+HSPLcom/android/credentialmanager/jetpack/provider/CredentialCountInformation$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLcom/android/credentialmanager/jetpack/provider/CredentialCountInformation$Companion;->getCountForType(Ljava/util/List;Ljava/lang/String;)Ljava/lang/Integer;
+HSPLcom/android/credentialmanager/jetpack/provider/CredentialCountInformation$Companion;->getPasskeyCount(Ljava/util/List;)Ljava/lang/Integer;
+HSPLcom/android/credentialmanager/jetpack/provider/CredentialCountInformation$Companion;->getPasswordCount(Ljava/util/List;)Ljava/lang/Integer;
+HSPLcom/android/credentialmanager/jetpack/provider/CredentialCountInformation$Companion;->getTotalCount(Ljava/util/List;)Ljava/lang/Integer;
+HSPLcom/android/credentialmanager/jetpack/provider/CredentialCountInformation;-><clinit>()V
+HSPLcom/android/credentialmanager/ui/theme/AndroidColorScheme;-><clinit>()V
+HSPLcom/android/credentialmanager/ui/theme/AndroidColorScheme;-><init>(Landroid/content/Context;)V
+HSPLcom/android/credentialmanager/ui/theme/AndroidColorScheme;->getColor-WaAFU9c(Landroid/content/Context;I)J
+HSPLcom/android/credentialmanager/ui/theme/AndroidColorScheme;->getColorAccentPrimaryVariant-0d7_KjU()J
+HSPLcom/android/credentialmanager/ui/theme/AndroidColorSchemeKt$LocalAndroidColorScheme$1;-><clinit>()V
+HSPLcom/android/credentialmanager/ui/theme/AndroidColorSchemeKt$LocalAndroidColorScheme$1;-><init>()V
+HSPLcom/android/credentialmanager/ui/theme/AndroidColorSchemeKt;-><clinit>()V
+HSPLcom/android/credentialmanager/ui/theme/AndroidColorSchemeKt;->getLocalAndroidColorScheme()Landroidx/compose/runtime/ProvidableCompositionLocal;
+HSPLcom/android/credentialmanager/ui/theme/ColorKt;-><clinit>()V
+HSPLcom/android/credentialmanager/ui/theme/ColorKt;->getTextColorPrimary()J
+HSPLcom/android/credentialmanager/ui/theme/ColorKt;->getTextColorSecondary()J
+HSPLcom/android/credentialmanager/ui/theme/EntryShape;-><clinit>()V
+HSPLcom/android/credentialmanager/ui/theme/EntryShape;-><init>()V
+HSPLcom/android/credentialmanager/ui/theme/EntryShape;->getFullSmallRoundedCorner()Landroidx/compose/foundation/shape/RoundedCornerShape;
+HSPLcom/android/credentialmanager/ui/theme/EntryShape;->getTopRoundedCorner()Landroidx/compose/foundation/shape/RoundedCornerShape;
+HSPLcom/android/credentialmanager/ui/theme/ShapeKt;-><clinit>()V
+HSPLcom/android/credentialmanager/ui/theme/ShapeKt;->getShapes()Landroidx/compose/material3/Shapes;
+HSPLcom/android/credentialmanager/ui/theme/ThemeKt$CredentialSelectorTheme$1$1;-><init>(Lkotlin/jvm/functions/Function2;I)V
+HSPLcom/android/credentialmanager/ui/theme/ThemeKt$CredentialSelectorTheme$1$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/ui/theme/ThemeKt$CredentialSelectorTheme$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/ui/theme/ThemeKt$CredentialSelectorTheme$1;-><init>(Lcom/android/credentialmanager/ui/theme/AndroidColorScheme;Lkotlin/jvm/functions/Function2;I)V
+HSPLcom/android/credentialmanager/ui/theme/ThemeKt$CredentialSelectorTheme$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/ui/theme/ThemeKt$CredentialSelectorTheme$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/ui/theme/ThemeKt$CredentialSelectorTheme$2;-><init>(ZLkotlin/jvm/functions/Function2;II)V
+HSPLcom/android/credentialmanager/ui/theme/ThemeKt$CredentialSelectorTheme$2;->invoke(Landroidx/compose/runtime/Composer;I)V
+HSPLcom/android/credentialmanager/ui/theme/ThemeKt$CredentialSelectorTheme$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/credentialmanager/ui/theme/ThemeKt;->CredentialSelectorTheme(ZLkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V
+HSPLcom/android/credentialmanager/ui/theme/TypeKt;-><clinit>()V
+HSPLcom/android/credentialmanager/ui/theme/TypeKt;->getTypography()Landroidx/compose/material3/Typography;
+HSPLkotlin/LazyKt;->lazy(Lkotlin/LazyThreadSafetyMode;Lkotlin/jvm/functions/Function0;)Lkotlin/Lazy;
+HSPLkotlin/LazyKt;->lazy(Lkotlin/jvm/functions/Function0;)Lkotlin/Lazy;
+HSPLkotlin/LazyKt__LazyJVMKt$WhenMappings;-><clinit>()V
+HSPLkotlin/LazyKt__LazyJVMKt;->lazy(Lkotlin/LazyThreadSafetyMode;Lkotlin/jvm/functions/Function0;)Lkotlin/Lazy;
+HSPLkotlin/LazyKt__LazyJVMKt;->lazy(Lkotlin/jvm/functions/Function0;)Lkotlin/Lazy;
+HSPLkotlin/LazyThreadSafetyMode;->$values()[Lkotlin/LazyThreadSafetyMode;
+HSPLkotlin/LazyThreadSafetyMode;-><clinit>()V
+HSPLkotlin/LazyThreadSafetyMode;-><init>(Ljava/lang/String;I)V
+HSPLkotlin/LazyThreadSafetyMode;->values()[Lkotlin/LazyThreadSafetyMode;
+HSPLkotlin/Pair;-><init>(Ljava/lang/Object;Ljava/lang/Object;)V
+HSPLkotlin/Pair;->component1()Ljava/lang/Object;
+HSPLkotlin/Pair;->component2()Ljava/lang/Object;
+HSPLkotlin/Pair;->getFirst()Ljava/lang/Object;
+HSPLkotlin/Pair;->getSecond()Ljava/lang/Object;
+HSPLkotlin/Result$Companion;-><init>()V
+HSPLkotlin/Result$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlin/Result$Failure;-><init>(Ljava/lang/Throwable;)V
+HSPLkotlin/Result;-><clinit>()V
+HSPLkotlin/Result;->constructor-impl(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlin/Result;->exceptionOrNull-impl(Ljava/lang/Object;)Ljava/lang/Throwable;
+HSPLkotlin/Result;->isFailure-impl(Ljava/lang/Object;)Z
+HSPLkotlin/Result;->isSuccess-impl(Ljava/lang/Object;)Z
+HSPLkotlin/ResultKt;->createFailure(Ljava/lang/Throwable;)Ljava/lang/Object;
+HSPLkotlin/ResultKt;->throwOnFailure(Ljava/lang/Object;)V
+HSPLkotlin/SynchronizedLazyImpl;-><init>(Lkotlin/jvm/functions/Function0;Ljava/lang/Object;)V
+HSPLkotlin/SynchronizedLazyImpl;-><init>(Lkotlin/jvm/functions/Function0;Ljava/lang/Object;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlin/SynchronizedLazyImpl;->getValue()Ljava/lang/Object;
+HSPLkotlin/TuplesKt;->to(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
+HSPLkotlin/ULong$Companion;-><init>()V
+HSPLkotlin/ULong$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlin/ULong;-><clinit>()V
+HSPLkotlin/ULong;->constructor-impl(J)J
+HSPLkotlin/UNINITIALIZED_VALUE;-><clinit>()V
+HSPLkotlin/UNINITIALIZED_VALUE;-><init>()V
+HSPLkotlin/Unit;-><clinit>()V
+HSPLkotlin/Unit;-><init>()V
+HSPLkotlin/UnsafeLazyImpl;-><init>(Lkotlin/jvm/functions/Function0;)V
+HSPLkotlin/UnsafeLazyImpl;->getValue()Ljava/lang/Object;
+HSPLkotlin/UnsignedKt;->ulongToDouble(J)D
+HSPLkotlin/collections/AbstractCollection;-><init>()V
+HSPLkotlin/collections/AbstractCollection;->isEmpty()Z
+HSPLkotlin/collections/AbstractCollection;->size()I
+HSPLkotlin/collections/AbstractList$Companion;-><init>()V
+HSPLkotlin/collections/AbstractList$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlin/collections/AbstractList;-><clinit>()V
+HSPLkotlin/collections/AbstractList;-><init>()V
+HSPLkotlin/collections/AbstractMap$Companion;-><init>()V
+HSPLkotlin/collections/AbstractMap$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlin/collections/AbstractMap;-><clinit>()V
+HSPLkotlin/collections/AbstractMap;-><init>()V
+HSPLkotlin/collections/AbstractMap;->containsEntry$kotlin_stdlib(Ljava/util/Map$Entry;)Z
+HSPLkotlin/collections/AbstractMap;->entrySet()Ljava/util/Set;
+HSPLkotlin/collections/AbstractMap;->equals(Ljava/lang/Object;)Z
+HSPLkotlin/collections/AbstractMap;->size()I
+HSPLkotlin/collections/AbstractMutableList;-><init>()V
+HSPLkotlin/collections/AbstractMutableList;->size()I
+HSPLkotlin/collections/AbstractMutableMap;-><init>()V
+HSPLkotlin/collections/AbstractMutableMap;->size()I
+HSPLkotlin/collections/AbstractSet$Companion;-><init>()V
+HSPLkotlin/collections/AbstractSet$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlin/collections/AbstractSet$Companion;->setEquals$kotlin_stdlib(Ljava/util/Set;Ljava/util/Set;)Z
+HSPLkotlin/collections/AbstractSet;-><clinit>()V
+HSPLkotlin/collections/AbstractSet;-><init>()V
+HSPLkotlin/collections/AbstractSet;->equals(Ljava/lang/Object;)Z
+HSPLkotlin/collections/ArrayAsCollection;-><init>([Ljava/lang/Object;Z)V
+HSPLkotlin/collections/ArrayAsCollection;->toArray()[Ljava/lang/Object;
+HSPLkotlin/collections/ArrayDeque$Companion;-><init>()V
+HSPLkotlin/collections/ArrayDeque$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlin/collections/ArrayDeque$Companion;->newCapacity$kotlin_stdlib(II)I
+HSPLkotlin/collections/ArrayDeque;-><clinit>()V
+HSPLkotlin/collections/ArrayDeque;-><init>()V
+HSPLkotlin/collections/ArrayDeque;->addLast(Ljava/lang/Object;)V
+HSPLkotlin/collections/ArrayDeque;->copyElements(I)V
+HSPLkotlin/collections/ArrayDeque;->ensureCapacity(I)V
+HSPLkotlin/collections/ArrayDeque;->getSize()I
+HSPLkotlin/collections/ArrayDeque;->incremented(I)I
+HSPLkotlin/collections/ArrayDeque;->isEmpty()Z
+HSPLkotlin/collections/ArrayDeque;->positiveMod(I)I
+HSPLkotlin/collections/ArrayDeque;->removeFirst()Ljava/lang/Object;
+HSPLkotlin/collections/ArrayDeque;->removeFirstOrNull()Ljava/lang/Object;
+HSPLkotlin/collections/ArraysKt;->asList([Ljava/lang/Object;)Ljava/util/List;
+HSPLkotlin/collections/ArraysKt;->copyInto$default([F[FIIIILjava/lang/Object;)[F
+HSPLkotlin/collections/ArraysKt;->copyInto$default([I[IIIIILjava/lang/Object;)[I
+HSPLkotlin/collections/ArraysKt;->copyInto$default([Ljava/lang/Object;[Ljava/lang/Object;IIIILjava/lang/Object;)[Ljava/lang/Object;
+HSPLkotlin/collections/ArraysKt;->copyInto([F[FIII)[F
+HSPLkotlin/collections/ArraysKt;->copyInto([I[IIII)[I
+HSPLkotlin/collections/ArraysKt;->copyInto([Ljava/lang/Object;[Ljava/lang/Object;III)[Ljava/lang/Object;
+HSPLkotlin/collections/ArraysKt;->copyOfRange([Ljava/lang/Object;II)[Ljava/lang/Object;
+HSPLkotlin/collections/ArraysKt;->fill$default([Ljava/lang/Object;Ljava/lang/Object;IIILjava/lang/Object;)V
+HSPLkotlin/collections/ArraysKt;->fill([Ljava/lang/Object;Ljava/lang/Object;II)V
+HSPLkotlin/collections/ArraysKt;->getLastIndex([Ljava/lang/Object;)I
+HSPLkotlin/collections/ArraysKt;->sortWith([Ljava/lang/Object;Ljava/util/Comparator;II)V
+HSPLkotlin/collections/ArraysKt;->toList([Ljava/lang/Object;)Ljava/util/List;
+HSPLkotlin/collections/ArraysKt__ArraysJVMKt;->copyOfRangeToIndexCheck(II)V
+HSPLkotlin/collections/ArraysKt___ArraysJvmKt;->asList([Ljava/lang/Object;)Ljava/util/List;
+HSPLkotlin/collections/ArraysKt___ArraysJvmKt;->copyInto$default([F[FIIIILjava/lang/Object;)[F
+HSPLkotlin/collections/ArraysKt___ArraysJvmKt;->copyInto$default([I[IIIIILjava/lang/Object;)[I
+HSPLkotlin/collections/ArraysKt___ArraysJvmKt;->copyInto$default([Ljava/lang/Object;[Ljava/lang/Object;IIIILjava/lang/Object;)[Ljava/lang/Object;
+HSPLkotlin/collections/ArraysKt___ArraysJvmKt;->copyInto([F[FIII)[F
+HSPLkotlin/collections/ArraysKt___ArraysJvmKt;->copyInto([I[IIII)[I
+HSPLkotlin/collections/ArraysKt___ArraysJvmKt;->copyInto([Ljava/lang/Object;[Ljava/lang/Object;III)[Ljava/lang/Object;
+HSPLkotlin/collections/ArraysKt___ArraysJvmKt;->copyOfRange([Ljava/lang/Object;II)[Ljava/lang/Object;
+HSPLkotlin/collections/ArraysKt___ArraysJvmKt;->fill$default([Ljava/lang/Object;Ljava/lang/Object;IIILjava/lang/Object;)V
+HSPLkotlin/collections/ArraysKt___ArraysJvmKt;->fill([Ljava/lang/Object;Ljava/lang/Object;II)V
+HSPLkotlin/collections/ArraysKt___ArraysJvmKt;->sortWith([Ljava/lang/Object;Ljava/util/Comparator;)V
+HSPLkotlin/collections/ArraysKt___ArraysJvmKt;->sortWith([Ljava/lang/Object;Ljava/util/Comparator;II)V
+HSPLkotlin/collections/ArraysKt___ArraysKt;->getLastIndex([Ljava/lang/Object;)I
+HSPLkotlin/collections/ArraysKt___ArraysKt;->toList([Ljava/lang/Object;)Ljava/util/List;
+HSPLkotlin/collections/ArraysKt___ArraysKt;->toMutableList([Ljava/lang/Object;)Ljava/util/List;
+HSPLkotlin/collections/ArraysUtilJVM;->asList([Ljava/lang/Object;)Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt;->addAll(Ljava/util/Collection;Ljava/lang/Iterable;)Z
+HSPLkotlin/collections/CollectionsKt;->collectionSizeOrDefault(Ljava/lang/Iterable;I)I
+HSPLkotlin/collections/CollectionsKt;->distinct(Ljava/lang/Iterable;)Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt;->emptyList()Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt;->first(Ljava/util/List;)Ljava/lang/Object;
+HSPLkotlin/collections/CollectionsKt;->firstOrNull(Ljava/lang/Iterable;)Ljava/lang/Object;
+HSPLkotlin/collections/CollectionsKt;->getLastIndex(Ljava/util/List;)I
+HSPLkotlin/collections/CollectionsKt;->last(Ljava/util/List;)Ljava/lang/Object;
+HSPLkotlin/collections/CollectionsKt;->lastOrNull(Ljava/util/List;)Ljava/lang/Object;
+HSPLkotlin/collections/CollectionsKt;->listOf(Ljava/lang/Object;)Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt;->listOf([Ljava/lang/Object;)Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt;->listOfNotNull(Ljava/lang/Object;)Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt;->maxOrNull(Ljava/lang/Iterable;)Ljava/lang/Float;
+HSPLkotlin/collections/CollectionsKt;->minOrNull(Ljava/lang/Iterable;)Ljava/lang/Float;
+HSPLkotlin/collections/CollectionsKt;->plus(Ljava/util/Collection;Ljava/lang/Iterable;)Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt;->singleOrNull(Ljava/util/List;)Ljava/lang/Object;
+HSPLkotlin/collections/CollectionsKt;->sortWith(Ljava/util/List;Ljava/util/Comparator;)V
+HSPLkotlin/collections/CollectionsKt;->sortedWith(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt;->toList(Ljava/lang/Iterable;)Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt;->toMutableList(Ljava/util/Collection;)Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt__CollectionsJVMKt;->copyToArrayOfAny([Ljava/lang/Object;Z)[Ljava/lang/Object;
+HSPLkotlin/collections/CollectionsKt__CollectionsJVMKt;->listOf(Ljava/lang/Object;)Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt__CollectionsKt;->asCollection([Ljava/lang/Object;)Ljava/util/Collection;
+HSPLkotlin/collections/CollectionsKt__CollectionsKt;->emptyList()Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt__CollectionsKt;->getLastIndex(Ljava/util/List;)I
+HSPLkotlin/collections/CollectionsKt__CollectionsKt;->listOf([Ljava/lang/Object;)Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt__CollectionsKt;->listOfNotNull(Ljava/lang/Object;)Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt__IterablesKt;->collectionSizeOrDefault(Ljava/lang/Iterable;I)I
+HSPLkotlin/collections/CollectionsKt__MutableCollectionsJVMKt;->sortWith(Ljava/util/List;Ljava/util/Comparator;)V
+HSPLkotlin/collections/CollectionsKt__MutableCollectionsKt;->addAll(Ljava/util/Collection;Ljava/lang/Iterable;)Z
+HSPLkotlin/collections/CollectionsKt___CollectionsKt;->distinct(Ljava/lang/Iterable;)Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt___CollectionsKt;->first(Ljava/util/List;)Ljava/lang/Object;
+HSPLkotlin/collections/CollectionsKt___CollectionsKt;->firstOrNull(Ljava/lang/Iterable;)Ljava/lang/Object;
+HSPLkotlin/collections/CollectionsKt___CollectionsKt;->last(Ljava/util/List;)Ljava/lang/Object;
+HSPLkotlin/collections/CollectionsKt___CollectionsKt;->lastOrNull(Ljava/util/List;)Ljava/lang/Object;
+HSPLkotlin/collections/CollectionsKt___CollectionsKt;->maxOrNull(Ljava/lang/Iterable;)Ljava/lang/Float;
+HSPLkotlin/collections/CollectionsKt___CollectionsKt;->minOrNull(Ljava/lang/Iterable;)Ljava/lang/Float;
+HSPLkotlin/collections/CollectionsKt___CollectionsKt;->plus(Ljava/util/Collection;Ljava/lang/Iterable;)Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt___CollectionsKt;->singleOrNull(Ljava/util/List;)Ljava/lang/Object;
+HSPLkotlin/collections/CollectionsKt___CollectionsKt;->sortedWith(Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt___CollectionsKt;->toList(Ljava/lang/Iterable;)Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt___CollectionsKt;->toMutableList(Ljava/util/Collection;)Ljava/util/List;
+HSPLkotlin/collections/CollectionsKt___CollectionsKt;->toMutableSet(Ljava/lang/Iterable;)Ljava/util/Set;
+HSPLkotlin/collections/EmptyIterator;-><clinit>()V
+HSPLkotlin/collections/EmptyIterator;-><init>()V
+HSPLkotlin/collections/EmptyIterator;->hasNext()Z
+HSPLkotlin/collections/EmptyList;-><clinit>()V
+HSPLkotlin/collections/EmptyList;-><init>()V
+HSPLkotlin/collections/EmptyList;->contains(Ljava/lang/Object;)Z
+HSPLkotlin/collections/EmptyList;->equals(Ljava/lang/Object;)Z
+HSPLkotlin/collections/EmptyList;->getSize()I
+HSPLkotlin/collections/EmptyList;->isEmpty()Z
+HSPLkotlin/collections/EmptyList;->iterator()Ljava/util/Iterator;
+HSPLkotlin/collections/EmptyList;->listIterator()Ljava/util/ListIterator;
+HSPLkotlin/collections/EmptyList;->size()I
+HSPLkotlin/collections/EmptyList;->toArray()[Ljava/lang/Object;
+HSPLkotlin/collections/EmptyMap;-><clinit>()V
+HSPLkotlin/collections/EmptyMap;-><init>()V
+HSPLkotlin/collections/EmptyMap;->entrySet()Ljava/util/Set;
+HSPLkotlin/collections/EmptyMap;->equals(Ljava/lang/Object;)Z
+HSPLkotlin/collections/EmptyMap;->get(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlin/collections/EmptyMap;->get(Ljava/lang/Object;)Ljava/lang/Void;
+HSPLkotlin/collections/EmptyMap;->getEntries()Ljava/util/Set;
+HSPLkotlin/collections/EmptyMap;->getKeys()Ljava/util/Set;
+HSPLkotlin/collections/EmptyMap;->getValues()Ljava/util/Collection;
+HSPLkotlin/collections/EmptyMap;->isEmpty()Z
+HSPLkotlin/collections/EmptyMap;->keySet()Ljava/util/Set;
+HSPLkotlin/collections/EmptyMap;->values()Ljava/util/Collection;
+HSPLkotlin/collections/EmptySet;-><clinit>()V
+HSPLkotlin/collections/EmptySet;-><init>()V
+HSPLkotlin/collections/EmptySet;->iterator()Ljava/util/Iterator;
+HSPLkotlin/collections/IntIterator;-><init>()V
+HSPLkotlin/collections/MapsKt;->emptyMap()Ljava/util/Map;
+HSPLkotlin/collections/MapsKt;->mapCapacity(I)I
+HSPLkotlin/collections/MapsKt;->mapOf([Lkotlin/Pair;)Ljava/util/Map;
+HSPLkotlin/collections/MapsKt;->toMap(Ljava/lang/Iterable;)Ljava/util/Map;
+HSPLkotlin/collections/MapsKt__MapsJVMKt;->mapCapacity(I)I
+HSPLkotlin/collections/MapsKt__MapsKt;->emptyMap()Ljava/util/Map;
+HSPLkotlin/collections/MapsKt__MapsKt;->mapOf([Lkotlin/Pair;)Ljava/util/Map;
+HSPLkotlin/collections/MapsKt__MapsKt;->putAll(Ljava/util/Map;Ljava/lang/Iterable;)V
+HSPLkotlin/collections/MapsKt__MapsKt;->putAll(Ljava/util/Map;[Lkotlin/Pair;)V
+HSPLkotlin/collections/MapsKt__MapsKt;->toMap(Ljava/lang/Iterable;)Ljava/util/Map;
+HSPLkotlin/collections/MapsKt__MapsKt;->toMap(Ljava/lang/Iterable;Ljava/util/Map;)Ljava/util/Map;
+HSPLkotlin/collections/MapsKt__MapsKt;->toMap([Lkotlin/Pair;Ljava/util/Map;)Ljava/util/Map;
+HSPLkotlin/comparisons/ComparisonsKt;->compareValues(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
+HSPLkotlin/comparisons/ComparisonsKt__ComparisonsKt;->compareValues(Ljava/lang/Comparable;Ljava/lang/Comparable;)I
+HSPLkotlin/coroutines/AbstractCoroutineContextElement;-><init>(Lkotlin/coroutines/CoroutineContext$Key;)V
+HSPLkotlin/coroutines/AbstractCoroutineContextElement;->fold(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
+HSPLkotlin/coroutines/AbstractCoroutineContextElement;->get(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
+HSPLkotlin/coroutines/AbstractCoroutineContextElement;->getKey()Lkotlin/coroutines/CoroutineContext$Key;
+HSPLkotlin/coroutines/AbstractCoroutineContextElement;->minusKey(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
+HSPLkotlin/coroutines/AbstractCoroutineContextElement;->plus(Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext;
+HSPLkotlin/coroutines/AbstractCoroutineContextKey;-><init>(Lkotlin/coroutines/CoroutineContext$Key;Lkotlin/jvm/functions/Function1;)V
+HSPLkotlin/coroutines/CombinedContext;-><init>(Lkotlin/coroutines/CoroutineContext;Lkotlin/coroutines/CoroutineContext$Element;)V
+HSPLkotlin/coroutines/CombinedContext;->fold(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
+HSPLkotlin/coroutines/CombinedContext;->get(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;+]Lkotlin/coroutines/CoroutineContext;megamorphic_types]Lkotlin/coroutines/CoroutineContext$Element;megamorphic_types
+HSPLkotlin/coroutines/CombinedContext;->minusKey(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
+HSPLkotlin/coroutines/CombinedContext;->plus(Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext;
+HSPLkotlin/coroutines/ContinuationInterceptor$DefaultImpls;->get(Lkotlin/coroutines/ContinuationInterceptor;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
+HSPLkotlin/coroutines/ContinuationInterceptor$DefaultImpls;->minusKey(Lkotlin/coroutines/ContinuationInterceptor;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
+HSPLkotlin/coroutines/ContinuationInterceptor$Key;-><clinit>()V
+HSPLkotlin/coroutines/ContinuationInterceptor$Key;-><init>()V
+HSPLkotlin/coroutines/ContinuationInterceptor;-><clinit>()V
+HSPLkotlin/coroutines/ContinuationKt;->createCoroutine(Lkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLkotlin/coroutines/ContinuationKt;->startCoroutine(Lkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)V
+HSPLkotlin/coroutines/CoroutineContext$DefaultImpls;->plus(Lkotlin/coroutines/CoroutineContext;Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext;
+HSPLkotlin/coroutines/CoroutineContext$Element$DefaultImpls;->fold(Lkotlin/coroutines/CoroutineContext$Element;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
+HSPLkotlin/coroutines/CoroutineContext$Element$DefaultImpls;->get(Lkotlin/coroutines/CoroutineContext$Element;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
+HSPLkotlin/coroutines/CoroutineContext$Element$DefaultImpls;->minusKey(Lkotlin/coroutines/CoroutineContext$Element;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
+HSPLkotlin/coroutines/CoroutineContext$Element$DefaultImpls;->plus(Lkotlin/coroutines/CoroutineContext$Element;Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext;
+HSPLkotlin/coroutines/CoroutineContext$plus$1;-><clinit>()V
+HSPLkotlin/coroutines/CoroutineContext$plus$1;-><init>()V
+HSPLkotlin/coroutines/CoroutineContext$plus$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlin/coroutines/CoroutineContext$plus$1;->invoke(Lkotlin/coroutines/CoroutineContext;Lkotlin/coroutines/CoroutineContext$Element;)Lkotlin/coroutines/CoroutineContext;
+HSPLkotlin/coroutines/EmptyCoroutineContext;-><clinit>()V
+HSPLkotlin/coroutines/EmptyCoroutineContext;-><init>()V
+HSPLkotlin/coroutines/EmptyCoroutineContext;->fold(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
+HSPLkotlin/coroutines/EmptyCoroutineContext;->get(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
+HSPLkotlin/coroutines/EmptyCoroutineContext;->plus(Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext;
+HSPLkotlin/coroutines/SafeContinuation$Companion;-><init>()V
+HSPLkotlin/coroutines/SafeContinuation$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlin/coroutines/SafeContinuation;-><clinit>()V
+HSPLkotlin/coroutines/SafeContinuation;-><init>(Lkotlin/coroutines/Continuation;Ljava/lang/Object;)V
+HSPLkotlin/coroutines/SafeContinuation;->resumeWith(Ljava/lang/Object;)V
+HSPLkotlin/coroutines/intrinsics/CoroutineSingletons;->$values()[Lkotlin/coroutines/intrinsics/CoroutineSingletons;
+HSPLkotlin/coroutines/intrinsics/CoroutineSingletons;-><clinit>()V
+HSPLkotlin/coroutines/intrinsics/CoroutineSingletons;-><init>(Ljava/lang/String;I)V
+HSPLkotlin/coroutines/intrinsics/IntrinsicsKt;->createCoroutineUnintercepted(Lkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLkotlin/coroutines/intrinsics/IntrinsicsKt;->getCOROUTINE_SUSPENDED()Ljava/lang/Object;
+HSPLkotlin/coroutines/intrinsics/IntrinsicsKt;->intercepted(Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLkotlin/coroutines/intrinsics/IntrinsicsKt__IntrinsicsJvmKt;->createCoroutineUnintercepted(Lkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLkotlin/coroutines/intrinsics/IntrinsicsKt__IntrinsicsJvmKt;->intercepted(Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLkotlin/coroutines/intrinsics/IntrinsicsKt__IntrinsicsKt;->getCOROUTINE_SUSPENDED()Ljava/lang/Object;
+HSPLkotlin/coroutines/jvm/internal/BaseContinuationImpl;-><init>(Lkotlin/coroutines/Continuation;)V
+HSPLkotlin/coroutines/jvm/internal/BaseContinuationImpl;->releaseIntercepted()V
+HSPLkotlin/coroutines/jvm/internal/BaseContinuationImpl;->resumeWith(Ljava/lang/Object;)V
+HSPLkotlin/coroutines/jvm/internal/Boxing;->boxBoolean(Z)Ljava/lang/Boolean;
+HSPLkotlin/coroutines/jvm/internal/CompletedContinuation;-><clinit>()V
+HSPLkotlin/coroutines/jvm/internal/CompletedContinuation;-><init>()V
+HSPLkotlin/coroutines/jvm/internal/ContinuationImpl;-><init>(Lkotlin/coroutines/Continuation;)V
+HSPLkotlin/coroutines/jvm/internal/ContinuationImpl;-><init>(Lkotlin/coroutines/Continuation;Lkotlin/coroutines/CoroutineContext;)V
+HSPLkotlin/coroutines/jvm/internal/ContinuationImpl;->getContext()Lkotlin/coroutines/CoroutineContext;
+HSPLkotlin/coroutines/jvm/internal/ContinuationImpl;->intercepted()Lkotlin/coroutines/Continuation;
+HSPLkotlin/coroutines/jvm/internal/ContinuationImpl;->releaseIntercepted()V
+HSPLkotlin/coroutines/jvm/internal/DebugProbesKt;->probeCoroutineCreated(Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLkotlin/coroutines/jvm/internal/DebugProbesKt;->probeCoroutineResumed(Lkotlin/coroutines/Continuation;)V
+HSPLkotlin/coroutines/jvm/internal/DebugProbesKt;->probeCoroutineSuspended(Lkotlin/coroutines/Continuation;)V
+HSPLkotlin/coroutines/jvm/internal/RestrictedContinuationImpl;-><init>(Lkotlin/coroutines/Continuation;)V
+HSPLkotlin/coroutines/jvm/internal/RestrictedContinuationImpl;->getContext()Lkotlin/coroutines/CoroutineContext;
+HSPLkotlin/coroutines/jvm/internal/RestrictedSuspendLambda;-><init>(ILkotlin/coroutines/Continuation;)V
+HSPLkotlin/coroutines/jvm/internal/SuspendLambda;-><init>(ILkotlin/coroutines/Continuation;)V
+HSPLkotlin/coroutines/jvm/internal/SuspendLambda;->getArity()I
+HSPLkotlin/internal/ProgressionUtilKt;->differenceModulo(III)I
+HSPLkotlin/internal/ProgressionUtilKt;->getProgressionLastElement(III)I
+HSPLkotlin/internal/ProgressionUtilKt;->mod(II)I
+HSPLkotlin/jvm/JvmClassMappingKt;->getJavaClass(Lkotlin/reflect/KClass;)Ljava/lang/Class;
+HSPLkotlin/jvm/JvmClassMappingKt;->getJavaObjectType(Lkotlin/reflect/KClass;)Ljava/lang/Class;
+HSPLkotlin/jvm/internal/CallableReference$NoReceiver;-><clinit>()V
+HSPLkotlin/jvm/internal/CallableReference$NoReceiver;-><init>()V
+HSPLkotlin/jvm/internal/CallableReference$NoReceiver;->access$000()Lkotlin/jvm/internal/CallableReference$NoReceiver;
+HSPLkotlin/jvm/internal/CallableReference;-><clinit>()V
+HSPLkotlin/jvm/internal/CallableReference;-><init>(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Z)V
+HSPLkotlin/jvm/internal/CallableReference;->getBoundReceiver()Ljava/lang/Object;
+HSPLkotlin/jvm/internal/CallableReference;->getName()Ljava/lang/String;
+HSPLkotlin/jvm/internal/CallableReference;->getOwner()Lkotlin/reflect/KDeclarationContainer;
+HSPLkotlin/jvm/internal/CallableReference;->getSignature()Ljava/lang/String;
+HSPLkotlin/jvm/internal/ClassReference$Companion;-><init>()V
+HSPLkotlin/jvm/internal/ClassReference$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlin/jvm/internal/ClassReference;-><clinit>()V
+HSPLkotlin/jvm/internal/ClassReference;-><init>(Ljava/lang/Class;)V
+HSPLkotlin/jvm/internal/ClassReference;->equals(Ljava/lang/Object;)Z
+HSPLkotlin/jvm/internal/ClassReference;->getJClass()Ljava/lang/Class;
+HSPLkotlin/jvm/internal/CollectionToArray;-><clinit>()V
+HSPLkotlin/jvm/internal/CollectionToArray;->toArray(Ljava/util/Collection;)[Ljava/lang/Object;
+HSPLkotlin/jvm/internal/FloatCompanionObject;-><clinit>()V
+HSPLkotlin/jvm/internal/FloatCompanionObject;-><init>()V
+HSPLkotlin/jvm/internal/FunctionReference;-><init>(ILjava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
+HSPLkotlin/jvm/internal/FunctionReference;->equals(Ljava/lang/Object;)Z
+HSPLkotlin/jvm/internal/FunctionReferenceImpl;-><init>(ILjava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
+HSPLkotlin/jvm/internal/FunctionReferenceImpl;-><init>(ILjava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
+HSPLkotlin/jvm/internal/InlineMarker;->mark(I)V
+HSPLkotlin/jvm/internal/IntCompanionObject;-><clinit>()V
+HSPLkotlin/jvm/internal/IntCompanionObject;-><init>()V
+HSPLkotlin/jvm/internal/Intrinsics;->areEqual(Ljava/lang/Float;Ljava/lang/Float;)Z
+HSPLkotlin/jvm/internal/Intrinsics;->areEqual(Ljava/lang/Object;Ljava/lang/Object;)Z+]Ljava/lang/Object;megamorphic_types
+HSPLkotlin/jvm/internal/Intrinsics;->checkNotNull(Ljava/lang/Object;)V
+HSPLkotlin/jvm/internal/Intrinsics;->checkNotNull(Ljava/lang/Object;Ljava/lang/String;)V
+HSPLkotlin/jvm/internal/Intrinsics;->checkNotNullExpressionValue(Ljava/lang/Object;Ljava/lang/String;)V
+HSPLkotlin/jvm/internal/Intrinsics;->checkNotNullParameter(Ljava/lang/Object;Ljava/lang/String;)V
+HSPLkotlin/jvm/internal/Intrinsics;->compare(II)I
+HSPLkotlin/jvm/internal/Lambda;-><init>(I)V
+HSPLkotlin/jvm/internal/Lambda;->getArity()I
+HSPLkotlin/jvm/internal/MutablePropertyReference1;-><init>(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
+HSPLkotlin/jvm/internal/MutablePropertyReference1Impl;-><init>(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
+HSPLkotlin/jvm/internal/MutablePropertyReference;-><init>(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
+HSPLkotlin/jvm/internal/PropertyReference;-><init>(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
+HSPLkotlin/jvm/internal/Ref$BooleanRef;-><init>()V
+HSPLkotlin/jvm/internal/Ref$IntRef;-><init>()V
+HSPLkotlin/jvm/internal/Ref$ObjectRef;-><init>()V
+HSPLkotlin/jvm/internal/Reflection;-><clinit>()V
+HSPLkotlin/jvm/internal/Reflection;->getOrCreateKotlinClass(Ljava/lang/Class;)Lkotlin/reflect/KClass;
+HSPLkotlin/jvm/internal/Reflection;->mutableProperty1(Lkotlin/jvm/internal/MutablePropertyReference1;)Lkotlin/reflect/KMutableProperty1;
+HSPLkotlin/jvm/internal/ReflectionFactory;-><init>()V
+HSPLkotlin/jvm/internal/ReflectionFactory;->getOrCreateKotlinClass(Ljava/lang/Class;)Lkotlin/reflect/KClass;
+HSPLkotlin/jvm/internal/ReflectionFactory;->mutableProperty1(Lkotlin/jvm/internal/MutablePropertyReference1;)Lkotlin/reflect/KMutableProperty1;
+HSPLkotlin/jvm/internal/SpreadBuilder;-><init>(I)V
+HSPLkotlin/jvm/internal/SpreadBuilder;->add(Ljava/lang/Object;)V
+HSPLkotlin/jvm/internal/SpreadBuilder;->addSpread(Ljava/lang/Object;)V
+HSPLkotlin/jvm/internal/SpreadBuilder;->size()I
+HSPLkotlin/jvm/internal/SpreadBuilder;->toArray([Ljava/lang/Object;)[Ljava/lang/Object;
+HSPLkotlin/jvm/internal/TypeIntrinsics;->beforeCheckcastToFunctionOfArity(Ljava/lang/Object;I)Ljava/lang/Object;
+HSPLkotlin/jvm/internal/TypeIntrinsics;->getFunctionArity(Ljava/lang/Object;)I
+HSPLkotlin/jvm/internal/TypeIntrinsics;->isFunctionOfArity(Ljava/lang/Object;I)Z
+HSPLkotlin/jvm/internal/TypeIntrinsics;->isMutableSet(Ljava/lang/Object;)Z
+HSPLkotlin/math/MathKt;->roundToInt(F)I
+HSPLkotlin/math/MathKt__MathJVMKt;->roundToInt(F)I
+HSPLkotlin/ranges/IntProgression$Companion;-><init>()V
+HSPLkotlin/ranges/IntProgression$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlin/ranges/IntProgression;-><clinit>()V
+HSPLkotlin/ranges/IntProgression;-><init>(III)V
+HSPLkotlin/ranges/IntProgression;->getFirst()I
+HSPLkotlin/ranges/IntProgression;->getLast()I
+HSPLkotlin/ranges/IntProgression;->iterator()Ljava/util/Iterator;
+HSPLkotlin/ranges/IntProgression;->iterator()Lkotlin/collections/IntIterator;
+HSPLkotlin/ranges/IntProgressionIterator;-><init>(III)V
+HSPLkotlin/ranges/IntProgressionIterator;->hasNext()Z
+HSPLkotlin/ranges/IntProgressionIterator;->nextInt()I
+HSPLkotlin/ranges/IntRange$Companion;-><init>()V
+HSPLkotlin/ranges/IntRange$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlin/ranges/IntRange;-><clinit>()V
+HSPLkotlin/ranges/IntRange;-><init>(II)V
+HSPLkotlin/ranges/IntRange;->contains(I)Z
+HSPLkotlin/ranges/RangesKt;->coerceAtLeast(II)I
+HSPLkotlin/ranges/RangesKt;->coerceAtLeast(Ljava/lang/Comparable;Ljava/lang/Comparable;)Ljava/lang/Comparable;
+HSPLkotlin/ranges/RangesKt;->coerceAtMost(II)I
+HSPLkotlin/ranges/RangesKt;->coerceIn(FFF)F
+HSPLkotlin/ranges/RangesKt;->coerceIn(III)I
+HSPLkotlin/ranges/RangesKt;->coerceIn(JJJ)J
+HSPLkotlin/ranges/RangesKt___RangesKt;->coerceAtLeast(II)I
+HSPLkotlin/ranges/RangesKt___RangesKt;->coerceAtLeast(Ljava/lang/Comparable;Ljava/lang/Comparable;)Ljava/lang/Comparable;
+HSPLkotlin/ranges/RangesKt___RangesKt;->coerceAtMost(II)I
+HSPLkotlin/ranges/RangesKt___RangesKt;->coerceIn(FFF)F
+HSPLkotlin/ranges/RangesKt___RangesKt;->coerceIn(III)I
+HSPLkotlin/ranges/RangesKt___RangesKt;->coerceIn(JJJ)J
+HSPLkotlin/sequences/FilteringSequence$iterator$1;-><init>(Lkotlin/sequences/FilteringSequence;)V
+HSPLkotlin/sequences/FilteringSequence$iterator$1;->calcNext()V
+HSPLkotlin/sequences/FilteringSequence$iterator$1;->hasNext()Z
+HSPLkotlin/sequences/FilteringSequence$iterator$1;->next()Ljava/lang/Object;
+HSPLkotlin/sequences/FilteringSequence;-><init>(Lkotlin/sequences/Sequence;ZLkotlin/jvm/functions/Function1;)V
+HSPLkotlin/sequences/FilteringSequence;->access$getPredicate$p(Lkotlin/sequences/FilteringSequence;)Lkotlin/jvm/functions/Function1;
+HSPLkotlin/sequences/FilteringSequence;->access$getSendWhen$p(Lkotlin/sequences/FilteringSequence;)Z
+HSPLkotlin/sequences/FilteringSequence;->access$getSequence$p(Lkotlin/sequences/FilteringSequence;)Lkotlin/sequences/Sequence;
+HSPLkotlin/sequences/FilteringSequence;->iterator()Ljava/util/Iterator;
+HSPLkotlin/sequences/GeneratorSequence$iterator$1;-><init>(Lkotlin/sequences/GeneratorSequence;)V
+HSPLkotlin/sequences/GeneratorSequence$iterator$1;->calcNext()V
+HSPLkotlin/sequences/GeneratorSequence$iterator$1;->hasNext()Z
+HSPLkotlin/sequences/GeneratorSequence$iterator$1;->next()Ljava/lang/Object;
+HSPLkotlin/sequences/GeneratorSequence;-><init>(Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;)V
+HSPLkotlin/sequences/GeneratorSequence;->access$getGetInitialValue$p(Lkotlin/sequences/GeneratorSequence;)Lkotlin/jvm/functions/Function0;
+HSPLkotlin/sequences/GeneratorSequence;->access$getGetNextValue$p(Lkotlin/sequences/GeneratorSequence;)Lkotlin/jvm/functions/Function1;
+HSPLkotlin/sequences/GeneratorSequence;->iterator()Ljava/util/Iterator;
+HSPLkotlin/sequences/SequencesKt;->firstOrNull(Lkotlin/sequences/Sequence;)Ljava/lang/Object;
+HSPLkotlin/sequences/SequencesKt;->generateSequence(Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
+HSPLkotlin/sequences/SequencesKt;->mapNotNull(Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
+HSPLkotlin/sequences/SequencesKt__SequencesKt$generateSequence$2;-><init>(Ljava/lang/Object;)V
+HSPLkotlin/sequences/SequencesKt__SequencesKt$generateSequence$2;->invoke()Ljava/lang/Object;
+HSPLkotlin/sequences/SequencesKt__SequencesKt;->generateSequence(Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
+HSPLkotlin/sequences/SequencesKt___SequencesKt$filterNotNull$1;-><clinit>()V
+HSPLkotlin/sequences/SequencesKt___SequencesKt$filterNotNull$1;-><init>()V
+HSPLkotlin/sequences/SequencesKt___SequencesKt$filterNotNull$1;->invoke(Ljava/lang/Object;)Ljava/lang/Boolean;
+HSPLkotlin/sequences/SequencesKt___SequencesKt$filterNotNull$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlin/sequences/SequencesKt___SequencesKt;->filterNot(Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
+HSPLkotlin/sequences/SequencesKt___SequencesKt;->filterNotNull(Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence;
+HSPLkotlin/sequences/SequencesKt___SequencesKt;->firstOrNull(Lkotlin/sequences/Sequence;)Ljava/lang/Object;
+HSPLkotlin/sequences/SequencesKt___SequencesKt;->mapNotNull(Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Lkotlin/sequences/Sequence;
+HSPLkotlin/sequences/TransformingSequence$iterator$1;-><init>(Lkotlin/sequences/TransformingSequence;)V
+HSPLkotlin/sequences/TransformingSequence$iterator$1;->hasNext()Z
+HSPLkotlin/sequences/TransformingSequence$iterator$1;->next()Ljava/lang/Object;
+HSPLkotlin/sequences/TransformingSequence;-><init>(Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)V
+HSPLkotlin/sequences/TransformingSequence;->access$getSequence$p(Lkotlin/sequences/TransformingSequence;)Lkotlin/sequences/Sequence;
+HSPLkotlin/sequences/TransformingSequence;->access$getTransformer$p(Lkotlin/sequences/TransformingSequence;)Lkotlin/jvm/functions/Function1;
+HSPLkotlin/sequences/TransformingSequence;->iterator()Ljava/util/Iterator;
+HSPLkotlin/text/CharsKt;->checkRadix(I)I
+HSPLkotlin/text/CharsKt__CharJVMKt;->checkRadix(I)I
+HSPLkotlin/text/CharsKt__CharJVMKt;->isWhitespace(C)Z
+HSPLkotlin/text/StringsKt;->isBlank(Ljava/lang/CharSequence;)Z
+HSPLkotlin/text/StringsKt;->substringAfterLast$default(Ljava/lang/String;CLjava/lang/String;ILjava/lang/Object;)Ljava/lang/String;
+HSPLkotlin/text/StringsKt__StringsJVMKt;->isBlank(Ljava/lang/CharSequence;)Z
+HSPLkotlin/text/StringsKt__StringsKt;->getIndices(Ljava/lang/CharSequence;)Lkotlin/ranges/IntRange;
+HSPLkotlin/text/StringsKt__StringsKt;->getLastIndex(Ljava/lang/CharSequence;)I
+HSPLkotlin/text/StringsKt__StringsKt;->lastIndexOf$default(Ljava/lang/CharSequence;CIZILjava/lang/Object;)I
+HSPLkotlin/text/StringsKt__StringsKt;->lastIndexOf(Ljava/lang/CharSequence;CIZ)I
+HSPLkotlin/text/StringsKt__StringsKt;->substringAfterLast$default(Ljava/lang/String;CLjava/lang/String;ILjava/lang/Object;)Ljava/lang/String;
+HSPLkotlin/text/StringsKt__StringsKt;->substringAfterLast(Ljava/lang/String;CLjava/lang/String;)Ljava/lang/String;
+HSPLkotlinx/atomicfu/AtomicArray;-><init>(I)V
+HSPLkotlinx/atomicfu/AtomicBoolean$Companion;-><init>()V
+HSPLkotlinx/atomicfu/AtomicBoolean$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlinx/atomicfu/AtomicBoolean;-><clinit>()V
+HSPLkotlinx/atomicfu/AtomicBoolean;-><init>(ZLkotlinx/atomicfu/TraceBase;)V
+HSPLkotlinx/atomicfu/AtomicBoolean;->compareAndSet(ZZ)Z
+HSPLkotlinx/atomicfu/AtomicBoolean;->getValue()Z
+HSPLkotlinx/atomicfu/AtomicBoolean;->setValue(Z)V
+HSPLkotlinx/atomicfu/AtomicFU;->atomic(I)Lkotlinx/atomicfu/AtomicInt;
+HSPLkotlinx/atomicfu/AtomicFU;->atomic(ILkotlinx/atomicfu/TraceBase;)Lkotlinx/atomicfu/AtomicInt;
+HSPLkotlinx/atomicfu/AtomicFU;->atomic(J)Lkotlinx/atomicfu/AtomicLong;
+HSPLkotlinx/atomicfu/AtomicFU;->atomic(JLkotlinx/atomicfu/TraceBase;)Lkotlinx/atomicfu/AtomicLong;
+HSPLkotlinx/atomicfu/AtomicFU;->atomic(Ljava/lang/Object;)Lkotlinx/atomicfu/AtomicRef;
+HSPLkotlinx/atomicfu/AtomicFU;->atomic(Ljava/lang/Object;Lkotlinx/atomicfu/TraceBase;)Lkotlinx/atomicfu/AtomicRef;
+HSPLkotlinx/atomicfu/AtomicFU;->atomic(Z)Lkotlinx/atomicfu/AtomicBoolean;
+HSPLkotlinx/atomicfu/AtomicFU;->atomic(ZLkotlinx/atomicfu/TraceBase;)Lkotlinx/atomicfu/AtomicBoolean;
+HSPLkotlinx/atomicfu/AtomicFU_commonKt;->atomicArrayOfNulls(I)Lkotlinx/atomicfu/AtomicArray;
+HSPLkotlinx/atomicfu/AtomicInt$Companion;-><init>()V
+HSPLkotlinx/atomicfu/AtomicInt$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlinx/atomicfu/AtomicInt;-><clinit>()V
+HSPLkotlinx/atomicfu/AtomicInt;-><init>(ILkotlinx/atomicfu/TraceBase;)V
+HSPLkotlinx/atomicfu/AtomicInt;->compareAndSet(II)Z
+HSPLkotlinx/atomicfu/AtomicInt;->getValue()I
+HSPLkotlinx/atomicfu/AtomicInt;->setValue(I)V
+HSPLkotlinx/atomicfu/AtomicLong$Companion;-><init>()V
+HSPLkotlinx/atomicfu/AtomicLong$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlinx/atomicfu/AtomicLong;-><clinit>()V
+HSPLkotlinx/atomicfu/AtomicLong;-><init>(JLkotlinx/atomicfu/TraceBase;)V
+HSPLkotlinx/atomicfu/AtomicRef$Companion;-><init>()V
+HSPLkotlinx/atomicfu/AtomicRef$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlinx/atomicfu/AtomicRef;-><clinit>()V
+HSPLkotlinx/atomicfu/AtomicRef;-><init>(Ljava/lang/Object;Lkotlinx/atomicfu/TraceBase;)V
+HSPLkotlinx/atomicfu/AtomicRef;->compareAndSet(Ljava/lang/Object;Ljava/lang/Object;)Z
+HSPLkotlinx/atomicfu/AtomicRef;->getAndSet(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/atomicfu/AtomicRef;->getValue()Ljava/lang/Object;
+HSPLkotlinx/atomicfu/AtomicRef;->lazySet(Ljava/lang/Object;)V
+HSPLkotlinx/atomicfu/AtomicRef;->setValue(Ljava/lang/Object;)V
+HSPLkotlinx/atomicfu/TraceBase$None;-><clinit>()V
+HSPLkotlinx/atomicfu/TraceBase$None;-><init>()V
+HSPLkotlinx/atomicfu/TraceBase;-><init>()V
+HSPLkotlinx/coroutines/AbstractCoroutine;-><init>(Lkotlin/coroutines/CoroutineContext;ZZ)V
+HSPLkotlinx/coroutines/AbstractCoroutine;->afterResume(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/AbstractCoroutine;->cancellationExceptionMessage()Ljava/lang/String;
+HSPLkotlinx/coroutines/AbstractCoroutine;->getContext()Lkotlin/coroutines/CoroutineContext;
+HSPLkotlinx/coroutines/AbstractCoroutine;->getCoroutineContext()Lkotlin/coroutines/CoroutineContext;
+HSPLkotlinx/coroutines/AbstractCoroutine;->isActive()Z
+HSPLkotlinx/coroutines/AbstractCoroutine;->onCancelled(Ljava/lang/Throwable;Z)V
+HSPLkotlinx/coroutines/AbstractCoroutine;->onCompleted(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/AbstractCoroutine;->onCompletionInternal(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/AbstractCoroutine;->resumeWith(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/AbstractCoroutine;->start(Lkotlinx/coroutines/CoroutineStart;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)V
+HSPLkotlinx/coroutines/Active;-><clinit>()V
+HSPLkotlinx/coroutines/Active;-><init>()V
+HSPLkotlinx/coroutines/BeforeResumeCancelHandler;-><init>()V
+HSPLkotlinx/coroutines/BlockingEventLoop;-><init>(Ljava/lang/Thread;)V
+HSPLkotlinx/coroutines/BuildersKt;->launch$default(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
+HSPLkotlinx/coroutines/BuildersKt;->launch(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job;
+HSPLkotlinx/coroutines/BuildersKt;->withContext(Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/BuildersKt__Builders_commonKt;->launch$default(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
+HSPLkotlinx/coroutines/BuildersKt__Builders_commonKt;->launch(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job;
+HSPLkotlinx/coroutines/BuildersKt__Builders_commonKt;->withContext(Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/CancelHandler;-><init>()V
+HSPLkotlinx/coroutines/CancelHandlerBase;-><init>()V
+HSPLkotlinx/coroutines/CancellableContinuationImpl;-><init>(Lkotlin/coroutines/Continuation;I)V
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->callCancelHandler(Lkotlinx/coroutines/CancelHandler;Ljava/lang/Throwable;)V
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->cancel(Ljava/lang/Throwable;)Z
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->cancelLater(Ljava/lang/Throwable;)Z
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->completeResume(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->detachChild$external__kotlinx_coroutines__android_common__kotlinx_coroutines()V
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->detachChildIfNonResuable()V
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->dispatchResume(I)V
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->getContext()Lkotlin/coroutines/CoroutineContext;
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->getContinuationCancellationCause(Lkotlinx/coroutines/Job;)Ljava/lang/Throwable;
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->getDelegate$external__kotlinx_coroutines__android_common__kotlinx_coroutines()Lkotlin/coroutines/Continuation;
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->getExceptionalResult$external__kotlinx_coroutines__android_common__kotlinx_coroutines(Ljava/lang/Object;)Ljava/lang/Throwable;
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->getResult()Ljava/lang/Object;
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->getState$external__kotlinx_coroutines__android_common__kotlinx_coroutines()Ljava/lang/Object;
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->getSuccessfulResult$external__kotlinx_coroutines__android_common__kotlinx_coroutines(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->initCancellability()V
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->installParentHandle()Lkotlinx/coroutines/DisposableHandle;
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->invokeOnCancellation(Lkotlin/jvm/functions/Function1;)V
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->isCompleted()Z
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->isReusable()Z
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->makeCancelHandler(Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/CancelHandler;
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->parentCancelled$external__kotlinx_coroutines__android_common__kotlinx_coroutines(Ljava/lang/Throwable;)V
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->releaseClaimedReusableContinuation()V
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->resetStateReusable()Z
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->resumeImpl$default(Lkotlinx/coroutines/CancellableContinuationImpl;Ljava/lang/Object;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->resumeImpl(Ljava/lang/Object;ILkotlin/jvm/functions/Function1;)V
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->resumeWith(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->resumedState(Lkotlinx/coroutines/NotCompleted;Ljava/lang/Object;ILkotlin/jvm/functions/Function1;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->takeState$external__kotlinx_coroutines__android_common__kotlinx_coroutines()Ljava/lang/Object;
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->tryResume()Z
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->tryResume(Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->tryResumeImpl(Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/internal/Symbol;
+HSPLkotlinx/coroutines/CancellableContinuationImpl;->trySuspend()Z
+HSPLkotlinx/coroutines/CancellableContinuationImplKt;-><clinit>()V
+HSPLkotlinx/coroutines/CancellableContinuationKt;->getOrCreateCancellableContinuation(Lkotlin/coroutines/Continuation;)Lkotlinx/coroutines/CancellableContinuationImpl;
+HSPLkotlinx/coroutines/CancelledContinuation;-><init>(Lkotlin/coroutines/Continuation;Ljava/lang/Throwable;Z)V
+HSPLkotlinx/coroutines/CancelledContinuation;->makeResumed()Z
+HSPLkotlinx/coroutines/ChildContinuation;-><init>(Lkotlinx/coroutines/CancellableContinuationImpl;)V
+HSPLkotlinx/coroutines/ChildContinuation;->invoke(Ljava/lang/Throwable;)V
+HSPLkotlinx/coroutines/ChildHandleNode;-><init>(Lkotlinx/coroutines/ChildJob;)V
+HSPLkotlinx/coroutines/ChildHandleNode;->childCancelled(Ljava/lang/Throwable;)Z
+HSPLkotlinx/coroutines/ChildHandleNode;->invoke(Ljava/lang/Throwable;)V
+HSPLkotlinx/coroutines/CompletedContinuation;-><init>(Ljava/lang/Object;Lkotlinx/coroutines/CancelHandler;Lkotlin/jvm/functions/Function1;Ljava/lang/Object;Ljava/lang/Throwable;)V
+HSPLkotlinx/coroutines/CompletedContinuation;-><init>(Ljava/lang/Object;Lkotlinx/coroutines/CancelHandler;Lkotlin/jvm/functions/Function1;Ljava/lang/Object;Ljava/lang/Throwable;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlinx/coroutines/CompletedExceptionally;-><init>(Ljava/lang/Throwable;Z)V
+HSPLkotlinx/coroutines/CompletedExceptionally;-><init>(Ljava/lang/Throwable;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlinx/coroutines/CompletedExceptionally;->getHandled()Z
+HSPLkotlinx/coroutines/CompletedExceptionally;->makeHandled()Z
+HSPLkotlinx/coroutines/CompletionHandlerBase;-><init>()V
+HSPLkotlinx/coroutines/CompletionStateKt;->recoverResult(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/CompletionStateKt;->toState$default(Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/CompletionStateKt;->toState(Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/CompletionStateKt;->toState(Ljava/lang/Object;Lkotlinx/coroutines/CancellableContinuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/CoroutineContextKt$hasCopyableElements$1;-><clinit>()V
+HSPLkotlinx/coroutines/CoroutineContextKt$hasCopyableElements$1;-><init>()V
+HSPLkotlinx/coroutines/CoroutineContextKt$hasCopyableElements$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/CoroutineContextKt$hasCopyableElements$1;->invoke(ZLkotlin/coroutines/CoroutineContext$Element;)Ljava/lang/Boolean;
+HSPLkotlinx/coroutines/CoroutineContextKt;->foldCopies(Lkotlin/coroutines/CoroutineContext;Lkotlin/coroutines/CoroutineContext;Z)Lkotlin/coroutines/CoroutineContext;
+HSPLkotlinx/coroutines/CoroutineContextKt;->hasCopyableElements(Lkotlin/coroutines/CoroutineContext;)Z
+HSPLkotlinx/coroutines/CoroutineContextKt;->newCoroutineContext(Lkotlin/coroutines/CoroutineContext;Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext;
+HSPLkotlinx/coroutines/CoroutineContextKt;->newCoroutineContext(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext;
+HSPLkotlinx/coroutines/CoroutineDispatcher$Key$1;-><clinit>()V
+HSPLkotlinx/coroutines/CoroutineDispatcher$Key$1;-><init>()V
+HSPLkotlinx/coroutines/CoroutineDispatcher$Key;-><init>()V
+HSPLkotlinx/coroutines/CoroutineDispatcher$Key;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlinx/coroutines/CoroutineDispatcher;-><clinit>()V
+HSPLkotlinx/coroutines/CoroutineDispatcher;-><init>()V
+HSPLkotlinx/coroutines/CoroutineDispatcher;->get(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
+HSPLkotlinx/coroutines/CoroutineDispatcher;->interceptContinuation(Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLkotlinx/coroutines/CoroutineDispatcher;->isDispatchNeeded(Lkotlin/coroutines/CoroutineContext;)Z
+HSPLkotlinx/coroutines/CoroutineDispatcher;->limitedParallelism(I)Lkotlinx/coroutines/CoroutineDispatcher;
+HSPLkotlinx/coroutines/CoroutineDispatcher;->minusKey(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
+HSPLkotlinx/coroutines/CoroutineDispatcher;->releaseInterceptedContinuation(Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/CoroutineExceptionHandler$Key;-><clinit>()V
+HSPLkotlinx/coroutines/CoroutineExceptionHandler$Key;-><init>()V
+HSPLkotlinx/coroutines/CoroutineExceptionHandler;-><clinit>()V
+HSPLkotlinx/coroutines/CoroutineScopeKt;->CoroutineScope(Lkotlin/coroutines/CoroutineContext;)Lkotlinx/coroutines/CoroutineScope;
+HSPLkotlinx/coroutines/CoroutineScopeKt;->MainScope()Lkotlinx/coroutines/CoroutineScope;
+HSPLkotlinx/coroutines/CoroutineScopeKt;->coroutineScope(Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/CoroutineScopeKt;->isActive(Lkotlinx/coroutines/CoroutineScope;)Z
+HSPLkotlinx/coroutines/CoroutineStart$WhenMappings;-><clinit>()V
+HSPLkotlinx/coroutines/CoroutineStart;->$values()[Lkotlinx/coroutines/CoroutineStart;
+HSPLkotlinx/coroutines/CoroutineStart;-><clinit>()V
+HSPLkotlinx/coroutines/CoroutineStart;-><init>(Ljava/lang/String;I)V
+HSPLkotlinx/coroutines/CoroutineStart;->invoke(Lkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/CoroutineStart;->isLazy()Z
+HSPLkotlinx/coroutines/CoroutineStart;->values()[Lkotlinx/coroutines/CoroutineStart;
+HSPLkotlinx/coroutines/DebugKt;-><clinit>()V
+HSPLkotlinx/coroutines/DebugKt;->getASSERTIONS_ENABLED()Z
+HSPLkotlinx/coroutines/DebugKt;->getDEBUG()Z
+HSPLkotlinx/coroutines/DebugKt;->getRECOVER_STACK_TRACES()Z
+HSPLkotlinx/coroutines/DebugStringsKt;->getClassSimpleName(Ljava/lang/Object;)Ljava/lang/String;
+HSPLkotlinx/coroutines/DefaultExecutor;-><clinit>()V
+HSPLkotlinx/coroutines/DefaultExecutor;-><init>()V
+HSPLkotlinx/coroutines/DefaultExecutorKt;-><clinit>()V
+HSPLkotlinx/coroutines/DefaultExecutorKt;->getDefaultDelay()Lkotlinx/coroutines/Delay;
+HSPLkotlinx/coroutines/DefaultExecutorKt;->initializeDefaultDelay()Lkotlinx/coroutines/Delay;
+HSPLkotlinx/coroutines/DispatchedTask;-><init>(I)V
+HSPLkotlinx/coroutines/DispatchedTask;->getExceptionalResult$external__kotlinx_coroutines__android_common__kotlinx_coroutines(Ljava/lang/Object;)Ljava/lang/Throwable;
+HSPLkotlinx/coroutines/DispatchedTask;->getSuccessfulResult$external__kotlinx_coroutines__android_common__kotlinx_coroutines(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/DispatchedTask;->handleFatalException(Ljava/lang/Throwable;Ljava/lang/Throwable;)V
+HSPLkotlinx/coroutines/DispatchedTask;->run()V
+HSPLkotlinx/coroutines/DispatchedTaskKt;->dispatch(Lkotlinx/coroutines/DispatchedTask;I)V
+HSPLkotlinx/coroutines/DispatchedTaskKt;->isCancellableMode(I)Z
+HSPLkotlinx/coroutines/DispatchedTaskKt;->isReusableMode(I)Z
+HSPLkotlinx/coroutines/DispatchedTaskKt;->resume(Lkotlinx/coroutines/DispatchedTask;Lkotlin/coroutines/Continuation;Z)V
+HSPLkotlinx/coroutines/DispatchedTaskKt;->resumeUnconfined(Lkotlinx/coroutines/DispatchedTask;)V
+HSPLkotlinx/coroutines/Dispatchers;-><clinit>()V
+HSPLkotlinx/coroutines/Dispatchers;-><init>()V
+HSPLkotlinx/coroutines/Dispatchers;->getDefault()Lkotlinx/coroutines/CoroutineDispatcher;
+HSPLkotlinx/coroutines/Dispatchers;->getMain()Lkotlinx/coroutines/MainCoroutineDispatcher;
+HSPLkotlinx/coroutines/Empty;-><init>(Z)V
+HSPLkotlinx/coroutines/Empty;->getList()Lkotlinx/coroutines/NodeList;
+HSPLkotlinx/coroutines/Empty;->isActive()Z
+HSPLkotlinx/coroutines/EventLoop;-><init>()V
+HSPLkotlinx/coroutines/EventLoop;->decrementUseCount(Z)V
+HSPLkotlinx/coroutines/EventLoop;->delta(Z)J
+HSPLkotlinx/coroutines/EventLoop;->incrementUseCount$default(Lkotlinx/coroutines/EventLoop;ZILjava/lang/Object;)V
+HSPLkotlinx/coroutines/EventLoop;->incrementUseCount(Z)V
+HSPLkotlinx/coroutines/EventLoop;->isUnconfinedLoopActive()Z
+HSPLkotlinx/coroutines/EventLoop;->processUnconfinedEvent()Z
+HSPLkotlinx/coroutines/EventLoopImplBase;-><init>()V
+HSPLkotlinx/coroutines/EventLoopImplPlatform;-><init>()V
+HSPLkotlinx/coroutines/EventLoopKt;->createEventLoop()Lkotlinx/coroutines/EventLoop;
+HSPLkotlinx/coroutines/ExecutorCoroutineDispatcher$Key$1;-><clinit>()V
+HSPLkotlinx/coroutines/ExecutorCoroutineDispatcher$Key$1;-><init>()V
+HSPLkotlinx/coroutines/ExecutorCoroutineDispatcher$Key;-><init>()V
+HSPLkotlinx/coroutines/ExecutorCoroutineDispatcher$Key;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlinx/coroutines/ExecutorCoroutineDispatcher;-><clinit>()V
+HSPLkotlinx/coroutines/ExecutorCoroutineDispatcher;-><init>()V
+HSPLkotlinx/coroutines/GlobalScope;-><clinit>()V
+HSPLkotlinx/coroutines/GlobalScope;-><init>()V
+HSPLkotlinx/coroutines/GlobalScope;->getCoroutineContext()Lkotlin/coroutines/CoroutineContext;
+HSPLkotlinx/coroutines/InvokeOnCancel;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLkotlinx/coroutines/InvokeOnCancel;->invoke(Ljava/lang/Throwable;)V
+HSPLkotlinx/coroutines/InvokeOnCompletion;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLkotlinx/coroutines/Job$DefaultImpls;->cancel$default(Lkotlinx/coroutines/Job;Ljava/util/concurrent/CancellationException;ILjava/lang/Object;)V
+HSPLkotlinx/coroutines/Job$DefaultImpls;->fold(Lkotlinx/coroutines/Job;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/Job$DefaultImpls;->get(Lkotlinx/coroutines/Job;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
+HSPLkotlinx/coroutines/Job$DefaultImpls;->invokeOnCompletion$default(Lkotlinx/coroutines/Job;ZZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlinx/coroutines/DisposableHandle;
+HSPLkotlinx/coroutines/Job$DefaultImpls;->minusKey(Lkotlinx/coroutines/Job;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
+HSPLkotlinx/coroutines/Job$DefaultImpls;->plus(Lkotlinx/coroutines/Job;Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext;
+HSPLkotlinx/coroutines/Job$Key;-><clinit>()V
+HSPLkotlinx/coroutines/Job$Key;-><init>()V
+HSPLkotlinx/coroutines/Job;-><clinit>()V
+HSPLkotlinx/coroutines/JobCancellationException;-><init>(Ljava/lang/String;Ljava/lang/Throwable;Lkotlinx/coroutines/Job;)V
+HSPLkotlinx/coroutines/JobCancellationException;->equals(Ljava/lang/Object;)Z
+HSPLkotlinx/coroutines/JobCancellationException;->fillInStackTrace()Ljava/lang/Throwable;
+HSPLkotlinx/coroutines/JobCancellingNode;-><init>()V
+HSPLkotlinx/coroutines/JobImpl;-><init>(Lkotlinx/coroutines/Job;)V
+HSPLkotlinx/coroutines/JobImpl;->getHandlesException$external__kotlinx_coroutines__android_common__kotlinx_coroutines()Z
+HSPLkotlinx/coroutines/JobImpl;->handlesException()Z
+HSPLkotlinx/coroutines/JobKt;->Job$default(Lkotlinx/coroutines/Job;ILjava/lang/Object;)Lkotlinx/coroutines/CompletableJob;
+HSPLkotlinx/coroutines/JobKt;->Job(Lkotlinx/coroutines/Job;)Lkotlinx/coroutines/CompletableJob;
+HSPLkotlinx/coroutines/JobKt;->ensureActive(Lkotlin/coroutines/CoroutineContext;)V
+HSPLkotlinx/coroutines/JobKt;->ensureActive(Lkotlinx/coroutines/Job;)V
+HSPLkotlinx/coroutines/JobKt;->getJob(Lkotlin/coroutines/CoroutineContext;)Lkotlinx/coroutines/Job;
+HSPLkotlinx/coroutines/JobKt;->isActive(Lkotlin/coroutines/CoroutineContext;)Z
+HSPLkotlinx/coroutines/JobKt__JobKt;->Job$default(Lkotlinx/coroutines/Job;ILjava/lang/Object;)Lkotlinx/coroutines/CompletableJob;
+HSPLkotlinx/coroutines/JobKt__JobKt;->Job(Lkotlinx/coroutines/Job;)Lkotlinx/coroutines/CompletableJob;
+HSPLkotlinx/coroutines/JobKt__JobKt;->ensureActive(Lkotlin/coroutines/CoroutineContext;)V
+HSPLkotlinx/coroutines/JobKt__JobKt;->ensureActive(Lkotlinx/coroutines/Job;)V
+HSPLkotlinx/coroutines/JobKt__JobKt;->getJob(Lkotlin/coroutines/CoroutineContext;)Lkotlinx/coroutines/Job;
+HSPLkotlinx/coroutines/JobKt__JobKt;->isActive(Lkotlin/coroutines/CoroutineContext;)Z
+HSPLkotlinx/coroutines/JobNode;-><init>()V
+HSPLkotlinx/coroutines/JobNode;->dispose()V
+HSPLkotlinx/coroutines/JobNode;->getJob()Lkotlinx/coroutines/JobSupport;
+HSPLkotlinx/coroutines/JobNode;->getList()Lkotlinx/coroutines/NodeList;
+HSPLkotlinx/coroutines/JobNode;->isActive()Z
+HSPLkotlinx/coroutines/JobNode;->setJob(Lkotlinx/coroutines/JobSupport;)V
+HSPLkotlinx/coroutines/JobSupport$Finishing;-><init>(Lkotlinx/coroutines/NodeList;ZLjava/lang/Throwable;)V
+HSPLkotlinx/coroutines/JobSupport$Finishing;->addExceptionLocked(Ljava/lang/Throwable;)V
+HSPLkotlinx/coroutines/JobSupport$Finishing;->allocateList()Ljava/util/ArrayList;
+HSPLkotlinx/coroutines/JobSupport$Finishing;->getExceptionsHolder()Ljava/lang/Object;
+HSPLkotlinx/coroutines/JobSupport$Finishing;->getList()Lkotlinx/coroutines/NodeList;
+HSPLkotlinx/coroutines/JobSupport$Finishing;->getRootCause()Ljava/lang/Throwable;
+HSPLkotlinx/coroutines/JobSupport$Finishing;->isActive()Z
+HSPLkotlinx/coroutines/JobSupport$Finishing;->isCancelling()Z
+HSPLkotlinx/coroutines/JobSupport$Finishing;->isCompleting()Z
+HSPLkotlinx/coroutines/JobSupport$Finishing;->sealLocked(Ljava/lang/Throwable;)Ljava/util/List;
+HSPLkotlinx/coroutines/JobSupport$Finishing;->setCompleting(Z)V
+HSPLkotlinx/coroutines/JobSupport$Finishing;->setExceptionsHolder(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/JobSupport$addLastAtomic$$inlined$addLastIf$1;-><init>(Lkotlinx/coroutines/internal/LockFreeLinkedListNode;Lkotlinx/coroutines/JobSupport;Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/JobSupport$addLastAtomic$$inlined$addLastIf$1;->prepare(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/JobSupport$addLastAtomic$$inlined$addLastIf$1;->prepare(Lkotlinx/coroutines/internal/LockFreeLinkedListNode;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/JobSupport;-><init>(Z)V
+HSPLkotlinx/coroutines/JobSupport;->access$cancellationExceptionMessage(Lkotlinx/coroutines/JobSupport;)Ljava/lang/String;
+HSPLkotlinx/coroutines/JobSupport;->addLastAtomic(Ljava/lang/Object;Lkotlinx/coroutines/NodeList;Lkotlinx/coroutines/JobNode;)Z
+HSPLkotlinx/coroutines/JobSupport;->addSuppressedExceptions(Ljava/lang/Throwable;Ljava/util/List;)V
+HSPLkotlinx/coroutines/JobSupport;->afterCompletion(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/JobSupport;->attachChild(Lkotlinx/coroutines/ChildJob;)Lkotlinx/coroutines/ChildHandle;
+HSPLkotlinx/coroutines/JobSupport;->cancel(Ljava/util/concurrent/CancellationException;)V
+HSPLkotlinx/coroutines/JobSupport;->cancelImpl$external__kotlinx_coroutines__android_common__kotlinx_coroutines(Ljava/lang/Object;)Z
+HSPLkotlinx/coroutines/JobSupport;->cancelInternal(Ljava/lang/Throwable;)V
+HSPLkotlinx/coroutines/JobSupport;->cancelParent(Ljava/lang/Throwable;)Z
+HSPLkotlinx/coroutines/JobSupport;->childCancelled(Ljava/lang/Throwable;)Z
+HSPLkotlinx/coroutines/JobSupport;->completeStateFinalization(Lkotlinx/coroutines/Incomplete;Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/JobSupport;->createCauseException(Ljava/lang/Object;)Ljava/lang/Throwable;
+HSPLkotlinx/coroutines/JobSupport;->finalizeFinishingState(Lkotlinx/coroutines/JobSupport$Finishing;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/JobSupport;->firstChild(Lkotlinx/coroutines/Incomplete;)Lkotlinx/coroutines/ChildHandleNode;
+HSPLkotlinx/coroutines/JobSupport;->fold(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/JobSupport;->get(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
+HSPLkotlinx/coroutines/JobSupport;->getCancellationException()Ljava/util/concurrent/CancellationException;
+HSPLkotlinx/coroutines/JobSupport;->getChildJobCancellationCause()Ljava/util/concurrent/CancellationException;
+HSPLkotlinx/coroutines/JobSupport;->getFinalRootCause(Lkotlinx/coroutines/JobSupport$Finishing;Ljava/util/List;)Ljava/lang/Throwable;
+HSPLkotlinx/coroutines/JobSupport;->getKey()Lkotlin/coroutines/CoroutineContext$Key;
+HSPLkotlinx/coroutines/JobSupport;->getOnCancelComplete$external__kotlinx_coroutines__android_common__kotlinx_coroutines()Z
+HSPLkotlinx/coroutines/JobSupport;->getOrPromoteCancellingList(Lkotlinx/coroutines/Incomplete;)Lkotlinx/coroutines/NodeList;
+HSPLkotlinx/coroutines/JobSupport;->getParentHandle$external__kotlinx_coroutines__android_common__kotlinx_coroutines()Lkotlinx/coroutines/ChildHandle;
+HSPLkotlinx/coroutines/JobSupport;->getState$external__kotlinx_coroutines__android_common__kotlinx_coroutines()Ljava/lang/Object;
+HSPLkotlinx/coroutines/JobSupport;->initParentJob(Lkotlinx/coroutines/Job;)V
+HSPLkotlinx/coroutines/JobSupport;->invokeOnCompletion(Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/DisposableHandle;
+HSPLkotlinx/coroutines/JobSupport;->invokeOnCompletion(ZZLkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/DisposableHandle;
+HSPLkotlinx/coroutines/JobSupport;->isActive()Z
+HSPLkotlinx/coroutines/JobSupport;->isCompleted()Z
+HSPLkotlinx/coroutines/JobSupport;->isScopedCoroutine()Z
+HSPLkotlinx/coroutines/JobSupport;->makeCancelling(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/JobSupport;->makeCompletingOnce$external__kotlinx_coroutines__android_common__kotlinx_coroutines(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/JobSupport;->makeNode(Lkotlin/jvm/functions/Function1;Z)Lkotlinx/coroutines/JobNode;
+HSPLkotlinx/coroutines/JobSupport;->minusKey(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
+HSPLkotlinx/coroutines/JobSupport;->nextChild(Lkotlinx/coroutines/internal/LockFreeLinkedListNode;)Lkotlinx/coroutines/ChildHandleNode;
+HSPLkotlinx/coroutines/JobSupport;->notifyCancelling(Lkotlinx/coroutines/NodeList;Ljava/lang/Throwable;)V
+HSPLkotlinx/coroutines/JobSupport;->notifyCompletion(Lkotlinx/coroutines/NodeList;Ljava/lang/Throwable;)V
+HSPLkotlinx/coroutines/JobSupport;->onCancelling(Ljava/lang/Throwable;)V
+HSPLkotlinx/coroutines/JobSupport;->parentCancelled(Lkotlinx/coroutines/ParentJob;)V
+HSPLkotlinx/coroutines/JobSupport;->plus(Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext;
+HSPLkotlinx/coroutines/JobSupport;->promoteSingleToNodeList(Lkotlinx/coroutines/JobNode;)V
+HSPLkotlinx/coroutines/JobSupport;->removeNode$external__kotlinx_coroutines__android_common__kotlinx_coroutines(Lkotlinx/coroutines/JobNode;)V
+HSPLkotlinx/coroutines/JobSupport;->setParentHandle$external__kotlinx_coroutines__android_common__kotlinx_coroutines(Lkotlinx/coroutines/ChildHandle;)V
+HSPLkotlinx/coroutines/JobSupport;->start()Z
+HSPLkotlinx/coroutines/JobSupport;->startInternal(Ljava/lang/Object;)I
+HSPLkotlinx/coroutines/JobSupport;->toCancellationException(Ljava/lang/Throwable;Ljava/lang/String;)Ljava/util/concurrent/CancellationException;
+HSPLkotlinx/coroutines/JobSupport;->tryFinalizeSimpleState(Lkotlinx/coroutines/Incomplete;Ljava/lang/Object;)Z
+HSPLkotlinx/coroutines/JobSupport;->tryMakeCancelling(Lkotlinx/coroutines/Incomplete;Ljava/lang/Throwable;)Z
+HSPLkotlinx/coroutines/JobSupport;->tryMakeCompleting(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/JobSupport;->tryMakeCompletingSlowPath(Lkotlinx/coroutines/Incomplete;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/JobSupportKt;-><clinit>()V
+HSPLkotlinx/coroutines/JobSupportKt;->access$getCOMPLETING_ALREADY$p()Lkotlinx/coroutines/internal/Symbol;
+HSPLkotlinx/coroutines/JobSupportKt;->access$getCOMPLETING_RETRY$p()Lkotlinx/coroutines/internal/Symbol;
+HSPLkotlinx/coroutines/JobSupportKt;->access$getEMPTY_ACTIVE$p()Lkotlinx/coroutines/Empty;
+HSPLkotlinx/coroutines/JobSupportKt;->access$getSEALED$p()Lkotlinx/coroutines/internal/Symbol;
+HSPLkotlinx/coroutines/JobSupportKt;->boxIncomplete(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/JobSupportKt;->unboxState(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/MainCoroutineDispatcher;-><init>()V
+HSPLkotlinx/coroutines/NodeList;-><init>()V
+HSPLkotlinx/coroutines/NodeList;->getList()Lkotlinx/coroutines/NodeList;
+HSPLkotlinx/coroutines/NodeList;->isActive()Z
+HSPLkotlinx/coroutines/NonDisposableHandle;-><clinit>()V
+HSPLkotlinx/coroutines/NonDisposableHandle;-><init>()V
+HSPLkotlinx/coroutines/NonDisposableHandle;->dispose()V
+HSPLkotlinx/coroutines/StandaloneCoroutine;-><init>(Lkotlin/coroutines/CoroutineContext;Z)V
+HSPLkotlinx/coroutines/SupervisorJobImpl;-><init>(Lkotlinx/coroutines/Job;)V
+HSPLkotlinx/coroutines/SupervisorKt;->SupervisorJob$default(Lkotlinx/coroutines/Job;ILjava/lang/Object;)Lkotlinx/coroutines/CompletableJob;
+HSPLkotlinx/coroutines/SupervisorKt;->SupervisorJob(Lkotlinx/coroutines/Job;)Lkotlinx/coroutines/CompletableJob;
+HSPLkotlinx/coroutines/ThreadLocalEventLoop;-><clinit>()V
+HSPLkotlinx/coroutines/ThreadLocalEventLoop;-><init>()V
+HSPLkotlinx/coroutines/ThreadLocalEventLoop;->getEventLoop$external__kotlinx_coroutines__android_common__kotlinx_coroutines()Lkotlinx/coroutines/EventLoop;
+HSPLkotlinx/coroutines/Unconfined;-><clinit>()V
+HSPLkotlinx/coroutines/Unconfined;-><init>()V
+HSPLkotlinx/coroutines/UndispatchedCoroutine;-><init>(Lkotlin/coroutines/CoroutineContext;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/UndispatchedMarker;-><clinit>()V
+HSPLkotlinx/coroutines/UndispatchedMarker;-><init>()V
+HSPLkotlinx/coroutines/UndispatchedMarker;->fold(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/UndispatchedMarker;->get(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
+HSPLkotlinx/coroutines/UndispatchedMarker;->getKey()Lkotlin/coroutines/CoroutineContext$Key;
+HSPLkotlinx/coroutines/android/AndroidDispatcherFactory;-><init>()V
+HSPLkotlinx/coroutines/android/AndroidDispatcherFactory;->createDispatcher(Ljava/util/List;)Lkotlinx/coroutines/MainCoroutineDispatcher;
+HSPLkotlinx/coroutines/android/HandlerContext;-><init>(Landroid/os/Handler;Ljava/lang/String;)V
+HSPLkotlinx/coroutines/android/HandlerContext;-><init>(Landroid/os/Handler;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlinx/coroutines/android/HandlerContext;-><init>(Landroid/os/Handler;Ljava/lang/String;Z)V
+HSPLkotlinx/coroutines/android/HandlerContext;->dispatch(Lkotlin/coroutines/CoroutineContext;Ljava/lang/Runnable;)V
+HSPLkotlinx/coroutines/android/HandlerContext;->getImmediate()Lkotlinx/coroutines/android/HandlerContext;
+HSPLkotlinx/coroutines/android/HandlerContext;->getImmediate()Lkotlinx/coroutines/android/HandlerDispatcher;
+HSPLkotlinx/coroutines/android/HandlerContext;->isDispatchNeeded(Lkotlin/coroutines/CoroutineContext;)Z
+HSPLkotlinx/coroutines/android/HandlerDispatcher;-><init>()V
+HSPLkotlinx/coroutines/android/HandlerDispatcher;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlinx/coroutines/android/HandlerDispatcherKt;-><clinit>()V
+HSPLkotlinx/coroutines/android/HandlerDispatcherKt;->asHandler(Landroid/os/Looper;Z)Landroid/os/Handler;
+HSPLkotlinx/coroutines/android/HandlerDispatcherKt;->from(Landroid/os/Handler;Ljava/lang/String;)Lkotlinx/coroutines/android/HandlerDispatcher;
+HSPLkotlinx/coroutines/channels/AbstractChannel$Itr;-><init>(Lkotlinx/coroutines/channels/AbstractChannel;)V
+HSPLkotlinx/coroutines/channels/AbstractChannel$Itr;->hasNext(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/AbstractChannel$Itr;->hasNextResult(Ljava/lang/Object;)Z
+HSPLkotlinx/coroutines/channels/AbstractChannel$Itr;->hasNextSuspend(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/AbstractChannel$Itr;->next()Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/AbstractChannel$Itr;->setResult(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/channels/AbstractChannel$ReceiveElement;-><init>(Lkotlinx/coroutines/CancellableContinuation;I)V
+HSPLkotlinx/coroutines/channels/AbstractChannel$ReceiveElement;->completeResumeReceive(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/channels/AbstractChannel$ReceiveElement;->resumeValue(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/AbstractChannel$ReceiveElement;->tryResumeReceive(Ljava/lang/Object;Lkotlinx/coroutines/internal/LockFreeLinkedListNode$PrepareOp;)Lkotlinx/coroutines/internal/Symbol;
+HSPLkotlinx/coroutines/channels/AbstractChannel$ReceiveHasNext;-><init>(Lkotlinx/coroutines/channels/AbstractChannel$Itr;Lkotlinx/coroutines/CancellableContinuation;)V
+HSPLkotlinx/coroutines/channels/AbstractChannel$ReceiveHasNext;->completeResumeReceive(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/channels/AbstractChannel$ReceiveHasNext;->resumeOnCancellationFun(Ljava/lang/Object;)Lkotlin/jvm/functions/Function1;
+HSPLkotlinx/coroutines/channels/AbstractChannel$ReceiveHasNext;->tryResumeReceive(Ljava/lang/Object;Lkotlinx/coroutines/internal/LockFreeLinkedListNode$PrepareOp;)Lkotlinx/coroutines/internal/Symbol;
+HSPLkotlinx/coroutines/channels/AbstractChannel$RemoveReceiveOnCancel;-><init>(Lkotlinx/coroutines/channels/AbstractChannel;Lkotlinx/coroutines/channels/Receive;)V
+HSPLkotlinx/coroutines/channels/AbstractChannel$enqueueReceiveInternal$$inlined$addLastIfPrevAndIf$1;-><init>(Lkotlinx/coroutines/internal/LockFreeLinkedListNode;Lkotlinx/coroutines/channels/AbstractChannel;)V
+HSPLkotlinx/coroutines/channels/AbstractChannel$enqueueReceiveInternal$$inlined$addLastIfPrevAndIf$1;->prepare(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/AbstractChannel$enqueueReceiveInternal$$inlined$addLastIfPrevAndIf$1;->prepare(Lkotlinx/coroutines/internal/LockFreeLinkedListNode;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/AbstractChannel$receiveCatching$1;-><init>(Lkotlinx/coroutines/channels/AbstractChannel;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/channels/AbstractChannel$receiveCatching$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/AbstractChannel;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLkotlinx/coroutines/channels/AbstractChannel;->access$enqueueReceive(Lkotlinx/coroutines/channels/AbstractChannel;Lkotlinx/coroutines/channels/Receive;)Z
+HSPLkotlinx/coroutines/channels/AbstractChannel;->access$removeReceiveOnCancel(Lkotlinx/coroutines/channels/AbstractChannel;Lkotlinx/coroutines/CancellableContinuation;Lkotlinx/coroutines/channels/Receive;)V
+HSPLkotlinx/coroutines/channels/AbstractChannel;->enqueueReceive(Lkotlinx/coroutines/channels/Receive;)Z
+HSPLkotlinx/coroutines/channels/AbstractChannel;->enqueueReceiveInternal(Lkotlinx/coroutines/channels/Receive;)Z
+HSPLkotlinx/coroutines/channels/AbstractChannel;->iterator()Lkotlinx/coroutines/channels/ChannelIterator;
+HSPLkotlinx/coroutines/channels/AbstractChannel;->onReceiveDequeued()V
+HSPLkotlinx/coroutines/channels/AbstractChannel;->onReceiveEnqueued()V
+HSPLkotlinx/coroutines/channels/AbstractChannel;->pollInternal()Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/AbstractChannel;->receive(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/AbstractChannel;->receiveCatching-JP2dKIU(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/AbstractChannel;->receiveSuspend(ILkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/AbstractChannel;->removeReceiveOnCancel(Lkotlinx/coroutines/CancellableContinuation;Lkotlinx/coroutines/channels/Receive;)V
+HSPLkotlinx/coroutines/channels/AbstractChannel;->takeFirstReceiveOrPeekClosed()Lkotlinx/coroutines/channels/ReceiveOrClosed;
+HSPLkotlinx/coroutines/channels/AbstractChannel;->tryReceive-PtdJZtk()Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/AbstractChannelKt;-><clinit>()V
+HSPLkotlinx/coroutines/channels/AbstractSendChannel;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLkotlinx/coroutines/channels/AbstractSendChannel;->getClosedForSend()Lkotlinx/coroutines/channels/Closed;
+HSPLkotlinx/coroutines/channels/AbstractSendChannel;->getQueue()Lkotlinx/coroutines/internal/LockFreeLinkedListHead;
+HSPLkotlinx/coroutines/channels/AbstractSendChannel;->send(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/AbstractSendChannel;->takeFirstReceiveOrPeekClosed()Lkotlinx/coroutines/channels/ReceiveOrClosed;
+HSPLkotlinx/coroutines/channels/AbstractSendChannel;->takeFirstSendOrPeekClosed()Lkotlinx/coroutines/channels/Send;
+HSPLkotlinx/coroutines/channels/AbstractSendChannel;->trySend-JP2dKIU(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/ArrayChannel;-><init>(ILkotlinx/coroutines/channels/BufferOverflow;Lkotlin/jvm/functions/Function1;)V
+HSPLkotlinx/coroutines/channels/ArrayChannel;->enqueueReceiveInternal(Lkotlinx/coroutines/channels/Receive;)Z
+HSPLkotlinx/coroutines/channels/ArrayChannel;->isBufferAlwaysEmpty()Z
+HSPLkotlinx/coroutines/channels/ArrayChannel;->isBufferEmpty()Z
+HSPLkotlinx/coroutines/channels/ArrayChannel;->offerInternal(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/ArrayChannel;->pollInternal()Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/ArrayChannel;->updateBufferSize(I)Lkotlinx/coroutines/internal/Symbol;
+HSPLkotlinx/coroutines/channels/BufferOverflow;->$values()[Lkotlinx/coroutines/channels/BufferOverflow;
+HSPLkotlinx/coroutines/channels/BufferOverflow;-><clinit>()V
+HSPLkotlinx/coroutines/channels/BufferOverflow;-><init>(Ljava/lang/String;I)V
+HSPLkotlinx/coroutines/channels/Channel$Factory;-><clinit>()V
+HSPLkotlinx/coroutines/channels/Channel$Factory;-><init>()V
+HSPLkotlinx/coroutines/channels/Channel$Factory;->getCHANNEL_DEFAULT_CAPACITY$external__kotlinx_coroutines__android_common__kotlinx_coroutines()I
+HSPLkotlinx/coroutines/channels/Channel;-><clinit>()V
+HSPLkotlinx/coroutines/channels/ChannelCoroutine;-><init>(Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/channels/Channel;ZZ)V
+HSPLkotlinx/coroutines/channels/ChannelCoroutine;->receiveCatching-JP2dKIU(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/ChannelCoroutine;->send(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/ChannelKt;->Channel$default(ILkotlinx/coroutines/channels/BufferOverflow;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlinx/coroutines/channels/Channel;
+HSPLkotlinx/coroutines/channels/ChannelKt;->Channel(ILkotlinx/coroutines/channels/BufferOverflow;Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/channels/Channel;
+HSPLkotlinx/coroutines/channels/ChannelResult$Companion;-><init>()V
+HSPLkotlinx/coroutines/channels/ChannelResult$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlinx/coroutines/channels/ChannelResult$Companion;->failure-PtdJZtk()Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/ChannelResult$Companion;->success-JP2dKIU(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/ChannelResult$Failed;-><init>()V
+HSPLkotlinx/coroutines/channels/ChannelResult;-><clinit>()V
+HSPLkotlinx/coroutines/channels/ChannelResult;-><init>(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/channels/ChannelResult;->access$getFailed$cp()Lkotlinx/coroutines/channels/ChannelResult$Failed;
+HSPLkotlinx/coroutines/channels/ChannelResult;->box-impl(Ljava/lang/Object;)Lkotlinx/coroutines/channels/ChannelResult;
+HSPLkotlinx/coroutines/channels/ChannelResult;->constructor-impl(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/ChannelResult;->getOrNull-impl(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/ChannelResult;->getOrThrow-impl(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/ChannelResult;->isClosed-impl(Ljava/lang/Object;)Z
+HSPLkotlinx/coroutines/channels/ChannelResult;->unbox-impl()Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/ConflatedChannel;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLkotlinx/coroutines/channels/ConflatedChannel;->enqueueReceiveInternal(Lkotlinx/coroutines/channels/Receive;)Z
+HSPLkotlinx/coroutines/channels/ConflatedChannel;->isBufferAlwaysEmpty()Z
+HSPLkotlinx/coroutines/channels/ConflatedChannel;->isBufferEmpty()Z
+HSPLkotlinx/coroutines/channels/ConflatedChannel;->offerInternal(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/ConflatedChannel;->pollInternal()Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/ConflatedChannel;->updateValueLocked(Ljava/lang/Object;)Lkotlinx/coroutines/internal/UndeliveredElementException;
+HSPLkotlinx/coroutines/channels/LinkedListChannel;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLkotlinx/coroutines/channels/LinkedListChannel;->isBufferAlwaysEmpty()Z
+HSPLkotlinx/coroutines/channels/ProduceKt;->produce$default(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/CoroutineContext;ILkotlinx/coroutines/channels/BufferOverflow;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/channels/ReceiveChannel;
+HSPLkotlinx/coroutines/channels/ProduceKt;->produce(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/CoroutineContext;ILkotlinx/coroutines/channels/BufferOverflow;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/channels/ReceiveChannel;
+HSPLkotlinx/coroutines/channels/ProducerCoroutine;-><init>(Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/channels/Channel;)V
+HSPLkotlinx/coroutines/channels/Receive;-><init>()V
+HSPLkotlinx/coroutines/channels/Receive;->getOfferResult()Ljava/lang/Object;
+HSPLkotlinx/coroutines/channels/Receive;->getOfferResult()Lkotlinx/coroutines/internal/Symbol;
+HSPLkotlinx/coroutines/channels/Receive;->resumeOnCancellationFun(Ljava/lang/Object;)Lkotlin/jvm/functions/Function1;
+HSPLkotlinx/coroutines/channels/RendezvousChannel;-><init>(Lkotlin/jvm/functions/Function1;)V
+HSPLkotlinx/coroutines/channels/RendezvousChannel;->isBufferAlwaysEmpty()Z
+HSPLkotlinx/coroutines/flow/AbstractFlow$collect$1;-><init>(Lkotlinx/coroutines/flow/AbstractFlow;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/flow/AbstractFlow;-><init>()V
+HSPLkotlinx/coroutines/flow/AbstractFlow;->collect(Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/DistinctFlowImpl$collect$2$emit$1;-><init>(Lkotlinx/coroutines/flow/DistinctFlowImpl$collect$2;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/flow/DistinctFlowImpl$collect$2;-><init>(Lkotlinx/coroutines/flow/DistinctFlowImpl;Lkotlin/jvm/internal/Ref$ObjectRef;Lkotlinx/coroutines/flow/FlowCollector;)V
+HSPLkotlinx/coroutines/flow/DistinctFlowImpl$collect$2;->emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/DistinctFlowImpl;-><init>(Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)V
+HSPLkotlinx/coroutines/flow/DistinctFlowImpl;->collect(Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt;->buffer$default(Lkotlinx/coroutines/flow/Flow;ILkotlinx/coroutines/channels/BufferOverflow;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/FlowKt;->buffer(Lkotlinx/coroutines/flow/Flow;ILkotlinx/coroutines/channels/BufferOverflow;)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/FlowKt;->collect(Lkotlinx/coroutines/flow/Flow;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt;->collectLatest(Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt;->distinctUntilChanged(Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/FlowKt;->dropWhile(Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/FlowKt;->emitAll(Lkotlinx/coroutines/flow/FlowCollector;Lkotlinx/coroutines/channels/ReceiveChannel;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt;->ensureActive(Lkotlinx/coroutines/flow/FlowCollector;)V
+HSPLkotlinx/coroutines/flow/FlowKt;->first(Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt;->flow(Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/FlowKt;->mapLatest(Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/FlowKt;->stateIn(Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/CoroutineScope;Lkotlinx/coroutines/flow/SharingStarted;Ljava/lang/Object;)Lkotlinx/coroutines/flow/StateFlow;
+HSPLkotlinx/coroutines/flow/FlowKt;->take(Lkotlinx/coroutines/flow/Flow;I)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/FlowKt;->transformLatest(Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function3;)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/FlowKt__BuildersKt;->flow(Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/FlowKt__ChannelsKt$emitAllImpl$1;-><init>(Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/flow/FlowKt__ChannelsKt$emitAllImpl$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__ChannelsKt;->access$emitAllImpl$FlowKt__ChannelsKt(Lkotlinx/coroutines/flow/FlowCollector;Lkotlinx/coroutines/channels/ReceiveChannel;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__ChannelsKt;->emitAll(Lkotlinx/coroutines/flow/FlowCollector;Lkotlinx/coroutines/channels/ReceiveChannel;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__ChannelsKt;->emitAllImpl$FlowKt__ChannelsKt(Lkotlinx/coroutines/flow/FlowCollector;Lkotlinx/coroutines/channels/ReceiveChannel;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__CollectKt;->collect(Lkotlinx/coroutines/flow/Flow;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__CollectKt;->collectLatest(Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__ContextKt;->buffer$default(Lkotlinx/coroutines/flow/Flow;ILkotlinx/coroutines/channels/BufferOverflow;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/FlowKt__ContextKt;->buffer(Lkotlinx/coroutines/flow/Flow;ILkotlinx/coroutines/channels/BufferOverflow;)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/FlowKt__DistinctKt$defaultAreEquivalent$1;-><clinit>()V
+HSPLkotlinx/coroutines/flow/FlowKt__DistinctKt$defaultAreEquivalent$1;-><init>()V
+HSPLkotlinx/coroutines/flow/FlowKt__DistinctKt$defaultKeySelector$1;-><clinit>()V
+HSPLkotlinx/coroutines/flow/FlowKt__DistinctKt$defaultKeySelector$1;-><init>()V
+HSPLkotlinx/coroutines/flow/FlowKt__DistinctKt$defaultKeySelector$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__DistinctKt;-><clinit>()V
+HSPLkotlinx/coroutines/flow/FlowKt__DistinctKt;->distinctUntilChanged(Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/FlowKt__DistinctKt;->distinctUntilChangedBy$FlowKt__DistinctKt(Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/FlowKt__EmittersKt;->ensureActive(Lkotlinx/coroutines/flow/FlowCollector;)V
+HSPLkotlinx/coroutines/flow/FlowKt__LimitKt$dropWhile$$inlined$unsafeFlow$1;-><init>(Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)V
+HSPLkotlinx/coroutines/flow/FlowKt__LimitKt$dropWhile$$inlined$unsafeFlow$1;->collect(Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__LimitKt$dropWhile$1$1$emit$1;-><init>(Lkotlinx/coroutines/flow/FlowKt__LimitKt$dropWhile$1$1;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/flow/FlowKt__LimitKt$dropWhile$1$1;-><init>(Lkotlin/jvm/internal/Ref$BooleanRef;Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/jvm/functions/Function2;)V
+HSPLkotlinx/coroutines/flow/FlowKt__LimitKt$dropWhile$1$1;->emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__LimitKt$take$$inlined$unsafeFlow$1;-><init>(Lkotlinx/coroutines/flow/Flow;I)V
+HSPLkotlinx/coroutines/flow/FlowKt__LimitKt;->dropWhile(Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/FlowKt__LimitKt;->take(Lkotlinx/coroutines/flow/Flow;I)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/FlowKt__MergeKt$mapLatest$1;-><init>(Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/flow/FlowKt__MergeKt$mapLatest$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__MergeKt$mapLatest$1;->invoke(Lkotlinx/coroutines/flow/FlowCollector;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__MergeKt$mapLatest$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__MergeKt;-><clinit>()V
+HSPLkotlinx/coroutines/flow/FlowKt__MergeKt;->mapLatest(Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/FlowKt__MergeKt;->transformLatest(Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function3;)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/FlowKt__ReduceKt$first$$inlined$collectWhile$2$1;-><init>(Lkotlinx/coroutines/flow/FlowKt__ReduceKt$first$$inlined$collectWhile$2;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/flow/FlowKt__ReduceKt$first$$inlined$collectWhile$2;-><init>(Lkotlin/jvm/functions/Function2;Lkotlin/jvm/internal/Ref$ObjectRef;)V
+HSPLkotlinx/coroutines/flow/FlowKt__ReduceKt$first$$inlined$collectWhile$2;->emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__ReduceKt$first$3;-><init>(Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/flow/FlowKt__ReduceKt;->first(Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__ShareKt$launchSharing$1$2$WhenMappings;-><clinit>()V
+HSPLkotlinx/coroutines/flow/FlowKt__ShareKt$launchSharing$1$2;-><init>(Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/flow/MutableSharedFlow;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/flow/FlowKt__ShareKt$launchSharing$1$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLkotlinx/coroutines/flow/FlowKt__ShareKt$launchSharing$1$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__ShareKt$launchSharing$1$2;->invoke(Lkotlinx/coroutines/flow/SharingCommand;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__ShareKt$launchSharing$1$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__ShareKt$launchSharing$1;-><init>(Lkotlinx/coroutines/flow/SharingStarted;Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/flow/MutableSharedFlow;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/flow/FlowKt__ShareKt$launchSharing$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLkotlinx/coroutines/flow/FlowKt__ShareKt$launchSharing$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__ShareKt$launchSharing$1;->invoke(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__ShareKt$launchSharing$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/FlowKt__ShareKt;->configureSharing$FlowKt__ShareKt(Lkotlinx/coroutines/flow/Flow;I)Lkotlinx/coroutines/flow/SharingConfig;
+HSPLkotlinx/coroutines/flow/FlowKt__ShareKt;->launchSharing$FlowKt__ShareKt(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/flow/MutableSharedFlow;Lkotlinx/coroutines/flow/SharingStarted;Ljava/lang/Object;)Lkotlinx/coroutines/Job;
+HSPLkotlinx/coroutines/flow/FlowKt__ShareKt;->stateIn(Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/CoroutineScope;Lkotlinx/coroutines/flow/SharingStarted;Ljava/lang/Object;)Lkotlinx/coroutines/flow/StateFlow;
+HSPLkotlinx/coroutines/flow/ReadonlyStateFlow;-><init>(Lkotlinx/coroutines/flow/StateFlow;Lkotlinx/coroutines/Job;)V
+HSPLkotlinx/coroutines/flow/ReadonlyStateFlow;->collect(Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/ReadonlyStateFlow;->getValue()Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/SafeFlow;-><init>(Lkotlin/jvm/functions/Function2;)V
+HSPLkotlinx/coroutines/flow/SafeFlow;->collectSafely(Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/SharedFlowImpl$collect$1;-><init>(Lkotlinx/coroutines/flow/SharedFlowImpl;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;-><init>(IILkotlinx/coroutines/channels/BufferOverflow;)V
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->access$tryPeekLocked(Lkotlinx/coroutines/flow/SharedFlowImpl;Lkotlinx/coroutines/flow/SharedFlowSlot;)J
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->awaitValue(Lkotlinx/coroutines/flow/SharedFlowSlot;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->cleanupTailLocked()V
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->collect$suspendImpl(Lkotlinx/coroutines/flow/SharedFlowImpl;Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->collect(Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->createSlot()Lkotlinx/coroutines/flow/SharedFlowSlot;
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->createSlot()Lkotlinx/coroutines/flow/internal/AbstractSharedFlowSlot;
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->createSlotArray(I)[Lkotlinx/coroutines/flow/SharedFlowSlot;
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->createSlotArray(I)[Lkotlinx/coroutines/flow/internal/AbstractSharedFlowSlot;
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->dropOldestLocked()V
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->enqueueLocked(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->findSlotsToResumeLocked([Lkotlin/coroutines/Continuation;)[Lkotlin/coroutines/Continuation;
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->getBufferEndIndex()J
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->getHead()J
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->getLastReplayedLocked()Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->getPeekedValueLockedAt(J)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->getReplaySize()I
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->getTotalSize()I
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->growBuffer([Ljava/lang/Object;II)[Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->tryEmit(Ljava/lang/Object;)Z
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->tryEmitLocked(Ljava/lang/Object;)Z
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->tryEmitNoCollectorsLocked(Ljava/lang/Object;)Z
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->tryPeekLocked(Lkotlinx/coroutines/flow/SharedFlowSlot;)J
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->tryTakeValue(Lkotlinx/coroutines/flow/SharedFlowSlot;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->updateBufferLocked(JJJJ)V
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->updateCollectorIndexLocked$external__kotlinx_coroutines__android_common__kotlinx_coroutines(J)[Lkotlin/coroutines/Continuation;
+HSPLkotlinx/coroutines/flow/SharedFlowImpl;->updateNewCollectorIndexLocked$external__kotlinx_coroutines__android_common__kotlinx_coroutines()J
+HSPLkotlinx/coroutines/flow/SharedFlowKt;-><clinit>()V
+HSPLkotlinx/coroutines/flow/SharedFlowKt;->MutableSharedFlow$default(IILkotlinx/coroutines/channels/BufferOverflow;ILjava/lang/Object;)Lkotlinx/coroutines/flow/MutableSharedFlow;
+HSPLkotlinx/coroutines/flow/SharedFlowKt;->MutableSharedFlow(IILkotlinx/coroutines/channels/BufferOverflow;)Lkotlinx/coroutines/flow/MutableSharedFlow;
+HSPLkotlinx/coroutines/flow/SharedFlowKt;->access$getBufferAt([Ljava/lang/Object;J)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/SharedFlowKt;->access$setBufferAt([Ljava/lang/Object;JLjava/lang/Object;)V
+HSPLkotlinx/coroutines/flow/SharedFlowKt;->getBufferAt([Ljava/lang/Object;J)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/SharedFlowKt;->setBufferAt([Ljava/lang/Object;JLjava/lang/Object;)V
+HSPLkotlinx/coroutines/flow/SharedFlowSlot;-><init>()V
+HSPLkotlinx/coroutines/flow/SharedFlowSlot;->allocateLocked(Ljava/lang/Object;)Z
+HSPLkotlinx/coroutines/flow/SharedFlowSlot;->allocateLocked(Lkotlinx/coroutines/flow/SharedFlowImpl;)Z
+HSPLkotlinx/coroutines/flow/SharingCommand;->$values()[Lkotlinx/coroutines/flow/SharingCommand;
+HSPLkotlinx/coroutines/flow/SharingCommand;-><clinit>()V
+HSPLkotlinx/coroutines/flow/SharingCommand;-><init>(Ljava/lang/String;I)V
+HSPLkotlinx/coroutines/flow/SharingCommand;->values()[Lkotlinx/coroutines/flow/SharingCommand;
+HSPLkotlinx/coroutines/flow/SharingConfig;-><init>(Lkotlinx/coroutines/flow/Flow;ILkotlinx/coroutines/channels/BufferOverflow;Lkotlin/coroutines/CoroutineContext;)V
+HSPLkotlinx/coroutines/flow/SharingStarted$Companion;-><clinit>()V
+HSPLkotlinx/coroutines/flow/SharingStarted$Companion;-><init>()V
+HSPLkotlinx/coroutines/flow/SharingStarted$Companion;->WhileSubscribed$default(Lkotlinx/coroutines/flow/SharingStarted$Companion;JJILjava/lang/Object;)Lkotlinx/coroutines/flow/SharingStarted;
+HSPLkotlinx/coroutines/flow/SharingStarted$Companion;->WhileSubscribed(JJ)Lkotlinx/coroutines/flow/SharingStarted;
+HSPLkotlinx/coroutines/flow/SharingStarted$Companion;->getEagerly()Lkotlinx/coroutines/flow/SharingStarted;
+HSPLkotlinx/coroutines/flow/SharingStarted$Companion;->getLazily()Lkotlinx/coroutines/flow/SharingStarted;
+HSPLkotlinx/coroutines/flow/SharingStarted;-><clinit>()V
+HSPLkotlinx/coroutines/flow/StartedEagerly;-><init>()V
+HSPLkotlinx/coroutines/flow/StartedLazily;-><init>()V
+HSPLkotlinx/coroutines/flow/StartedWhileSubscribed$command$1;-><init>(Lkotlinx/coroutines/flow/StartedWhileSubscribed;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/flow/StartedWhileSubscribed$command$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/StartedWhileSubscribed$command$1;->invoke(Lkotlinx/coroutines/flow/FlowCollector;ILkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/StartedWhileSubscribed$command$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/StartedWhileSubscribed$command$2;-><init>(Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/flow/StartedWhileSubscribed$command$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLkotlinx/coroutines/flow/StartedWhileSubscribed$command$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/StartedWhileSubscribed$command$2;->invoke(Lkotlinx/coroutines/flow/SharingCommand;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/StartedWhileSubscribed$command$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/StartedWhileSubscribed;-><init>(JJ)V
+HSPLkotlinx/coroutines/flow/StartedWhileSubscribed;->command(Lkotlinx/coroutines/flow/StateFlow;)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/StartedWhileSubscribed;->equals(Ljava/lang/Object;)Z
+HSPLkotlinx/coroutines/flow/StateFlowImpl$collect$1;-><init>(Lkotlinx/coroutines/flow/StateFlowImpl;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/flow/StateFlowImpl$collect$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/StateFlowImpl;-><init>(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/flow/StateFlowImpl;->collect(Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/StateFlowImpl;->compareAndSet(Ljava/lang/Object;Ljava/lang/Object;)Z
+HSPLkotlinx/coroutines/flow/StateFlowImpl;->createSlot()Lkotlinx/coroutines/flow/StateFlowSlot;
+HSPLkotlinx/coroutines/flow/StateFlowImpl;->createSlot()Lkotlinx/coroutines/flow/internal/AbstractSharedFlowSlot;
+HSPLkotlinx/coroutines/flow/StateFlowImpl;->createSlotArray(I)[Lkotlinx/coroutines/flow/StateFlowSlot;
+HSPLkotlinx/coroutines/flow/StateFlowImpl;->createSlotArray(I)[Lkotlinx/coroutines/flow/internal/AbstractSharedFlowSlot;
+HSPLkotlinx/coroutines/flow/StateFlowImpl;->getValue()Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/StateFlowImpl;->setValue(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/flow/StateFlowImpl;->updateState(Ljava/lang/Object;Ljava/lang/Object;)Z
+HSPLkotlinx/coroutines/flow/StateFlowKt;-><clinit>()V
+HSPLkotlinx/coroutines/flow/StateFlowKt;->MutableStateFlow(Ljava/lang/Object;)Lkotlinx/coroutines/flow/MutableStateFlow;
+HSPLkotlinx/coroutines/flow/StateFlowKt;->access$getNONE$p()Lkotlinx/coroutines/internal/Symbol;
+HSPLkotlinx/coroutines/flow/StateFlowKt;->access$getPENDING$p()Lkotlinx/coroutines/internal/Symbol;
+HSPLkotlinx/coroutines/flow/StateFlowSlot;-><init>()V
+HSPLkotlinx/coroutines/flow/StateFlowSlot;->access$get_state$p(Lkotlinx/coroutines/flow/StateFlowSlot;)Lkotlinx/atomicfu/AtomicRef;
+HSPLkotlinx/coroutines/flow/StateFlowSlot;->allocateLocked(Ljava/lang/Object;)Z
+HSPLkotlinx/coroutines/flow/StateFlowSlot;->allocateLocked(Lkotlinx/coroutines/flow/StateFlowImpl;)Z
+HSPLkotlinx/coroutines/flow/StateFlowSlot;->awaitPending(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/StateFlowSlot;->makePending()V
+HSPLkotlinx/coroutines/flow/StateFlowSlot;->takePending()Z
+HSPLkotlinx/coroutines/flow/internal/AbstractSharedFlow;-><init>()V
+HSPLkotlinx/coroutines/flow/internal/AbstractSharedFlow;->access$getNCollectors(Lkotlinx/coroutines/flow/internal/AbstractSharedFlow;)I
+HSPLkotlinx/coroutines/flow/internal/AbstractSharedFlow;->access$getSlots(Lkotlinx/coroutines/flow/internal/AbstractSharedFlow;)[Lkotlinx/coroutines/flow/internal/AbstractSharedFlowSlot;
+HSPLkotlinx/coroutines/flow/internal/AbstractSharedFlow;->allocateSlot()Lkotlinx/coroutines/flow/internal/AbstractSharedFlowSlot;
+HSPLkotlinx/coroutines/flow/internal/AbstractSharedFlow;->getNCollectors()I
+HSPLkotlinx/coroutines/flow/internal/AbstractSharedFlow;->getSlots()[Lkotlinx/coroutines/flow/internal/AbstractSharedFlowSlot;
+HSPLkotlinx/coroutines/flow/internal/AbstractSharedFlow;->getSubscriptionCount()Lkotlinx/coroutines/flow/StateFlow;
+HSPLkotlinx/coroutines/flow/internal/AbstractSharedFlowKt;-><clinit>()V
+HSPLkotlinx/coroutines/flow/internal/AbstractSharedFlowSlot;-><init>()V
+HSPLkotlinx/coroutines/flow/internal/ChannelFlow$collect$2;-><init>(Lkotlinx/coroutines/flow/FlowCollector;Lkotlinx/coroutines/flow/internal/ChannelFlow;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/flow/internal/ChannelFlow$collect$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlow$collect$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlow$collect$2;->invoke(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlow$collect$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlow$collectToFun$1;-><init>(Lkotlinx/coroutines/flow/internal/ChannelFlow;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/flow/internal/ChannelFlow$collectToFun$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlow$collectToFun$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlow;-><init>(Lkotlin/coroutines/CoroutineContext;ILkotlinx/coroutines/channels/BufferOverflow;)V
+HSPLkotlinx/coroutines/flow/internal/ChannelFlow;->collect$suspendImpl(Lkotlinx/coroutines/flow/internal/ChannelFlow;Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlow;->collect(Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlow;->fuse(Lkotlin/coroutines/CoroutineContext;ILkotlinx/coroutines/channels/BufferOverflow;)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlow;->getCollectToFun$external__kotlinx_coroutines__android_common__kotlinx_coroutines()Lkotlin/jvm/functions/Function2;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlow;->getProduceCapacity$external__kotlinx_coroutines__android_common__kotlinx_coroutines()I
+HSPLkotlinx/coroutines/flow/internal/ChannelFlow;->produceImpl(Lkotlinx/coroutines/CoroutineScope;)Lkotlinx/coroutines/channels/ReceiveChannel;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowOperator;-><init>(Lkotlinx/coroutines/flow/Flow;Lkotlin/coroutines/CoroutineContext;ILkotlinx/coroutines/channels/BufferOverflow;)V
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowOperator;->collect$suspendImpl(Lkotlinx/coroutines/flow/internal/ChannelFlowOperator;Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowOperator;->collect(Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowOperator;->collectTo$suspendImpl(Lkotlinx/coroutines/flow/internal/ChannelFlowOperator;Lkotlinx/coroutines/channels/ProducerScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowOperator;->collectTo(Lkotlinx/coroutines/channels/ProducerScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3$1$2;-><init>(Lkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest;Lkotlinx/coroutines/flow/FlowCollector;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3$1$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3$1$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3$1$2;->invoke(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3$1$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3$1$emit$1;-><init>(Lkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3$1;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3$1;-><init>(Lkotlin/jvm/internal/Ref$ObjectRef;Lkotlinx/coroutines/CoroutineScope;Lkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest;Lkotlinx/coroutines/flow/FlowCollector;)V
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3$1;->emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3;-><init>(Lkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest;Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3;->invoke(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest;-><init>(Lkotlin/jvm/functions/Function3;Lkotlinx/coroutines/flow/Flow;Lkotlin/coroutines/CoroutineContext;ILkotlinx/coroutines/channels/BufferOverflow;)V
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest;-><init>(Lkotlin/jvm/functions/Function3;Lkotlinx/coroutines/flow/Flow;Lkotlin/coroutines/CoroutineContext;ILkotlinx/coroutines/channels/BufferOverflow;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest;->access$getTransform$p(Lkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest;)Lkotlin/jvm/functions/Function3;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest;->create(Lkotlin/coroutines/CoroutineContext;ILkotlinx/coroutines/channels/BufferOverflow;)Lkotlinx/coroutines/flow/internal/ChannelFlow;
+HSPLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest;->flowCollect(Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/FusibleFlow$DefaultImpls;->fuse$default(Lkotlinx/coroutines/flow/internal/FusibleFlow;Lkotlin/coroutines/CoroutineContext;ILkotlinx/coroutines/channels/BufferOverflow;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
+HSPLkotlinx/coroutines/flow/internal/NoOpContinuation;-><clinit>()V
+HSPLkotlinx/coroutines/flow/internal/NoOpContinuation;-><init>()V
+HSPLkotlinx/coroutines/flow/internal/NopCollector;-><clinit>()V
+HSPLkotlinx/coroutines/flow/internal/NopCollector;-><init>()V
+HSPLkotlinx/coroutines/flow/internal/NullSurrogateKt;-><clinit>()V
+HSPLkotlinx/coroutines/flow/internal/SafeCollector$collectContextSize$1;-><clinit>()V
+HSPLkotlinx/coroutines/flow/internal/SafeCollector$collectContextSize$1;-><init>()V
+HSPLkotlinx/coroutines/flow/internal/SafeCollector$collectContextSize$1;->invoke(ILkotlin/coroutines/CoroutineContext$Element;)Ljava/lang/Integer;
+HSPLkotlinx/coroutines/flow/internal/SafeCollector$collectContextSize$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/SafeCollector;-><init>(Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/CoroutineContext;)V
+HSPLkotlinx/coroutines/flow/internal/SendingCollector;-><init>(Lkotlinx/coroutines/channels/SendChannel;)V
+HSPLkotlinx/coroutines/flow/internal/SendingCollector;->emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/flow/internal/SubscriptionCountStateFlow;-><init>(I)V
+HSPLkotlinx/coroutines/flow/internal/SubscriptionCountStateFlow;->increment(I)Z
+HSPLkotlinx/coroutines/internal/AtomicKt;-><clinit>()V
+HSPLkotlinx/coroutines/internal/AtomicOp;-><init>()V
+HSPLkotlinx/coroutines/internal/AtomicOp;->decide(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/internal/AtomicOp;->perform(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/internal/ContextScope;-><init>(Lkotlin/coroutines/CoroutineContext;)V
+HSPLkotlinx/coroutines/internal/ContextScope;->getCoroutineContext()Lkotlin/coroutines/CoroutineContext;
+HSPLkotlinx/coroutines/internal/DispatchedContinuation;-><init>(Lkotlinx/coroutines/CoroutineDispatcher;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/internal/DispatchedContinuation;->awaitReusability()V
+HSPLkotlinx/coroutines/internal/DispatchedContinuation;->cancelCompletedResult$external__kotlinx_coroutines__android_common__kotlinx_coroutines(Ljava/lang/Object;Ljava/lang/Throwable;)V
+HSPLkotlinx/coroutines/internal/DispatchedContinuation;->claimReusableCancellableContinuation()Lkotlinx/coroutines/CancellableContinuationImpl;
+HSPLkotlinx/coroutines/internal/DispatchedContinuation;->getContext()Lkotlin/coroutines/CoroutineContext;
+HSPLkotlinx/coroutines/internal/DispatchedContinuation;->getDelegate$external__kotlinx_coroutines__android_common__kotlinx_coroutines()Lkotlin/coroutines/Continuation;
+HSPLkotlinx/coroutines/internal/DispatchedContinuation;->getReusableCancellableContinuation()Lkotlinx/coroutines/CancellableContinuationImpl;
+HSPLkotlinx/coroutines/internal/DispatchedContinuation;->isReusable()Z
+HSPLkotlinx/coroutines/internal/DispatchedContinuation;->release()V
+HSPLkotlinx/coroutines/internal/DispatchedContinuation;->resumeWith(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/internal/DispatchedContinuation;->takeState$external__kotlinx_coroutines__android_common__kotlinx_coroutines()Ljava/lang/Object;
+HSPLkotlinx/coroutines/internal/DispatchedContinuation;->tryReleaseClaimedContinuation(Lkotlinx/coroutines/CancellableContinuation;)Ljava/lang/Throwable;
+HSPLkotlinx/coroutines/internal/DispatchedContinuationKt;-><clinit>()V
+HSPLkotlinx/coroutines/internal/DispatchedContinuationKt;->access$getUNDEFINED$p()Lkotlinx/coroutines/internal/Symbol;
+HSPLkotlinx/coroutines/internal/DispatchedContinuationKt;->resumeCancellableWith(Lkotlin/coroutines/Continuation;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
+HSPLkotlinx/coroutines/internal/FastServiceLoader;-><clinit>()V
+HSPLkotlinx/coroutines/internal/FastServiceLoader;-><init>()V
+HSPLkotlinx/coroutines/internal/FastServiceLoader;->loadMainDispatcherFactory$external__kotlinx_coroutines__android_common__kotlinx_coroutines()Ljava/util/List;
+HSPLkotlinx/coroutines/internal/FastServiceLoaderKt;-><clinit>()V
+HSPLkotlinx/coroutines/internal/FastServiceLoaderKt;->getANDROID_DETECTED()Z
+HSPLkotlinx/coroutines/internal/LimitedDispatcher;-><init>(Lkotlinx/coroutines/CoroutineDispatcher;I)V
+HSPLkotlinx/coroutines/internal/LimitedDispatcherKt;->checkParallelism(I)V
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListHead;-><init>()V
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListHead;->isRemoved()Z
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListKt;-><clinit>()V
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListKt;->unwrap(Ljava/lang/Object;)Lkotlinx/coroutines/internal/LockFreeLinkedListNode;
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListNode$CondAddOp;-><init>(Lkotlinx/coroutines/internal/LockFreeLinkedListNode;)V
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListNode$CondAddOp;->complete(Ljava/lang/Object;Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListNode$CondAddOp;->complete(Lkotlinx/coroutines/internal/LockFreeLinkedListNode;Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListNode;-><init>()V
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListNode;->access$finishAdd(Lkotlinx/coroutines/internal/LockFreeLinkedListNode;Lkotlinx/coroutines/internal/LockFreeLinkedListNode;)V
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListNode;->access$get_next$p(Lkotlinx/coroutines/internal/LockFreeLinkedListNode;)Lkotlinx/atomicfu/AtomicRef;
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListNode;->addNext(Lkotlinx/coroutines/internal/LockFreeLinkedListNode;Lkotlinx/coroutines/internal/LockFreeLinkedListNode;)Z
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListNode;->addOneIfEmpty(Lkotlinx/coroutines/internal/LockFreeLinkedListNode;)Z
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListNode;->correctPrev(Lkotlinx/coroutines/internal/OpDescriptor;)Lkotlinx/coroutines/internal/LockFreeLinkedListNode;
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListNode;->finishAdd(Lkotlinx/coroutines/internal/LockFreeLinkedListNode;)V
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListNode;->getNext()Ljava/lang/Object;
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListNode;->getNextNode()Lkotlinx/coroutines/internal/LockFreeLinkedListNode;
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListNode;->getPrevNode()Lkotlinx/coroutines/internal/LockFreeLinkedListNode;
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListNode;->isRemoved()Z
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListNode;->remove()Z
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListNode;->removeOrNext()Lkotlinx/coroutines/internal/LockFreeLinkedListNode;
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListNode;->removed()Lkotlinx/coroutines/internal/Removed;
+HSPLkotlinx/coroutines/internal/LockFreeLinkedListNode;->tryCondAddNext(Lkotlinx/coroutines/internal/LockFreeLinkedListNode;Lkotlinx/coroutines/internal/LockFreeLinkedListNode;Lkotlinx/coroutines/internal/LockFreeLinkedListNode$CondAddOp;)I
+HSPLkotlinx/coroutines/internal/LockFreeTaskQueue;-><init>(Z)V
+HSPLkotlinx/coroutines/internal/LockFreeTaskQueueCore$Companion;-><init>()V
+HSPLkotlinx/coroutines/internal/LockFreeTaskQueueCore$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlinx/coroutines/internal/LockFreeTaskQueueCore;-><clinit>()V
+HSPLkotlinx/coroutines/internal/LockFreeTaskQueueCore;-><init>(IZ)V
+HSPLkotlinx/coroutines/internal/MainDispatcherLoader;-><clinit>()V
+HSPLkotlinx/coroutines/internal/MainDispatcherLoader;-><init>()V
+HSPLkotlinx/coroutines/internal/MainDispatcherLoader;->loadMainDispatcher()Lkotlinx/coroutines/MainCoroutineDispatcher;
+HSPLkotlinx/coroutines/internal/MainDispatchersKt;-><clinit>()V
+HSPLkotlinx/coroutines/internal/MainDispatchersKt;->tryCreateDispatcher(Lkotlinx/coroutines/internal/MainDispatcherFactory;Ljava/util/List;)Lkotlinx/coroutines/MainCoroutineDispatcher;
+HSPLkotlinx/coroutines/internal/OpDescriptor;-><init>()V
+HSPLkotlinx/coroutines/internal/Removed;-><init>(Lkotlinx/coroutines/internal/LockFreeLinkedListNode;)V
+HSPLkotlinx/coroutines/internal/ResizableAtomicArray;-><init>(I)V
+HSPLkotlinx/coroutines/internal/ScopeCoroutine;-><init>(Lkotlin/coroutines/CoroutineContext;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/internal/ScopeCoroutine;->afterResume(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/internal/ScopeCoroutine;->isScopedCoroutine()Z
+HSPLkotlinx/coroutines/internal/Symbol;-><init>(Ljava/lang/String;)V
+HSPLkotlinx/coroutines/internal/SystemPropsKt;->getAVAILABLE_PROCESSORS()I
+HSPLkotlinx/coroutines/internal/SystemPropsKt;->systemProp$default(Ljava/lang/String;IIIILjava/lang/Object;)I
+HSPLkotlinx/coroutines/internal/SystemPropsKt;->systemProp$default(Ljava/lang/String;JJJILjava/lang/Object;)J
+HSPLkotlinx/coroutines/internal/SystemPropsKt;->systemProp(Ljava/lang/String;)Ljava/lang/String;
+HSPLkotlinx/coroutines/internal/SystemPropsKt;->systemProp(Ljava/lang/String;III)I
+HSPLkotlinx/coroutines/internal/SystemPropsKt;->systemProp(Ljava/lang/String;JJJ)J
+HSPLkotlinx/coroutines/internal/SystemPropsKt;->systemProp(Ljava/lang/String;Z)Z
+HSPLkotlinx/coroutines/internal/SystemPropsKt__SystemPropsKt;-><clinit>()V
+HSPLkotlinx/coroutines/internal/SystemPropsKt__SystemPropsKt;->getAVAILABLE_PROCESSORS()I
+HSPLkotlinx/coroutines/internal/SystemPropsKt__SystemPropsKt;->systemProp(Ljava/lang/String;)Ljava/lang/String;
+HSPLkotlinx/coroutines/internal/SystemPropsKt__SystemProps_commonKt;->systemProp$default(Ljava/lang/String;IIIILjava/lang/Object;)I
+HSPLkotlinx/coroutines/internal/SystemPropsKt__SystemProps_commonKt;->systemProp$default(Ljava/lang/String;JJJILjava/lang/Object;)J
+HSPLkotlinx/coroutines/internal/SystemPropsKt__SystemProps_commonKt;->systemProp(Ljava/lang/String;III)I
+HSPLkotlinx/coroutines/internal/SystemPropsKt__SystemProps_commonKt;->systemProp(Ljava/lang/String;JJJ)J
+HSPLkotlinx/coroutines/internal/SystemPropsKt__SystemProps_commonKt;->systemProp(Ljava/lang/String;Z)Z
+HSPLkotlinx/coroutines/internal/ThreadContextKt$countAll$1;-><clinit>()V
+HSPLkotlinx/coroutines/internal/ThreadContextKt$countAll$1;-><init>()V
+HSPLkotlinx/coroutines/internal/ThreadContextKt$countAll$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/internal/ThreadContextKt$countAll$1;->invoke(Ljava/lang/Object;Lkotlin/coroutines/CoroutineContext$Element;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/internal/ThreadContextKt$findOne$1;-><clinit>()V
+HSPLkotlinx/coroutines/internal/ThreadContextKt$findOne$1;-><init>()V
+HSPLkotlinx/coroutines/internal/ThreadContextKt$updateState$1;-><clinit>()V
+HSPLkotlinx/coroutines/internal/ThreadContextKt$updateState$1;-><init>()V
+HSPLkotlinx/coroutines/internal/ThreadContextKt;-><clinit>()V
+HSPLkotlinx/coroutines/internal/ThreadContextKt;->restoreThreadContext(Lkotlin/coroutines/CoroutineContext;Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/internal/ThreadContextKt;->threadContextElements(Lkotlin/coroutines/CoroutineContext;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/internal/ThreadContextKt;->updateThreadContext(Lkotlin/coroutines/CoroutineContext;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/intrinsics/CancellableKt;->startCoroutineCancellable$default(Lkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/coroutines/Continuation;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
+HSPLkotlinx/coroutines/intrinsics/CancellableKt;->startCoroutineCancellable(Lkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/coroutines/Continuation;Lkotlin/jvm/functions/Function1;)V
+HSPLkotlinx/coroutines/intrinsics/UndispatchedKt;->startCoroutineUndispatched(Lkotlin/jvm/functions/Function2;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)V
+HSPLkotlinx/coroutines/intrinsics/UndispatchedKt;->startUndispatchedOrReturn(Lkotlinx/coroutines/internal/ScopeCoroutine;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/scheduling/CoroutineScheduler$Companion;-><init>()V
+HSPLkotlinx/coroutines/scheduling/CoroutineScheduler$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLkotlinx/coroutines/scheduling/CoroutineScheduler;-><clinit>()V
+HSPLkotlinx/coroutines/scheduling/CoroutineScheduler;-><init>(IIJLjava/lang/String;)V
+HSPLkotlinx/coroutines/scheduling/DefaultIoScheduler;-><clinit>()V
+HSPLkotlinx/coroutines/scheduling/DefaultIoScheduler;-><init>()V
+HSPLkotlinx/coroutines/scheduling/DefaultScheduler;-><clinit>()V
+HSPLkotlinx/coroutines/scheduling/DefaultScheduler;-><init>()V
+HSPLkotlinx/coroutines/scheduling/GlobalQueue;-><init>()V
+HSPLkotlinx/coroutines/scheduling/NanoTimeSource;-><clinit>()V
+HSPLkotlinx/coroutines/scheduling/NanoTimeSource;-><init>()V
+HSPLkotlinx/coroutines/scheduling/SchedulerCoroutineDispatcher;-><init>(IIJLjava/lang/String;)V
+HSPLkotlinx/coroutines/scheduling/SchedulerCoroutineDispatcher;->createScheduler()Lkotlinx/coroutines/scheduling/CoroutineScheduler;
+HSPLkotlinx/coroutines/scheduling/SchedulerTimeSource;-><init>()V
+HSPLkotlinx/coroutines/scheduling/Task;-><init>()V
+HSPLkotlinx/coroutines/scheduling/Task;-><init>(JLkotlinx/coroutines/scheduling/TaskContext;)V
+HSPLkotlinx/coroutines/scheduling/TaskContextImpl;-><init>(I)V
+HSPLkotlinx/coroutines/scheduling/TaskContextImpl;->afterTask()V
+HSPLkotlinx/coroutines/scheduling/TasksKt;-><clinit>()V
+HSPLkotlinx/coroutines/scheduling/UnlimitedIoScheduler;-><clinit>()V
+HSPLkotlinx/coroutines/scheduling/UnlimitedIoScheduler;-><init>()V
+HSPLkotlinx/coroutines/sync/Empty;-><init>(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/sync/Mutex$DefaultImpls;->lock$default(Lkotlinx/coroutines/sync/Mutex;Ljava/lang/Object;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/sync/MutexImpl;-><init>(Z)V
+HSPLkotlinx/coroutines/sync/MutexImpl;->lock(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+HSPLkotlinx/coroutines/sync/MutexImpl;->tryLock(Ljava/lang/Object;)Z
+HSPLkotlinx/coroutines/sync/MutexImpl;->unlock(Ljava/lang/Object;)V
+HSPLkotlinx/coroutines/sync/MutexKt;-><clinit>()V
+HSPLkotlinx/coroutines/sync/MutexKt;->Mutex$default(ZILjava/lang/Object;)Lkotlinx/coroutines/sync/Mutex;
+HSPLkotlinx/coroutines/sync/MutexKt;->Mutex(Z)Lkotlinx/coroutines/sync/Mutex;
+HSPLkotlinx/coroutines/sync/MutexKt;->access$getEMPTY_LOCKED$p()Lkotlinx/coroutines/sync/Empty;
+HSPLkotlinx/coroutines/sync/MutexKt;->access$getEMPTY_UNLOCKED$p()Lkotlinx/coroutines/sync/Empty;
+HSPLkotlinx/coroutines/sync/MutexKt;->access$getUNLOCKED$p()Lkotlinx/coroutines/internal/Symbol;
+Landroidx/activity/Cancellable;
+Landroidx/activity/ComponentActivity$$ExternalSyntheticLambda0;
+Landroidx/activity/ComponentActivity$$ExternalSyntheticLambda1;
+Landroidx/activity/ComponentActivity$$ExternalSyntheticLambda2;
+Landroidx/activity/ComponentActivity$$ExternalSyntheticLambda3;
+Landroidx/activity/ComponentActivity$1;
+Landroidx/activity/ComponentActivity$2$2;
+Landroidx/activity/ComponentActivity$2;
+Landroidx/activity/ComponentActivity$3;
+Landroidx/activity/ComponentActivity$4;
+Landroidx/activity/ComponentActivity$5;
+Landroidx/activity/ComponentActivity$Api19Impl;
+Landroidx/activity/ComponentActivity$Api33Impl;
+Landroidx/activity/ComponentActivity$NonConfigurationInstances;
+Landroidx/activity/ComponentActivity$ReportFullyDrawnExecutor;
+Landroidx/activity/ComponentActivity$ReportFullyDrawnExecutorApi16Impl$$ExternalSyntheticLambda0;
+Landroidx/activity/ComponentActivity$ReportFullyDrawnExecutorApi16Impl;
+Landroidx/activity/ComponentActivity;
+Landroidx/activity/FullyDrawnReporter$$ExternalSyntheticLambda0;
+Landroidx/activity/FullyDrawnReporter;
+Landroidx/activity/FullyDrawnReporterOwner;
+Landroidx/activity/OnBackPressedCallback;
+Landroidx/activity/OnBackPressedDispatcher$$ExternalSyntheticLambda1;
+Landroidx/activity/OnBackPressedDispatcher$$ExternalSyntheticLambda2;
+Landroidx/activity/OnBackPressedDispatcher$$ExternalSyntheticThrowCCEIfNotNull0;
+Landroidx/activity/OnBackPressedDispatcher$Api33Impl$$ExternalSyntheticLambda0;
+Landroidx/activity/OnBackPressedDispatcher$Api33Impl;
+Landroidx/activity/OnBackPressedDispatcher$OnBackPressedCancellable;
+Landroidx/activity/OnBackPressedDispatcher;
+Landroidx/activity/OnBackPressedDispatcherOwner;
+Landroidx/activity/R$id;
+Landroidx/activity/ViewTreeFullyDrawnReporterOwner;
+Landroidx/activity/ViewTreeOnBackPressedDispatcherOwner;
+Landroidx/activity/compose/ActivityResultLauncherHolder;
+Landroidx/activity/compose/ActivityResultRegistryKt$rememberLauncherForActivityResult$1$1;
+Landroidx/activity/compose/ActivityResultRegistryKt$rememberLauncherForActivityResult$1$invoke$$inlined$onDispose$1;
+Landroidx/activity/compose/ActivityResultRegistryKt$rememberLauncherForActivityResult$1;
+Landroidx/activity/compose/ActivityResultRegistryKt$rememberLauncherForActivityResult$key$1;
+Landroidx/activity/compose/ActivityResultRegistryKt;
+Landroidx/activity/compose/ComponentActivityKt;
+Landroidx/activity/compose/LocalActivityResultRegistryOwner$LocalComposition$1;
+Landroidx/activity/compose/LocalActivityResultRegistryOwner;
+Landroidx/activity/compose/ManagedActivityResultLauncher;
+Landroidx/activity/contextaware/ContextAwareHelper;
+Landroidx/activity/contextaware/OnContextAvailableListener;
+Landroidx/activity/result/ActivityResult;
+Landroidx/activity/result/ActivityResultCallback;
+Landroidx/activity/result/ActivityResultLauncher;
+Landroidx/activity/result/ActivityResultRegistry$3;
+Landroidx/activity/result/ActivityResultRegistry$CallbackAndContract;
+Landroidx/activity/result/ActivityResultRegistry;
+Landroidx/activity/result/ActivityResultRegistryOwner;
+Landroidx/activity/result/IntentSenderRequest$Builder;
+Landroidx/activity/result/IntentSenderRequest;
+Landroidx/activity/result/contract/ActivityResultContract$SynchronousResult;
+Landroidx/activity/result/contract/ActivityResultContract;
+Landroidx/activity/result/contract/ActivityResultContracts$StartIntentSenderForResult$Companion;
+Landroidx/activity/result/contract/ActivityResultContracts$StartIntentSenderForResult;
+Landroidx/arch/core/executor/ArchTaskExecutor$$ExternalSyntheticLambda0;
+Landroidx/arch/core/executor/ArchTaskExecutor$$ExternalSyntheticLambda1;
+Landroidx/arch/core/executor/ArchTaskExecutor;
+Landroidx/arch/core/executor/DefaultTaskExecutor$1;
+Landroidx/arch/core/executor/DefaultTaskExecutor$Api28Impl;
+Landroidx/arch/core/executor/DefaultTaskExecutor;
+Landroidx/arch/core/executor/TaskExecutor;
+Landroidx/arch/core/internal/FastSafeIterableMap;
+Landroidx/arch/core/internal/SafeIterableMap$AscendingIterator;
+Landroidx/arch/core/internal/SafeIterableMap$DescendingIterator;
+Landroidx/arch/core/internal/SafeIterableMap$Entry;
+Landroidx/arch/core/internal/SafeIterableMap$IteratorWithAdditions;
+Landroidx/arch/core/internal/SafeIterableMap$ListIterator;
+Landroidx/arch/core/internal/SafeIterableMap$SupportRemove;
+Landroidx/arch/core/internal/SafeIterableMap;
+Landroidx/collection/ArraySet$Companion;
+Landroidx/collection/ArraySet$ElementIterator;
+Landroidx/collection/ArraySet;
+Landroidx/collection/IndexBasedArrayIterator;
+Landroidx/collection/LruCache;
+Landroidx/collection/SimpleArrayMap;
+Landroidx/collection/SparseArrayCompat;
+Landroidx/collection/SparseArrayCompatKt;
+Landroidx/collection/internal/ContainerHelpersKt;
+Landroidx/collection/internal/Lock;
+Landroidx/collection/internal/LruHashMap;
+Landroidx/compose/animation/core/Animatable$runAnimation$2$1;
+Landroidx/compose/animation/core/Animatable$runAnimation$2;
+Landroidx/compose/animation/core/Animatable$snapTo$2;
+Landroidx/compose/animation/core/Animatable;
+Landroidx/compose/animation/core/AnimatableKt;
+Landroidx/compose/animation/core/AnimateAsStateKt$animateValueAsState$2;
+Landroidx/compose/animation/core/AnimateAsStateKt$animateValueAsState$3$1;
+Landroidx/compose/animation/core/AnimateAsStateKt$animateValueAsState$3;
+Landroidx/compose/animation/core/AnimateAsStateKt;
+Landroidx/compose/animation/core/Animation;
+Landroidx/compose/animation/core/AnimationEndReason;
+Landroidx/compose/animation/core/AnimationKt;
+Landroidx/compose/animation/core/AnimationResult;
+Landroidx/compose/animation/core/AnimationScope;
+Landroidx/compose/animation/core/AnimationSpec;
+Landroidx/compose/animation/core/AnimationSpecKt;
+Landroidx/compose/animation/core/AnimationState;
+Landroidx/compose/animation/core/AnimationStateKt;
+Landroidx/compose/animation/core/AnimationVector1D;
+Landroidx/compose/animation/core/AnimationVector2D;
+Landroidx/compose/animation/core/AnimationVector4D;
+Landroidx/compose/animation/core/AnimationVector;
+Landroidx/compose/animation/core/AnimationVectorsKt;
+Landroidx/compose/animation/core/Animations;
+Landroidx/compose/animation/core/CubicBezierEasing;
+Landroidx/compose/animation/core/DecayAnimation;
+Landroidx/compose/animation/core/DecayAnimationSpec;
+Landroidx/compose/animation/core/Easing;
+Landroidx/compose/animation/core/EasingKt$LinearEasing$1;
+Landroidx/compose/animation/core/EasingKt;
+Landroidx/compose/animation/core/FiniteAnimationSpec;
+Landroidx/compose/animation/core/FloatAnimationSpec;
+Landroidx/compose/animation/core/FloatTweenSpec;
+Landroidx/compose/animation/core/InfiniteAnimationPolicyKt;
+Landroidx/compose/animation/core/MutatePriority;
+Landroidx/compose/animation/core/MutatorMutex$Mutator;
+Landroidx/compose/animation/core/MutatorMutex$mutate$2;
+Landroidx/compose/animation/core/MutatorMutex;
+Landroidx/compose/animation/core/SpringSpec;
+Landroidx/compose/animation/core/SuspendAnimationKt$animate$3;
+Landroidx/compose/animation/core/SuspendAnimationKt$animate$4;
+Landroidx/compose/animation/core/SuspendAnimationKt$animate$5;
+Landroidx/compose/animation/core/SuspendAnimationKt$animate$6$1;
+Landroidx/compose/animation/core/SuspendAnimationKt$animate$6;
+Landroidx/compose/animation/core/SuspendAnimationKt$animate$7;
+Landroidx/compose/animation/core/SuspendAnimationKt$animate$9;
+Landroidx/compose/animation/core/SuspendAnimationKt$animateDecay$4;
+Landroidx/compose/animation/core/SuspendAnimationKt$callWithFrameNanos$2;
+Landroidx/compose/animation/core/SuspendAnimationKt;
+Landroidx/compose/animation/core/TargetBasedAnimation;
+Landroidx/compose/animation/core/TweenSpec;
+Landroidx/compose/animation/core/TwoWayConverter;
+Landroidx/compose/animation/core/TwoWayConverterImpl;
+Landroidx/compose/animation/core/VectorConvertersKt$DpOffsetToVector$1;
+Landroidx/compose/animation/core/VectorConvertersKt$DpOffsetToVector$2;
+Landroidx/compose/animation/core/VectorConvertersKt$DpToVector$1;
+Landroidx/compose/animation/core/VectorConvertersKt$DpToVector$2;
+Landroidx/compose/animation/core/VectorConvertersKt$FloatToVector$1;
+Landroidx/compose/animation/core/VectorConvertersKt$FloatToVector$2;
+Landroidx/compose/animation/core/VectorConvertersKt$IntOffsetToVector$1;
+Landroidx/compose/animation/core/VectorConvertersKt$IntOffsetToVector$2;
+Landroidx/compose/animation/core/VectorConvertersKt$IntSizeToVector$1;
+Landroidx/compose/animation/core/VectorConvertersKt$IntSizeToVector$2;
+Landroidx/compose/animation/core/VectorConvertersKt$IntToVector$1;
+Landroidx/compose/animation/core/VectorConvertersKt$IntToVector$2;
+Landroidx/compose/animation/core/VectorConvertersKt$OffsetToVector$1;
+Landroidx/compose/animation/core/VectorConvertersKt$OffsetToVector$2;
+Landroidx/compose/animation/core/VectorConvertersKt$RectToVector$1;
+Landroidx/compose/animation/core/VectorConvertersKt$RectToVector$2;
+Landroidx/compose/animation/core/VectorConvertersKt$SizeToVector$1;
+Landroidx/compose/animation/core/VectorConvertersKt$SizeToVector$2;
+Landroidx/compose/animation/core/VectorConvertersKt;
+Landroidx/compose/animation/core/VectorizedAnimationSpec;
+Landroidx/compose/animation/core/VectorizedDurationBasedAnimationSpec;
+Landroidx/compose/animation/core/VectorizedFiniteAnimationSpec;
+Landroidx/compose/animation/core/VectorizedFloatAnimationSpec$1;
+Landroidx/compose/animation/core/VectorizedFloatAnimationSpec;
+Landroidx/compose/animation/core/VectorizedSpringSpec;
+Landroidx/compose/animation/core/VectorizedTweenSpec;
+Landroidx/compose/animation/core/VisibilityThresholdsKt;
+Landroidx/compose/foundation/Background;
+Landroidx/compose/foundation/BackgroundKt$background-bw27NRU$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/BackgroundKt;
+Landroidx/compose/foundation/BorderKt;
+Landroidx/compose/foundation/BorderStroke;
+Landroidx/compose/foundation/CanvasKt$Canvas$1;
+Landroidx/compose/foundation/CanvasKt;
+Landroidx/compose/foundation/ClickableKt$PressedInteractionSourceDisposableEffect$1$invoke$$inlined$onDispose$1;
+Landroidx/compose/foundation/ClickableKt$PressedInteractionSourceDisposableEffect$1;
+Landroidx/compose/foundation/ClickableKt$PressedInteractionSourceDisposableEffect$2;
+Landroidx/compose/foundation/ClickableKt$clickable$4$1$1$1;
+Landroidx/compose/foundation/ClickableKt$clickable$4$1$1;
+Landroidx/compose/foundation/ClickableKt$clickable$4$delayPressInteraction$1$1;
+Landroidx/compose/foundation/ClickableKt$clickable$4$gesture$1$1$1;
+Landroidx/compose/foundation/ClickableKt$clickable$4$gesture$1$1$2;
+Landroidx/compose/foundation/ClickableKt$clickable$4$gesture$1$1;
+Landroidx/compose/foundation/ClickableKt$clickable$4;
+Landroidx/compose/foundation/ClickableKt$clickable-O2vRcR0$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/ClickableKt$genericClickableWithoutGesture$clickSemantics$1$1;
+Landroidx/compose/foundation/ClickableKt$genericClickableWithoutGesture$clickSemantics$1$2;
+Landroidx/compose/foundation/ClickableKt$genericClickableWithoutGesture$clickSemantics$1;
+Landroidx/compose/foundation/ClickableKt$genericClickableWithoutGesture$detectPressAndClickFromKey$1$1;
+Landroidx/compose/foundation/ClickableKt$genericClickableWithoutGesture$detectPressAndClickFromKey$1$2$1;
+Landroidx/compose/foundation/ClickableKt$genericClickableWithoutGesture$detectPressAndClickFromKey$1;
+Landroidx/compose/foundation/ClickableKt$handlePressInteraction$2;
+Landroidx/compose/foundation/ClickableKt;
+Landroidx/compose/foundation/Clickable_androidKt;
+Landroidx/compose/foundation/DarkThemeKt;
+Landroidx/compose/foundation/DarkTheme_androidKt;
+Landroidx/compose/foundation/DefaultDebugIndication;
+Landroidx/compose/foundation/FocusableKt$focusGroup$1;
+Landroidx/compose/foundation/FocusableKt$focusable$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/FocusableKt$focusable$2$1$1$invoke$$inlined$onDispose$1;
+Landroidx/compose/foundation/FocusableKt$focusable$2$1$1;
+Landroidx/compose/foundation/FocusableKt$focusable$2$2$1;
+Landroidx/compose/foundation/FocusableKt$focusable$2$2$invoke$$inlined$onDispose$1;
+Landroidx/compose/foundation/FocusableKt$focusable$2$2;
+Landroidx/compose/foundation/FocusableKt$focusable$2$3$1;
+Landroidx/compose/foundation/FocusableKt$focusable$2$3;
+Landroidx/compose/foundation/FocusableKt$focusable$2$4$1;
+Landroidx/compose/foundation/FocusableKt$focusable$2$5$1;
+Landroidx/compose/foundation/FocusableKt$focusable$2$5$2;
+Landroidx/compose/foundation/FocusableKt$focusable$2$5$3;
+Landroidx/compose/foundation/FocusableKt$focusable$2$5;
+Landroidx/compose/foundation/FocusableKt$focusable$2;
+Landroidx/compose/foundation/FocusableKt$focusableInNonTouchMode$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/FocusableKt$focusableInNonTouchMode$2$1;
+Landroidx/compose/foundation/FocusableKt$focusableInNonTouchMode$2;
+Landroidx/compose/foundation/FocusableKt$onPinnableParentAvailable$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/FocusableKt$special$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/FocusableKt;
+Landroidx/compose/foundation/FocusedBoundsModifier;
+Landroidx/compose/foundation/HoverableKt$hoverable$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/HoverableKt$hoverable$2$1$1$invoke$$inlined$onDispose$1;
+Landroidx/compose/foundation/HoverableKt$hoverable$2$1$1;
+Landroidx/compose/foundation/HoverableKt$hoverable$2$2$1;
+Landroidx/compose/foundation/HoverableKt$hoverable$2$3$1$1;
+Landroidx/compose/foundation/HoverableKt$hoverable$2$3$1$2;
+Landroidx/compose/foundation/HoverableKt$hoverable$2$3$1;
+Landroidx/compose/foundation/HoverableKt$hoverable$2$3;
+Landroidx/compose/foundation/HoverableKt$hoverable$2$invoke$emitEnter$1;
+Landroidx/compose/foundation/HoverableKt$hoverable$2$invoke$emitExit$1;
+Landroidx/compose/foundation/HoverableKt$hoverable$2;
+Landroidx/compose/foundation/HoverableKt;
+Landroidx/compose/foundation/ImageKt;
+Landroidx/compose/foundation/Indication;
+Landroidx/compose/foundation/IndicationInstance;
+Landroidx/compose/foundation/IndicationKt$LocalIndication$1;
+Landroidx/compose/foundation/IndicationKt$indication$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/IndicationKt$indication$2;
+Landroidx/compose/foundation/IndicationKt;
+Landroidx/compose/foundation/IndicationModifier;
+Landroidx/compose/foundation/MutatePriority;
+Landroidx/compose/foundation/MutatorMutex$Mutator;
+Landroidx/compose/foundation/MutatorMutex$mutateWith$2;
+Landroidx/compose/foundation/MutatorMutex;
+Landroidx/compose/foundation/NoIndication;
+Landroidx/compose/foundation/PinnableParentConsumer;
+Landroidx/compose/foundation/gestures/DefaultDraggableState$drag$2;
+Landroidx/compose/foundation/gestures/DefaultDraggableState$dragScope$1;
+Landroidx/compose/foundation/gestures/DefaultDraggableState;
+Landroidx/compose/foundation/gestures/DragEvent$DragCancelled;
+Landroidx/compose/foundation/gestures/DragEvent$DragDelta;
+Landroidx/compose/foundation/gestures/DragEvent$DragStarted;
+Landroidx/compose/foundation/gestures/DragEvent$DragStopped;
+Landroidx/compose/foundation/gestures/DragEvent;
+Landroidx/compose/foundation/gestures/DragGestureDetectorKt;
+Landroidx/compose/foundation/gestures/DragLogic$processDragCancel$1;
+Landroidx/compose/foundation/gestures/DragLogic$processDragStart$1;
+Landroidx/compose/foundation/gestures/DragLogic$processDragStop$1;
+Landroidx/compose/foundation/gestures/DragLogic;
+Landroidx/compose/foundation/gestures/DragScope;
+Landroidx/compose/foundation/gestures/DraggableKt$awaitDownAndSlop$1;
+Landroidx/compose/foundation/gestures/DraggableKt$awaitDownAndSlop$postPointerSlop$1;
+Landroidx/compose/foundation/gestures/DraggableKt$awaitDrag$dragTick$1;
+Landroidx/compose/foundation/gestures/DraggableKt$draggable$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/gestures/DraggableKt$draggable$1;
+Landroidx/compose/foundation/gestures/DraggableKt$draggable$2;
+Landroidx/compose/foundation/gestures/DraggableKt$draggable$3;
+Landroidx/compose/foundation/gestures/DraggableKt$draggable$4;
+Landroidx/compose/foundation/gestures/DraggableKt$draggable$5;
+Landroidx/compose/foundation/gestures/DraggableKt$draggable$6;
+Landroidx/compose/foundation/gestures/DraggableKt$draggable$7;
+Landroidx/compose/foundation/gestures/DraggableKt$draggable$9$1$1$invoke$$inlined$onDispose$1;
+Landroidx/compose/foundation/gestures/DraggableKt$draggable$9$1$1;
+Landroidx/compose/foundation/gestures/DraggableKt$draggable$9$2$2;
+Landroidx/compose/foundation/gestures/DraggableKt$draggable$9$2;
+Landroidx/compose/foundation/gestures/DraggableKt$draggable$9$3$1$1;
+Landroidx/compose/foundation/gestures/DraggableKt$draggable$9$3$1;
+Landroidx/compose/foundation/gestures/DraggableKt$draggable$9$3;
+Landroidx/compose/foundation/gestures/DraggableKt$draggable$9;
+Landroidx/compose/foundation/gestures/DraggableKt$rememberDraggableState$1$1;
+Landroidx/compose/foundation/gestures/DraggableKt;
+Landroidx/compose/foundation/gestures/DraggableState;
+Landroidx/compose/foundation/gestures/ForEachGestureKt$awaitAllPointersUp$3;
+Landroidx/compose/foundation/gestures/ForEachGestureKt$awaitEachGesture$2;
+Landroidx/compose/foundation/gestures/ForEachGestureKt;
+Landroidx/compose/foundation/gestures/Orientation;
+Landroidx/compose/foundation/gestures/PointerDirectionConfig;
+Landroidx/compose/foundation/gestures/PressGestureScope;
+Landroidx/compose/foundation/gestures/PressGestureScopeImpl$reset$1;
+Landroidx/compose/foundation/gestures/PressGestureScopeImpl$tryAwaitRelease$1;
+Landroidx/compose/foundation/gestures/PressGestureScopeImpl;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$NoPressGesture$1;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$awaitFirstDown$2;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$awaitSecondDown$2;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$consumeUntilUp$1;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1$1;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1$2;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1$3;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1$4;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$10;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$1;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$2;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$3;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$4;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$5;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$6;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$7;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$8;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$9;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt$waitForUpOrCancellation$2;
+Landroidx/compose/foundation/gestures/TapGestureDetectorKt;
+Landroidx/compose/foundation/interaction/DragInteraction$Cancel;
+Landroidx/compose/foundation/interaction/DragInteraction$Start;
+Landroidx/compose/foundation/interaction/DragInteraction$Stop;
+Landroidx/compose/foundation/interaction/FocusInteraction$Focus;
+Landroidx/compose/foundation/interaction/FocusInteraction$Unfocus;
+Landroidx/compose/foundation/interaction/HoverInteraction$Enter;
+Landroidx/compose/foundation/interaction/HoverInteraction$Exit;
+Landroidx/compose/foundation/interaction/Interaction;
+Landroidx/compose/foundation/interaction/InteractionSource;
+Landroidx/compose/foundation/interaction/InteractionSourceKt;
+Landroidx/compose/foundation/interaction/MutableInteractionSource;
+Landroidx/compose/foundation/interaction/MutableInteractionSourceImpl;
+Landroidx/compose/foundation/interaction/PressInteraction$Cancel;
+Landroidx/compose/foundation/interaction/PressInteraction$Press;
+Landroidx/compose/foundation/interaction/PressInteraction$Release;
+Landroidx/compose/foundation/layout/Arrangement$Bottom$1;
+Landroidx/compose/foundation/layout/Arrangement$Center$1;
+Landroidx/compose/foundation/layout/Arrangement$End$1;
+Landroidx/compose/foundation/layout/Arrangement$Horizontal;
+Landroidx/compose/foundation/layout/Arrangement$HorizontalOrVertical;
+Landroidx/compose/foundation/layout/Arrangement$SpaceAround$1;
+Landroidx/compose/foundation/layout/Arrangement$SpaceBetween$1;
+Landroidx/compose/foundation/layout/Arrangement$SpaceEvenly$1;
+Landroidx/compose/foundation/layout/Arrangement$SpacedAligned;
+Landroidx/compose/foundation/layout/Arrangement$Start$1;
+Landroidx/compose/foundation/layout/Arrangement$Top$1;
+Landroidx/compose/foundation/layout/Arrangement$Vertical;
+Landroidx/compose/foundation/layout/Arrangement$spacedBy$1;
+Landroidx/compose/foundation/layout/Arrangement;
+Landroidx/compose/foundation/layout/BoxChildData;
+Landroidx/compose/foundation/layout/BoxKt$Box$3;
+Landroidx/compose/foundation/layout/BoxKt$EmptyBoxMeasurePolicy$1$measure$1;
+Landroidx/compose/foundation/layout/BoxKt$EmptyBoxMeasurePolicy$1;
+Landroidx/compose/foundation/layout/BoxKt$boxMeasurePolicy$1$measure$1;
+Landroidx/compose/foundation/layout/BoxKt$boxMeasurePolicy$1$measure$2;
+Landroidx/compose/foundation/layout/BoxKt$boxMeasurePolicy$1$measure$5;
+Landroidx/compose/foundation/layout/BoxKt$boxMeasurePolicy$1;
+Landroidx/compose/foundation/layout/BoxKt;
+Landroidx/compose/foundation/layout/BoxScopeInstance;
+Landroidx/compose/foundation/layout/BoxWithConstraintsKt$BoxWithConstraints$1$1$measurables$1;
+Landroidx/compose/foundation/layout/BoxWithConstraintsKt$BoxWithConstraints$1$1;
+Landroidx/compose/foundation/layout/BoxWithConstraintsKt$BoxWithConstraints$2;
+Landroidx/compose/foundation/layout/BoxWithConstraintsKt;
+Landroidx/compose/foundation/layout/BoxWithConstraintsScope;
+Landroidx/compose/foundation/layout/BoxWithConstraintsScopeImpl;
+Landroidx/compose/foundation/layout/ColumnKt$DefaultColumnMeasurePolicy$1;
+Landroidx/compose/foundation/layout/ColumnKt$columnMeasurePolicy$1$1;
+Landroidx/compose/foundation/layout/ColumnKt;
+Landroidx/compose/foundation/layout/ColumnScope;
+Landroidx/compose/foundation/layout/ColumnScopeInstance$align$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/layout/ColumnScopeInstance;
+Landroidx/compose/foundation/layout/CrossAxisAlignment$CenterCrossAxisAlignment;
+Landroidx/compose/foundation/layout/CrossAxisAlignment$Companion;
+Landroidx/compose/foundation/layout/CrossAxisAlignment$EndCrossAxisAlignment;
+Landroidx/compose/foundation/layout/CrossAxisAlignment$HorizontalCrossAxisAlignment;
+Landroidx/compose/foundation/layout/CrossAxisAlignment$StartCrossAxisAlignment;
+Landroidx/compose/foundation/layout/CrossAxisAlignment$VerticalCrossAxisAlignment;
+Landroidx/compose/foundation/layout/CrossAxisAlignment;
+Landroidx/compose/foundation/layout/Direction;
+Landroidx/compose/foundation/layout/FillModifier$measure$1;
+Landroidx/compose/foundation/layout/FillModifier;
+Landroidx/compose/foundation/layout/HorizontalAlignModifier;
+Landroidx/compose/foundation/layout/LayoutOrientation;
+Landroidx/compose/foundation/layout/OffsetKt$offset$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/layout/OffsetKt;
+Landroidx/compose/foundation/layout/OffsetPxModifier$measure$1;
+Landroidx/compose/foundation/layout/OffsetPxModifier;
+Landroidx/compose/foundation/layout/OrientationIndependentConstraints;
+Landroidx/compose/foundation/layout/PaddingKt$padding$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/layout/PaddingKt$padding-3ABfNKs$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/layout/PaddingKt$padding-VpY3zN4$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/layout/PaddingKt$padding-qDBjuR0$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/layout/PaddingKt;
+Landroidx/compose/foundation/layout/PaddingModifier$measure$1;
+Landroidx/compose/foundation/layout/PaddingModifier;
+Landroidx/compose/foundation/layout/PaddingValues;
+Landroidx/compose/foundation/layout/PaddingValuesImpl;
+Landroidx/compose/foundation/layout/PaddingValuesModifier$measure$2;
+Landroidx/compose/foundation/layout/PaddingValuesModifier;
+Landroidx/compose/foundation/layout/RowColumnImplKt$rowColumnMeasurePolicy$1$measure$4;
+Landroidx/compose/foundation/layout/RowColumnImplKt$rowColumnMeasurePolicy$1;
+Landroidx/compose/foundation/layout/RowColumnImplKt;
+Landroidx/compose/foundation/layout/RowColumnParentData;
+Landroidx/compose/foundation/layout/RowKt$DefaultRowMeasurePolicy$1;
+Landroidx/compose/foundation/layout/RowKt$rowMeasurePolicy$1$1;
+Landroidx/compose/foundation/layout/RowKt;
+Landroidx/compose/foundation/layout/RowScope;
+Landroidx/compose/foundation/layout/RowScopeInstance$align$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/layout/RowScopeInstance;
+Landroidx/compose/foundation/layout/SizeKt$createFillHeightModifier$1;
+Landroidx/compose/foundation/layout/SizeKt$createFillSizeModifier$1;
+Landroidx/compose/foundation/layout/SizeKt$createFillWidthModifier$1;
+Landroidx/compose/foundation/layout/SizeKt$createWrapContentHeightModifier$1;
+Landroidx/compose/foundation/layout/SizeKt$createWrapContentHeightModifier$2;
+Landroidx/compose/foundation/layout/SizeKt$createWrapContentSizeModifier$1;
+Landroidx/compose/foundation/layout/SizeKt$createWrapContentSizeModifier$2;
+Landroidx/compose/foundation/layout/SizeKt$createWrapContentWidthModifier$1;
+Landroidx/compose/foundation/layout/SizeKt$createWrapContentWidthModifier$2;
+Landroidx/compose/foundation/layout/SizeKt$defaultMinSize-VpY3zN4$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/layout/SizeKt$height-3ABfNKs$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/layout/SizeKt$heightIn-VpY3zN4$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/layout/SizeKt$size-3ABfNKs$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/layout/SizeKt$size-VpY3zN4$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/layout/SizeKt$sizeIn-qDBjuR0$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/layout/SizeKt$width-3ABfNKs$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/layout/SizeKt$widthIn-VpY3zN4$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/layout/SizeKt;
+Landroidx/compose/foundation/layout/SizeMode;
+Landroidx/compose/foundation/layout/SizeModifier$measure$1;
+Landroidx/compose/foundation/layout/SizeModifier;
+Landroidx/compose/foundation/layout/SpacerKt;
+Landroidx/compose/foundation/layout/SpacerMeasurePolicy$measure$1$1;
+Landroidx/compose/foundation/layout/SpacerMeasurePolicy;
+Landroidx/compose/foundation/layout/UnspecifiedConstraintsModifier$measure$1;
+Landroidx/compose/foundation/layout/UnspecifiedConstraintsModifier;
+Landroidx/compose/foundation/layout/VerticalAlignModifier;
+Landroidx/compose/foundation/layout/WrapContentModifier$measure$1;
+Landroidx/compose/foundation/layout/WrapContentModifier;
+Landroidx/compose/foundation/lazy/layout/PinnableParent;
+Landroidx/compose/foundation/lazy/layout/PinnableParentKt$ModifierLocalPinnableParent$1;
+Landroidx/compose/foundation/lazy/layout/PinnableParentKt;
+Landroidx/compose/foundation/relocation/AndroidBringIntoViewParent;
+Landroidx/compose/foundation/relocation/BringIntoViewChildModifier;
+Landroidx/compose/foundation/relocation/BringIntoViewKt$ModifierLocalBringIntoViewParent$1;
+Landroidx/compose/foundation/relocation/BringIntoViewKt;
+Landroidx/compose/foundation/relocation/BringIntoViewParent;
+Landroidx/compose/foundation/relocation/BringIntoViewRequester;
+Landroidx/compose/foundation/relocation/BringIntoViewRequesterImpl$bringIntoView$1;
+Landroidx/compose/foundation/relocation/BringIntoViewRequesterImpl;
+Landroidx/compose/foundation/relocation/BringIntoViewRequesterKt$bringIntoViewRequester$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/relocation/BringIntoViewRequesterKt$bringIntoViewRequester$2$1$invoke$$inlined$onDispose$1;
+Landroidx/compose/foundation/relocation/BringIntoViewRequesterKt$bringIntoViewRequester$2$1;
+Landroidx/compose/foundation/relocation/BringIntoViewRequesterKt$bringIntoViewRequester$2;
+Landroidx/compose/foundation/relocation/BringIntoViewRequesterKt;
+Landroidx/compose/foundation/relocation/BringIntoViewRequesterModifier$bringIntoView$2;
+Landroidx/compose/foundation/relocation/BringIntoViewRequesterModifier;
+Landroidx/compose/foundation/relocation/BringIntoViewResponder_androidKt;
+Landroidx/compose/foundation/shape/CornerBasedShape;
+Landroidx/compose/foundation/shape/CornerSize;
+Landroidx/compose/foundation/shape/CornerSizeKt$ZeroCornerSize$1;
+Landroidx/compose/foundation/shape/CornerSizeKt;
+Landroidx/compose/foundation/shape/DpCornerSize;
+Landroidx/compose/foundation/shape/PercentCornerSize;
+Landroidx/compose/foundation/shape/RoundedCornerShape;
+Landroidx/compose/foundation/shape/RoundedCornerShapeKt;
+Landroidx/compose/foundation/text/BasicTextKt$BasicText$1;
+Landroidx/compose/foundation/text/BasicTextKt$BasicText$2;
+Landroidx/compose/foundation/text/BasicTextKt$BasicText-4YKlhWE$$inlined$Layout$1;
+Landroidx/compose/foundation/text/BasicTextKt;
+Landroidx/compose/foundation/text/CoreTextKt;
+Landroidx/compose/foundation/text/HeightInLinesModifierKt$heightInLines$$inlined$debugInspectorInfo$1;
+Landroidx/compose/foundation/text/HeightInLinesModifierKt$heightInLines$2;
+Landroidx/compose/foundation/text/HeightInLinesModifierKt;
+Landroidx/compose/foundation/text/TextController$coreModifiers$1;
+Landroidx/compose/foundation/text/TextController$createSemanticsModifierFor$1$1;
+Landroidx/compose/foundation/text/TextController$createSemanticsModifierFor$1;
+Landroidx/compose/foundation/text/TextController$drawTextAndSelectionBehind$1;
+Landroidx/compose/foundation/text/TextController$measurePolicy$1$measure$2;
+Landroidx/compose/foundation/text/TextController$measurePolicy$1;
+Landroidx/compose/foundation/text/TextController$update$1;
+Landroidx/compose/foundation/text/TextController$update$2;
+Landroidx/compose/foundation/text/TextController$update$3;
+Landroidx/compose/foundation/text/TextController$update$mouseSelectionObserver$1;
+Landroidx/compose/foundation/text/TextController;
+Landroidx/compose/foundation/text/TextDelegate$Companion;
+Landroidx/compose/foundation/text/TextDelegate;
+Landroidx/compose/foundation/text/TextDelegateKt;
+Landroidx/compose/foundation/text/TextDragObserver;
+Landroidx/compose/foundation/text/TextFieldDelegateKt;
+Landroidx/compose/foundation/text/TextLayoutHelperKt;
+Landroidx/compose/foundation/text/TextPointerIcon_androidKt;
+Landroidx/compose/foundation/text/TextState$onTextLayout$1;
+Landroidx/compose/foundation/text/TextState;
+Landroidx/compose/foundation/text/TouchMode_androidKt;
+Landroidx/compose/foundation/text/selection/MouseSelectionObserver;
+Landroidx/compose/foundation/text/selection/Selectable;
+Landroidx/compose/foundation/text/selection/SelectionRegistrar;
+Landroidx/compose/foundation/text/selection/SelectionRegistrarKt$LocalSelectionRegistrar$1;
+Landroidx/compose/foundation/text/selection/SelectionRegistrarKt;
+Landroidx/compose/foundation/text/selection/TextSelectionColors;
+Landroidx/compose/foundation/text/selection/TextSelectionColorsKt$LocalTextSelectionColors$1;
+Landroidx/compose/foundation/text/selection/TextSelectionColorsKt;
+Landroidx/compose/material/icons/Icons$Filled;
+Landroidx/compose/material/icons/filled/AddKt;
+Landroidx/compose/material/icons/filled/ArrowBackKt;
+Landroidx/compose/material/ripple/AndroidRippleIndicationInstance$onInvalidateRipple$1;
+Landroidx/compose/material/ripple/AndroidRippleIndicationInstance;
+Landroidx/compose/material/ripple/CommonRippleIndicationInstance;
+Landroidx/compose/material/ripple/DebugRippleTheme;
+Landroidx/compose/material/ripple/PlatformRipple;
+Landroidx/compose/material/ripple/Ripple$rememberUpdatedInstance$1$1;
+Landroidx/compose/material/ripple/Ripple$rememberUpdatedInstance$1;
+Landroidx/compose/material/ripple/Ripple;
+Landroidx/compose/material/ripple/RippleAlpha;
+Landroidx/compose/material/ripple/RippleAnimationKt;
+Landroidx/compose/material/ripple/RippleContainer;
+Landroidx/compose/material/ripple/RippleHostMap;
+Landroidx/compose/material/ripple/RippleHostView$$ExternalSyntheticLambda0;
+Landroidx/compose/material/ripple/RippleHostView$Companion;
+Landroidx/compose/material/ripple/RippleHostView;
+Landroidx/compose/material/ripple/RippleIndicationInstance;
+Landroidx/compose/material/ripple/RippleKt;
+Landroidx/compose/material/ripple/RippleTheme;
+Landroidx/compose/material/ripple/RippleThemeKt$LocalRippleTheme$1;
+Landroidx/compose/material/ripple/RippleThemeKt;
+Landroidx/compose/material/ripple/StateLayer$handleInteraction$1;
+Landroidx/compose/material/ripple/StateLayer$handleInteraction$2;
+Landroidx/compose/material/ripple/StateLayer;
+Landroidx/compose/material/ripple/UnprojectedRipple;
+Landroidx/compose/material3/ButtonColors;
+Landroidx/compose/material3/ButtonDefaults;
+Landroidx/compose/material3/ButtonElevation$animateElevation$1$1$1;
+Landroidx/compose/material3/ButtonElevation$animateElevation$1$1;
+Landroidx/compose/material3/ButtonElevation$animateElevation$2;
+Landroidx/compose/material3/ButtonElevation$animateElevation$3;
+Landroidx/compose/material3/ButtonElevation;
+Landroidx/compose/material3/ButtonKt$Button$2$1$1;
+Landroidx/compose/material3/ButtonKt$Button$2$1;
+Landroidx/compose/material3/ButtonKt$Button$2;
+Landroidx/compose/material3/ButtonKt$Button$3;
+Landroidx/compose/material3/ButtonKt$FilledTonalButton$2;
+Landroidx/compose/material3/ButtonKt$TextButton$2;
+Landroidx/compose/material3/ButtonKt;
+Landroidx/compose/material3/CardColors;
+Landroidx/compose/material3/CardDefaults;
+Landroidx/compose/material3/CardElevation$animateElevation$1$1;
+Landroidx/compose/material3/CardElevation$animateElevation$2;
+Landroidx/compose/material3/CardElevation;
+Landroidx/compose/material3/CardKt$Card$1;
+Landroidx/compose/material3/CardKt$Card$2;
+Landroidx/compose/material3/CardKt;
+Landroidx/compose/material3/ChipBorder;
+Landroidx/compose/material3/ChipColors;
+Landroidx/compose/material3/ChipElevation$animateElevation$1$1$1;
+Landroidx/compose/material3/ChipElevation$animateElevation$1$1;
+Landroidx/compose/material3/ChipElevation$animateElevation$2;
+Landroidx/compose/material3/ChipElevation$animateElevation$3;
+Landroidx/compose/material3/ChipElevation;
+Landroidx/compose/material3/ChipKt$Chip$1;
+Landroidx/compose/material3/ChipKt$Chip$2;
+Landroidx/compose/material3/ChipKt$ChipContent$1;
+Landroidx/compose/material3/ChipKt$ChipContent$2;
+Landroidx/compose/material3/ChipKt$SuggestionChip$2;
+Landroidx/compose/material3/ChipKt;
+Landroidx/compose/material3/ColorResourceHelper;
+Landroidx/compose/material3/ColorScheme;
+Landroidx/compose/material3/ColorSchemeKt$LocalColorScheme$1;
+Landroidx/compose/material3/ColorSchemeKt$WhenMappings;
+Landroidx/compose/material3/ColorSchemeKt;
+Landroidx/compose/material3/ContentColorKt$LocalContentColor$1;
+Landroidx/compose/material3/ContentColorKt;
+Landroidx/compose/material3/DividerDefaults;
+Landroidx/compose/material3/DividerKt$Divider$1;
+Landroidx/compose/material3/DividerKt;
+Landroidx/compose/material3/DynamicTonalPaletteKt;
+Landroidx/compose/material3/ElevationDefaults;
+Landroidx/compose/material3/ElevationKt;
+Landroidx/compose/material3/IconKt$Icon$1;
+Landroidx/compose/material3/IconKt$Icon$2;
+Landroidx/compose/material3/IconKt$Icon$3;
+Landroidx/compose/material3/IconKt$Icon$semantics$1$1;
+Landroidx/compose/material3/IconKt;
+Landroidx/compose/material3/MaterialRippleTheme;
+Landroidx/compose/material3/MaterialTheme;
+Landroidx/compose/material3/MaterialThemeKt$MaterialTheme$1;
+Landroidx/compose/material3/MaterialThemeKt$MaterialTheme$2;
+Landroidx/compose/material3/MaterialThemeKt;
+Landroidx/compose/material3/MinimumTouchTargetModifier$measure$1;
+Landroidx/compose/material3/MinimumTouchTargetModifier;
+Landroidx/compose/material3/ShapeDefaults;
+Landroidx/compose/material3/Shapes;
+Landroidx/compose/material3/ShapesKt$LocalShapes$1;
+Landroidx/compose/material3/ShapesKt$WhenMappings;
+Landroidx/compose/material3/ShapesKt;
+Landroidx/compose/material3/SuggestionChipDefaults;
+Landroidx/compose/material3/SurfaceKt$LocalAbsoluteTonalElevation$1;
+Landroidx/compose/material3/SurfaceKt$Surface$1$1;
+Landroidx/compose/material3/SurfaceKt$Surface$1$2;
+Landroidx/compose/material3/SurfaceKt$Surface$1;
+Landroidx/compose/material3/SurfaceKt$Surface$3;
+Landroidx/compose/material3/SurfaceKt;
+Landroidx/compose/material3/TextKt$LocalTextStyle$1;
+Landroidx/compose/material3/TextKt$ProvideTextStyle$1;
+Landroidx/compose/material3/TextKt$Text$1;
+Landroidx/compose/material3/TextKt$Text$2;
+Landroidx/compose/material3/TextKt;
+Landroidx/compose/material3/TonalPalette;
+Landroidx/compose/material3/TouchTargetKt$LocalMinimumTouchTargetEnforcement$1;
+Landroidx/compose/material3/TouchTargetKt$minimumTouchTargetSize$$inlined$debugInspectorInfo$1;
+Landroidx/compose/material3/TouchTargetKt$minimumTouchTargetSize$2;
+Landroidx/compose/material3/TouchTargetKt;
+Landroidx/compose/material3/Typography;
+Landroidx/compose/material3/TypographyKt$LocalTypography$1;
+Landroidx/compose/material3/TypographyKt$WhenMappings;
+Landroidx/compose/material3/TypographyKt;
+Landroidx/compose/material3/tokens/ColorDarkTokens;
+Landroidx/compose/material3/tokens/ColorLightTokens;
+Landroidx/compose/material3/tokens/ColorSchemeKeyTokens;
+Landroidx/compose/material3/tokens/ElevationTokens;
+Landroidx/compose/material3/tokens/FilledButtonTokens;
+Landroidx/compose/material3/tokens/FilledCardTokens;
+Landroidx/compose/material3/tokens/FilledTonalButtonTokens;
+Landroidx/compose/material3/tokens/IconButtonTokens;
+Landroidx/compose/material3/tokens/PaletteTokens;
+Landroidx/compose/material3/tokens/ShapeKeyTokens;
+Landroidx/compose/material3/tokens/ShapeTokens;
+Landroidx/compose/material3/tokens/SuggestionChipTokens;
+Landroidx/compose/material3/tokens/TextButtonTokens;
+Landroidx/compose/material3/tokens/TypeScaleTokens;
+Landroidx/compose/material3/tokens/TypefaceTokens;
+Landroidx/compose/material3/tokens/TypographyKeyTokens;
+Landroidx/compose/material3/tokens/TypographyTokens;
+Landroidx/compose/runtime/AbstractApplier;
+Landroidx/compose/runtime/ActualAndroid_androidKt$DefaultMonotonicFrameClock$2;
+Landroidx/compose/runtime/ActualAndroid_androidKt;
+Landroidx/compose/runtime/ActualJvm_jvmKt;
+Landroidx/compose/runtime/Anchor;
+Landroidx/compose/runtime/Applier;
+Landroidx/compose/runtime/BroadcastFrameClock$FrameAwaiter;
+Landroidx/compose/runtime/BroadcastFrameClock$withFrameNanos$2$1;
+Landroidx/compose/runtime/BroadcastFrameClock;
+Landroidx/compose/runtime/ComposableSingletons$CompositionKt$lambda-1$1;
+Landroidx/compose/runtime/ComposableSingletons$CompositionKt$lambda-2$1;
+Landroidx/compose/runtime/ComposableSingletons$CompositionKt;
+Landroidx/compose/runtime/ComposablesKt;
+Landroidx/compose/runtime/ComposeRuntimeError;
+Landroidx/compose/runtime/Composer$Companion$Empty$1;
+Landroidx/compose/runtime/Composer$Companion;
+Landroidx/compose/runtime/Composer;
+Landroidx/compose/runtime/ComposerImpl$CompositionContextHolder;
+Landroidx/compose/runtime/ComposerImpl$CompositionContextImpl;
+Landroidx/compose/runtime/ComposerImpl$apply$operation$1;
+Landroidx/compose/runtime/ComposerImpl$createNode$2;
+Landroidx/compose/runtime/ComposerImpl$createNode$3;
+Landroidx/compose/runtime/ComposerImpl$deactivateToEndGroup$2;
+Landroidx/compose/runtime/ComposerImpl$doCompose$2$3;
+Landroidx/compose/runtime/ComposerImpl$doCompose$2$4;
+Landroidx/compose/runtime/ComposerImpl$doCompose$2$5;
+Landroidx/compose/runtime/ComposerImpl$doCompose$lambda$37$$inlined$sortBy$1;
+Landroidx/compose/runtime/ComposerImpl$endRestartGroup$1$1;
+Landroidx/compose/runtime/ComposerImpl$insertMovableContentGuarded$1$1$1;
+Landroidx/compose/runtime/ComposerImpl$insertMovableContentGuarded$1$1$2$1;
+Landroidx/compose/runtime/ComposerImpl$insertMovableContentGuarded$1$1$2$2;
+Landroidx/compose/runtime/ComposerImpl$insertMovableContentGuarded$1$1$3;
+Landroidx/compose/runtime/ComposerImpl$insertMovableContentGuarded$1$1$4;
+Landroidx/compose/runtime/ComposerImpl$insertMovableContentGuarded$1$1$5$1$1$1;
+Landroidx/compose/runtime/ComposerImpl$insertMovableContentGuarded$1$1$5$1$2;
+Landroidx/compose/runtime/ComposerImpl$insertMovableContentGuarded$1$2;
+Landroidx/compose/runtime/ComposerImpl$invokeMovableContentLambda$1;
+Landroidx/compose/runtime/ComposerImpl$realizeDowns$1;
+Landroidx/compose/runtime/ComposerImpl$realizeMovement$1;
+Landroidx/compose/runtime/ComposerImpl$realizeMovement$2;
+Landroidx/compose/runtime/ComposerImpl$realizeOperationLocation$2;
+Landroidx/compose/runtime/ComposerImpl$realizeUps$1;
+Landroidx/compose/runtime/ComposerImpl$recordInsert$1;
+Landroidx/compose/runtime/ComposerImpl$recordInsert$2;
+Landroidx/compose/runtime/ComposerImpl$recordSideEffect$1;
+Landroidx/compose/runtime/ComposerImpl$recordSlotEditing$1;
+Landroidx/compose/runtime/ComposerImpl$start$2;
+Landroidx/compose/runtime/ComposerImpl$startProviders$currentProviders$1;
+Landroidx/compose/runtime/ComposerImpl$startReaderGroup$1;
+Landroidx/compose/runtime/ComposerImpl$updateValue$1;
+Landroidx/compose/runtime/ComposerImpl$updateValue$2;
+Landroidx/compose/runtime/ComposerImpl;
+Landroidx/compose/runtime/ComposerKt$endGroupInstance$1;
+Landroidx/compose/runtime/ComposerKt$removeCurrentGroupInstance$1;
+Landroidx/compose/runtime/ComposerKt$resetSlotsInstance$1;
+Landroidx/compose/runtime/ComposerKt$skipToGroupEndInstance$1;
+Landroidx/compose/runtime/ComposerKt$startRootGroup$1;
+Landroidx/compose/runtime/ComposerKt;
+Landroidx/compose/runtime/Composition;
+Landroidx/compose/runtime/CompositionContext;
+Landroidx/compose/runtime/CompositionContextKt;
+Landroidx/compose/runtime/CompositionImpl$RememberEventDispatcher;
+Landroidx/compose/runtime/CompositionImpl;
+Landroidx/compose/runtime/CompositionKt;
+Landroidx/compose/runtime/CompositionLocal;
+Landroidx/compose/runtime/CompositionLocalKt$CompositionLocalProvider$1;
+Landroidx/compose/runtime/CompositionLocalKt;
+Landroidx/compose/runtime/CompositionScopedCoroutineScopeCanceller;
+Landroidx/compose/runtime/ControlledComposition;
+Landroidx/compose/runtime/DefaultChoreographerFrameClock;
+Landroidx/compose/runtime/DerivedSnapshotState;
+Landroidx/compose/runtime/DerivedState;
+Landroidx/compose/runtime/DisposableEffectImpl;
+Landroidx/compose/runtime/DisposableEffectResult;
+Landroidx/compose/runtime/DisposableEffectScope;
+Landroidx/compose/runtime/DynamicProvidableCompositionLocal;
+Landroidx/compose/runtime/EffectsKt;
+Landroidx/compose/runtime/GroupInfo;
+Landroidx/compose/runtime/GroupIterator;
+Landroidx/compose/runtime/IntStack;
+Landroidx/compose/runtime/Invalidation;
+Landroidx/compose/runtime/InvalidationResult;
+Landroidx/compose/runtime/JoinedKey;
+Landroidx/compose/runtime/KeyInfo;
+Landroidx/compose/runtime/Latch$await$2$2;
+Landroidx/compose/runtime/Latch;
+Landroidx/compose/runtime/LaunchedEffectImpl;
+Landroidx/compose/runtime/LazyValueHolder;
+Landroidx/compose/runtime/MonotonicFrameClock$DefaultImpls;
+Landroidx/compose/runtime/MonotonicFrameClock$Key;
+Landroidx/compose/runtime/MonotonicFrameClock;
+Landroidx/compose/runtime/MonotonicFrameClockKt;
+Landroidx/compose/runtime/MovableContent;
+Landroidx/compose/runtime/MovableContentState;
+Landroidx/compose/runtime/MovableContentStateReference;
+Landroidx/compose/runtime/MutableState;
+Landroidx/compose/runtime/NeverEqualPolicy;
+Landroidx/compose/runtime/OpaqueKey;
+Landroidx/compose/runtime/ParcelableSnapshotMutableState$Companion$CREATOR$1;
+Landroidx/compose/runtime/ParcelableSnapshotMutableState$Companion;
+Landroidx/compose/runtime/ParcelableSnapshotMutableState;
+Landroidx/compose/runtime/PausableMonotonicFrameClock$withFrameNanos$1;
+Landroidx/compose/runtime/PausableMonotonicFrameClock;
+Landroidx/compose/runtime/Pending$keyMap$2;
+Landroidx/compose/runtime/Pending;
+Landroidx/compose/runtime/PrioritySet;
+Landroidx/compose/runtime/ProvidableCompositionLocal;
+Landroidx/compose/runtime/ProvidedValue;
+Landroidx/compose/runtime/RecomposeScope;
+Landroidx/compose/runtime/RecomposeScopeImpl$end$1$2;
+Landroidx/compose/runtime/RecomposeScopeImpl;
+Landroidx/compose/runtime/RecomposeScopeImplKt;
+Landroidx/compose/runtime/Recomposer$Companion;
+Landroidx/compose/runtime/Recomposer$RecomposerErrorState;
+Landroidx/compose/runtime/Recomposer$RecomposerInfoImpl;
+Landroidx/compose/runtime/Recomposer$State;
+Landroidx/compose/runtime/Recomposer$broadcastFrameClock$1;
+Landroidx/compose/runtime/Recomposer$effectJob$1$1$1$1;
+Landroidx/compose/runtime/Recomposer$effectJob$1$1;
+Landroidx/compose/runtime/Recomposer$join$2;
+Landroidx/compose/runtime/Recomposer$performRecompose$1$1;
+Landroidx/compose/runtime/Recomposer$readObserverOf$1;
+Landroidx/compose/runtime/Recomposer$recompositionRunner$2$2;
+Landroidx/compose/runtime/Recomposer$recompositionRunner$2$unregisterApplyObserver$1;
+Landroidx/compose/runtime/Recomposer$recompositionRunner$2;
+Landroidx/compose/runtime/Recomposer$runRecomposeAndApplyChanges$2$2;
+Landroidx/compose/runtime/Recomposer$runRecomposeAndApplyChanges$2;
+Landroidx/compose/runtime/Recomposer$writeObserverOf$1;
+Landroidx/compose/runtime/Recomposer;
+Landroidx/compose/runtime/RecomposerKt;
+Landroidx/compose/runtime/ReferentialEqualityPolicy;
+Landroidx/compose/runtime/RememberManager;
+Landroidx/compose/runtime/RememberObserver;
+Landroidx/compose/runtime/ScopeUpdateScope;
+Landroidx/compose/runtime/SdkStubsFallbackFrameClock;
+Landroidx/compose/runtime/SkippableUpdater;
+Landroidx/compose/runtime/SlotReader;
+Landroidx/compose/runtime/SlotTable;
+Landroidx/compose/runtime/SlotTableKt;
+Landroidx/compose/runtime/SlotWriter$Companion;
+Landroidx/compose/runtime/SlotWriter$groupSlots$1;
+Landroidx/compose/runtime/SlotWriter;
+Landroidx/compose/runtime/SnapshotMutableStateImpl$StateStateRecord;
+Landroidx/compose/runtime/SnapshotMutableStateImpl;
+Landroidx/compose/runtime/SnapshotMutationPolicy;
+Landroidx/compose/runtime/SnapshotStateKt;
+Landroidx/compose/runtime/SnapshotStateKt__DerivedStateKt;
+Landroidx/compose/runtime/SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1$readObserver$1;
+Landroidx/compose/runtime/SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1$unregisterApplyObserver$1;
+Landroidx/compose/runtime/SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1;
+Landroidx/compose/runtime/SnapshotStateKt__SnapshotFlowKt;
+Landroidx/compose/runtime/SnapshotStateKt__SnapshotMutationPolicyKt;
+Landroidx/compose/runtime/SnapshotStateKt__SnapshotStateKt;
+Landroidx/compose/runtime/SnapshotThreadLocal;
+Landroidx/compose/runtime/Stack;
+Landroidx/compose/runtime/State;
+Landroidx/compose/runtime/StaticProvidableCompositionLocal;
+Landroidx/compose/runtime/StaticValueHolder;
+Landroidx/compose/runtime/StructuralEqualityPolicy;
+Landroidx/compose/runtime/Trace;
+Landroidx/compose/runtime/Updater;
+Landroidx/compose/runtime/collection/IdentityArrayIntMap;
+Landroidx/compose/runtime/collection/IdentityArrayMap;
+Landroidx/compose/runtime/collection/IdentityArraySet$iterator$1;
+Landroidx/compose/runtime/collection/IdentityArraySet;
+Landroidx/compose/runtime/collection/IdentityScopeMap;
+Landroidx/compose/runtime/collection/MutableVector$MutableVectorList;
+Landroidx/compose/runtime/collection/MutableVector$SubList;
+Landroidx/compose/runtime/collection/MutableVector$VectorListIterator;
+Landroidx/compose/runtime/collection/MutableVector;
+Landroidx/compose/runtime/collection/MutableVectorKt;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/ExtensionsKt;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/ImmutableCollection;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/ImmutableList$SubList;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/ImmutableList;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/ImmutableSet;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentList$Builder;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentList;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap$Builder;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentMap;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentSet;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/AbstractListIterator;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/AbstractPersistentList$removeAll$1;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/AbstractPersistentList;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/BufferIterator;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/PersistentVector;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/PersistentVectorBuilder;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/SmallPersistentVector$Companion;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/SmallPersistentVector;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/UtilsKt;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/AbstractMapBuilderEntries;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/MapEntry;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap$Companion;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBaseIterator;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilder;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilderEntries;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilderKeys;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapBuilderValues;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapEntries;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapEntriesIterator;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapKeys;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapValues;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode$Companion;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode$ModificationResult;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeBaseIterator;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeEntriesIterator;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeKt;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/Links;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/PersistentOrderedSet$Companion;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/PersistentOrderedSet;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/PersistentOrderedSetIterator;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/internal/CommonFunctionsKt;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/internal/DeltaCounter;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/internal/EndOfChain;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/internal/ListImplementation;
+Landroidx/compose/runtime/external/kotlinx/collections/immutable/internal/MutabilityOwnership;
+Landroidx/compose/runtime/internal/ComposableLambda;
+Landroidx/compose/runtime/internal/ComposableLambdaImpl$invoke$1;
+Landroidx/compose/runtime/internal/ComposableLambdaImpl$invoke$2;
+Landroidx/compose/runtime/internal/ComposableLambdaImpl$invoke$3;
+Landroidx/compose/runtime/internal/ComposableLambdaImpl;
+Landroidx/compose/runtime/internal/ComposableLambdaKt;
+Landroidx/compose/runtime/internal/ThreadMap;
+Landroidx/compose/runtime/internal/ThreadMapKt;
+Landroidx/compose/runtime/saveable/RememberSaveableKt$rememberSaveable$1$invoke$$inlined$onDispose$1;
+Landroidx/compose/runtime/saveable/RememberSaveableKt$rememberSaveable$1$valueProvider$1$1$1;
+Landroidx/compose/runtime/saveable/RememberSaveableKt$rememberSaveable$1$valueProvider$1;
+Landroidx/compose/runtime/saveable/RememberSaveableKt$rememberSaveable$1;
+Landroidx/compose/runtime/saveable/RememberSaveableKt;
+Landroidx/compose/runtime/saveable/SaveableStateRegistry$Entry;
+Landroidx/compose/runtime/saveable/SaveableStateRegistry;
+Landroidx/compose/runtime/saveable/SaveableStateRegistryImpl$registerProvider$3;
+Landroidx/compose/runtime/saveable/SaveableStateRegistryImpl;
+Landroidx/compose/runtime/saveable/SaveableStateRegistryKt$LocalSaveableStateRegistry$1;
+Landroidx/compose/runtime/saveable/SaveableStateRegistryKt;
+Landroidx/compose/runtime/saveable/Saver;
+Landroidx/compose/runtime/saveable/SaverKt$AutoSaver$1;
+Landroidx/compose/runtime/saveable/SaverKt$AutoSaver$2;
+Landroidx/compose/runtime/saveable/SaverKt$Saver$1;
+Landroidx/compose/runtime/saveable/SaverKt;
+Landroidx/compose/runtime/saveable/SaverScope;
+Landroidx/compose/runtime/snapshots/GlobalSnapshot$1$1$1;
+Landroidx/compose/runtime/snapshots/GlobalSnapshot$takeNestedMutableSnapshot$1;
+Landroidx/compose/runtime/snapshots/GlobalSnapshot$takeNestedSnapshot$1;
+Landroidx/compose/runtime/snapshots/GlobalSnapshot;
+Landroidx/compose/runtime/snapshots/ListUtilsKt;
+Landroidx/compose/runtime/snapshots/MutableSnapshot;
+Landroidx/compose/runtime/snapshots/NestedMutableSnapshot;
+Landroidx/compose/runtime/snapshots/NestedReadonlySnapshot;
+Landroidx/compose/runtime/snapshots/ObserverHandle;
+Landroidx/compose/runtime/snapshots/Snapshot$Companion$registerApplyObserver$2;
+Landroidx/compose/runtime/snapshots/Snapshot$Companion$registerGlobalWriteObserver$2;
+Landroidx/compose/runtime/snapshots/Snapshot$Companion;
+Landroidx/compose/runtime/snapshots/Snapshot;
+Landroidx/compose/runtime/snapshots/SnapshotApplyResult$Failure;
+Landroidx/compose/runtime/snapshots/SnapshotApplyResult$Success;
+Landroidx/compose/runtime/snapshots/SnapshotApplyResult;
+Landroidx/compose/runtime/snapshots/SnapshotDoubleIndexHeap;
+Landroidx/compose/runtime/snapshots/SnapshotIdSet$Companion;
+Landroidx/compose/runtime/snapshots/SnapshotIdSet$iterator$1;
+Landroidx/compose/runtime/snapshots/SnapshotIdSet;
+Landroidx/compose/runtime/snapshots/SnapshotIdSetKt;
+Landroidx/compose/runtime/snapshots/SnapshotKt$advanceGlobalSnapshot$2;
+Landroidx/compose/runtime/snapshots/SnapshotKt$emptyLambda$1;
+Landroidx/compose/runtime/snapshots/SnapshotKt$mergedReadObserver$1;
+Landroidx/compose/runtime/snapshots/SnapshotKt$mergedWriteObserver$1;
+Landroidx/compose/runtime/snapshots/SnapshotKt$takeNewSnapshot$1;
+Landroidx/compose/runtime/snapshots/SnapshotKt;
+Landroidx/compose/runtime/snapshots/SnapshotMutableState;
+Landroidx/compose/runtime/snapshots/SnapshotStateList$StateListStateRecord;
+Landroidx/compose/runtime/snapshots/SnapshotStateList$addAll$1;
+Landroidx/compose/runtime/snapshots/SnapshotStateList$retainAll$1;
+Landroidx/compose/runtime/snapshots/SnapshotStateList;
+Landroidx/compose/runtime/snapshots/SnapshotStateListKt;
+Landroidx/compose/runtime/snapshots/SnapshotStateMap;
+Landroidx/compose/runtime/snapshots/SnapshotStateMapKt;
+Landroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap$derivedStateEnterObserver$1;
+Landroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap$derivedStateExitObserver$1;
+Landroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;
+Landroidx/compose/runtime/snapshots/SnapshotStateObserver$applyObserver$1$2;
+Landroidx/compose/runtime/snapshots/SnapshotStateObserver$applyObserver$1;
+Landroidx/compose/runtime/snapshots/SnapshotStateObserver$observeReads$1$1;
+Landroidx/compose/runtime/snapshots/SnapshotStateObserver$readObserver$1;
+Landroidx/compose/runtime/snapshots/SnapshotStateObserver;
+Landroidx/compose/runtime/snapshots/StateListIterator;
+Landroidx/compose/runtime/snapshots/StateObject;
+Landroidx/compose/runtime/snapshots/StateRecord;
+Landroidx/compose/runtime/snapshots/SubList;
+Landroidx/compose/runtime/snapshots/TransparentObserverMutableSnapshot;
+Landroidx/compose/runtime/snapshots/TransparentObserverSnapshot;
+Landroidx/compose/runtime/tooling/CompositionData;
+Landroidx/compose/runtime/tooling/InspectionTablesKt$LocalInspectionTables$1;
+Landroidx/compose/runtime/tooling/InspectionTablesKt;
+Landroidx/compose/ui/ActualKt;
+Landroidx/compose/ui/Alignment$Companion;
+Landroidx/compose/ui/Alignment$Horizontal;
+Landroidx/compose/ui/Alignment$Vertical;
+Landroidx/compose/ui/Alignment;
+Landroidx/compose/ui/BiasAlignment$Horizontal;
+Landroidx/compose/ui/BiasAlignment$Vertical;
+Landroidx/compose/ui/BiasAlignment;
+Landroidx/compose/ui/CombinedModifier$toString$1;
+Landroidx/compose/ui/CombinedModifier;
+Landroidx/compose/ui/ComposedModifier;
+Landroidx/compose/ui/ComposedModifierKt$WrapFocusEventModifier$1$1$1;
+Landroidx/compose/ui/ComposedModifierKt$WrapFocusEventModifier$1$modifier$1$1;
+Landroidx/compose/ui/ComposedModifierKt$WrapFocusEventModifier$1;
+Landroidx/compose/ui/ComposedModifierKt$WrapFocusRequesterModifier$1;
+Landroidx/compose/ui/ComposedModifierKt$materialize$1;
+Landroidx/compose/ui/ComposedModifierKt$materialize$result$1;
+Landroidx/compose/ui/ComposedModifierKt;
+Landroidx/compose/ui/Modifier$Companion;
+Landroidx/compose/ui/Modifier$Element;
+Landroidx/compose/ui/Modifier$Node;
+Landroidx/compose/ui/Modifier;
+Landroidx/compose/ui/MotionDurationScale$DefaultImpls;
+Landroidx/compose/ui/MotionDurationScale$Key;
+Landroidx/compose/ui/MotionDurationScale;
+Landroidx/compose/ui/R$id;
+Landroidx/compose/ui/R$string;
+Landroidx/compose/ui/TempListUtilsKt;
+Landroidx/compose/ui/autofill/AndroidAutofill;
+Landroidx/compose/ui/autofill/AndroidAutofill_androidKt;
+Landroidx/compose/ui/autofill/Autofill;
+Landroidx/compose/ui/autofill/AutofillCallback;
+Landroidx/compose/ui/autofill/AutofillTree;
+Landroidx/compose/ui/draw/BuildDrawCacheParams;
+Landroidx/compose/ui/draw/ClipKt;
+Landroidx/compose/ui/draw/DrawBackgroundModifier;
+Landroidx/compose/ui/draw/DrawCacheModifier;
+Landroidx/compose/ui/draw/DrawModifier;
+Landroidx/compose/ui/draw/DrawModifierKt$drawBehind$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/draw/DrawModifierKt$drawWithCache$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/draw/DrawModifierKt$drawWithCache$2;
+Landroidx/compose/ui/draw/DrawModifierKt;
+Landroidx/compose/ui/draw/PainterModifier$measure$1;
+Landroidx/compose/ui/draw/PainterModifier;
+Landroidx/compose/ui/draw/PainterModifierKt$paint$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/draw/PainterModifierKt;
+Landroidx/compose/ui/draw/ShadowKt$shadow$2$1;
+Landroidx/compose/ui/draw/ShadowKt$shadow-s4CzXII$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/draw/ShadowKt;
+Landroidx/compose/ui/focus/FocusChangedModifierKt$onFocusChanged$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/focus/FocusChangedModifierKt$onFocusChanged$2$1$1;
+Landroidx/compose/ui/focus/FocusChangedModifierKt$onFocusChanged$2;
+Landroidx/compose/ui/focus/FocusChangedModifierKt;
+Landroidx/compose/ui/focus/FocusDirection$Companion;
+Landroidx/compose/ui/focus/FocusDirection;
+Landroidx/compose/ui/focus/FocusEventModifier;
+Landroidx/compose/ui/focus/FocusEventModifierKt$ModifierLocalFocusEvent$1;
+Landroidx/compose/ui/focus/FocusEventModifierKt$onFocusEvent$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/focus/FocusEventModifierKt$onFocusEvent$2$1$1;
+Landroidx/compose/ui/focus/FocusEventModifierKt$onFocusEvent$2;
+Landroidx/compose/ui/focus/FocusEventModifierKt;
+Landroidx/compose/ui/focus/FocusEventModifierLocal$WhenMappings;
+Landroidx/compose/ui/focus/FocusEventModifierLocal;
+Landroidx/compose/ui/focus/FocusManager;
+Landroidx/compose/ui/focus/FocusManagerImpl$WhenMappings;
+Landroidx/compose/ui/focus/FocusManagerImpl$moveFocus$foundNextItem$1;
+Landroidx/compose/ui/focus/FocusManagerImpl;
+Landroidx/compose/ui/focus/FocusManagerKt$WhenMappings;
+Landroidx/compose/ui/focus/FocusManagerKt;
+Landroidx/compose/ui/focus/FocusModifier$Companion$RefreshFocusProperties$1;
+Landroidx/compose/ui/focus/FocusModifier$Companion;
+Landroidx/compose/ui/focus/FocusModifier$WhenMappings;
+Landroidx/compose/ui/focus/FocusModifier;
+Landroidx/compose/ui/focus/FocusModifierKt$ModifierLocalParentFocusModifier$1;
+Landroidx/compose/ui/focus/FocusModifierKt$ResetFocusModifierLocals$1;
+Landroidx/compose/ui/focus/FocusModifierKt$ResetFocusModifierLocals$2;
+Landroidx/compose/ui/focus/FocusModifierKt$ResetFocusModifierLocals$3;
+Landroidx/compose/ui/focus/FocusModifierKt$focusTarget$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/focus/FocusModifierKt$focusTarget$2$1$1;
+Landroidx/compose/ui/focus/FocusModifierKt$focusTarget$2;
+Landroidx/compose/ui/focus/FocusModifierKt;
+Landroidx/compose/ui/focus/FocusOrderModifierKt;
+Landroidx/compose/ui/focus/FocusProperties;
+Landroidx/compose/ui/focus/FocusPropertiesImpl$enter$1;
+Landroidx/compose/ui/focus/FocusPropertiesImpl$exit$1;
+Landroidx/compose/ui/focus/FocusPropertiesImpl;
+Landroidx/compose/ui/focus/FocusPropertiesKt$ModifierLocalFocusProperties$1;
+Landroidx/compose/ui/focus/FocusPropertiesKt$clear$1;
+Landroidx/compose/ui/focus/FocusPropertiesKt$clear$2;
+Landroidx/compose/ui/focus/FocusPropertiesKt$focusProperties$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/focus/FocusPropertiesKt$refreshFocusProperties$1;
+Landroidx/compose/ui/focus/FocusPropertiesKt;
+Landroidx/compose/ui/focus/FocusPropertiesModifier;
+Landroidx/compose/ui/focus/FocusRequester$Companion;
+Landroidx/compose/ui/focus/FocusRequester$requestFocus$2;
+Landroidx/compose/ui/focus/FocusRequester;
+Landroidx/compose/ui/focus/FocusRequesterModifier;
+Landroidx/compose/ui/focus/FocusRequesterModifierKt$ModifierLocalFocusRequester$1;
+Landroidx/compose/ui/focus/FocusRequesterModifierKt$focusRequester$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/focus/FocusRequesterModifierKt$focusRequester$2;
+Landroidx/compose/ui/focus/FocusRequesterModifierKt;
+Landroidx/compose/ui/focus/FocusRequesterModifierLocal;
+Landroidx/compose/ui/focus/FocusState;
+Landroidx/compose/ui/focus/FocusStateImpl$WhenMappings;
+Landroidx/compose/ui/focus/FocusStateImpl;
+Landroidx/compose/ui/focus/FocusTransactionsKt$WhenMappings;
+Landroidx/compose/ui/focus/FocusTransactionsKt$requestFocus$1;
+Landroidx/compose/ui/focus/FocusTransactionsKt;
+Landroidx/compose/ui/focus/FocusTraversalKt;
+Landroidx/compose/ui/focus/TwoDimensionalFocusSearchKt;
+Landroidx/compose/ui/geometry/CornerRadius$Companion;
+Landroidx/compose/ui/geometry/CornerRadius;
+Landroidx/compose/ui/geometry/CornerRadiusKt;
+Landroidx/compose/ui/geometry/GeometryUtilsKt;
+Landroidx/compose/ui/geometry/MutableRect;
+Landroidx/compose/ui/geometry/MutableRectKt;
+Landroidx/compose/ui/geometry/Offset$Companion;
+Landroidx/compose/ui/geometry/Offset;
+Landroidx/compose/ui/geometry/OffsetKt;
+Landroidx/compose/ui/geometry/Rect$Companion;
+Landroidx/compose/ui/geometry/Rect;
+Landroidx/compose/ui/geometry/RectKt;
+Landroidx/compose/ui/geometry/RoundRect$Companion;
+Landroidx/compose/ui/geometry/RoundRect;
+Landroidx/compose/ui/geometry/RoundRectKt;
+Landroidx/compose/ui/geometry/Size$Companion;
+Landroidx/compose/ui/geometry/Size;
+Landroidx/compose/ui/geometry/SizeKt;
+Landroidx/compose/ui/graphics/AndroidBlendMode_androidKt;
+Landroidx/compose/ui/graphics/AndroidCanvas;
+Landroidx/compose/ui/graphics/AndroidCanvas_androidKt;
+Landroidx/compose/ui/graphics/AndroidColorFilter_androidKt;
+Landroidx/compose/ui/graphics/AndroidImageBitmap;
+Landroidx/compose/ui/graphics/AndroidImageBitmap_androidKt;
+Landroidx/compose/ui/graphics/AndroidMatrixConversions_androidKt;
+Landroidx/compose/ui/graphics/AndroidPaint;
+Landroidx/compose/ui/graphics/AndroidPaint_androidKt$WhenMappings;
+Landroidx/compose/ui/graphics/AndroidPaint_androidKt;
+Landroidx/compose/ui/graphics/AndroidPath;
+Landroidx/compose/ui/graphics/AndroidPath_androidKt;
+Landroidx/compose/ui/graphics/Api26Bitmap;
+Landroidx/compose/ui/graphics/BlendMode$Companion;
+Landroidx/compose/ui/graphics/BlendMode;
+Landroidx/compose/ui/graphics/BlendModeColorFilterHelper;
+Landroidx/compose/ui/graphics/BlockGraphicsLayerModifier$measure$1;
+Landroidx/compose/ui/graphics/BlockGraphicsLayerModifier;
+Landroidx/compose/ui/graphics/Brush;
+Landroidx/compose/ui/graphics/Canvas;
+Landroidx/compose/ui/graphics/CanvasHolder;
+Landroidx/compose/ui/graphics/CanvasUtils;
+Landroidx/compose/ui/graphics/CanvasZHelper;
+Landroidx/compose/ui/graphics/ClipOp$Companion;
+Landroidx/compose/ui/graphics/ClipOp;
+Landroidx/compose/ui/graphics/Color$Companion;
+Landroidx/compose/ui/graphics/Color;
+Landroidx/compose/ui/graphics/ColorFilter$Companion;
+Landroidx/compose/ui/graphics/ColorFilter;
+Landroidx/compose/ui/graphics/ColorKt;
+Landroidx/compose/ui/graphics/CompositingStrategy$Companion;
+Landroidx/compose/ui/graphics/CompositingStrategy;
+Landroidx/compose/ui/graphics/FilterQuality$Companion;
+Landroidx/compose/ui/graphics/FilterQuality;
+Landroidx/compose/ui/graphics/Float16$Companion;
+Landroidx/compose/ui/graphics/Float16;
+Landroidx/compose/ui/graphics/GraphicsLayerModifierKt$graphicsLayer$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/graphics/GraphicsLayerModifierKt$graphicsLayer-Ap8cVGQ$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/graphics/GraphicsLayerModifierKt;
+Landroidx/compose/ui/graphics/GraphicsLayerScope;
+Landroidx/compose/ui/graphics/GraphicsLayerScopeKt;
+Landroidx/compose/ui/graphics/ImageBitmap;
+Landroidx/compose/ui/graphics/ImageBitmapConfig$Companion;
+Landroidx/compose/ui/graphics/ImageBitmapConfig;
+Landroidx/compose/ui/graphics/Matrix$Companion;
+Landroidx/compose/ui/graphics/Matrix;
+Landroidx/compose/ui/graphics/MatrixKt;
+Landroidx/compose/ui/graphics/Outline$Rectangle;
+Landroidx/compose/ui/graphics/Outline$Rounded;
+Landroidx/compose/ui/graphics/Outline;
+Landroidx/compose/ui/graphics/OutlineKt;
+Landroidx/compose/ui/graphics/Paint;
+Landroidx/compose/ui/graphics/PaintingStyle$Companion;
+Landroidx/compose/ui/graphics/PaintingStyle;
+Landroidx/compose/ui/graphics/Path;
+Landroidx/compose/ui/graphics/PathEffect;
+Landroidx/compose/ui/graphics/PathFillType$Companion;
+Landroidx/compose/ui/graphics/PathFillType;
+Landroidx/compose/ui/graphics/PathOperation$Companion;
+Landroidx/compose/ui/graphics/PathOperation;
+Landroidx/compose/ui/graphics/RectHelper_androidKt;
+Landroidx/compose/ui/graphics/RectangleShapeKt$RectangleShape$1;
+Landroidx/compose/ui/graphics/RectangleShapeKt;
+Landroidx/compose/ui/graphics/RenderEffect;
+Landroidx/compose/ui/graphics/ReusableGraphicsLayerScope;
+Landroidx/compose/ui/graphics/ShaderBrush;
+Landroidx/compose/ui/graphics/Shadow$Companion;
+Landroidx/compose/ui/graphics/Shadow;
+Landroidx/compose/ui/graphics/Shape;
+Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier$layerBlock$1;
+Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier$measure$1;
+Landroidx/compose/ui/graphics/SimpleGraphicsLayerModifier;
+Landroidx/compose/ui/graphics/SolidColor;
+Landroidx/compose/ui/graphics/StrokeCap$Companion;
+Landroidx/compose/ui/graphics/StrokeCap;
+Landroidx/compose/ui/graphics/StrokeJoin$Companion;
+Landroidx/compose/ui/graphics/StrokeJoin;
+Landroidx/compose/ui/graphics/TransformOrigin$Companion;
+Landroidx/compose/ui/graphics/TransformOrigin;
+Landroidx/compose/ui/graphics/TransformOriginKt;
+Landroidx/compose/ui/graphics/WrapperVerificationHelperMethods;
+Landroidx/compose/ui/graphics/colorspace/Adaptation$Companion$Bradford$1;
+Landroidx/compose/ui/graphics/colorspace/Adaptation$Companion$Ciecat02$1;
+Landroidx/compose/ui/graphics/colorspace/Adaptation$Companion$VonKries$1;
+Landroidx/compose/ui/graphics/colorspace/Adaptation$Companion;
+Landroidx/compose/ui/graphics/colorspace/Adaptation;
+Landroidx/compose/ui/graphics/colorspace/ColorModel$Companion;
+Landroidx/compose/ui/graphics/colorspace/ColorModel;
+Landroidx/compose/ui/graphics/colorspace/ColorSpace$Companion;
+Landroidx/compose/ui/graphics/colorspace/ColorSpace;
+Landroidx/compose/ui/graphics/colorspace/ColorSpaceKt;
+Landroidx/compose/ui/graphics/colorspace/ColorSpaces$ExtendedSrgb$1;
+Landroidx/compose/ui/graphics/colorspace/ColorSpaces$ExtendedSrgb$2;
+Landroidx/compose/ui/graphics/colorspace/ColorSpaces;
+Landroidx/compose/ui/graphics/colorspace/Connector$Companion;
+Landroidx/compose/ui/graphics/colorspace/Connector$RgbConnector;
+Landroidx/compose/ui/graphics/colorspace/Connector;
+Landroidx/compose/ui/graphics/colorspace/Illuminant;
+Landroidx/compose/ui/graphics/colorspace/Lab$Companion;
+Landroidx/compose/ui/graphics/colorspace/Lab;
+Landroidx/compose/ui/graphics/colorspace/Oklab$Companion;
+Landroidx/compose/ui/graphics/colorspace/Oklab;
+Landroidx/compose/ui/graphics/colorspace/RenderIntent$Companion;
+Landroidx/compose/ui/graphics/colorspace/RenderIntent;
+Landroidx/compose/ui/graphics/colorspace/Rgb$1;
+Landroidx/compose/ui/graphics/colorspace/Rgb$2;
+Landroidx/compose/ui/graphics/colorspace/Rgb$3;
+Landroidx/compose/ui/graphics/colorspace/Rgb$4;
+Landroidx/compose/ui/graphics/colorspace/Rgb$5;
+Landroidx/compose/ui/graphics/colorspace/Rgb$6;
+Landroidx/compose/ui/graphics/colorspace/Rgb$Companion$DoubleIdentity$1;
+Landroidx/compose/ui/graphics/colorspace/Rgb$Companion;
+Landroidx/compose/ui/graphics/colorspace/Rgb$eotf$1;
+Landroidx/compose/ui/graphics/colorspace/Rgb$oetf$1;
+Landroidx/compose/ui/graphics/colorspace/Rgb;
+Landroidx/compose/ui/graphics/colorspace/TransferParameters;
+Landroidx/compose/ui/graphics/colorspace/WhitePoint;
+Landroidx/compose/ui/graphics/colorspace/Xyz;
+Landroidx/compose/ui/graphics/drawscope/CanvasDrawScope$DrawParams;
+Landroidx/compose/ui/graphics/drawscope/CanvasDrawScope$drawContext$1;
+Landroidx/compose/ui/graphics/drawscope/CanvasDrawScope;
+Landroidx/compose/ui/graphics/drawscope/CanvasDrawScopeKt$asDrawTransform$1;
+Landroidx/compose/ui/graphics/drawscope/CanvasDrawScopeKt;
+Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;
+Landroidx/compose/ui/graphics/drawscope/DrawContext;
+Landroidx/compose/ui/graphics/drawscope/DrawScope$Companion;
+Landroidx/compose/ui/graphics/drawscope/DrawScope;
+Landroidx/compose/ui/graphics/drawscope/DrawStyle;
+Landroidx/compose/ui/graphics/drawscope/DrawTransform;
+Landroidx/compose/ui/graphics/drawscope/EmptyCanvas;
+Landroidx/compose/ui/graphics/drawscope/Fill;
+Landroidx/compose/ui/graphics/drawscope/Stroke;
+Landroidx/compose/ui/graphics/painter/BitmapPainter;
+Landroidx/compose/ui/graphics/painter/Painter$drawLambda$1;
+Landroidx/compose/ui/graphics/painter/Painter;
+Landroidx/compose/ui/graphics/vector/ImageVector;
+Landroidx/compose/ui/graphics/vector/VectorPainter;
+Landroidx/compose/ui/graphics/vector/VectorPainterKt;
+Landroidx/compose/ui/hapticfeedback/HapticFeedback;
+Landroidx/compose/ui/hapticfeedback/PlatformHapticFeedback;
+Landroidx/compose/ui/input/InputMode$Companion;
+Landroidx/compose/ui/input/InputMode;
+Landroidx/compose/ui/input/InputModeManager;
+Landroidx/compose/ui/input/InputModeManagerImpl;
+Landroidx/compose/ui/input/ScrollContainerInfo;
+Landroidx/compose/ui/input/ScrollContainerInfoKt$ModifierLocalScrollContainerInfo$1;
+Landroidx/compose/ui/input/ScrollContainerInfoKt$consumeScrollContainerInfo$1;
+Landroidx/compose/ui/input/ScrollContainerInfoKt$provideScrollContainerInfo$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/input/ScrollContainerInfoKt$provideScrollContainerInfo$2;
+Landroidx/compose/ui/input/ScrollContainerInfoKt;
+Landroidx/compose/ui/input/focus/FocusAwareInputModifier;
+Landroidx/compose/ui/input/focus/FocusDirectedInputEvent;
+Landroidx/compose/ui/input/key/Key$Companion;
+Landroidx/compose/ui/input/key/Key;
+Landroidx/compose/ui/input/key/KeyEvent;
+Landroidx/compose/ui/input/key/KeyEventType$Companion;
+Landroidx/compose/ui/input/key/KeyEventType;
+Landroidx/compose/ui/input/key/KeyEvent_androidKt;
+Landroidx/compose/ui/input/key/KeyInputModifier;
+Landroidx/compose/ui/input/key/KeyInputModifierKt$ModifierLocalKeyInput$1;
+Landroidx/compose/ui/input/key/KeyInputModifierKt$onKeyEvent$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/input/key/KeyInputModifierKt;
+Landroidx/compose/ui/input/nestedscroll/NestedScrollConnection;
+Landroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher$calculateNestedScrollScope$1;
+Landroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher$dispatchPostFling$1;
+Landroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher$dispatchPreFling$1;
+Landroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;
+Landroidx/compose/ui/input/nestedscroll/NestedScrollModifierKt$nestedScroll$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/input/nestedscroll/NestedScrollModifierKt$nestedScroll$2;
+Landroidx/compose/ui/input/nestedscroll/NestedScrollModifierKt;
+Landroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal$1;
+Landroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal$onPostFling$1;
+Landroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal$onPreFling$1;
+Landroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;
+Landroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocalKt$ModifierLocalNestedScroll$1;
+Landroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocalKt;
+Landroidx/compose/ui/input/nestedscroll/NestedScrollSource$Companion;
+Landroidx/compose/ui/input/nestedscroll/NestedScrollSource;
+Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;
+Landroidx/compose/ui/input/pointer/HistoricalChange;
+Landroidx/compose/ui/input/pointer/HitPathTracker;
+Landroidx/compose/ui/input/pointer/InternalPointerEvent;
+Landroidx/compose/ui/input/pointer/MotionEventAdapter;
+Landroidx/compose/ui/input/pointer/MotionEventHelper;
+Landroidx/compose/ui/input/pointer/Node;
+Landroidx/compose/ui/input/pointer/NodeParent;
+Landroidx/compose/ui/input/pointer/PointerButtons;
+Landroidx/compose/ui/input/pointer/PointerEvent;
+Landroidx/compose/ui/input/pointer/PointerEventKt;
+Landroidx/compose/ui/input/pointer/PointerEventPass;
+Landroidx/compose/ui/input/pointer/PointerEventTimeoutCancellationException;
+Landroidx/compose/ui/input/pointer/PointerEventType$Companion;
+Landroidx/compose/ui/input/pointer/PointerEventType;
+Landroidx/compose/ui/input/pointer/PointerEvent_androidKt;
+Landroidx/compose/ui/input/pointer/PointerIcon;
+Landroidx/compose/ui/input/pointer/PointerIconKt;
+Landroidx/compose/ui/input/pointer/PointerIconService;
+Landroidx/compose/ui/input/pointer/PointerId;
+Landroidx/compose/ui/input/pointer/PointerInputChange;
+Landroidx/compose/ui/input/pointer/PointerInputChangeEventProducer$PointerInputData;
+Landroidx/compose/ui/input/pointer/PointerInputChangeEventProducer;
+Landroidx/compose/ui/input/pointer/PointerInputEvent;
+Landroidx/compose/ui/input/pointer/PointerInputEventData;
+Landroidx/compose/ui/input/pointer/PointerInputEventProcessor;
+Landroidx/compose/ui/input/pointer/PointerInputEventProcessorKt;
+Landroidx/compose/ui/input/pointer/PointerInputFilter;
+Landroidx/compose/ui/input/pointer/PointerInputModifier;
+Landroidx/compose/ui/input/pointer/PointerInputScope;
+Landroidx/compose/ui/input/pointer/PointerKeyboardModifiers;
+Landroidx/compose/ui/input/pointer/PointerType$Companion;
+Landroidx/compose/ui/input/pointer/PointerType;
+Landroidx/compose/ui/input/pointer/PositionCalculator;
+Landroidx/compose/ui/input/pointer/ProcessResult;
+Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine$withTimeout$1;
+Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine$withTimeout$job$1;
+Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine$withTimeoutOrNull$1;
+Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;
+Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$WhenMappings;
+Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$awaitPointerEventScope$2$2;
+Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;
+Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$$inlined$debugInspectorInfo$2;
+Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$$inlined$debugInspectorInfo$3;
+Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$2$2$1;
+Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$2;
+Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$4$2$1;
+Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$4;
+Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$6$2$1;
+Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt$pointerInput$6;
+Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt;
+Landroidx/compose/ui/input/pointer/util/PointAtTime;
+Landroidx/compose/ui/input/pointer/util/PolynomialFit;
+Landroidx/compose/ui/input/pointer/util/VelocityEstimate$Companion;
+Landroidx/compose/ui/input/pointer/util/VelocityEstimate;
+Landroidx/compose/ui/input/pointer/util/VelocityTracker;
+Landroidx/compose/ui/input/pointer/util/VelocityTrackerKt;
+Landroidx/compose/ui/input/rotary/RotaryInputModifierKt$ModifierLocalRotaryScrollParent$1;
+Landroidx/compose/ui/input/rotary/RotaryInputModifierKt$focusAwareCallback$1;
+Landroidx/compose/ui/input/rotary/RotaryInputModifierKt$onRotaryScrollEvent$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/input/rotary/RotaryInputModifierKt;
+Landroidx/compose/ui/input/rotary/RotaryScrollEvent;
+Landroidx/compose/ui/layout/AlignmentLine$Companion;
+Landroidx/compose/ui/layout/AlignmentLine;
+Landroidx/compose/ui/layout/AlignmentLineKt$FirstBaseline$1;
+Landroidx/compose/ui/layout/AlignmentLineKt$LastBaseline$1;
+Landroidx/compose/ui/layout/AlignmentLineKt;
+Landroidx/compose/ui/layout/BeyondBoundsLayout;
+Landroidx/compose/ui/layout/BeyondBoundsLayoutKt$ModifierLocalBeyondBoundsLayout$1;
+Landroidx/compose/ui/layout/BeyondBoundsLayoutKt;
+Landroidx/compose/ui/layout/ComposableSingletons$SubcomposeLayoutKt$lambda-1$1;
+Landroidx/compose/ui/layout/ComposableSingletons$SubcomposeLayoutKt;
+Landroidx/compose/ui/layout/ContentScale$Companion$Crop$1;
+Landroidx/compose/ui/layout/ContentScale$Companion$FillBounds$1;
+Landroidx/compose/ui/layout/ContentScale$Companion$FillHeight$1;
+Landroidx/compose/ui/layout/ContentScale$Companion$FillWidth$1;
+Landroidx/compose/ui/layout/ContentScale$Companion$Fit$1;
+Landroidx/compose/ui/layout/ContentScale$Companion$Inside$1;
+Landroidx/compose/ui/layout/ContentScale$Companion;
+Landroidx/compose/ui/layout/ContentScale;
+Landroidx/compose/ui/layout/ContentScaleKt;
+Landroidx/compose/ui/layout/FixedScale;
+Landroidx/compose/ui/layout/HorizontalAlignmentLine;
+Landroidx/compose/ui/layout/IntrinsicMeasurable;
+Landroidx/compose/ui/layout/IntrinsicMeasureScope;
+Landroidx/compose/ui/layout/LayoutCoordinates;
+Landroidx/compose/ui/layout/LayoutCoordinatesKt;
+Landroidx/compose/ui/layout/LayoutInfo;
+Landroidx/compose/ui/layout/LayoutKt$materializerOf$1;
+Landroidx/compose/ui/layout/LayoutKt;
+Landroidx/compose/ui/layout/LayoutModifier;
+Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState$NodeState;
+Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState$Scope;
+Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState$createMeasurePolicy$1$measure$1;
+Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState$createMeasurePolicy$1;
+Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState$precompose$1;
+Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState$subcompose$2$1$1;
+Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState;
+Landroidx/compose/ui/layout/LookaheadLayoutCoordinates;
+Landroidx/compose/ui/layout/LookaheadLayoutCoordinatesImpl;
+Landroidx/compose/ui/layout/LookaheadScope;
+Landroidx/compose/ui/layout/Measurable;
+Landroidx/compose/ui/layout/MeasurePolicy;
+Landroidx/compose/ui/layout/MeasureResult;
+Landroidx/compose/ui/layout/MeasureScope$layout$1;
+Landroidx/compose/ui/layout/MeasureScope;
+Landroidx/compose/ui/layout/Measured;
+Landroidx/compose/ui/layout/NoOpSubcomposeSlotReusePolicy;
+Landroidx/compose/ui/layout/OnGloballyPositionedModifier;
+Landroidx/compose/ui/layout/OnGloballyPositionedModifierImpl;
+Landroidx/compose/ui/layout/OnGloballyPositionedModifierKt$onGloballyPositioned$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/layout/OnGloballyPositionedModifierKt;
+Landroidx/compose/ui/layout/OnPlacedModifier;
+Landroidx/compose/ui/layout/OnRemeasuredModifier;
+Landroidx/compose/ui/layout/ParentDataModifier;
+Landroidx/compose/ui/layout/Placeable$PlacementScope$Companion;
+Landroidx/compose/ui/layout/Placeable$PlacementScope;
+Landroidx/compose/ui/layout/Placeable;
+Landroidx/compose/ui/layout/PlaceableKt$DefaultLayerBlock$1;
+Landroidx/compose/ui/layout/PlaceableKt;
+Landroidx/compose/ui/layout/Remeasurement;
+Landroidx/compose/ui/layout/RemeasurementModifier;
+Landroidx/compose/ui/layout/RootMeasurePolicy$measure$1;
+Landroidx/compose/ui/layout/RootMeasurePolicy$measure$2;
+Landroidx/compose/ui/layout/RootMeasurePolicy$measure$4;
+Landroidx/compose/ui/layout/RootMeasurePolicy;
+Landroidx/compose/ui/layout/ScaleFactor$Companion;
+Landroidx/compose/ui/layout/ScaleFactor;
+Landroidx/compose/ui/layout/ScaleFactorKt;
+Landroidx/compose/ui/layout/SubcomposeLayoutKt$SubcomposeLayout$$inlined$ComposeNode$1;
+Landroidx/compose/ui/layout/SubcomposeLayoutKt$SubcomposeLayout$2;
+Landroidx/compose/ui/layout/SubcomposeLayoutKt$SubcomposeLayout$4;
+Landroidx/compose/ui/layout/SubcomposeLayoutKt$SubcomposeLayout$5$1$invoke$$inlined$onDispose$1;
+Landroidx/compose/ui/layout/SubcomposeLayoutKt$SubcomposeLayout$5$1;
+Landroidx/compose/ui/layout/SubcomposeLayoutKt$SubcomposeLayout$6;
+Landroidx/compose/ui/layout/SubcomposeLayoutKt;
+Landroidx/compose/ui/layout/SubcomposeLayoutState$PrecomposedSlotHandle;
+Landroidx/compose/ui/layout/SubcomposeLayoutState$setCompositionContext$1;
+Landroidx/compose/ui/layout/SubcomposeLayoutState$setMeasurePolicy$1;
+Landroidx/compose/ui/layout/SubcomposeLayoutState$setRoot$1;
+Landroidx/compose/ui/layout/SubcomposeLayoutState;
+Landroidx/compose/ui/layout/SubcomposeMeasureScope;
+Landroidx/compose/ui/layout/SubcomposeSlotReusePolicy$SlotIdsSet;
+Landroidx/compose/ui/layout/SubcomposeSlotReusePolicy;
+Landroidx/compose/ui/modifier/BackwardsCompatLocalMap;
+Landroidx/compose/ui/modifier/EmptyMap;
+Landroidx/compose/ui/modifier/ModifierLocal;
+Landroidx/compose/ui/modifier/ModifierLocalConsumer;
+Landroidx/compose/ui/modifier/ModifierLocalConsumerImpl;
+Landroidx/compose/ui/modifier/ModifierLocalConsumerKt$modifierLocalConsumer$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/modifier/ModifierLocalConsumerKt;
+Landroidx/compose/ui/modifier/ModifierLocalKt;
+Landroidx/compose/ui/modifier/ModifierLocalManager$invalidate$1;
+Landroidx/compose/ui/modifier/ModifierLocalManager;
+Landroidx/compose/ui/modifier/ModifierLocalMap;
+Landroidx/compose/ui/modifier/ModifierLocalNode;
+Landroidx/compose/ui/modifier/ModifierLocalNodeKt;
+Landroidx/compose/ui/modifier/ModifierLocalProvider;
+Landroidx/compose/ui/modifier/ModifierLocalReadScope;
+Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+Landroidx/compose/ui/node/AlignmentLines$recalculate$1;
+Landroidx/compose/ui/node/AlignmentLines;
+Landroidx/compose/ui/node/AlignmentLinesOwner;
+Landroidx/compose/ui/node/BackwardsCompatNode$initializeModifier$1;
+Landroidx/compose/ui/node/BackwardsCompatNode$initializeModifier$4;
+Landroidx/compose/ui/node/BackwardsCompatNode$updateDrawCache$1;
+Landroidx/compose/ui/node/BackwardsCompatNode$updateFocusOrderModifierLocalConsumer$1;
+Landroidx/compose/ui/node/BackwardsCompatNode$updateModifierLocalConsumer$1;
+Landroidx/compose/ui/node/BackwardsCompatNode;
+Landroidx/compose/ui/node/BackwardsCompatNodeKt$DetachedModifierLocalReadScope$1;
+Landroidx/compose/ui/node/BackwardsCompatNodeKt$onDrawCacheReadsChanged$1;
+Landroidx/compose/ui/node/BackwardsCompatNodeKt$updateFocusOrderModifierLocalConsumer$1;
+Landroidx/compose/ui/node/BackwardsCompatNodeKt$updateModifierLocalConsumer$1;
+Landroidx/compose/ui/node/BackwardsCompatNodeKt;
+Landroidx/compose/ui/node/CenteredArray;
+Landroidx/compose/ui/node/ComposeUiNode$Companion$SetDensity$1;
+Landroidx/compose/ui/node/ComposeUiNode$Companion$SetLayoutDirection$1;
+Landroidx/compose/ui/node/ComposeUiNode$Companion$SetMeasurePolicy$1;
+Landroidx/compose/ui/node/ComposeUiNode$Companion$SetModifier$1;
+Landroidx/compose/ui/node/ComposeUiNode$Companion$SetViewConfiguration$1;
+Landroidx/compose/ui/node/ComposeUiNode$Companion$VirtualConstructor$1;
+Landroidx/compose/ui/node/ComposeUiNode$Companion;
+Landroidx/compose/ui/node/ComposeUiNode;
+Landroidx/compose/ui/node/DelegatableNode;
+Landroidx/compose/ui/node/DelegatableNodeKt;
+Landroidx/compose/ui/node/DepthSortedSet$DepthComparator$1;
+Landroidx/compose/ui/node/DepthSortedSet$mapOfOriginalDepth$2;
+Landroidx/compose/ui/node/DepthSortedSet;
+Landroidx/compose/ui/node/DiffCallback;
+Landroidx/compose/ui/node/DistanceAndInLayer;
+Landroidx/compose/ui/node/DrawModifierNode;
+Landroidx/compose/ui/node/DrawModifierNodeKt;
+Landroidx/compose/ui/node/GlobalPositionAwareModifierNode;
+Landroidx/compose/ui/node/HitTestResult$HitTestResultIterator;
+Landroidx/compose/ui/node/HitTestResult$SubList;
+Landroidx/compose/ui/node/HitTestResult;
+Landroidx/compose/ui/node/HitTestResultKt;
+Landroidx/compose/ui/node/InnerNodeCoordinator$Companion;
+Landroidx/compose/ui/node/InnerNodeCoordinator$LookaheadDelegateImpl;
+Landroidx/compose/ui/node/InnerNodeCoordinator$tail$1;
+Landroidx/compose/ui/node/InnerNodeCoordinator;
+Landroidx/compose/ui/node/IntStack;
+Landroidx/compose/ui/node/IntermediateLayoutModifierNode;
+Landroidx/compose/ui/node/IntrinsicsPolicy$Companion;
+Landroidx/compose/ui/node/IntrinsicsPolicy;
+Landroidx/compose/ui/node/LayerPositionalProperties;
+Landroidx/compose/ui/node/LayoutAwareModifierNode;
+Landroidx/compose/ui/node/LayoutModifierNode;
+Landroidx/compose/ui/node/LayoutModifierNodeCoordinator$Companion;
+Landroidx/compose/ui/node/LayoutModifierNodeCoordinator$LookaheadDelegateForIntermediateLayoutModifier;
+Landroidx/compose/ui/node/LayoutModifierNodeCoordinator$LookaheadDelegateForLayoutModifierNode;
+Landroidx/compose/ui/node/LayoutModifierNodeCoordinator;
+Landroidx/compose/ui/node/LayoutModifierNodeCoordinatorKt;
+Landroidx/compose/ui/node/LayoutModifierNodeKt;
+Landroidx/compose/ui/node/LayoutNode$$ExternalSyntheticLambda0;
+Landroidx/compose/ui/node/LayoutNode$Companion$Constructor$1;
+Landroidx/compose/ui/node/LayoutNode$Companion$DummyViewConfiguration$1;
+Landroidx/compose/ui/node/LayoutNode$Companion$ErrorMeasurePolicy$1;
+Landroidx/compose/ui/node/LayoutNode$Companion;
+Landroidx/compose/ui/node/LayoutNode$LayoutState;
+Landroidx/compose/ui/node/LayoutNode$NoIntrinsicsMeasurePolicy;
+Landroidx/compose/ui/node/LayoutNode$UsageByParent;
+Landroidx/compose/ui/node/LayoutNode$WhenMappings;
+Landroidx/compose/ui/node/LayoutNode$_foldedChildren$1;
+Landroidx/compose/ui/node/LayoutNode;
+Landroidx/compose/ui/node/LayoutNodeAlignmentLines;
+Landroidx/compose/ui/node/LayoutNodeDrawScope;
+Landroidx/compose/ui/node/LayoutNodeDrawScopeKt;
+Landroidx/compose/ui/node/LayoutNodeKt;
+Landroidx/compose/ui/node/LayoutNodeLayoutDelegate$LookaheadPassDelegate;
+Landroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$WhenMappings;
+Landroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$childMeasurables$1;
+Landroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$layoutChildren$1$1$1;
+Landroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$layoutChildren$1$1$2;
+Landroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$layoutChildren$1$1;
+Landroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$placeOuterCoordinator$1;
+Landroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate$remeasure$1;
+Landroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;
+Landroidx/compose/ui/node/LayoutNodeLayoutDelegate$performLookaheadMeasure$1;
+Landroidx/compose/ui/node/LayoutNodeLayoutDelegate$performMeasure$2;
+Landroidx/compose/ui/node/LayoutNodeLayoutDelegate;
+Landroidx/compose/ui/node/LayoutNodeLayoutDelegateKt;
+Landroidx/compose/ui/node/LayoutTreeConsistencyChecker;
+Landroidx/compose/ui/node/LookaheadCapablePlaceable;
+Landroidx/compose/ui/node/LookaheadDelegate;
+Landroidx/compose/ui/node/MeasureAndLayoutDelegate$PostponedRequest;
+Landroidx/compose/ui/node/MeasureAndLayoutDelegate$WhenMappings;
+Landroidx/compose/ui/node/MeasureAndLayoutDelegate;
+Landroidx/compose/ui/node/MutableVectorWithMutationTracking;
+Landroidx/compose/ui/node/MyersDiffKt;
+Landroidx/compose/ui/node/NodeChain$Differ;
+Landroidx/compose/ui/node/NodeChain$Logger;
+Landroidx/compose/ui/node/NodeChain;
+Landroidx/compose/ui/node/NodeChainKt$SentinelHead$1;
+Landroidx/compose/ui/node/NodeChainKt$fillVector$1;
+Landroidx/compose/ui/node/NodeChainKt;
+Landroidx/compose/ui/node/NodeCoordinator$Companion$PointerInputSource$1;
+Landroidx/compose/ui/node/NodeCoordinator$Companion$SemanticsSource$1;
+Landroidx/compose/ui/node/NodeCoordinator$Companion$onCommitAffectingLayer$1;
+Landroidx/compose/ui/node/NodeCoordinator$Companion$onCommitAffectingLayerParams$1;
+Landroidx/compose/ui/node/NodeCoordinator$Companion;
+Landroidx/compose/ui/node/NodeCoordinator$HitTestSource;
+Landroidx/compose/ui/node/NodeCoordinator$hit$1;
+Landroidx/compose/ui/node/NodeCoordinator$hitNear$1;
+Landroidx/compose/ui/node/NodeCoordinator$invalidateParentLayer$1;
+Landroidx/compose/ui/node/NodeCoordinator$invoke$1;
+Landroidx/compose/ui/node/NodeCoordinator$speculativeHit$1;
+Landroidx/compose/ui/node/NodeCoordinator$updateLayerParameters$1;
+Landroidx/compose/ui/node/NodeCoordinator;
+Landroidx/compose/ui/node/NodeCoordinatorKt;
+Landroidx/compose/ui/node/NodeKind;
+Landroidx/compose/ui/node/NodeKindKt;
+Landroidx/compose/ui/node/OnPositionedDispatcher$Companion$DepthComparator;
+Landroidx/compose/ui/node/OnPositionedDispatcher$Companion;
+Landroidx/compose/ui/node/OnPositionedDispatcher;
+Landroidx/compose/ui/node/OwnedLayer;
+Landroidx/compose/ui/node/Owner$Companion;
+Landroidx/compose/ui/node/Owner$OnLayoutCompletedListener;
+Landroidx/compose/ui/node/Owner;
+Landroidx/compose/ui/node/OwnerScope;
+Landroidx/compose/ui/node/OwnerSnapshotObserver$clearInvalidObservations$1;
+Landroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingLayout$1;
+Landroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingLayoutModifier$1;
+Landroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingLayoutModifierInLookahead$1;
+Landroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingLookaheadLayout$1;
+Landroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingLookaheadMeasure$1;
+Landroidx/compose/ui/node/OwnerSnapshotObserver$onCommitAffectingMeasure$1;
+Landroidx/compose/ui/node/OwnerSnapshotObserver;
+Landroidx/compose/ui/node/ParentDataModifierNode;
+Landroidx/compose/ui/node/ParentDataModifierNodeKt;
+Landroidx/compose/ui/node/PointerInputModifierNode;
+Landroidx/compose/ui/node/PointerInputModifierNodeKt;
+Landroidx/compose/ui/node/RootForTest;
+Landroidx/compose/ui/node/SemanticsModifierNode;
+Landroidx/compose/ui/node/SemanticsModifierNodeKt;
+Landroidx/compose/ui/node/Snake;
+Landroidx/compose/ui/node/TreeSet;
+Landroidx/compose/ui/node/UiApplier;
+Landroidx/compose/ui/platform/AbstractComposeView$ensureCompositionCreated$1;
+Landroidx/compose/ui/platform/AbstractComposeView;
+Landroidx/compose/ui/platform/AccessibilityIterators$AbstractTextSegmentIterator;
+Landroidx/compose/ui/platform/AccessibilityIterators$CharacterTextSegmentIterator$Companion;
+Landroidx/compose/ui/platform/AccessibilityIterators$CharacterTextSegmentIterator;
+Landroidx/compose/ui/platform/AccessibilityIterators$LineTextSegmentIterator$Companion;
+Landroidx/compose/ui/platform/AccessibilityIterators$LineTextSegmentIterator;
+Landroidx/compose/ui/platform/AccessibilityIterators$PageTextSegmentIterator$Companion;
+Landroidx/compose/ui/platform/AccessibilityIterators$PageTextSegmentIterator;
+Landroidx/compose/ui/platform/AccessibilityIterators$ParagraphTextSegmentIterator$Companion;
+Landroidx/compose/ui/platform/AccessibilityIterators$ParagraphTextSegmentIterator;
+Landroidx/compose/ui/platform/AccessibilityIterators$TextSegmentIterator;
+Landroidx/compose/ui/platform/AccessibilityIterators$WordTextSegmentIterator$Companion;
+Landroidx/compose/ui/platform/AccessibilityIterators$WordTextSegmentIterator;
+Landroidx/compose/ui/platform/AccessibilityManager;
+Landroidx/compose/ui/platform/AccessibilityNodeInfoVerificationHelperMethods;
+Landroidx/compose/ui/platform/AndroidAccessibilityManager$Companion;
+Landroidx/compose/ui/platform/AndroidAccessibilityManager;
+Landroidx/compose/ui/platform/AndroidClipboardManager;
+Landroidx/compose/ui/platform/AndroidComposeView$$ExternalSyntheticLambda0;
+Landroidx/compose/ui/platform/AndroidComposeView$$ExternalSyntheticLambda1;
+Landroidx/compose/ui/platform/AndroidComposeView$$ExternalSyntheticLambda2;
+Landroidx/compose/ui/platform/AndroidComposeView$$ExternalSyntheticLambda3;
+Landroidx/compose/ui/platform/AndroidComposeView$Companion;
+Landroidx/compose/ui/platform/AndroidComposeView$ViewTreeOwners;
+Landroidx/compose/ui/platform/AndroidComposeView$_inputModeManager$1;
+Landroidx/compose/ui/platform/AndroidComposeView$configurationChangeObserver$1;
+Landroidx/compose/ui/platform/AndroidComposeView$keyInputModifier$1;
+Landroidx/compose/ui/platform/AndroidComposeView$pointerIconService$1;
+Landroidx/compose/ui/platform/AndroidComposeView$resendMotionEventOnLayout$1;
+Landroidx/compose/ui/platform/AndroidComposeView$resendMotionEventRunnable$1;
+Landroidx/compose/ui/platform/AndroidComposeView$rotaryInputModifier$1;
+Landroidx/compose/ui/platform/AndroidComposeView$scrollContainerInfo$1$value$1;
+Landroidx/compose/ui/platform/AndroidComposeView$scrollContainerInfo$1;
+Landroidx/compose/ui/platform/AndroidComposeView$semanticsModifier$1;
+Landroidx/compose/ui/platform/AndroidComposeView$snapshotObserver$1$$ExternalSyntheticLambda0;
+Landroidx/compose/ui/platform/AndroidComposeView$snapshotObserver$1;
+Landroidx/compose/ui/platform/AndroidComposeView;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$$ExternalSyntheticLambda0;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$$ExternalSyntheticLambda1;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$$ExternalSyntheticLambda2;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$1;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$Api24Impl;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$Api29Impl;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$Companion;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$MyNodeProvider;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$PendingTextTraversedEvent;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$SemanticsNodeCopy;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$WhenMappings;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$boundsUpdatesEventLoop$1;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$populateAccessibilityNodeInfoProperties$isUnmergedLeafNode$1;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$sendScrollEventIfNeeded$1;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$sendScrollEventIfNeededLambda$1;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$sendSubtreeChangeAccessibilityEvents$1;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$sendSubtreeChangeAccessibilityEvents$semanticsWrapper$1;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;
+Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat_androidKt;
+Landroidx/compose/ui/platform/AndroidComposeViewForceDarkModeQ;
+Landroidx/compose/ui/platform/AndroidComposeViewVerificationHelperMethodsN;
+Landroidx/compose/ui/platform/AndroidComposeViewVerificationHelperMethodsO;
+Landroidx/compose/ui/platform/AndroidComposeView_androidKt$textInputServiceFactory$1;
+Landroidx/compose/ui/platform/AndroidComposeView_androidKt;
+Landroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$LocalConfiguration$1;
+Landroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$LocalContext$1;
+Landroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$LocalImageVectorCache$1;
+Landroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$LocalLifecycleOwner$1;
+Landroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$LocalSavedStateRegistryOwner$1;
+Landroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$LocalView$1;
+Landroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$1$1;
+Landroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$2$invoke$$inlined$onDispose$1;
+Landroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$2;
+Landroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3;
+Landroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$4;
+Landroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$obtainImageVectorCache$1$invoke$$inlined$onDispose$1;
+Landroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$obtainImageVectorCache$1;
+Landroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$obtainImageVectorCache$callbacks$1$1;
+Landroidx/compose/ui/platform/AndroidCompositionLocals_androidKt;
+Landroidx/compose/ui/platform/AndroidFontResourceLoader;
+Landroidx/compose/ui/platform/AndroidTextToolbar$textActionModeCallback$1;
+Landroidx/compose/ui/platform/AndroidTextToolbar;
+Landroidx/compose/ui/platform/AndroidUiDispatcher$Companion$Main$2$dispatcher$1;
+Landroidx/compose/ui/platform/AndroidUiDispatcher$Companion$Main$2;
+Landroidx/compose/ui/platform/AndroidUiDispatcher$Companion$currentThread$1;
+Landroidx/compose/ui/platform/AndroidUiDispatcher$Companion;
+Landroidx/compose/ui/platform/AndroidUiDispatcher$dispatchCallback$1;
+Landroidx/compose/ui/platform/AndroidUiDispatcher;
+Landroidx/compose/ui/platform/AndroidUiDispatcher_androidKt;
+Landroidx/compose/ui/platform/AndroidUiFrameClock$withFrameNanos$2$1;
+Landroidx/compose/ui/platform/AndroidUiFrameClock$withFrameNanos$2$2;
+Landroidx/compose/ui/platform/AndroidUiFrameClock$withFrameNanos$2$callback$1;
+Landroidx/compose/ui/platform/AndroidUiFrameClock;
+Landroidx/compose/ui/platform/AndroidUriHandler;
+Landroidx/compose/ui/platform/AndroidViewConfiguration;
+Landroidx/compose/ui/platform/AndroidViewsHandler;
+Landroidx/compose/ui/platform/CalculateMatrixToWindow;
+Landroidx/compose/ui/platform/CalculateMatrixToWindowApi29;
+Landroidx/compose/ui/platform/ClipboardManager;
+Landroidx/compose/ui/platform/ComposableSingletons$Wrapper_androidKt$lambda-1$1;
+Landroidx/compose/ui/platform/ComposableSingletons$Wrapper_androidKt;
+Landroidx/compose/ui/platform/ComposeView$Content$1;
+Landroidx/compose/ui/platform/ComposeView;
+Landroidx/compose/ui/platform/CompositionLocalsKt$LocalAccessibilityManager$1;
+Landroidx/compose/ui/platform/CompositionLocalsKt$LocalAutofill$1;
+Landroidx/compose/ui/platform/CompositionLocalsKt$LocalAutofillTree$1;
+Landroidx/compose/ui/platform/CompositionLocalsKt$LocalClipboardManager$1;
+Landroidx/compose/ui/platform/CompositionLocalsKt$LocalDensity$1;
+Landroidx/compose/ui/platform/CompositionLocalsKt$LocalFocusManager$1;
+Landroidx/compose/ui/platform/CompositionLocalsKt$LocalFontFamilyResolver$1;
+Landroidx/compose/ui/platform/CompositionLocalsKt$LocalFontLoader$1;
+Landroidx/compose/ui/platform/CompositionLocalsKt$LocalHapticFeedback$1;
+Landroidx/compose/ui/platform/CompositionLocalsKt$LocalInputModeManager$1;
+Landroidx/compose/ui/platform/CompositionLocalsKt$LocalLayoutDirection$1;
+Landroidx/compose/ui/platform/CompositionLocalsKt$LocalPointerIconService$1;
+Landroidx/compose/ui/platform/CompositionLocalsKt$LocalTextInputService$1;
+Landroidx/compose/ui/platform/CompositionLocalsKt$LocalTextToolbar$1;
+Landroidx/compose/ui/platform/CompositionLocalsKt$LocalUriHandler$1;
+Landroidx/compose/ui/platform/CompositionLocalsKt$LocalViewConfiguration$1;
+Landroidx/compose/ui/platform/CompositionLocalsKt$LocalWindowInfo$1;
+Landroidx/compose/ui/platform/CompositionLocalsKt$ProvideCommonCompositionLocals$1;
+Landroidx/compose/ui/platform/CompositionLocalsKt;
+Landroidx/compose/ui/platform/DeviceRenderNode;
+Landroidx/compose/ui/platform/DisposableSaveableStateRegistry;
+Landroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt$DisposableSaveableStateRegistry$1;
+Landroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt$DisposableSaveableStateRegistry$registered$1;
+Landroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt$DisposableSaveableStateRegistry$saveableStateRegistry$1;
+Landroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt;
+Landroidx/compose/ui/platform/DrawChildContainer;
+Landroidx/compose/ui/platform/GlobalSnapshotManager$ensureStarted$1;
+Landroidx/compose/ui/platform/GlobalSnapshotManager$ensureStarted$2;
+Landroidx/compose/ui/platform/GlobalSnapshotManager;
+Landroidx/compose/ui/platform/InspectableModifier$End;
+Landroidx/compose/ui/platform/InspectableModifier;
+Landroidx/compose/ui/platform/InspectableValueKt$NoInspectorInfo$1;
+Landroidx/compose/ui/platform/InspectableValueKt;
+Landroidx/compose/ui/platform/InspectorInfo;
+Landroidx/compose/ui/platform/InspectorValueInfo;
+Landroidx/compose/ui/platform/InvertMatrixKt;
+Landroidx/compose/ui/platform/JvmActuals_jvmKt;
+Landroidx/compose/ui/platform/LayerMatrixCache;
+Landroidx/compose/ui/platform/MotionDurationScaleImpl;
+Landroidx/compose/ui/platform/OutlineResolver;
+Landroidx/compose/ui/platform/RenderNodeApi29;
+Landroidx/compose/ui/platform/RenderNodeApi29VerificationHelper;
+Landroidx/compose/ui/platform/RenderNodeLayer$Companion$getMatrix$1;
+Landroidx/compose/ui/platform/RenderNodeLayer$Companion;
+Landroidx/compose/ui/platform/RenderNodeLayer;
+Landroidx/compose/ui/platform/ScrollObservationScope;
+Landroidx/compose/ui/platform/SemanticsNodeWithAdjustedBounds;
+Landroidx/compose/ui/platform/ShapeContainingUtilKt;
+Landroidx/compose/ui/platform/TextToolbar;
+Landroidx/compose/ui/platform/TextToolbarStatus;
+Landroidx/compose/ui/platform/UriHandler;
+Landroidx/compose/ui/platform/ViewCompositionStrategy$Companion;
+Landroidx/compose/ui/platform/ViewCompositionStrategy$DisposeOnDetachedFromWindowOrReleasedFromPool$installFor$1;
+Landroidx/compose/ui/platform/ViewCompositionStrategy$DisposeOnDetachedFromWindowOrReleasedFromPool$installFor$listener$1;
+Landroidx/compose/ui/platform/ViewCompositionStrategy$DisposeOnDetachedFromWindowOrReleasedFromPool$installFor$poolingContainerListener$1;
+Landroidx/compose/ui/platform/ViewCompositionStrategy$DisposeOnDetachedFromWindowOrReleasedFromPool;
+Landroidx/compose/ui/platform/ViewCompositionStrategy;
+Landroidx/compose/ui/platform/ViewConfiguration;
+Landroidx/compose/ui/platform/ViewLayer$Companion$OutlineProvider$1;
+Landroidx/compose/ui/platform/ViewLayer$Companion$getMatrix$1;
+Landroidx/compose/ui/platform/ViewLayer$Companion;
+Landroidx/compose/ui/platform/ViewLayer;
+Landroidx/compose/ui/platform/ViewLayerContainer;
+Landroidx/compose/ui/platform/ViewLayerVerificationHelper28;
+Landroidx/compose/ui/platform/ViewLayerVerificationHelper31;
+Landroidx/compose/ui/platform/ViewRootForTest$Companion;
+Landroidx/compose/ui/platform/ViewRootForTest;
+Landroidx/compose/ui/platform/WeakCache;
+Landroidx/compose/ui/platform/WindowInfo;
+Landroidx/compose/ui/platform/WindowInfoImpl$Companion;
+Landroidx/compose/ui/platform/WindowInfoImpl;
+Landroidx/compose/ui/platform/WindowRecomposerFactory$Companion$LifecycleAware$1;
+Landroidx/compose/ui/platform/WindowRecomposerFactory$Companion;
+Landroidx/compose/ui/platform/WindowRecomposerFactory;
+Landroidx/compose/ui/platform/WindowRecomposerPolicy$createAndInstallWindowRecomposer$1;
+Landroidx/compose/ui/platform/WindowRecomposerPolicy$createAndInstallWindowRecomposer$unsetJob$1;
+Landroidx/compose/ui/platform/WindowRecomposerPolicy;
+Landroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$1;
+Landroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2$WhenMappings;
+Landroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2$onStateChanged$1$1$1$1;
+Landroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2$onStateChanged$1$1$1;
+Landroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2$onStateChanged$1;
+Landroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$2;
+Landroidx/compose/ui/platform/WindowRecomposer_androidKt$getAnimationScaleFlowFor$1$1$1;
+Landroidx/compose/ui/platform/WindowRecomposer_androidKt$getAnimationScaleFlowFor$1$1$contentObserver$1;
+Landroidx/compose/ui/platform/WindowRecomposer_androidKt;
+Landroidx/compose/ui/platform/WrappedComposition$setContent$1$1$1;
+Landroidx/compose/ui/platform/WrappedComposition$setContent$1$1$2;
+Landroidx/compose/ui/platform/WrappedComposition$setContent$1$1$3;
+Landroidx/compose/ui/platform/WrappedComposition$setContent$1$1;
+Landroidx/compose/ui/platform/WrappedComposition$setContent$1;
+Landroidx/compose/ui/platform/WrappedComposition;
+Landroidx/compose/ui/platform/WrapperRenderNodeLayerHelperMethods;
+Landroidx/compose/ui/platform/WrapperVerificationHelperMethods;
+Landroidx/compose/ui/platform/Wrapper_androidKt;
+Landroidx/compose/ui/platform/accessibility/CollectionInfoKt;
+Landroidx/compose/ui/platform/actionmodecallback/TextActionModeCallback;
+Landroidx/compose/ui/res/ImageVectorCache$ImageVectorEntry;
+Landroidx/compose/ui/res/ImageVectorCache$Key;
+Landroidx/compose/ui/res/ImageVectorCache;
+Landroidx/compose/ui/res/PainterResources_androidKt;
+Landroidx/compose/ui/res/Resources_androidKt;
+Landroidx/compose/ui/res/StringResources_androidKt;
+Landroidx/compose/ui/semantics/AccessibilityAction;
+Landroidx/compose/ui/semantics/CollectionInfo;
+Landroidx/compose/ui/semantics/LiveRegionMode$Companion;
+Landroidx/compose/ui/semantics/LiveRegionMode;
+Landroidx/compose/ui/semantics/ProgressBarRangeInfo$Companion;
+Landroidx/compose/ui/semantics/ProgressBarRangeInfo;
+Landroidx/compose/ui/semantics/Role$Companion;
+Landroidx/compose/ui/semantics/Role;
+Landroidx/compose/ui/semantics/ScrollAxisRange;
+Landroidx/compose/ui/semantics/SemanticsActions;
+Landroidx/compose/ui/semantics/SemanticsConfiguration;
+Landroidx/compose/ui/semantics/SemanticsConfigurationKt$getOrNull$1;
+Landroidx/compose/ui/semantics/SemanticsConfigurationKt;
+Landroidx/compose/ui/semantics/SemanticsModifier;
+Landroidx/compose/ui/semantics/SemanticsModifierCore$Companion;
+Landroidx/compose/ui/semantics/SemanticsModifierCore;
+Landroidx/compose/ui/semantics/SemanticsModifierKt$clearAndSetSemantics$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/semantics/SemanticsModifierKt$semantics$$inlined$debugInspectorInfo$1;
+Landroidx/compose/ui/semantics/SemanticsModifierKt;
+Landroidx/compose/ui/semantics/SemanticsNode$emitFakeNodes$fakeNode$1;
+Landroidx/compose/ui/semantics/SemanticsNode$emitFakeNodes$fakeNode$2;
+Landroidx/compose/ui/semantics/SemanticsNode$fakeSemanticsNode$fakeNode$1;
+Landroidx/compose/ui/semantics/SemanticsNode$parent$1;
+Landroidx/compose/ui/semantics/SemanticsNode$parent$2;
+Landroidx/compose/ui/semantics/SemanticsNode;
+Landroidx/compose/ui/semantics/SemanticsNodeKt;
+Landroidx/compose/ui/semantics/SemanticsOwner;
+Landroidx/compose/ui/semantics/SemanticsProperties$ContentDescription$1;
+Landroidx/compose/ui/semantics/SemanticsProperties$InvisibleToUser$1;
+Landroidx/compose/ui/semantics/SemanticsProperties$IsDialog$1;
+Landroidx/compose/ui/semantics/SemanticsProperties$IsPopup$1;
+Landroidx/compose/ui/semantics/SemanticsProperties$PaneTitle$1;
+Landroidx/compose/ui/semantics/SemanticsProperties$Role$1;
+Landroidx/compose/ui/semantics/SemanticsProperties$TestTag$1;
+Landroidx/compose/ui/semantics/SemanticsProperties$Text$1;
+Landroidx/compose/ui/semantics/SemanticsProperties;
+Landroidx/compose/ui/semantics/SemanticsPropertiesAndroid;
+Landroidx/compose/ui/semantics/SemanticsPropertiesKt$ActionPropertyKey$1;
+Landroidx/compose/ui/semantics/SemanticsPropertiesKt;
+Landroidx/compose/ui/semantics/SemanticsPropertyKey$1;
+Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;
+Landroidx/compose/ui/semantics/SemanticsSortKt;
+Landroidx/compose/ui/state/ToggleableState;
+Landroidx/compose/ui/text/AndroidParagraph$WhenMappings;
+Landroidx/compose/ui/text/AndroidParagraph$wordBoundary$2;
+Landroidx/compose/ui/text/AndroidParagraph;
+Landroidx/compose/ui/text/AndroidParagraph_androidKt;
+Landroidx/compose/ui/text/AnnotatedString$Range;
+Landroidx/compose/ui/text/AnnotatedString$special$$inlined$sortedBy$1;
+Landroidx/compose/ui/text/AnnotatedString;
+Landroidx/compose/ui/text/AnnotatedStringKt;
+Landroidx/compose/ui/text/MultiParagraph;
+Landroidx/compose/ui/text/MultiParagraphIntrinsics$maxIntrinsicWidth$2;
+Landroidx/compose/ui/text/MultiParagraphIntrinsics$minIntrinsicWidth$2;
+Landroidx/compose/ui/text/MultiParagraphIntrinsics;
+Landroidx/compose/ui/text/MultiParagraphIntrinsicsKt;
+Landroidx/compose/ui/text/MultiParagraphKt;
+Landroidx/compose/ui/text/Paragraph;
+Landroidx/compose/ui/text/ParagraphInfo;
+Landroidx/compose/ui/text/ParagraphIntrinsicInfo;
+Landroidx/compose/ui/text/ParagraphIntrinsics;
+Landroidx/compose/ui/text/ParagraphIntrinsicsKt;
+Landroidx/compose/ui/text/ParagraphKt;
+Landroidx/compose/ui/text/ParagraphStyle;
+Landroidx/compose/ui/text/ParagraphStyleKt;
+Landroidx/compose/ui/text/Placeholder;
+Landroidx/compose/ui/text/PlatformParagraphStyle;
+Landroidx/compose/ui/text/PlatformSpanStyle;
+Landroidx/compose/ui/text/PlatformTextStyle;
+Landroidx/compose/ui/text/SaversKt;
+Landroidx/compose/ui/text/SpanStyle;
+Landroidx/compose/ui/text/SpanStyleKt$resolveSpanStyleDefaults$1;
+Landroidx/compose/ui/text/SpanStyleKt;
+Landroidx/compose/ui/text/TempListUtilsKt;
+Landroidx/compose/ui/text/TextLayoutInput;
+Landroidx/compose/ui/text/TextLayoutResult;
+Landroidx/compose/ui/text/TextPainter;
+Landroidx/compose/ui/text/TextRange$Companion;
+Landroidx/compose/ui/text/TextRange;
+Landroidx/compose/ui/text/TextRangeKt;
+Landroidx/compose/ui/text/TextStyle$Companion;
+Landroidx/compose/ui/text/TextStyle;
+Landroidx/compose/ui/text/TextStyleKt$WhenMappings;
+Landroidx/compose/ui/text/TextStyleKt;
+Landroidx/compose/ui/text/TtsAnnotation;
+Landroidx/compose/ui/text/UrlAnnotation;
+Landroidx/compose/ui/text/android/BoringLayoutConstructor33;
+Landroidx/compose/ui/text/android/BoringLayoutFactory33;
+Landroidx/compose/ui/text/android/BoringLayoutFactory;
+Landroidx/compose/ui/text/android/BoringLayoutFactoryDefault;
+Landroidx/compose/ui/text/android/CharSequenceCharacterIterator;
+Landroidx/compose/ui/text/android/LayoutCompat;
+Landroidx/compose/ui/text/android/LayoutHelper;
+Landroidx/compose/ui/text/android/LayoutIntrinsics$boringMetrics$2;
+Landroidx/compose/ui/text/android/LayoutIntrinsics$maxIntrinsicWidth$2;
+Landroidx/compose/ui/text/android/LayoutIntrinsics$minIntrinsicWidth$2;
+Landroidx/compose/ui/text/android/LayoutIntrinsics;
+Landroidx/compose/ui/text/android/LayoutIntrinsicsKt$$ExternalSyntheticLambda0;
+Landroidx/compose/ui/text/android/LayoutIntrinsicsKt;
+Landroidx/compose/ui/text/android/PaintExtensionsKt;
+Landroidx/compose/ui/text/android/SpannedExtensionsKt;
+Landroidx/compose/ui/text/android/StaticLayoutFactory23;
+Landroidx/compose/ui/text/android/StaticLayoutFactory26;
+Landroidx/compose/ui/text/android/StaticLayoutFactory28;
+Landroidx/compose/ui/text/android/StaticLayoutFactory33;
+Landroidx/compose/ui/text/android/StaticLayoutFactory;
+Landroidx/compose/ui/text/android/StaticLayoutFactoryImpl;
+Landroidx/compose/ui/text/android/StaticLayoutParams;
+Landroidx/compose/ui/text/android/TextAlignmentAdapter;
+Landroidx/compose/ui/text/android/TextAndroidCanvas;
+Landroidx/compose/ui/text/android/TextLayout$Companion;
+Landroidx/compose/ui/text/android/TextLayout$layoutHelper$2;
+Landroidx/compose/ui/text/android/TextLayout;
+Landroidx/compose/ui/text/android/TextLayoutKt;
+Landroidx/compose/ui/text/android/selection/WordBoundary;
+Landroidx/compose/ui/text/android/style/BaselineShiftSpan;
+Landroidx/compose/ui/text/android/style/FontFeatureSpan;
+Landroidx/compose/ui/text/android/style/IndentationFixSpan;
+Landroidx/compose/ui/text/android/style/IndentationFixSpanKt$WhenMappings;
+Landroidx/compose/ui/text/android/style/IndentationFixSpanKt;
+Landroidx/compose/ui/text/android/style/LetterSpacingSpanEm;
+Landroidx/compose/ui/text/android/style/LetterSpacingSpanPx;
+Landroidx/compose/ui/text/android/style/LineHeightSpan;
+Landroidx/compose/ui/text/android/style/LineHeightStyleSpan;
+Landroidx/compose/ui/text/android/style/LineHeightStyleSpanKt;
+Landroidx/compose/ui/text/android/style/PlaceholderSpan;
+Landroidx/compose/ui/text/android/style/ShadowSpan;
+Landroidx/compose/ui/text/android/style/SkewXSpan;
+Landroidx/compose/ui/text/android/style/TextDecorationSpan;
+Landroidx/compose/ui/text/android/style/TypefaceSpan;
+Landroidx/compose/ui/text/caches/ContainerHelpersKt;
+Landroidx/compose/ui/text/caches/LruCache;
+Landroidx/compose/ui/text/caches/SimpleArrayMap;
+Landroidx/compose/ui/text/font/AndroidFontLoader;
+Landroidx/compose/ui/text/font/AndroidFontResolveInterceptor;
+Landroidx/compose/ui/text/font/AndroidFontResolveInterceptor_androidKt;
+Landroidx/compose/ui/text/font/AsyncTypefaceCache$AsyncTypefaceResult;
+Landroidx/compose/ui/text/font/AsyncTypefaceCache;
+Landroidx/compose/ui/text/font/DefaultFontFamily;
+Landroidx/compose/ui/text/font/Font$ResourceLoader;
+Landroidx/compose/ui/text/font/FontFamily$Companion;
+Landroidx/compose/ui/text/font/FontFamily$Resolver;
+Landroidx/compose/ui/text/font/FontFamily;
+Landroidx/compose/ui/text/font/FontFamilyResolverImpl$createDefaultTypeface$1;
+Landroidx/compose/ui/text/font/FontFamilyResolverImpl$resolve$result$1;
+Landroidx/compose/ui/text/font/FontFamilyResolverImpl;
+Landroidx/compose/ui/text/font/FontFamilyResolverKt;
+Landroidx/compose/ui/text/font/FontFamilyResolver_androidKt;
+Landroidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter$Companion;
+Landroidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter$special$$inlined$CoroutineExceptionHandler$1;
+Landroidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter;
+Landroidx/compose/ui/text/font/FontMatcher;
+Landroidx/compose/ui/text/font/FontStyle$Companion;
+Landroidx/compose/ui/text/font/FontStyle;
+Landroidx/compose/ui/text/font/FontSynthesis$Companion;
+Landroidx/compose/ui/text/font/FontSynthesis;
+Landroidx/compose/ui/text/font/FontWeight$Companion;
+Landroidx/compose/ui/text/font/FontWeight;
+Landroidx/compose/ui/text/font/GenericFontFamily;
+Landroidx/compose/ui/text/font/PlatformFontFamilyTypefaceAdapter;
+Landroidx/compose/ui/text/font/PlatformFontLoader;
+Landroidx/compose/ui/text/font/PlatformResolveInterceptor$Companion$Default$1;
+Landroidx/compose/ui/text/font/PlatformResolveInterceptor$Companion;
+Landroidx/compose/ui/text/font/PlatformResolveInterceptor;
+Landroidx/compose/ui/text/font/PlatformTypefaces;
+Landroidx/compose/ui/text/font/PlatformTypefacesApi28;
+Landroidx/compose/ui/text/font/PlatformTypefacesKt;
+Landroidx/compose/ui/text/font/SystemFontFamily;
+Landroidx/compose/ui/text/font/TypefaceRequest;
+Landroidx/compose/ui/text/font/TypefaceRequestCache$runCached$currentTypefaceResult$1;
+Landroidx/compose/ui/text/font/TypefaceRequestCache;
+Landroidx/compose/ui/text/font/TypefaceResult$Immutable;
+Landroidx/compose/ui/text/font/TypefaceResult;
+Landroidx/compose/ui/text/input/ImeAction$Companion;
+Landroidx/compose/ui/text/input/ImeAction;
+Landroidx/compose/ui/text/input/ImeOptions$Companion;
+Landroidx/compose/ui/text/input/ImeOptions;
+Landroidx/compose/ui/text/input/ImmHelper21;
+Landroidx/compose/ui/text/input/ImmHelper30;
+Landroidx/compose/ui/text/input/ImmHelper;
+Landroidx/compose/ui/text/input/InputEventCallback2;
+Landroidx/compose/ui/text/input/InputMethodManager;
+Landroidx/compose/ui/text/input/InputMethodManagerImpl$imm$2;
+Landroidx/compose/ui/text/input/InputMethodManagerImpl;
+Landroidx/compose/ui/text/input/KeyboardCapitalization$Companion;
+Landroidx/compose/ui/text/input/KeyboardCapitalization;
+Landroidx/compose/ui/text/input/KeyboardType$Companion;
+Landroidx/compose/ui/text/input/KeyboardType;
+Landroidx/compose/ui/text/input/PlatformTextInputService;
+Landroidx/compose/ui/text/input/RecordingInputConnection;
+Landroidx/compose/ui/text/input/TextFieldValue$Companion$Saver$1;
+Landroidx/compose/ui/text/input/TextFieldValue$Companion$Saver$2;
+Landroidx/compose/ui/text/input/TextFieldValue$Companion;
+Landroidx/compose/ui/text/input/TextFieldValue;
+Landroidx/compose/ui/text/input/TextInputService;
+Landroidx/compose/ui/text/input/TextInputServiceAndroid$TextInputCommand;
+Landroidx/compose/ui/text/input/TextInputServiceAndroid$WhenMappings;
+Landroidx/compose/ui/text/input/TextInputServiceAndroid$baseInputConnection$2;
+Landroidx/compose/ui/text/input/TextInputServiceAndroid$createInputConnection$1;
+Landroidx/compose/ui/text/input/TextInputServiceAndroid$onEditCommand$1;
+Landroidx/compose/ui/text/input/TextInputServiceAndroid$onImeActionPerformed$1;
+Landroidx/compose/ui/text/input/TextInputServiceAndroid$textInputCommandEventLoop$1;
+Landroidx/compose/ui/text/input/TextInputServiceAndroid;
+Landroidx/compose/ui/text/input/TextInputServiceAndroid_androidKt;
+Landroidx/compose/ui/text/intl/AndroidLocale;
+Landroidx/compose/ui/text/intl/AndroidLocaleDelegateAPI24;
+Landroidx/compose/ui/text/intl/AndroidPlatformLocale_androidKt;
+Landroidx/compose/ui/text/intl/Locale$Companion;
+Landroidx/compose/ui/text/intl/Locale;
+Landroidx/compose/ui/text/intl/LocaleList$Companion;
+Landroidx/compose/ui/text/intl/LocaleList;
+Landroidx/compose/ui/text/intl/PlatformLocale;
+Landroidx/compose/ui/text/intl/PlatformLocaleDelegate;
+Landroidx/compose/ui/text/intl/PlatformLocaleKt;
+Landroidx/compose/ui/text/platform/AndroidAccessibilitySpannableString_androidKt;
+Landroidx/compose/ui/text/platform/AndroidMultiParagraphDrawKt;
+Landroidx/compose/ui/text/platform/AndroidParagraphHelper_androidKt$NoopSpan$1;
+Landroidx/compose/ui/text/platform/AndroidParagraphHelper_androidKt;
+Landroidx/compose/ui/text/platform/AndroidParagraphIntrinsics$resolveTypeface$1;
+Landroidx/compose/ui/text/platform/AndroidParagraphIntrinsics;
+Landroidx/compose/ui/text/platform/AndroidParagraphIntrinsics_androidKt;
+Landroidx/compose/ui/text/platform/AndroidParagraph_androidKt;
+Landroidx/compose/ui/text/platform/AndroidTextPaint;
+Landroidx/compose/ui/text/platform/DefaultImpl$getFontLoadState$initCallback$1;
+Landroidx/compose/ui/text/platform/DefaultImpl;
+Landroidx/compose/ui/text/platform/EmojiCompatStatus;
+Landroidx/compose/ui/text/platform/EmojiCompatStatusDelegate;
+Landroidx/compose/ui/text/platform/EmojiCompatStatusKt;
+Landroidx/compose/ui/text/platform/ImmutableBool;
+Landroidx/compose/ui/text/platform/Synchronization_jvmKt;
+Landroidx/compose/ui/text/platform/SynchronizedObject;
+Landroidx/compose/ui/text/platform/TypefaceDirtyTracker;
+Landroidx/compose/ui/text/platform/extensions/LocaleListHelperMethods;
+Landroidx/compose/ui/text/platform/extensions/PlaceholderExtensions_androidKt;
+Landroidx/compose/ui/text/platform/extensions/SpanRange;
+Landroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt$setFontAttributes$1;
+Landroidx/compose/ui/text/platform/extensions/SpannableExtensions_androidKt;
+Landroidx/compose/ui/text/platform/extensions/TextPaintExtensions_androidKt;
+Landroidx/compose/ui/text/platform/style/DrawStyleSpan;
+Landroidx/compose/ui/text/platform/style/ShaderBrushSpan;
+Landroidx/compose/ui/text/style/BaselineShift$Companion;
+Landroidx/compose/ui/text/style/BaselineShift;
+Landroidx/compose/ui/text/style/BrushStyle;
+Landroidx/compose/ui/text/style/ColorStyle;
+Landroidx/compose/ui/text/style/Hyphens$Companion;
+Landroidx/compose/ui/text/style/Hyphens;
+Landroidx/compose/ui/text/style/LineBreak$Companion;
+Landroidx/compose/ui/text/style/LineBreak$Strategy$Companion;
+Landroidx/compose/ui/text/style/LineBreak$Strategy;
+Landroidx/compose/ui/text/style/LineBreak$Strictness$Companion;
+Landroidx/compose/ui/text/style/LineBreak$Strictness;
+Landroidx/compose/ui/text/style/LineBreak$WordBreak$Companion;
+Landroidx/compose/ui/text/style/LineBreak$WordBreak;
+Landroidx/compose/ui/text/style/LineBreak;
+Landroidx/compose/ui/text/style/LineHeightStyle$Companion;
+Landroidx/compose/ui/text/style/LineHeightStyle$Trim;
+Landroidx/compose/ui/text/style/LineHeightStyle;
+Landroidx/compose/ui/text/style/ResolvedTextDirection;
+Landroidx/compose/ui/text/style/TextAlign$Companion;
+Landroidx/compose/ui/text/style/TextAlign;
+Landroidx/compose/ui/text/style/TextDecoration$Companion;
+Landroidx/compose/ui/text/style/TextDecoration;
+Landroidx/compose/ui/text/style/TextDirection$Companion;
+Landroidx/compose/ui/text/style/TextDirection;
+Landroidx/compose/ui/text/style/TextDrawStyleKt;
+Landroidx/compose/ui/text/style/TextForegroundStyle$Companion;
+Landroidx/compose/ui/text/style/TextForegroundStyle$Unspecified;
+Landroidx/compose/ui/text/style/TextForegroundStyle$merge$1;
+Landroidx/compose/ui/text/style/TextForegroundStyle$merge$2;
+Landroidx/compose/ui/text/style/TextForegroundStyle;
+Landroidx/compose/ui/text/style/TextGeometricTransform$Companion;
+Landroidx/compose/ui/text/style/TextGeometricTransform;
+Landroidx/compose/ui/text/style/TextIndent$Companion;
+Landroidx/compose/ui/text/style/TextIndent;
+Landroidx/compose/ui/text/style/TextOverflow$Companion;
+Landroidx/compose/ui/text/style/TextOverflow;
+Landroidx/compose/ui/unit/AndroidDensity_androidKt;
+Landroidx/compose/ui/unit/Constraints$Companion;
+Landroidx/compose/ui/unit/Constraints;
+Landroidx/compose/ui/unit/ConstraintsKt;
+Landroidx/compose/ui/unit/Density;
+Landroidx/compose/ui/unit/DensityImpl;
+Landroidx/compose/ui/unit/DensityKt;
+Landroidx/compose/ui/unit/Dp$Companion;
+Landroidx/compose/ui/unit/Dp;
+Landroidx/compose/ui/unit/DpKt;
+Landroidx/compose/ui/unit/DpOffset$Companion;
+Landroidx/compose/ui/unit/DpOffset;
+Landroidx/compose/ui/unit/DpSize$Companion;
+Landroidx/compose/ui/unit/DpSize;
+Landroidx/compose/ui/unit/IntOffset$Companion;
+Landroidx/compose/ui/unit/IntOffset;
+Landroidx/compose/ui/unit/IntOffsetKt;
+Landroidx/compose/ui/unit/IntSize$Companion;
+Landroidx/compose/ui/unit/IntSize;
+Landroidx/compose/ui/unit/IntSizeKt;
+Landroidx/compose/ui/unit/LayoutDirection;
+Landroidx/compose/ui/unit/TextUnit$Companion;
+Landroidx/compose/ui/unit/TextUnit;
+Landroidx/compose/ui/unit/TextUnitKt;
+Landroidx/compose/ui/unit/TextUnitType$Companion;
+Landroidx/compose/ui/unit/TextUnitType;
+Landroidx/compose/ui/unit/Velocity$Companion;
+Landroidx/compose/ui/unit/Velocity;
+Landroidx/compose/ui/unit/VelocityKt;
+Landroidx/compose/ui/util/MathHelpersKt;
+Landroidx/core/R$id;
+Landroidx/core/app/ActivityCompat;
+Landroidx/core/app/ActivityOptionsCompat;
+Landroidx/core/app/ComponentActivity;
+Landroidx/core/app/CoreComponentFactory;
+Landroidx/core/app/MultiWindowModeChangedInfo;
+Landroidx/core/app/PictureInPictureModeChangedInfo;
+Landroidx/core/content/ContextCompat;
+Landroidx/core/content/res/FontResourcesParserCompat$FamilyResourceEntry;
+Landroidx/core/content/res/FontResourcesParserCompat$FontFamilyFilesResourceEntry;
+Landroidx/core/content/res/FontResourcesParserCompat$FontFileResourceEntry;
+Landroidx/core/content/res/FontResourcesParserCompat$ProviderResourceEntry;
+Landroidx/core/content/res/FontResourcesParserCompat;
+Landroidx/core/content/res/ResourcesCompat$FontCallback;
+Landroidx/core/graphics/PaintCompat;
+Landroidx/core/graphics/TypefaceCompat$ResourcesCallbackAdapter;
+Landroidx/core/graphics/TypefaceCompat;
+Landroidx/core/graphics/TypefaceCompatApi29Impl;
+Landroidx/core/graphics/TypefaceCompatBaseImpl;
+Landroidx/core/graphics/TypefaceCompatUtil$Api19Impl;
+Landroidx/core/graphics/TypefaceCompatUtil;
+Landroidx/core/graphics/drawable/DrawableKt;
+Landroidx/core/os/BuildCompat;
+Landroidx/core/os/HandlerCompat$Api28Impl;
+Landroidx/core/os/HandlerCompat;
+Landroidx/core/os/TraceCompat$Api18Impl;
+Landroidx/core/os/TraceCompat;
+Landroidx/core/provider/CallbackWithHandler;
+Landroidx/core/provider/FontProvider$$ExternalSyntheticLambda0;
+Landroidx/core/provider/FontProvider$Api16Impl;
+Landroidx/core/provider/FontProvider;
+Landroidx/core/provider/FontRequest;
+Landroidx/core/provider/FontRequestWorker;
+Landroidx/core/provider/FontsContractCompat$FontFamilyResult;
+Landroidx/core/provider/FontsContractCompat$FontInfo;
+Landroidx/core/provider/FontsContractCompat$FontRequestCallback;
+Landroidx/core/provider/FontsContractCompat;
+Landroidx/core/text/TextUtilsCompat;
+Landroidx/core/util/Consumer;
+Landroidx/core/util/Preconditions;
+Landroidx/core/view/AccessibilityDelegateCompat$AccessibilityDelegateAdapter;
+Landroidx/core/view/AccessibilityDelegateCompat$Api16Impl;
+Landroidx/core/view/AccessibilityDelegateCompat;
+Landroidx/core/view/KeyEventDispatcher$Component;
+Landroidx/core/view/KeyEventDispatcher;
+Landroidx/core/view/MenuHostHelper;
+Landroidx/core/view/OnApplyWindowInsetsListener;
+Landroidx/core/view/OnReceiveContentViewBehavior;
+Landroidx/core/view/ViewCompat$$ExternalSyntheticLambda0;
+Landroidx/core/view/ViewCompat$1;
+Landroidx/core/view/ViewCompat$2;
+Landroidx/core/view/ViewCompat$3;
+Landroidx/core/view/ViewCompat$4;
+Landroidx/core/view/ViewCompat$AccessibilityPaneVisibilityManager;
+Landroidx/core/view/ViewCompat$AccessibilityViewProperty;
+Landroidx/core/view/ViewCompat$Api16Impl;
+Landroidx/core/view/ViewCompat$Api17Impl;
+Landroidx/core/view/ViewCompat$Api19Impl;
+Landroidx/core/view/ViewCompat$Api20Impl;
+Landroidx/core/view/ViewCompat$Api21Impl;
+Landroidx/core/view/ViewCompat$Api23Impl;
+Landroidx/core/view/ViewCompat$Api29Impl;
+Landroidx/core/view/ViewCompat;
+Landroidx/core/view/ViewConfigurationCompat;
+Landroidx/core/view/ViewKt;
+Landroidx/core/view/WindowInsetsAnimationCompat$Callback;
+Landroidx/core/view/WindowInsetsAnimationCompat;
+Landroidx/core/view/WindowInsetsCompat$Type;
+Landroidx/core/view/WindowInsetsCompat;
+Landroidx/core/view/WindowInsetsControllerCompat;
+Landroidx/core/view/accessibility/AccessibilityNodeInfoCompat$AccessibilityActionCompat;
+Landroidx/core/view/accessibility/AccessibilityNodeInfoCompat$RangeInfoCompat;
+Landroidx/core/view/accessibility/AccessibilityNodeInfoCompat;
+Landroidx/core/view/accessibility/AccessibilityNodeProviderCompat;
+Landroidx/customview/poolingcontainer/PoolingContainer;
+Landroidx/customview/poolingcontainer/PoolingContainerListener;
+Landroidx/customview/poolingcontainer/PoolingContainerListenerHolder;
+Landroidx/customview/poolingcontainer/R$id;
+Landroidx/emoji2/text/ConcurrencyHelpers$$ExternalSyntheticLambda0;
+Landroidx/emoji2/text/ConcurrencyHelpers$Handler28Impl;
+Landroidx/emoji2/text/ConcurrencyHelpers;
+Landroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigFactory;
+Landroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigHelper;
+Landroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigHelper_API19;
+Landroidx/emoji2/text/DefaultEmojiCompatConfig$DefaultEmojiCompatConfigHelper_API28;
+Landroidx/emoji2/text/DefaultEmojiCompatConfig;
+Landroidx/emoji2/text/DefaultGlyphChecker;
+Landroidx/emoji2/text/EmojiCompat$CompatInternal19$1;
+Landroidx/emoji2/text/EmojiCompat$CompatInternal19;
+Landroidx/emoji2/text/EmojiCompat$CompatInternal;
+Landroidx/emoji2/text/EmojiCompat$Config;
+Landroidx/emoji2/text/EmojiCompat$GlyphChecker;
+Landroidx/emoji2/text/EmojiCompat$InitCallback;
+Landroidx/emoji2/text/EmojiCompat$ListenerDispatcher;
+Landroidx/emoji2/text/EmojiCompat$MetadataRepoLoader;
+Landroidx/emoji2/text/EmojiCompat$MetadataRepoLoaderCallback;
+Landroidx/emoji2/text/EmojiCompat$SpanFactory;
+Landroidx/emoji2/text/EmojiCompat;
+Landroidx/emoji2/text/EmojiCompatInitializer$1;
+Landroidx/emoji2/text/EmojiCompatInitializer$BackgroundDefaultConfig;
+Landroidx/emoji2/text/EmojiCompatInitializer$BackgroundDefaultLoader$$ExternalSyntheticLambda0;
+Landroidx/emoji2/text/EmojiCompatInitializer$BackgroundDefaultLoader$1;
+Landroidx/emoji2/text/EmojiCompatInitializer$BackgroundDefaultLoader;
+Landroidx/emoji2/text/EmojiCompatInitializer$LoadEmojiCompatRunnable;
+Landroidx/emoji2/text/EmojiCompatInitializer;
+Landroidx/emoji2/text/EmojiMetadata;
+Landroidx/emoji2/text/EmojiProcessor$CodepointIndexFinder;
+Landroidx/emoji2/text/EmojiProcessor$ProcessorSm;
+Landroidx/emoji2/text/EmojiProcessor;
+Landroidx/emoji2/text/EmojiSpan;
+Landroidx/emoji2/text/FontRequestEmojiCompatConfig$FontProviderHelper;
+Landroidx/emoji2/text/FontRequestEmojiCompatConfig$FontRequestMetadataLoader$$ExternalSyntheticLambda0;
+Landroidx/emoji2/text/FontRequestEmojiCompatConfig$FontRequestMetadataLoader;
+Landroidx/emoji2/text/FontRequestEmojiCompatConfig;
+Landroidx/emoji2/text/MetadataListReader$ByteBufferReader;
+Landroidx/emoji2/text/MetadataListReader$OffsetInfo;
+Landroidx/emoji2/text/MetadataListReader$OpenTypeReader;
+Landroidx/emoji2/text/MetadataListReader;
+Landroidx/emoji2/text/MetadataRepo$Node;
+Landroidx/emoji2/text/MetadataRepo;
+Landroidx/emoji2/text/SpannableBuilder;
+Landroidx/emoji2/text/TypefaceEmojiSpan;
+Landroidx/emoji2/text/UnprecomputeTextOnModificationSpannable;
+Landroidx/emoji2/text/flatbuffer/MetadataItem;
+Landroidx/emoji2/text/flatbuffer/MetadataList;
+Landroidx/emoji2/text/flatbuffer/Table;
+Landroidx/emoji2/text/flatbuffer/Utf8;
+Landroidx/emoji2/text/flatbuffer/Utf8Safe;
+Landroidx/lifecycle/AndroidViewModel;
+Landroidx/lifecycle/ClassesInfoCache;
+Landroidx/lifecycle/CompositeGeneratedAdaptersObserver;
+Landroidx/lifecycle/DefaultLifecycleObserver;
+Landroidx/lifecycle/EmptyActivityLifecycleCallbacks;
+Landroidx/lifecycle/FullLifecycleObserver;
+Landroidx/lifecycle/FullLifecycleObserverAdapter$1;
+Landroidx/lifecycle/FullLifecycleObserverAdapter;
+Landroidx/lifecycle/GeneratedAdapter;
+Landroidx/lifecycle/HasDefaultViewModelProviderFactory;
+Landroidx/lifecycle/LegacySavedStateHandleController$1;
+Landroidx/lifecycle/LegacySavedStateHandleController$OnRecreation;
+Landroidx/lifecycle/LegacySavedStateHandleController;
+Landroidx/lifecycle/Lifecycle$1;
+Landroidx/lifecycle/Lifecycle$Event;
+Landroidx/lifecycle/Lifecycle$State;
+Landroidx/lifecycle/Lifecycle;
+Landroidx/lifecycle/LifecycleDispatcher$DispatcherActivityCallback;
+Landroidx/lifecycle/LifecycleDispatcher;
+Landroidx/lifecycle/LifecycleEventObserver;
+Landroidx/lifecycle/LifecycleObserver;
+Landroidx/lifecycle/LifecycleOwner;
+Landroidx/lifecycle/LifecycleRegistry$ObserverWithState;
+Landroidx/lifecycle/LifecycleRegistry;
+Landroidx/lifecycle/Lifecycling;
+Landroidx/lifecycle/LiveData$1;
+Landroidx/lifecycle/LiveData$LifecycleBoundObserver;
+Landroidx/lifecycle/LiveData$ObserverWrapper;
+Landroidx/lifecycle/LiveData;
+Landroidx/lifecycle/MutableLiveData;
+Landroidx/lifecycle/Observer;
+Landroidx/lifecycle/ProcessLifecycleInitializer;
+Landroidx/lifecycle/ProcessLifecycleOwner$1;
+Landroidx/lifecycle/ProcessLifecycleOwner$2;
+Landroidx/lifecycle/ProcessLifecycleOwner$3$1;
+Landroidx/lifecycle/ProcessLifecycleOwner$3;
+Landroidx/lifecycle/ProcessLifecycleOwner$Api29Impl;
+Landroidx/lifecycle/ProcessLifecycleOwner;
+Landroidx/lifecycle/ReflectiveGenericLifecycleObserver;
+Landroidx/lifecycle/ReportFragment$ActivityInitializationListener;
+Landroidx/lifecycle/ReportFragment$LifecycleCallbacks;
+Landroidx/lifecycle/ReportFragment;
+Landroidx/lifecycle/SavedStateHandle$Companion;
+Landroidx/lifecycle/SavedStateHandle;
+Landroidx/lifecycle/SavedStateHandleAttacher;
+Landroidx/lifecycle/SavedStateHandleController;
+Landroidx/lifecycle/SavedStateHandleSupport$DEFAULT_ARGS_KEY$1;
+Landroidx/lifecycle/SavedStateHandleSupport$SAVED_STATE_REGISTRY_OWNER_KEY$1;
+Landroidx/lifecycle/SavedStateHandleSupport$VIEW_MODEL_STORE_OWNER_KEY$1;
+Landroidx/lifecycle/SavedStateHandleSupport$savedStateHandlesVM$1$1;
+Landroidx/lifecycle/SavedStateHandleSupport;
+Landroidx/lifecycle/SavedStateHandlesProvider$viewModel$2;
+Landroidx/lifecycle/SavedStateHandlesProvider;
+Landroidx/lifecycle/SavedStateHandlesVM;
+Landroidx/lifecycle/SavedStateViewModelFactory;
+Landroidx/lifecycle/SavedStateViewModelFactoryKt;
+Landroidx/lifecycle/SingleGeneratedAdapterObserver;
+Landroidx/lifecycle/ViewModel;
+Landroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory$Companion$ApplicationKeyImpl;
+Landroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory$Companion;
+Landroidx/lifecycle/ViewModelProvider$AndroidViewModelFactory;
+Landroidx/lifecycle/ViewModelProvider$Factory$Companion;
+Landroidx/lifecycle/ViewModelProvider$Factory;
+Landroidx/lifecycle/ViewModelProvider$NewInstanceFactory$Companion$ViewModelKeyImpl;
+Landroidx/lifecycle/ViewModelProvider$NewInstanceFactory$Companion;
+Landroidx/lifecycle/ViewModelProvider$NewInstanceFactory;
+Landroidx/lifecycle/ViewModelProvider$OnRequeryFactory;
+Landroidx/lifecycle/ViewModelProvider;
+Landroidx/lifecycle/ViewModelProviderGetKt;
+Landroidx/lifecycle/ViewModelStore;
+Landroidx/lifecycle/ViewModelStoreOwner;
+Landroidx/lifecycle/ViewTreeLifecycleOwner;
+Landroidx/lifecycle/ViewTreeViewModelStoreOwner;
+Landroidx/lifecycle/runtime/R$id;
+Landroidx/lifecycle/viewmodel/CreationExtras$Empty;
+Landroidx/lifecycle/viewmodel/CreationExtras$Key;
+Landroidx/lifecycle/viewmodel/CreationExtras;
+Landroidx/lifecycle/viewmodel/InitializerViewModelFactory;
+Landroidx/lifecycle/viewmodel/InitializerViewModelFactoryBuilder;
+Landroidx/lifecycle/viewmodel/MutableCreationExtras;
+Landroidx/lifecycle/viewmodel/R$id;
+Landroidx/lifecycle/viewmodel/ViewModelInitializer;
+Landroidx/lifecycle/viewmodel/compose/LocalViewModelStoreOwner$LocalViewModelStoreOwner$1;
+Landroidx/lifecycle/viewmodel/compose/LocalViewModelStoreOwner;
+Landroidx/lifecycle/viewmodel/compose/ViewModelKt;
+Landroidx/profileinstaller/ProfileInstaller;
+Landroidx/profileinstaller/ProfileInstallerInitializer$$ExternalSyntheticLambda0;
+Landroidx/profileinstaller/ProfileInstallerInitializer$$ExternalSyntheticLambda1;
+Landroidx/profileinstaller/ProfileInstallerInitializer$$ExternalSyntheticLambda2;
+Landroidx/profileinstaller/ProfileInstallerInitializer$Choreographer16Impl$$ExternalSyntheticLambda0;
+Landroidx/profileinstaller/ProfileInstallerInitializer$Choreographer16Impl;
+Landroidx/profileinstaller/ProfileInstallerInitializer$Handler28Impl;
+Landroidx/profileinstaller/ProfileInstallerInitializer$Result;
+Landroidx/profileinstaller/ProfileInstallerInitializer;
+Landroidx/savedstate/R$id;
+Landroidx/savedstate/Recreator$Companion;
+Landroidx/savedstate/Recreator$SavedStateProvider;
+Landroidx/savedstate/Recreator;
+Landroidx/savedstate/SavedStateRegistry$$ExternalSyntheticLambda0;
+Landroidx/savedstate/SavedStateRegistry$AutoRecreated;
+Landroidx/savedstate/SavedStateRegistry$Companion;
+Landroidx/savedstate/SavedStateRegistry$SavedStateProvider;
+Landroidx/savedstate/SavedStateRegistry;
+Landroidx/savedstate/SavedStateRegistryController$Companion;
+Landroidx/savedstate/SavedStateRegistryController;
+Landroidx/savedstate/SavedStateRegistryOwner;
+Landroidx/savedstate/ViewTreeSavedStateRegistryOwner$findViewTreeSavedStateRegistryOwner$1;
+Landroidx/savedstate/ViewTreeSavedStateRegistryOwner$findViewTreeSavedStateRegistryOwner$2;
+Landroidx/savedstate/ViewTreeSavedStateRegistryOwner;
+Landroidx/startup/AppInitializer;
+Landroidx/startup/InitializationProvider;
+Landroidx/startup/Initializer;
+Landroidx/startup/R$string;
+Landroidx/startup/StartupException;
+Landroidx/tracing/Trace;
+Landroidx/tracing/TraceApi18Impl;
+Landroidx/tracing/TraceApi29Impl;
+Lcom/android/credentialmanager/CreateFlowUtils$Companion$toCreateCredentialUiState$$inlined$compareByDescending$1;
+Lcom/android/credentialmanager/CreateFlowUtils$Companion;
+Lcom/android/credentialmanager/CreateFlowUtils;
+Lcom/android/credentialmanager/CredentialManagerRepo$Companion;
+Lcom/android/credentialmanager/CredentialManagerRepo;
+Lcom/android/credentialmanager/CredentialSelectorActivity$CredentialManagerBottomSheet$3;
+Lcom/android/credentialmanager/CredentialSelectorActivity$CredentialManagerBottomSheet$launcher$1$1;
+Lcom/android/credentialmanager/CredentialSelectorActivity$WhenMappings;
+Lcom/android/credentialmanager/CredentialSelectorActivity$onCancel$1;
+Lcom/android/credentialmanager/CredentialSelectorActivity$onCreate$1$1;
+Lcom/android/credentialmanager/CredentialSelectorActivity$onCreate$1;
+Lcom/android/credentialmanager/CredentialSelectorActivity;
+Lcom/android/credentialmanager/GetFlowUtils$Companion;
+Lcom/android/credentialmanager/GetFlowUtils;
+Lcom/android/credentialmanager/UserConfigRepo$Companion;
+Lcom/android/credentialmanager/UserConfigRepo;
+Lcom/android/credentialmanager/common/DialogResult;
+Lcom/android/credentialmanager/common/DialogType$Companion;
+Lcom/android/credentialmanager/common/DialogType;
+Lcom/android/credentialmanager/common/ProviderActivityResult;
+Lcom/android/credentialmanager/common/ResultState;
+Lcom/android/credentialmanager/common/material/FixedThreshold;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetDefaults;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$1$1$1;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$1$1;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$2$1;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$3$1;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$4$1$1;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$4$1;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$4$2;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$4$3;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$4;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$5;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$2;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$1$1;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$2;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$dismissModifier$1$1$1;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$dismissModifier$1$1;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$dismissModifier$2$1$1;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$dismissModifier$2$1;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$rememberModalBottomSheetState$1;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$rememberModalBottomSheetState$2;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt$rememberModalBottomSheetState$3;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetKt;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetState$Companion$Saver$1;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetState$Companion$Saver$2;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetState$Companion;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetState;
+Lcom/android/credentialmanager/common/material/ModalBottomSheetValue;
+Lcom/android/credentialmanager/common/material/ResistanceConfig;
+Lcom/android/credentialmanager/common/material/SwipeableDefaults;
+Lcom/android/credentialmanager/common/material/SwipeableKt$PreUpPostDownNestedScrollConnection$1$onPostFling$1;
+Lcom/android/credentialmanager/common/material/SwipeableKt$PreUpPostDownNestedScrollConnection$1$onPreFling$1;
+Lcom/android/credentialmanager/common/material/SwipeableKt$PreUpPostDownNestedScrollConnection$1;
+Lcom/android/credentialmanager/common/material/SwipeableKt$swipeable$1;
+Lcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3$3$1;
+Lcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3$3;
+Lcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3$4$1$1;
+Lcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3$4$1;
+Lcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3;
+Lcom/android/credentialmanager/common/material/SwipeableKt$swipeable-pPrIpRY$$inlined$debugInspectorInfo$1;
+Lcom/android/credentialmanager/common/material/SwipeableKt;
+Lcom/android/credentialmanager/common/material/SwipeableState$Companion;
+Lcom/android/credentialmanager/common/material/SwipeableState$animateInternalToOffset$2;
+Lcom/android/credentialmanager/common/material/SwipeableState$animateTo$2;
+Lcom/android/credentialmanager/common/material/SwipeableState$draggableState$1;
+Lcom/android/credentialmanager/common/material/SwipeableState$latestNonEmptyAnchorsFlow$1;
+Lcom/android/credentialmanager/common/material/SwipeableState$performFling$2;
+Lcom/android/credentialmanager/common/material/SwipeableState$processNewAnchors$1;
+Lcom/android/credentialmanager/common/material/SwipeableState$snapInternalToOffset$2;
+Lcom/android/credentialmanager/common/material/SwipeableState$special$$inlined$filter$1$2;
+Lcom/android/credentialmanager/common/material/SwipeableState$special$$inlined$filter$1;
+Lcom/android/credentialmanager/common/material/SwipeableState$thresholds$2;
+Lcom/android/credentialmanager/common/material/SwipeableState;
+Lcom/android/credentialmanager/common/material/ThresholdConfig;
+Lcom/android/credentialmanager/common/ui/ActionButtonKt$ActionButton$1;
+Lcom/android/credentialmanager/common/ui/ActionButtonKt$ActionButton$2;
+Lcom/android/credentialmanager/common/ui/ActionButtonKt;
+Lcom/android/credentialmanager/common/ui/CardsKt$ContainerCard$1;
+Lcom/android/credentialmanager/common/ui/CardsKt;
+Lcom/android/credentialmanager/common/ui/ConfirmButtonKt$ConfirmButton$1;
+Lcom/android/credentialmanager/common/ui/ConfirmButtonKt$ConfirmButton$2;
+Lcom/android/credentialmanager/common/ui/ConfirmButtonKt;
+Lcom/android/credentialmanager/common/ui/EntryKt$Entry$1;
+Lcom/android/credentialmanager/common/ui/EntryKt$TransparentBackgroundEntry$1;
+Lcom/android/credentialmanager/common/ui/EntryKt;
+Lcom/android/credentialmanager/common/ui/TextsKt$TextInternal$1;
+Lcom/android/credentialmanager/common/ui/TextsKt$TextOnSurface$1;
+Lcom/android/credentialmanager/common/ui/TextsKt$TextOnSurfaceVariant$1;
+Lcom/android/credentialmanager/common/ui/TextsKt$TextSecondary$1;
+Lcom/android/credentialmanager/common/ui/TextsKt;
+Lcom/android/credentialmanager/createflow/ActiveEntry;
+Lcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-1$1;
+Lcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-2$1;
+Lcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-3$1;
+Lcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-4$1;
+Lcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-5$1;
+Lcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$ConfirmationCard$1;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$ConfirmationCard$2;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$10;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$11;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$12;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$13;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$14;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$15;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$16;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$17;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$18;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$1;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$2;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$3;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$4;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$5;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$6;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$7;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$8;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$9;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$WhenMappings;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$2;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$3;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreationSelectionCard$1$1$1;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreationSelectionCard$1;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreationSelectionCard$2;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$ExternalOnlySelectionCard$1;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$ExternalOnlySelectionCard$2;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsDisabledProvidersRow$1;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsDisabledProvidersRow$2;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsInfoRow$1;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsInfoRow$2;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsInfoRow$3;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsRowIntroCard$1;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsRowIntroCard$2;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$2;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$PrimaryCreateOptionRow$1;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$PrimaryCreateOptionRow$2;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$PrimaryCreateOptionRow$3;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$PrimaryCreateOptionRow$4;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$ProviderSelectionCard$1;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$ProviderSelectionCard$2;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$RemoteEntryRow$1$1;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$RemoteEntryRow$2;
+Lcom/android/credentialmanager/createflow/CreateCredentialComponentsKt;
+Lcom/android/credentialmanager/createflow/CreateCredentialUiState;
+Lcom/android/credentialmanager/createflow/CreateCredentialViewModel$dialogResult$2;
+Lcom/android/credentialmanager/createflow/CreateCredentialViewModel;
+Lcom/android/credentialmanager/createflow/CreateOptionInfo;
+Lcom/android/credentialmanager/createflow/CreateScreenState;
+Lcom/android/credentialmanager/createflow/DisabledProviderInfo;
+Lcom/android/credentialmanager/createflow/EnabledProviderInfo;
+Lcom/android/credentialmanager/createflow/EntryInfo;
+Lcom/android/credentialmanager/createflow/ProviderInfo;
+Lcom/android/credentialmanager/createflow/RemoteInfo;
+Lcom/android/credentialmanager/createflow/RequestDisplayInfo;
+Lcom/android/credentialmanager/getflow/EntryInfo;
+Lcom/android/credentialmanager/getflow/GetCredentialComponentsKt;
+Lcom/android/credentialmanager/getflow/GetCredentialUiState;
+Lcom/android/credentialmanager/getflow/GetCredentialViewModel;
+Lcom/android/credentialmanager/getflow/GetScreenState;
+Lcom/android/credentialmanager/getflow/ProviderDisplayInfo;
+Lcom/android/credentialmanager/getflow/RequestDisplayInfo;
+Lcom/android/credentialmanager/jetpack/developer/CreateCredentialRequest$Companion;
+Lcom/android/credentialmanager/jetpack/developer/CreateCredentialRequest;
+Lcom/android/credentialmanager/jetpack/developer/CreateCustomCredentialRequest;
+Lcom/android/credentialmanager/jetpack/developer/CreatePasswordRequest$Companion;
+Lcom/android/credentialmanager/jetpack/developer/CreatePasswordRequest;
+Lcom/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest$Companion;
+Lcom/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest;
+Lcom/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequestPrivileged$Companion;
+Lcom/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequestPrivileged;
+Lcom/android/credentialmanager/jetpack/developer/FrameworkClassParsingException;
+Lcom/android/credentialmanager/jetpack/provider/Action$Companion;
+Lcom/android/credentialmanager/jetpack/provider/Action;
+Lcom/android/credentialmanager/jetpack/provider/CreateEntry$Companion;
+Lcom/android/credentialmanager/jetpack/provider/CreateEntry;
+Lcom/android/credentialmanager/jetpack/provider/CredentialCountInformation$Companion;
+Lcom/android/credentialmanager/jetpack/provider/CredentialCountInformation;
+Lcom/android/credentialmanager/jetpack/provider/CredentialEntry$Companion;
+Lcom/android/credentialmanager/jetpack/provider/CredentialEntry;
+Lcom/android/credentialmanager/ui/theme/AndroidColorScheme;
+Lcom/android/credentialmanager/ui/theme/AndroidColorSchemeKt$LocalAndroidColorScheme$1;
+Lcom/android/credentialmanager/ui/theme/AndroidColorSchemeKt;
+Lcom/android/credentialmanager/ui/theme/ColorKt;
+Lcom/android/credentialmanager/ui/theme/EntryShape;
+Lcom/android/credentialmanager/ui/theme/ShapeKt;
+Lcom/android/credentialmanager/ui/theme/ThemeKt$CredentialSelectorTheme$1$1;
+Lcom/android/credentialmanager/ui/theme/ThemeKt$CredentialSelectorTheme$1;
+Lcom/android/credentialmanager/ui/theme/ThemeKt$CredentialSelectorTheme$2;
+Lcom/android/credentialmanager/ui/theme/ThemeKt;
+Lcom/android/credentialmanager/ui/theme/TypeKt;
+Lkotlin/ExceptionsKt;
+Lkotlin/ExceptionsKt__ExceptionsKt;
+Lkotlin/Function;
+Lkotlin/InitializedLazyImpl;
+Lkotlin/KotlinNothingValueException;
+Lkotlin/Lazy;
+Lkotlin/LazyKt;
+Lkotlin/LazyKt__LazyJVMKt$WhenMappings;
+Lkotlin/LazyKt__LazyJVMKt;
+Lkotlin/LazyKt__LazyKt;
+Lkotlin/LazyThreadSafetyMode;
+Lkotlin/NoWhenBranchMatchedException;
+Lkotlin/Pair;
+Lkotlin/Result$Companion;
+Lkotlin/Result$Failure;
+Lkotlin/Result;
+Lkotlin/ResultKt;
+Lkotlin/SafePublicationLazyImpl;
+Lkotlin/SynchronizedLazyImpl;
+Lkotlin/TuplesKt;
+Lkotlin/ULong$Companion;
+Lkotlin/ULong;
+Lkotlin/UNINITIALIZED_VALUE;
+Lkotlin/UninitializedPropertyAccessException;
+Lkotlin/Unit;
+Lkotlin/UnsafeLazyImpl;
+Lkotlin/UnsignedKt;
+Lkotlin/collections/AbstractCollection$toString$1;
+Lkotlin/collections/AbstractCollection;
+Lkotlin/collections/AbstractList$Companion;
+Lkotlin/collections/AbstractList$IteratorImpl;
+Lkotlin/collections/AbstractList$ListIteratorImpl;
+Lkotlin/collections/AbstractList;
+Lkotlin/collections/AbstractMap$Companion;
+Lkotlin/collections/AbstractMap$toString$1;
+Lkotlin/collections/AbstractMap;
+Lkotlin/collections/AbstractMutableCollection;
+Lkotlin/collections/AbstractMutableList;
+Lkotlin/collections/AbstractMutableMap;
+Lkotlin/collections/AbstractMutableSet;
+Lkotlin/collections/AbstractSet$Companion;
+Lkotlin/collections/AbstractSet;
+Lkotlin/collections/ArrayAsCollection;
+Lkotlin/collections/ArrayDeque$Companion;
+Lkotlin/collections/ArrayDeque;
+Lkotlin/collections/ArraysKt;
+Lkotlin/collections/ArraysKt__ArraysJVMKt;
+Lkotlin/collections/ArraysKt__ArraysKt;
+Lkotlin/collections/ArraysKt___ArraysJvmKt;
+Lkotlin/collections/ArraysKt___ArraysKt;
+Lkotlin/collections/ArraysUtilJVM;
+Lkotlin/collections/CollectionsKt;
+Lkotlin/collections/CollectionsKt__CollectionsJVMKt;
+Lkotlin/collections/CollectionsKt__CollectionsKt;
+Lkotlin/collections/CollectionsKt__IterablesKt;
+Lkotlin/collections/CollectionsKt__IteratorsJVMKt;
+Lkotlin/collections/CollectionsKt__IteratorsKt;
+Lkotlin/collections/CollectionsKt__MutableCollectionsJVMKt;
+Lkotlin/collections/CollectionsKt__MutableCollectionsKt;
+Lkotlin/collections/CollectionsKt__ReversedViewsKt;
+Lkotlin/collections/CollectionsKt___CollectionsJvmKt;
+Lkotlin/collections/CollectionsKt___CollectionsKt;
+Lkotlin/collections/EmptyIterator;
+Lkotlin/collections/EmptyList;
+Lkotlin/collections/EmptyMap;
+Lkotlin/collections/EmptySet;
+Lkotlin/collections/IntIterator;
+Lkotlin/collections/MapsKt;
+Lkotlin/collections/MapsKt__MapWithDefaultKt;
+Lkotlin/collections/MapsKt__MapsJVMKt;
+Lkotlin/collections/MapsKt__MapsKt;
+Lkotlin/collections/MapsKt___MapsJvmKt;
+Lkotlin/collections/MapsKt___MapsKt;
+Lkotlin/collections/SetsKt__SetsJVMKt;
+Lkotlin/collections/SetsKt__SetsKt;
+Lkotlin/collections/builders/ListBuilder;
+Lkotlin/collections/builders/MapBuilder;
+Lkotlin/comparisons/ComparisonsKt;
+Lkotlin/comparisons/ComparisonsKt__ComparisonsKt;
+Lkotlin/comparisons/ComparisonsKt___ComparisonsJvmKt;
+Lkotlin/comparisons/ComparisonsKt___ComparisonsKt;
+Lkotlin/coroutines/AbstractCoroutineContextElement;
+Lkotlin/coroutines/AbstractCoroutineContextKey;
+Lkotlin/coroutines/CombinedContext$Serialized;
+Lkotlin/coroutines/CombinedContext$toString$1;
+Lkotlin/coroutines/CombinedContext$writeReplace$1;
+Lkotlin/coroutines/CombinedContext;
+Lkotlin/coroutines/Continuation;
+Lkotlin/coroutines/ContinuationInterceptor$DefaultImpls;
+Lkotlin/coroutines/ContinuationInterceptor$Key;
+Lkotlin/coroutines/ContinuationInterceptor;
+Lkotlin/coroutines/ContinuationKt;
+Lkotlin/coroutines/CoroutineContext$DefaultImpls;
+Lkotlin/coroutines/CoroutineContext$Element$DefaultImpls;
+Lkotlin/coroutines/CoroutineContext$Element;
+Lkotlin/coroutines/CoroutineContext$Key;
+Lkotlin/coroutines/CoroutineContext$plus$1;
+Lkotlin/coroutines/CoroutineContext;
+Lkotlin/coroutines/EmptyCoroutineContext;
+Lkotlin/coroutines/SafeContinuation$Companion;
+Lkotlin/coroutines/SafeContinuation;
+Lkotlin/coroutines/intrinsics/CoroutineSingletons;
+Lkotlin/coroutines/intrinsics/IntrinsicsKt;
+Lkotlin/coroutines/intrinsics/IntrinsicsKt__IntrinsicsJvmKt$createCoroutineUnintercepted$$inlined$createCoroutineFromSuspendFunction$IntrinsicsKt__IntrinsicsJvmKt$3;
+Lkotlin/coroutines/intrinsics/IntrinsicsKt__IntrinsicsJvmKt$createCoroutineUnintercepted$$inlined$createCoroutineFromSuspendFunction$IntrinsicsKt__IntrinsicsJvmKt$4;
+Lkotlin/coroutines/intrinsics/IntrinsicsKt__IntrinsicsJvmKt;
+Lkotlin/coroutines/intrinsics/IntrinsicsKt__IntrinsicsKt;
+Lkotlin/coroutines/jvm/internal/BaseContinuationImpl;
+Lkotlin/coroutines/jvm/internal/Boxing;
+Lkotlin/coroutines/jvm/internal/CompletedContinuation;
+Lkotlin/coroutines/jvm/internal/ContinuationImpl;
+Lkotlin/coroutines/jvm/internal/CoroutineStackFrame;
+Lkotlin/coroutines/jvm/internal/DebugMetadataKt;
+Lkotlin/coroutines/jvm/internal/DebugProbesKt;
+Lkotlin/coroutines/jvm/internal/RestrictedContinuationImpl;
+Lkotlin/coroutines/jvm/internal/RestrictedSuspendLambda;
+Lkotlin/coroutines/jvm/internal/SuspendLambda;
+Lkotlin/internal/ProgressionUtilKt;
+Lkotlin/io/CloseableKt;
+Lkotlin/jvm/JvmClassMappingKt;
+Lkotlin/jvm/KotlinReflectionNotSupportedError;
+Lkotlin/jvm/functions/Function0;
+Lkotlin/jvm/functions/Function10;
+Lkotlin/jvm/functions/Function11;
+Lkotlin/jvm/functions/Function12;
+Lkotlin/jvm/functions/Function13;
+Lkotlin/jvm/functions/Function14;
+Lkotlin/jvm/functions/Function15;
+Lkotlin/jvm/functions/Function16;
+Lkotlin/jvm/functions/Function17;
+Lkotlin/jvm/functions/Function18;
+Lkotlin/jvm/functions/Function19;
+Lkotlin/jvm/functions/Function1;
+Lkotlin/jvm/functions/Function20;
+Lkotlin/jvm/functions/Function21;
+Lkotlin/jvm/functions/Function22;
+Lkotlin/jvm/functions/Function2;
+Lkotlin/jvm/functions/Function3;
+Lkotlin/jvm/functions/Function4;
+Lkotlin/jvm/functions/Function5;
+Lkotlin/jvm/functions/Function6;
+Lkotlin/jvm/functions/Function7;
+Lkotlin/jvm/functions/Function8;
+Lkotlin/jvm/functions/Function9;
+Lkotlin/jvm/internal/ArrayIteratorKt;
+Lkotlin/jvm/internal/CallableReference$NoReceiver;
+Lkotlin/jvm/internal/CallableReference;
+Lkotlin/jvm/internal/ClassBasedDeclarationContainer;
+Lkotlin/jvm/internal/ClassReference$Companion;
+Lkotlin/jvm/internal/ClassReference;
+Lkotlin/jvm/internal/CollectionToArray;
+Lkotlin/jvm/internal/DefaultConstructorMarker;
+Lkotlin/jvm/internal/FloatCompanionObject;
+Lkotlin/jvm/internal/FunctionBase;
+Lkotlin/jvm/internal/FunctionReference;
+Lkotlin/jvm/internal/FunctionReferenceImpl;
+Lkotlin/jvm/internal/InlineMarker;
+Lkotlin/jvm/internal/IntCompanionObject;
+Lkotlin/jvm/internal/Intrinsics;
+Lkotlin/jvm/internal/Lambda;
+Lkotlin/jvm/internal/MutablePropertyReference1;
+Lkotlin/jvm/internal/MutablePropertyReference1Impl;
+Lkotlin/jvm/internal/MutablePropertyReference;
+Lkotlin/jvm/internal/PackageReference;
+Lkotlin/jvm/internal/PropertyReference0;
+Lkotlin/jvm/internal/PropertyReference0Impl;
+Lkotlin/jvm/internal/PropertyReference;
+Lkotlin/jvm/internal/Ref$BooleanRef;
+Lkotlin/jvm/internal/Ref$IntRef;
+Lkotlin/jvm/internal/Ref$LongRef;
+Lkotlin/jvm/internal/Ref$ObjectRef;
+Lkotlin/jvm/internal/Reflection;
+Lkotlin/jvm/internal/ReflectionFactory;
+Lkotlin/jvm/internal/SpreadBuilder;
+Lkotlin/jvm/internal/TypeIntrinsics;
+Lkotlin/jvm/internal/markers/KMappedMarker;
+Lkotlin/jvm/internal/markers/KMutableCollection;
+Lkotlin/jvm/internal/markers/KMutableIterable;
+Lkotlin/jvm/internal/markers/KMutableMap$Entry;
+Lkotlin/jvm/internal/markers/KMutableMap;
+Lkotlin/jvm/internal/markers/KMutableSet;
+Lkotlin/math/MathKt;
+Lkotlin/math/MathKt__MathHKt;
+Lkotlin/math/MathKt__MathJVMKt;
+Lkotlin/ranges/ClosedFloatRange;
+Lkotlin/ranges/ClosedFloatingPointRange;
+Lkotlin/ranges/ClosedRange;
+Lkotlin/ranges/IntProgression$Companion;
+Lkotlin/ranges/IntProgression;
+Lkotlin/ranges/IntProgressionIterator;
+Lkotlin/ranges/IntRange$Companion;
+Lkotlin/ranges/IntRange;
+Lkotlin/ranges/RangesKt;
+Lkotlin/ranges/RangesKt__RangesKt;
+Lkotlin/ranges/RangesKt___RangesKt;
+Lkotlin/reflect/KCallable;
+Lkotlin/reflect/KClass;
+Lkotlin/reflect/KDeclarationContainer;
+Lkotlin/reflect/KFunction;
+Lkotlin/reflect/KMutableProperty1;
+Lkotlin/reflect/KProperty0;
+Lkotlin/reflect/KProperty1$Getter;
+Lkotlin/reflect/KProperty1;
+Lkotlin/reflect/KProperty;
+Lkotlin/sequences/ConstrainedOnceSequence;
+Lkotlin/sequences/EmptySequence;
+Lkotlin/sequences/FilteringSequence$iterator$1;
+Lkotlin/sequences/FilteringSequence;
+Lkotlin/sequences/GeneratorSequence$iterator$1;
+Lkotlin/sequences/GeneratorSequence;
+Lkotlin/sequences/Sequence;
+Lkotlin/sequences/SequenceBuilderIterator;
+Lkotlin/sequences/SequenceScope;
+Lkotlin/sequences/SequencesKt;
+Lkotlin/sequences/SequencesKt__SequenceBuilderKt$sequence$$inlined$Sequence$1;
+Lkotlin/sequences/SequencesKt__SequenceBuilderKt;
+Lkotlin/sequences/SequencesKt__SequencesJVMKt;
+Lkotlin/sequences/SequencesKt__SequencesKt$asSequence$$inlined$Sequence$1;
+Lkotlin/sequences/SequencesKt__SequencesKt$generateSequence$2;
+Lkotlin/sequences/SequencesKt__SequencesKt;
+Lkotlin/sequences/SequencesKt___SequencesJvmKt;
+Lkotlin/sequences/SequencesKt___SequencesKt$filterNotNull$1;
+Lkotlin/sequences/SequencesKt___SequencesKt;
+Lkotlin/sequences/TransformingSequence$iterator$1;
+Lkotlin/sequences/TransformingSequence;
+Lkotlin/text/CharsKt;
+Lkotlin/text/CharsKt__CharJVMKt;
+Lkotlin/text/CharsKt__CharKt;
+Lkotlin/text/DelimitedRangesSequence;
+Lkotlin/text/StringsKt;
+Lkotlin/text/StringsKt__AppendableKt;
+Lkotlin/text/StringsKt__IndentKt$getIndentFunction$1;
+Lkotlin/text/StringsKt__IndentKt$getIndentFunction$2;
+Lkotlin/text/StringsKt__IndentKt;
+Lkotlin/text/StringsKt__RegexExtensionsJVMKt;
+Lkotlin/text/StringsKt__RegexExtensionsKt;
+Lkotlin/text/StringsKt__StringBuilderJVMKt;
+Lkotlin/text/StringsKt__StringBuilderKt;
+Lkotlin/text/StringsKt__StringNumberConversionsJVMKt;
+Lkotlin/text/StringsKt__StringNumberConversionsKt;
+Lkotlin/text/StringsKt__StringsJVMKt;
+Lkotlin/text/StringsKt__StringsKt$rangesDelimitedBy$2;
+Lkotlin/text/StringsKt__StringsKt$splitToSequence$1;
+Lkotlin/text/StringsKt__StringsKt;
+Lkotlin/text/StringsKt___StringsJvmKt;
+Lkotlin/text/StringsKt___StringsKt;
+Lkotlinx/atomicfu/AtomicArray;
+Lkotlinx/atomicfu/AtomicBoolean$Companion;
+Lkotlinx/atomicfu/AtomicBoolean;
+Lkotlinx/atomicfu/AtomicFU;
+Lkotlinx/atomicfu/AtomicFU_commonKt;
+Lkotlinx/atomicfu/AtomicInt$Companion;
+Lkotlinx/atomicfu/AtomicInt;
+Lkotlinx/atomicfu/AtomicLong$Companion;
+Lkotlinx/atomicfu/AtomicLong;
+Lkotlinx/atomicfu/AtomicRef$Companion;
+Lkotlinx/atomicfu/AtomicRef;
+Lkotlinx/atomicfu/TraceBase$None;
+Lkotlinx/atomicfu/TraceBase;
+Lkotlinx/coroutines/AbstractCoroutine;
+Lkotlinx/coroutines/AbstractTimeSource;
+Lkotlinx/coroutines/AbstractTimeSourceKt;
+Lkotlinx/coroutines/Active;
+Lkotlinx/coroutines/BeforeResumeCancelHandler;
+Lkotlinx/coroutines/BlockingEventLoop;
+Lkotlinx/coroutines/BuildersKt;
+Lkotlinx/coroutines/BuildersKt__BuildersKt;
+Lkotlinx/coroutines/BuildersKt__Builders_commonKt;
+Lkotlinx/coroutines/CancelHandler;
+Lkotlinx/coroutines/CancelHandlerBase;
+Lkotlinx/coroutines/CancellableContinuation$DefaultImpls;
+Lkotlinx/coroutines/CancellableContinuation;
+Lkotlinx/coroutines/CancellableContinuationImpl;
+Lkotlinx/coroutines/CancellableContinuationImplKt;
+Lkotlinx/coroutines/CancellableContinuationKt;
+Lkotlinx/coroutines/CancelledContinuation;
+Lkotlinx/coroutines/ChildContinuation;
+Lkotlinx/coroutines/ChildHandle;
+Lkotlinx/coroutines/ChildHandleNode;
+Lkotlinx/coroutines/ChildJob;
+Lkotlinx/coroutines/CompletableJob;
+Lkotlinx/coroutines/CompletedContinuation;
+Lkotlinx/coroutines/CompletedExceptionally;
+Lkotlinx/coroutines/CompletedWithCancellation;
+Lkotlinx/coroutines/CompletionHandlerBase;
+Lkotlinx/coroutines/CompletionHandlerException;
+Lkotlinx/coroutines/CompletionStateKt;
+Lkotlinx/coroutines/CopyableThrowable;
+Lkotlinx/coroutines/CoroutineContextKt$foldCopies$1;
+Lkotlinx/coroutines/CoroutineContextKt$foldCopies$folded$1;
+Lkotlinx/coroutines/CoroutineContextKt$hasCopyableElements$1;
+Lkotlinx/coroutines/CoroutineContextKt;
+Lkotlinx/coroutines/CoroutineDispatcher$Key$1;
+Lkotlinx/coroutines/CoroutineDispatcher$Key;
+Lkotlinx/coroutines/CoroutineDispatcher;
+Lkotlinx/coroutines/CoroutineExceptionHandler$Key;
+Lkotlinx/coroutines/CoroutineExceptionHandler;
+Lkotlinx/coroutines/CoroutineExceptionHandlerKt;
+Lkotlinx/coroutines/CoroutineId$Key;
+Lkotlinx/coroutines/CoroutineId;
+Lkotlinx/coroutines/CoroutineName$Key;
+Lkotlinx/coroutines/CoroutineName;
+Lkotlinx/coroutines/CoroutineScope;
+Lkotlinx/coroutines/CoroutineScopeKt;
+Lkotlinx/coroutines/CoroutineStart$WhenMappings;
+Lkotlinx/coroutines/CoroutineStart;
+Lkotlinx/coroutines/CoroutinesInternalError;
+Lkotlinx/coroutines/DebugKt;
+Lkotlinx/coroutines/DebugStringsKt;
+Lkotlinx/coroutines/DefaultExecutor;
+Lkotlinx/coroutines/DefaultExecutorKt;
+Lkotlinx/coroutines/Delay;
+Lkotlinx/coroutines/DelayKt;
+Lkotlinx/coroutines/DispatchedCoroutine;
+Lkotlinx/coroutines/DispatchedTask;
+Lkotlinx/coroutines/DispatchedTaskKt;
+Lkotlinx/coroutines/Dispatchers;
+Lkotlinx/coroutines/DisposableHandle;
+Lkotlinx/coroutines/DisposeOnCancel;
+Lkotlinx/coroutines/Empty;
+Lkotlinx/coroutines/EventLoop;
+Lkotlinx/coroutines/EventLoopImplBase$DelayedResumeTask;
+Lkotlinx/coroutines/EventLoopImplBase$DelayedTask;
+Lkotlinx/coroutines/EventLoopImplBase$DelayedTaskQueue;
+Lkotlinx/coroutines/EventLoopImplBase;
+Lkotlinx/coroutines/EventLoopImplPlatform;
+Lkotlinx/coroutines/EventLoopKt;
+Lkotlinx/coroutines/EventLoop_commonKt;
+Lkotlinx/coroutines/ExceptionsKt;
+Lkotlinx/coroutines/ExecutorCoroutineDispatcher$Key$1;
+Lkotlinx/coroutines/ExecutorCoroutineDispatcher$Key;
+Lkotlinx/coroutines/ExecutorCoroutineDispatcher;
+Lkotlinx/coroutines/GlobalScope;
+Lkotlinx/coroutines/InactiveNodeList;
+Lkotlinx/coroutines/Incomplete;
+Lkotlinx/coroutines/IncompleteStateBox;
+Lkotlinx/coroutines/InvokeOnCancel;
+Lkotlinx/coroutines/InvokeOnCancelling;
+Lkotlinx/coroutines/InvokeOnCompletion;
+Lkotlinx/coroutines/Job$DefaultImpls;
+Lkotlinx/coroutines/Job$Key;
+Lkotlinx/coroutines/Job;
+Lkotlinx/coroutines/JobCancellationException;
+Lkotlinx/coroutines/JobCancellingNode;
+Lkotlinx/coroutines/JobImpl;
+Lkotlinx/coroutines/JobKt;
+Lkotlinx/coroutines/JobKt__JobKt;
+Lkotlinx/coroutines/JobNode;
+Lkotlinx/coroutines/JobSupport$AwaitContinuation;
+Lkotlinx/coroutines/JobSupport$ChildCompletion;
+Lkotlinx/coroutines/JobSupport$Finishing;
+Lkotlinx/coroutines/JobSupport$addLastAtomic$$inlined$addLastIf$1;
+Lkotlinx/coroutines/JobSupport$children$1;
+Lkotlinx/coroutines/JobSupport;
+Lkotlinx/coroutines/JobSupportKt;
+Lkotlinx/coroutines/LazyStandaloneCoroutine;
+Lkotlinx/coroutines/MainCoroutineDispatcher;
+Lkotlinx/coroutines/NodeList;
+Lkotlinx/coroutines/NonDisposableHandle;
+Lkotlinx/coroutines/NotCompleted;
+Lkotlinx/coroutines/ParentJob;
+Lkotlinx/coroutines/RemoveOnCancel;
+Lkotlinx/coroutines/ResumeAwaitOnCompletion;
+Lkotlinx/coroutines/ResumeOnCompletion;
+Lkotlinx/coroutines/StandaloneCoroutine;
+Lkotlinx/coroutines/SupervisorJobImpl;
+Lkotlinx/coroutines/SupervisorKt;
+Lkotlinx/coroutines/ThreadContextElement;
+Lkotlinx/coroutines/ThreadLocalEventLoop;
+Lkotlinx/coroutines/TimeoutCancellationException;
+Lkotlinx/coroutines/Unconfined;
+Lkotlinx/coroutines/UndispatchedCoroutine;
+Lkotlinx/coroutines/UndispatchedMarker;
+Lkotlinx/coroutines/YieldContext$Key;
+Lkotlinx/coroutines/YieldContext;
+Lkotlinx/coroutines/android/AndroidDispatcherFactory;
+Lkotlinx/coroutines/android/HandlerContext$scheduleResumeAfterDelay$$inlined$Runnable$1;
+Lkotlinx/coroutines/android/HandlerContext$scheduleResumeAfterDelay$1;
+Lkotlinx/coroutines/android/HandlerContext;
+Lkotlinx/coroutines/android/HandlerDispatcher;
+Lkotlinx/coroutines/android/HandlerDispatcherKt;
+Lkotlinx/coroutines/channels/AbstractChannel$Itr;
+Lkotlinx/coroutines/channels/AbstractChannel$ReceiveElement;
+Lkotlinx/coroutines/channels/AbstractChannel$ReceiveElementWithUndeliveredHandler;
+Lkotlinx/coroutines/channels/AbstractChannel$ReceiveHasNext;
+Lkotlinx/coroutines/channels/AbstractChannel$RemoveReceiveOnCancel;
+Lkotlinx/coroutines/channels/AbstractChannel$enqueueReceiveInternal$$inlined$addLastIfPrevAndIf$1;
+Lkotlinx/coroutines/channels/AbstractChannel$receiveCatching$1;
+Lkotlinx/coroutines/channels/AbstractChannel;
+Lkotlinx/coroutines/channels/AbstractChannelKt;
+Lkotlinx/coroutines/channels/AbstractSendChannel$SendBuffered;
+Lkotlinx/coroutines/channels/AbstractSendChannel$enqueueSend$$inlined$addLastIfPrevAndIf$1;
+Lkotlinx/coroutines/channels/AbstractSendChannel;
+Lkotlinx/coroutines/channels/ArrayChannel$WhenMappings;
+Lkotlinx/coroutines/channels/ArrayChannel;
+Lkotlinx/coroutines/channels/BufferOverflow;
+Lkotlinx/coroutines/channels/Channel$Factory;
+Lkotlinx/coroutines/channels/Channel;
+Lkotlinx/coroutines/channels/ChannelCoroutine;
+Lkotlinx/coroutines/channels/ChannelIterator;
+Lkotlinx/coroutines/channels/ChannelKt;
+Lkotlinx/coroutines/channels/ChannelResult$Closed;
+Lkotlinx/coroutines/channels/ChannelResult$Companion;
+Lkotlinx/coroutines/channels/ChannelResult$Failed;
+Lkotlinx/coroutines/channels/ChannelResult;
+Lkotlinx/coroutines/channels/ChannelsKt;
+Lkotlinx/coroutines/channels/Closed;
+Lkotlinx/coroutines/channels/ConflatedChannel;
+Lkotlinx/coroutines/channels/LinkedListChannel;
+Lkotlinx/coroutines/channels/ProduceKt;
+Lkotlinx/coroutines/channels/ProducerCoroutine;
+Lkotlinx/coroutines/channels/ProducerScope;
+Lkotlinx/coroutines/channels/Receive;
+Lkotlinx/coroutines/channels/ReceiveChannel;
+Lkotlinx/coroutines/channels/ReceiveOrClosed;
+Lkotlinx/coroutines/channels/RendezvousChannel;
+Lkotlinx/coroutines/channels/Send;
+Lkotlinx/coroutines/channels/SendChannel$DefaultImpls;
+Lkotlinx/coroutines/channels/SendChannel;
+Lkotlinx/coroutines/channels/SendElement;
+Lkotlinx/coroutines/channels/SendElementWithUndeliveredHandler;
+Lkotlinx/coroutines/flow/AbstractFlow$collect$1;
+Lkotlinx/coroutines/flow/AbstractFlow;
+Lkotlinx/coroutines/flow/DistinctFlowImpl$collect$2$emit$1;
+Lkotlinx/coroutines/flow/DistinctFlowImpl$collect$2;
+Lkotlinx/coroutines/flow/DistinctFlowImpl;
+Lkotlinx/coroutines/flow/Flow;
+Lkotlinx/coroutines/flow/FlowCollector;
+Lkotlinx/coroutines/flow/FlowKt;
+Lkotlinx/coroutines/flow/FlowKt__BuildersKt$flowOf$$inlined$unsafeFlow$2;
+Lkotlinx/coroutines/flow/FlowKt__BuildersKt;
+Lkotlinx/coroutines/flow/FlowKt__ChannelsKt$emitAllImpl$1;
+Lkotlinx/coroutines/flow/FlowKt__ChannelsKt;
+Lkotlinx/coroutines/flow/FlowKt__CollectKt;
+Lkotlinx/coroutines/flow/FlowKt__ContextKt;
+Lkotlinx/coroutines/flow/FlowKt__DistinctKt$defaultAreEquivalent$1;
+Lkotlinx/coroutines/flow/FlowKt__DistinctKt$defaultKeySelector$1;
+Lkotlinx/coroutines/flow/FlowKt__DistinctKt;
+Lkotlinx/coroutines/flow/FlowKt__EmittersKt;
+Lkotlinx/coroutines/flow/FlowKt__LimitKt$dropWhile$$inlined$unsafeFlow$1;
+Lkotlinx/coroutines/flow/FlowKt__LimitKt$dropWhile$1$1$emit$1;
+Lkotlinx/coroutines/flow/FlowKt__LimitKt$dropWhile$1$1;
+Lkotlinx/coroutines/flow/FlowKt__LimitKt$emitAbort$1;
+Lkotlinx/coroutines/flow/FlowKt__LimitKt$take$$inlined$unsafeFlow$1$1;
+Lkotlinx/coroutines/flow/FlowKt__LimitKt$take$$inlined$unsafeFlow$1;
+Lkotlinx/coroutines/flow/FlowKt__LimitKt$take$2$1;
+Lkotlinx/coroutines/flow/FlowKt__LimitKt;
+Lkotlinx/coroutines/flow/FlowKt__MergeKt$mapLatest$1;
+Lkotlinx/coroutines/flow/FlowKt__MergeKt;
+Lkotlinx/coroutines/flow/FlowKt__ReduceKt$first$$inlined$collectWhile$2$1;
+Lkotlinx/coroutines/flow/FlowKt__ReduceKt$first$$inlined$collectWhile$2;
+Lkotlinx/coroutines/flow/FlowKt__ReduceKt$first$3;
+Lkotlinx/coroutines/flow/FlowKt__ReduceKt;
+Lkotlinx/coroutines/flow/FlowKt__ShareKt$launchSharing$1$1;
+Lkotlinx/coroutines/flow/FlowKt__ShareKt$launchSharing$1$2$WhenMappings;
+Lkotlinx/coroutines/flow/FlowKt__ShareKt$launchSharing$1$2;
+Lkotlinx/coroutines/flow/FlowKt__ShareKt$launchSharing$1;
+Lkotlinx/coroutines/flow/FlowKt__ShareKt;
+Lkotlinx/coroutines/flow/MutableSharedFlow;
+Lkotlinx/coroutines/flow/MutableStateFlow;
+Lkotlinx/coroutines/flow/ReadonlyStateFlow;
+Lkotlinx/coroutines/flow/SafeFlow;
+Lkotlinx/coroutines/flow/SharedFlow;
+Lkotlinx/coroutines/flow/SharedFlowImpl$Emitter;
+Lkotlinx/coroutines/flow/SharedFlowImpl$WhenMappings;
+Lkotlinx/coroutines/flow/SharedFlowImpl$collect$1;
+Lkotlinx/coroutines/flow/SharedFlowImpl;
+Lkotlinx/coroutines/flow/SharedFlowKt;
+Lkotlinx/coroutines/flow/SharedFlowSlot;
+Lkotlinx/coroutines/flow/SharingCommand;
+Lkotlinx/coroutines/flow/SharingConfig;
+Lkotlinx/coroutines/flow/SharingStarted$Companion;
+Lkotlinx/coroutines/flow/SharingStarted;
+Lkotlinx/coroutines/flow/StartedEagerly;
+Lkotlinx/coroutines/flow/StartedLazily$command$1;
+Lkotlinx/coroutines/flow/StartedLazily;
+Lkotlinx/coroutines/flow/StartedWhileSubscribed$command$1;
+Lkotlinx/coroutines/flow/StartedWhileSubscribed$command$2;
+Lkotlinx/coroutines/flow/StartedWhileSubscribed;
+Lkotlinx/coroutines/flow/StateFlow;
+Lkotlinx/coroutines/flow/StateFlowImpl$collect$1;
+Lkotlinx/coroutines/flow/StateFlowImpl;
+Lkotlinx/coroutines/flow/StateFlowKt;
+Lkotlinx/coroutines/flow/StateFlowSlot;
+Lkotlinx/coroutines/flow/internal/AbortFlowException;
+Lkotlinx/coroutines/flow/internal/AbstractSharedFlow;
+Lkotlinx/coroutines/flow/internal/AbstractSharedFlowKt;
+Lkotlinx/coroutines/flow/internal/AbstractSharedFlowSlot;
+Lkotlinx/coroutines/flow/internal/ChannelFlow$collect$2;
+Lkotlinx/coroutines/flow/internal/ChannelFlow$collectToFun$1;
+Lkotlinx/coroutines/flow/internal/ChannelFlow;
+Lkotlinx/coroutines/flow/internal/ChannelFlowKt;
+Lkotlinx/coroutines/flow/internal/ChannelFlowOperator$collectWithContextUndispatched$2;
+Lkotlinx/coroutines/flow/internal/ChannelFlowOperator;
+Lkotlinx/coroutines/flow/internal/ChannelFlowOperatorImpl;
+Lkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3$1$2;
+Lkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3$1$emit$1;
+Lkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3$1;
+Lkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3;
+Lkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest;
+Lkotlinx/coroutines/flow/internal/ChildCancelledException;
+Lkotlinx/coroutines/flow/internal/DownstreamExceptionContext;
+Lkotlinx/coroutines/flow/internal/FlowExceptions_commonKt;
+Lkotlinx/coroutines/flow/internal/FusibleFlow$DefaultImpls;
+Lkotlinx/coroutines/flow/internal/FusibleFlow;
+Lkotlinx/coroutines/flow/internal/NoOpContinuation;
+Lkotlinx/coroutines/flow/internal/NopCollector;
+Lkotlinx/coroutines/flow/internal/NullSurrogateKt;
+Lkotlinx/coroutines/flow/internal/SafeCollector$collectContextSize$1;
+Lkotlinx/coroutines/flow/internal/SafeCollector;
+Lkotlinx/coroutines/flow/internal/SafeCollectorKt;
+Lkotlinx/coroutines/flow/internal/SafeCollector_commonKt;
+Lkotlinx/coroutines/flow/internal/SendingCollector;
+Lkotlinx/coroutines/flow/internal/SubscriptionCountStateFlow;
+Lkotlinx/coroutines/internal/ArrayQueue;
+Lkotlinx/coroutines/internal/AtomicKt;
+Lkotlinx/coroutines/internal/AtomicOp;
+Lkotlinx/coroutines/internal/ContextScope;
+Lkotlinx/coroutines/internal/DispatchedContinuation;
+Lkotlinx/coroutines/internal/DispatchedContinuationKt;
+Lkotlinx/coroutines/internal/FastServiceLoader;
+Lkotlinx/coroutines/internal/FastServiceLoaderKt;
+Lkotlinx/coroutines/internal/InlineList;
+Lkotlinx/coroutines/internal/LimitedDispatcher;
+Lkotlinx/coroutines/internal/LimitedDispatcherKt;
+Lkotlinx/coroutines/internal/LockFreeLinkedListHead;
+Lkotlinx/coroutines/internal/LockFreeLinkedListKt;
+Lkotlinx/coroutines/internal/LockFreeLinkedListNode$CondAddOp;
+Lkotlinx/coroutines/internal/LockFreeLinkedListNode$PrepareOp;
+Lkotlinx/coroutines/internal/LockFreeLinkedListNode$toString$1;
+Lkotlinx/coroutines/internal/LockFreeLinkedListNode;
+Lkotlinx/coroutines/internal/LockFreeTaskQueue;
+Lkotlinx/coroutines/internal/LockFreeTaskQueueCore$Companion;
+Lkotlinx/coroutines/internal/LockFreeTaskQueueCore$Placeholder;
+Lkotlinx/coroutines/internal/LockFreeTaskQueueCore;
+Lkotlinx/coroutines/internal/MainDispatcherFactory;
+Lkotlinx/coroutines/internal/MainDispatcherLoader;
+Lkotlinx/coroutines/internal/MainDispatchersKt;
+Lkotlinx/coroutines/internal/MissingMainCoroutineDispatcher;
+Lkotlinx/coroutines/internal/OnUndeliveredElementKt;
+Lkotlinx/coroutines/internal/OpDescriptor;
+Lkotlinx/coroutines/internal/Removed;
+Lkotlinx/coroutines/internal/ResizableAtomicArray;
+Lkotlinx/coroutines/internal/ScopeCoroutine;
+Lkotlinx/coroutines/internal/StackTraceRecoveryKt;
+Lkotlinx/coroutines/internal/Symbol;
+Lkotlinx/coroutines/internal/SystemPropsKt;
+Lkotlinx/coroutines/internal/SystemPropsKt__SystemPropsKt;
+Lkotlinx/coroutines/internal/SystemPropsKt__SystemProps_commonKt;
+Lkotlinx/coroutines/internal/ThreadContextKt$countAll$1;
+Lkotlinx/coroutines/internal/ThreadContextKt$findOne$1;
+Lkotlinx/coroutines/internal/ThreadContextKt$updateState$1;
+Lkotlinx/coroutines/internal/ThreadContextKt;
+Lkotlinx/coroutines/internal/ThreadSafeHeap;
+Lkotlinx/coroutines/internal/ThreadSafeHeapNode;
+Lkotlinx/coroutines/internal/ThreadState;
+Lkotlinx/coroutines/internal/UndeliveredElementException;
+Lkotlinx/coroutines/intrinsics/CancellableKt;
+Lkotlinx/coroutines/intrinsics/UndispatchedKt;
+Lkotlinx/coroutines/scheduling/CoroutineScheduler$Companion;
+Lkotlinx/coroutines/scheduling/CoroutineScheduler$WhenMappings;
+Lkotlinx/coroutines/scheduling/CoroutineScheduler$Worker;
+Lkotlinx/coroutines/scheduling/CoroutineScheduler$WorkerState;
+Lkotlinx/coroutines/scheduling/CoroutineScheduler;
+Lkotlinx/coroutines/scheduling/DefaultIoScheduler;
+Lkotlinx/coroutines/scheduling/DefaultScheduler;
+Lkotlinx/coroutines/scheduling/GlobalQueue;
+Lkotlinx/coroutines/scheduling/NanoTimeSource;
+Lkotlinx/coroutines/scheduling/SchedulerCoroutineDispatcher;
+Lkotlinx/coroutines/scheduling/SchedulerTimeSource;
+Lkotlinx/coroutines/scheduling/Task;
+Lkotlinx/coroutines/scheduling/TaskContext;
+Lkotlinx/coroutines/scheduling/TaskContextImpl;
+Lkotlinx/coroutines/scheduling/TaskImpl;
+Lkotlinx/coroutines/scheduling/TasksKt;
+Lkotlinx/coroutines/scheduling/UnlimitedIoScheduler;
+Lkotlinx/coroutines/scheduling/WorkQueue;
+Lkotlinx/coroutines/sync/Empty;
+Lkotlinx/coroutines/sync/Mutex$DefaultImpls;
+Lkotlinx/coroutines/sync/Mutex;
+Lkotlinx/coroutines/sync/MutexImpl$LockCont;
+Lkotlinx/coroutines/sync/MutexImpl$LockWaiter;
+Lkotlinx/coroutines/sync/MutexImpl$LockedQueue;
+Lkotlinx/coroutines/sync/MutexImpl$UnlockOp;
+Lkotlinx/coroutines/sync/MutexImpl$lockSuspend$2$1$1;
+Lkotlinx/coroutines/sync/MutexImpl;
+Lkotlinx/coroutines/sync/MutexKt;
+PLandroidx/activity/ComponentActivity$$ExternalSyntheticLambda2;->saveState()Landroid/os/Bundle;
+PLandroidx/activity/ComponentActivity$1;->run()V
+PLandroidx/activity/ComponentActivity$2;->onLaunch(ILandroidx/activity/result/contract/ActivityResultContract;Ljava/lang/Object;Landroidx/core/app/ActivityOptionsCompat;)V
+PLandroidx/activity/ComponentActivity$Api19Impl;->cancelPendingInputEvents(Landroid/view/View;)V
+PLandroidx/activity/ComponentActivity$ReportFullyDrawnExecutorApi16Impl;->run()V
+PLandroidx/activity/ComponentActivity;->$r8$lambda$OnwlVMZzrLePIRy-6IUDTtLLUV0(Landroidx/activity/ComponentActivity;)Landroid/os/Bundle;
+PLandroidx/activity/ComponentActivity;->access$001(Landroidx/activity/ComponentActivity;)V
+PLandroidx/activity/ComponentActivity;->lambda$new$1()Landroid/os/Bundle;
+PLandroidx/activity/ComponentActivity;->onActivityResult(IILandroid/content/Intent;)V
+PLandroidx/activity/ComponentActivity;->onBackPressed()V
+PLandroidx/activity/ComponentActivity;->onNewIntent(Landroid/content/Intent;)V
+PLandroidx/activity/ComponentActivity;->onSaveInstanceState(Landroid/os/Bundle;)V
+PLandroidx/activity/ComponentActivity;->onTrimMemory(I)V
+PLandroidx/activity/ComponentActivity;->startIntentSenderForResult(Landroid/content/IntentSender;ILandroid/content/Intent;IIILandroid/os/Bundle;)V
+PLandroidx/activity/OnBackPressedDispatcher;->onBackPressed()V
+PLandroidx/activity/compose/ActivityResultLauncherHolder;->launch(Ljava/lang/Object;Landroidx/core/app/ActivityOptionsCompat;)V
+PLandroidx/activity/compose/ActivityResultRegistryKt$rememberLauncherForActivityResult$1$1;->onActivityResult(Ljava/lang/Object;)V
+PLandroidx/activity/compose/ManagedActivityResultLauncher;->launch(Ljava/lang/Object;Landroidx/core/app/ActivityOptionsCompat;)V
+PLandroidx/activity/contextaware/ContextAwareHelper;->clearAvailableContext()V
+PLandroidx/activity/result/ActivityResult$1;-><init>()V
+PLandroidx/activity/result/ActivityResult;-><clinit>()V
+PLandroidx/activity/result/ActivityResult;-><init>(ILandroid/content/Intent;)V
+PLandroidx/activity/result/ActivityResult;->getData()Landroid/content/Intent;
+PLandroidx/activity/result/ActivityResult;->getResultCode()I
+PLandroidx/activity/result/ActivityResultLauncher;->launch(Ljava/lang/Object;)V
+PLandroidx/activity/result/ActivityResultRegistry$3;->launch(Ljava/lang/Object;Landroidx/core/app/ActivityOptionsCompat;)V
+PLandroidx/activity/result/ActivityResultRegistry;->dispatchResult(IILandroid/content/Intent;)Z
+PLandroidx/activity/result/ActivityResultRegistry;->doDispatch(Ljava/lang/String;ILandroid/content/Intent;Landroidx/activity/result/ActivityResultRegistry$CallbackAndContract;)V
+PLandroidx/activity/result/ActivityResultRegistry;->onSaveInstanceState(Landroid/os/Bundle;)V
+PLandroidx/activity/result/IntentSenderRequest$1;-><init>()V
+PLandroidx/activity/result/IntentSenderRequest$Builder;-><init>(Landroid/app/PendingIntent;)V
+PLandroidx/activity/result/IntentSenderRequest$Builder;-><init>(Landroid/content/IntentSender;)V
+PLandroidx/activity/result/IntentSenderRequest$Builder;->build()Landroidx/activity/result/IntentSenderRequest;
+PLandroidx/activity/result/IntentSenderRequest$Builder;->setFillInIntent(Landroid/content/Intent;)Landroidx/activity/result/IntentSenderRequest$Builder;
+PLandroidx/activity/result/IntentSenderRequest;-><clinit>()V
+PLandroidx/activity/result/IntentSenderRequest;-><init>(Landroid/content/IntentSender;Landroid/content/Intent;II)V
+PLandroidx/activity/result/IntentSenderRequest;->getFillInIntent()Landroid/content/Intent;
+PLandroidx/activity/result/IntentSenderRequest;->getFlagsMask()I
+PLandroidx/activity/result/IntentSenderRequest;->getFlagsValues()I
+PLandroidx/activity/result/IntentSenderRequest;->getIntentSender()Landroid/content/IntentSender;
+PLandroidx/activity/result/contract/ActivityResultContract;->getSynchronousResult(Landroid/content/Context;Ljava/lang/Object;)Landroidx/activity/result/contract/ActivityResultContract$SynchronousResult;
+PLandroidx/activity/result/contract/ActivityResultContracts$StartIntentSenderForResult;->createIntent(Landroid/content/Context;Landroidx/activity/result/IntentSenderRequest;)Landroid/content/Intent;
+PLandroidx/activity/result/contract/ActivityResultContracts$StartIntentSenderForResult;->createIntent(Landroid/content/Context;Ljava/lang/Object;)Landroid/content/Intent;
+PLandroidx/activity/result/contract/ActivityResultContracts$StartIntentSenderForResult;->parseResult(ILandroid/content/Intent;)Landroidx/activity/result/ActivityResult;
+PLandroidx/activity/result/contract/ActivityResultContracts$StartIntentSenderForResult;->parseResult(ILandroid/content/Intent;)Ljava/lang/Object;
+PLandroidx/arch/core/internal/SafeIterableMap$DescendingIterator;-><init>(Landroidx/arch/core/internal/SafeIterableMap$Entry;Landroidx/arch/core/internal/SafeIterableMap$Entry;)V
+PLandroidx/arch/core/internal/SafeIterableMap$DescendingIterator;->forward(Landroidx/arch/core/internal/SafeIterableMap$Entry;)Landroidx/arch/core/internal/SafeIterableMap$Entry;
+PLandroidx/arch/core/internal/SafeIterableMap$ListIterator;->next()Ljava/lang/Object;
+PLandroidx/arch/core/internal/SafeIterableMap$ListIterator;->next()Ljava/util/Map$Entry;
+PLandroidx/arch/core/internal/SafeIterableMap$ListIterator;->nextNode()Landroidx/arch/core/internal/SafeIterableMap$Entry;
+PLandroidx/arch/core/internal/SafeIterableMap$ListIterator;->supportRemove(Landroidx/arch/core/internal/SafeIterableMap$Entry;)V
+PLandroidx/arch/core/internal/SafeIterableMap;->descendingIterator()Ljava/util/Iterator;
+PLandroidx/compose/animation/AndroidFlingSpline$FlingResult;-><clinit>()V
+PLandroidx/compose/animation/AndroidFlingSpline$FlingResult;-><init>(FF)V
+PLandroidx/compose/animation/AndroidFlingSpline$FlingResult;->getDistanceCoefficient()F
+PLandroidx/compose/animation/AndroidFlingSpline$FlingResult;->getVelocityCoefficient()F
+PLandroidx/compose/animation/AndroidFlingSpline;-><clinit>()V
+PLandroidx/compose/animation/AndroidFlingSpline;-><init>()V
+PLandroidx/compose/animation/AndroidFlingSpline;->deceleration(FF)D
+PLandroidx/compose/animation/AndroidFlingSpline;->flingPosition(F)Landroidx/compose/animation/AndroidFlingSpline$FlingResult;
+PLandroidx/compose/animation/ColorVectorConverterKt$ColorToVector$1$1;-><clinit>()V
+PLandroidx/compose/animation/ColorVectorConverterKt$ColorToVector$1$1;-><init>()V
+PLandroidx/compose/animation/ColorVectorConverterKt$ColorToVector$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/animation/ColorVectorConverterKt$ColorToVector$1$1;->invoke-8_81llA(J)Landroidx/compose/animation/core/AnimationVector4D;
+PLandroidx/compose/animation/ColorVectorConverterKt$ColorToVector$1$2;-><init>(Landroidx/compose/ui/graphics/colorspace/ColorSpace;)V
+PLandroidx/compose/animation/ColorVectorConverterKt$ColorToVector$1;-><clinit>()V
+PLandroidx/compose/animation/ColorVectorConverterKt$ColorToVector$1;-><init>()V
+PLandroidx/compose/animation/ColorVectorConverterKt$ColorToVector$1;->invoke(Landroidx/compose/ui/graphics/colorspace/ColorSpace;)Landroidx/compose/animation/core/TwoWayConverter;
+PLandroidx/compose/animation/ColorVectorConverterKt$ColorToVector$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/animation/ColorVectorConverterKt;-><clinit>()V
+PLandroidx/compose/animation/ColorVectorConverterKt;->access$getM1$p()[F
+PLandroidx/compose/animation/ColorVectorConverterKt;->access$multiplyColumn(IFFF[F)F
+PLandroidx/compose/animation/ColorVectorConverterKt;->getVectorConverter(Landroidx/compose/ui/graphics/Color$Companion;)Lkotlin/jvm/functions/Function1;
+PLandroidx/compose/animation/ColorVectorConverterKt;->multiplyColumn(IFFF[F)F
+PLandroidx/compose/animation/FlingCalculator$FlingInfo;-><clinit>()V
+PLandroidx/compose/animation/FlingCalculator$FlingInfo;-><init>(FFJ)V
+PLandroidx/compose/animation/FlingCalculator$FlingInfo;->position(J)F
+PLandroidx/compose/animation/FlingCalculator$FlingInfo;->velocity(J)F
+PLandroidx/compose/animation/FlingCalculator;-><init>(FLandroidx/compose/ui/unit/Density;)V
+PLandroidx/compose/animation/FlingCalculator;->computeDeceleration(Landroidx/compose/ui/unit/Density;)F
+PLandroidx/compose/animation/FlingCalculator;->flingDistance(F)F
+PLandroidx/compose/animation/FlingCalculator;->flingDuration(F)J
+PLandroidx/compose/animation/FlingCalculator;->flingInfo(F)Landroidx/compose/animation/FlingCalculator$FlingInfo;
+PLandroidx/compose/animation/FlingCalculator;->getSplineDeceleration(F)D
+PLandroidx/compose/animation/FlingCalculatorKt;-><clinit>()V
+PLandroidx/compose/animation/FlingCalculatorKt;->access$computeDeceleration(FF)F
+PLandroidx/compose/animation/FlingCalculatorKt;->access$getDecelerationRate$p()F
+PLandroidx/compose/animation/FlingCalculatorKt;->computeDeceleration(FF)F
+PLandroidx/compose/animation/SingleValueAnimationKt;-><clinit>()V
+PLandroidx/compose/animation/SingleValueAnimationKt;->animateColorAsState-KTwxG1Y(JLandroidx/compose/animation/core/AnimationSpec;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)Landroidx/compose/runtime/State;
+PLandroidx/compose/animation/SingleValueAnimationKt;->animateColorAsState-euL9pac(JLandroidx/compose/animation/core/AnimationSpec;Ljava/lang/String;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)Landroidx/compose/runtime/State;
+PLandroidx/compose/animation/SplineBasedDecayKt;->access$computeSplineInfo([F[FI)V
+PLandroidx/compose/animation/SplineBasedDecayKt;->computeSplineInfo([F[FI)V
+PLandroidx/compose/animation/SplineBasedFloatDecayAnimationSpec;-><clinit>()V
+PLandroidx/compose/animation/SplineBasedFloatDecayAnimationSpec;-><init>(Landroidx/compose/ui/unit/Density;)V
+PLandroidx/compose/animation/SplineBasedFloatDecayAnimationSpec;->flingDistance(F)F
+PLandroidx/compose/animation/SplineBasedFloatDecayAnimationSpec;->getAbsVelocityThreshold()F
+PLandroidx/compose/animation/SplineBasedFloatDecayAnimationSpec;->getDurationNanos(FF)J
+PLandroidx/compose/animation/SplineBasedFloatDecayAnimationSpec;->getTargetValue(FF)F
+PLandroidx/compose/animation/SplineBasedFloatDecayAnimationSpec;->getValueFromNanos(JFF)F
+PLandroidx/compose/animation/SplineBasedFloatDecayAnimationSpec;->getVelocityFromNanos(JFF)F
+PLandroidx/compose/animation/SplineBasedFloatDecayAnimationSpec_androidKt;-><clinit>()V
+PLandroidx/compose/animation/SplineBasedFloatDecayAnimationSpec_androidKt;->getPlatformFlingScrollFriction()F
+PLandroidx/compose/animation/SplineBasedFloatDecayAnimationSpec_androidKt;->rememberSplineBasedDecay(Landroidx/compose/runtime/Composer;I)Landroidx/compose/animation/core/DecayAnimationSpec;
+PLandroidx/compose/animation/core/AnimateAsStateKt;->access$animateValueAsState$lambda$4(Landroidx/compose/runtime/State;)Lkotlin/jvm/functions/Function1;
+PLandroidx/compose/animation/core/AnimateAsStateKt;->access$animateValueAsState$lambda$6(Landroidx/compose/runtime/State;)Landroidx/compose/animation/core/AnimationSpec;
+PLandroidx/compose/animation/core/AnimateAsStateKt;->animateValueAsState$lambda$4(Landroidx/compose/runtime/State;)Lkotlin/jvm/functions/Function1;
+PLandroidx/compose/animation/core/AnimateAsStateKt;->animateValueAsState$lambda$6(Landroidx/compose/runtime/State;)Landroidx/compose/animation/core/AnimationSpec;
+PLandroidx/compose/animation/core/AnimationScope;->cancelAnimation()V
+PLandroidx/compose/animation/core/AnimationScope;->getVelocity()Ljava/lang/Object;
+PLandroidx/compose/animation/core/AnimationSpecKt;->access$convert(Landroidx/compose/animation/core/TwoWayConverter;Ljava/lang/Object;)Landroidx/compose/animation/core/AnimationVector;
+PLandroidx/compose/animation/core/AnimationSpecKt;->convert(Landroidx/compose/animation/core/TwoWayConverter;Ljava/lang/Object;)Landroidx/compose/animation/core/AnimationVector;
+PLandroidx/compose/animation/core/AnimationStateKt;->AnimationState$default(FFJJZILjava/lang/Object;)Landroidx/compose/animation/core/AnimationState;
+PLandroidx/compose/animation/core/AnimationStateKt;->AnimationState(FFJJZ)Landroidx/compose/animation/core/AnimationState;
+PLandroidx/compose/animation/core/AnimationVector4D;-><clinit>()V
+PLandroidx/compose/animation/core/AnimationVector4D;-><init>(FFFF)V
+PLandroidx/compose/animation/core/AnimationVector4D;->getSize$animation_core_release()I
+PLandroidx/compose/animation/core/AnimationVector4D;->newVector$animation_core_release()Landroidx/compose/animation/core/AnimationVector4D;
+PLandroidx/compose/animation/core/AnimationVector4D;->newVector$animation_core_release()Landroidx/compose/animation/core/AnimationVector;
+PLandroidx/compose/animation/core/AnimationVector4D;->set$animation_core_release(IF)V
+PLandroidx/compose/animation/core/AnimationVectorsKt;->AnimationVector(F)Landroidx/compose/animation/core/AnimationVector1D;
+PLandroidx/compose/animation/core/ComplexDouble;-><init>(DD)V
+PLandroidx/compose/animation/core/ComplexDouble;->access$get_imaginary$p(Landroidx/compose/animation/core/ComplexDouble;)D
+PLandroidx/compose/animation/core/ComplexDouble;->access$get_real$p(Landroidx/compose/animation/core/ComplexDouble;)D
+PLandroidx/compose/animation/core/ComplexDouble;->access$set_imaginary$p(Landroidx/compose/animation/core/ComplexDouble;D)V
+PLandroidx/compose/animation/core/ComplexDouble;->access$set_real$p(Landroidx/compose/animation/core/ComplexDouble;D)V
+PLandroidx/compose/animation/core/ComplexDouble;->getReal()D
+PLandroidx/compose/animation/core/ComplexDoubleKt;->complexQuadraticFormula(DDD)Lkotlin/Pair;
+PLandroidx/compose/animation/core/ComplexDoubleKt;->complexSqrt(D)Landroidx/compose/animation/core/ComplexDouble;
+PLandroidx/compose/animation/core/DecayAnimation;-><clinit>()V
+PLandroidx/compose/animation/core/DecayAnimation;-><init>(Landroidx/compose/animation/core/DecayAnimationSpec;Landroidx/compose/animation/core/TwoWayConverter;Ljava/lang/Object;Landroidx/compose/animation/core/AnimationVector;)V
+PLandroidx/compose/animation/core/DecayAnimation;-><init>(Landroidx/compose/animation/core/VectorizedDecayAnimationSpec;Landroidx/compose/animation/core/TwoWayConverter;Ljava/lang/Object;Landroidx/compose/animation/core/AnimationVector;)V
+PLandroidx/compose/animation/core/DecayAnimation;->getDurationNanos()J
+PLandroidx/compose/animation/core/DecayAnimation;->getTargetValue()Ljava/lang/Object;
+PLandroidx/compose/animation/core/DecayAnimation;->getTypeConverter()Landroidx/compose/animation/core/TwoWayConverter;
+PLandroidx/compose/animation/core/DecayAnimation;->getValueFromNanos(J)Ljava/lang/Object;
+PLandroidx/compose/animation/core/DecayAnimation;->getVelocityVectorFromNanos(J)Landroidx/compose/animation/core/AnimationVector;
+PLandroidx/compose/animation/core/DecayAnimation;->isInfinite()Z
+PLandroidx/compose/animation/core/DecayAnimationSpecImpl;-><init>(Landroidx/compose/animation/core/FloatDecayAnimationSpec;)V
+PLandroidx/compose/animation/core/DecayAnimationSpecImpl;->vectorize(Landroidx/compose/animation/core/TwoWayConverter;)Landroidx/compose/animation/core/VectorizedDecayAnimationSpec;
+PLandroidx/compose/animation/core/DecayAnimationSpecKt;->generateDecayAnimationSpec(Landroidx/compose/animation/core/FloatDecayAnimationSpec;)Landroidx/compose/animation/core/DecayAnimationSpec;
+PLandroidx/compose/animation/core/EasingKt;->getFastOutLinearInEasing()Landroidx/compose/animation/core/Easing;
+PLandroidx/compose/animation/core/FloatSpringSpec;-><clinit>()V
+PLandroidx/compose/animation/core/FloatSpringSpec;-><init>(FFF)V
+PLandroidx/compose/animation/core/FloatSpringSpec;-><init>(FFFILkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/animation/core/FloatSpringSpec;->getDurationNanos(FFF)J
+PLandroidx/compose/animation/core/FloatSpringSpec;->getEndVelocity(FFF)F
+PLandroidx/compose/animation/core/Motion;->constructor-impl(J)J
+PLandroidx/compose/animation/core/Motion;->getValue-impl(J)F
+PLandroidx/compose/animation/core/Motion;->getVelocity-impl(J)F
+PLandroidx/compose/animation/core/SpringEstimationKt$estimateCriticallyDamped$fn$1;-><init>(DDDD)V
+PLandroidx/compose/animation/core/SpringEstimationKt$estimateCriticallyDamped$fn$1;->invoke(D)Ljava/lang/Double;
+PLandroidx/compose/animation/core/SpringEstimationKt$estimateCriticallyDamped$fn$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/animation/core/SpringEstimationKt$estimateCriticallyDamped$fnPrime$1;-><init>(DDD)V
+PLandroidx/compose/animation/core/SpringEstimationKt$estimateCriticallyDamped$fnPrime$1;->invoke(D)Ljava/lang/Double;
+PLandroidx/compose/animation/core/SpringEstimationKt$estimateCriticallyDamped$fnPrime$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/animation/core/SpringEstimationKt;->estimateAnimationDurationMillis(DDDDD)J
+PLandroidx/compose/animation/core/SpringEstimationKt;->estimateAnimationDurationMillis(FFFFF)J
+PLandroidx/compose/animation/core/SpringEstimationKt;->estimateCriticallyDamped$t2Iterate(DD)D
+PLandroidx/compose/animation/core/SpringEstimationKt;->estimateCriticallyDamped(Lkotlin/Pair;DDD)D
+PLandroidx/compose/animation/core/SpringEstimationKt;->estimateDurationInternal(Lkotlin/Pair;DDDD)J
+PLandroidx/compose/animation/core/SpringSimulation;-><init>(F)V
+PLandroidx/compose/animation/core/SpringSimulation;->getDampingRatio()F
+PLandroidx/compose/animation/core/SpringSimulation;->getStiffness()F
+PLandroidx/compose/animation/core/SpringSimulation;->init()V
+PLandroidx/compose/animation/core/SpringSimulation;->setDampingRatio(F)V
+PLandroidx/compose/animation/core/SpringSimulation;->setFinalPosition(F)V
+PLandroidx/compose/animation/core/SpringSimulation;->setStiffness(F)V
+PLandroidx/compose/animation/core/SpringSimulationKt;-><clinit>()V
+PLandroidx/compose/animation/core/SpringSimulationKt;->Motion(FF)J
+PLandroidx/compose/animation/core/SpringSimulationKt;->getUNSET()F
+PLandroidx/compose/animation/core/SpringSpec;->vectorize(Landroidx/compose/animation/core/TwoWayConverter;)Landroidx/compose/animation/core/VectorizedAnimationSpec;
+PLandroidx/compose/animation/core/SpringSpec;->vectorize(Landroidx/compose/animation/core/TwoWayConverter;)Landroidx/compose/animation/core/VectorizedSpringSpec;
+PLandroidx/compose/animation/core/SuspendAnimationKt$animate$6$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/animation/core/SuspendAnimationKt$animate$6$1;->invoke()V
+PLandroidx/compose/animation/core/SuspendAnimationKt;->animateDecay$default(Landroidx/compose/animation/core/AnimationState;Landroidx/compose/animation/core/DecayAnimationSpec;ZLkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/animation/core/SuspendAnimationKt;->animateDecay(Landroidx/compose/animation/core/AnimationState;Landroidx/compose/animation/core/DecayAnimationSpec;ZLkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/animation/core/VectorConvertersKt$FloatToVector$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/animation/core/VectorizedAnimationSpecKt$createSpringAnimations$2;-><init>(FF)V
+PLandroidx/compose/animation/core/VectorizedAnimationSpecKt$createSpringAnimations$2;->get(I)Landroidx/compose/animation/core/FloatAnimationSpec;
+PLandroidx/compose/animation/core/VectorizedAnimationSpecKt$createSpringAnimations$2;->get(I)Landroidx/compose/animation/core/FloatSpringSpec;
+PLandroidx/compose/animation/core/VectorizedAnimationSpecKt;->access$createSpringAnimations(Landroidx/compose/animation/core/AnimationVector;FF)Landroidx/compose/animation/core/Animations;
+PLandroidx/compose/animation/core/VectorizedAnimationSpecKt;->createSpringAnimations(Landroidx/compose/animation/core/AnimationVector;FF)Landroidx/compose/animation/core/Animations;
+PLandroidx/compose/animation/core/VectorizedFloatAnimationSpec;->getDurationNanos(Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;)J
+PLandroidx/compose/animation/core/VectorizedFloatAnimationSpec;->getEndVelocity(Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;)Landroidx/compose/animation/core/AnimationVector;
+PLandroidx/compose/animation/core/VectorizedFloatDecaySpec;-><init>(Landroidx/compose/animation/core/FloatDecayAnimationSpec;)V
+PLandroidx/compose/animation/core/VectorizedFloatDecaySpec;->getAbsVelocityThreshold()F
+PLandroidx/compose/animation/core/VectorizedFloatDecaySpec;->getDurationNanos(Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;)J
+PLandroidx/compose/animation/core/VectorizedFloatDecaySpec;->getTargetValue(Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;)Landroidx/compose/animation/core/AnimationVector;
+PLandroidx/compose/animation/core/VectorizedFloatDecaySpec;->getValueFromNanos(JLandroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;)Landroidx/compose/animation/core/AnimationVector;
+PLandroidx/compose/animation/core/VectorizedFloatDecaySpec;->getVelocityFromNanos(JLandroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;)Landroidx/compose/animation/core/AnimationVector;
+PLandroidx/compose/animation/core/VectorizedSpringSpec;-><clinit>()V
+PLandroidx/compose/animation/core/VectorizedSpringSpec;-><init>(FFLandroidx/compose/animation/core/AnimationVector;)V
+PLandroidx/compose/animation/core/VectorizedSpringSpec;-><init>(FFLandroidx/compose/animation/core/Animations;)V
+PLandroidx/compose/animation/core/VectorizedSpringSpec;->getDurationNanos(Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;)J
+PLandroidx/compose/animation/core/VectorizedSpringSpec;->getEndVelocity(Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;Landroidx/compose/animation/core/AnimationVector;)Landroidx/compose/animation/core/AnimationVector;
+PLandroidx/compose/animation/core/VectorizedSpringSpec;->isInfinite()Z
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect$effectModifier$1$1;-><init>(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect$effectModifier$1$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect$effectModifier$1$1;->invoke(Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect$effectModifier$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect$effectModifier$1$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect$effectModifier$1;-><init>(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect$effectModifier$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect$effectModifier$1;->invoke(Landroidx/compose/ui/input/pointer/PointerInputScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect$effectModifier$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect$effectModifier$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect$onNewSize$1;-><init>(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;)V
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect$onNewSize$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect$onNewSize$1;->invoke-ozmzZPI(J)V
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;-><init>(Landroid/content/Context;Landroidx/compose/foundation/OverscrollConfiguration;)V
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->access$animateToRelease(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;)V
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->access$getBottomEffect$p(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;)Landroid/widget/EdgeEffect;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->access$getBottomEffectNegation$p(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;)Landroid/widget/EdgeEffect;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->access$getContainerSize$p(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;)J
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->access$getLeftEffect$p(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;)Landroid/widget/EdgeEffect;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->access$getLeftEffectNegation$p(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;)Landroid/widget/EdgeEffect;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->access$getPointerId$p(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;)Landroidx/compose/ui/input/pointer/PointerId;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->access$getRightEffect$p(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;)Landroid/widget/EdgeEffect;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->access$getRightEffectNegation$p(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;)Landroid/widget/EdgeEffect;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->access$getTopEffect$p(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;)Landroid/widget/EdgeEffect;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->access$getTopEffectNegation$p(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;)Landroid/widget/EdgeEffect;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->access$invalidateOverscroll(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;)V
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->access$setContainerSize$p(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;J)V
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->access$setPointerId$p(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;Landroidx/compose/ui/input/pointer/PointerId;)V
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->access$setPointerPosition$p(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;Landroidx/compose/ui/geometry/Offset;)V
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->animateToRelease()V
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->consumePostFling-sF-c-tU(JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->consumePostScroll-OMhpSzk(JJI)V
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->consumePreFling-QWom1Mo(JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->consumePreScroll-OzD1aCk(JI)J
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->drawOverscroll(Landroidx/compose/ui/graphics/drawscope/DrawScope;)V
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->getEffectModifier()Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->invalidateOverscroll()V
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->isInProgress()Z
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->releaseOppositeOverscroll-k-4lQ0M(J)Z
+PLandroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;->stopOverscrollAnimation()Z
+PLandroidx/compose/foundation/AndroidOverscrollKt$NoOpOverscrollEffect$1;-><init>()V
+PLandroidx/compose/foundation/AndroidOverscrollKt$StretchOverscrollNonClippingLayer$1$1;-><init>(Landroidx/compose/ui/layout/Placeable;I)V
+PLandroidx/compose/foundation/AndroidOverscrollKt$StretchOverscrollNonClippingLayer$1$1;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+PLandroidx/compose/foundation/AndroidOverscrollKt$StretchOverscrollNonClippingLayer$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/AndroidOverscrollKt$StretchOverscrollNonClippingLayer$1;-><clinit>()V
+PLandroidx/compose/foundation/AndroidOverscrollKt$StretchOverscrollNonClippingLayer$1;-><init>()V
+PLandroidx/compose/foundation/AndroidOverscrollKt$StretchOverscrollNonClippingLayer$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/AndroidOverscrollKt$StretchOverscrollNonClippingLayer$1;->invoke-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult;
+PLandroidx/compose/foundation/AndroidOverscrollKt$StretchOverscrollNonClippingLayer$2$1;-><init>(Landroidx/compose/ui/layout/Placeable;I)V
+PLandroidx/compose/foundation/AndroidOverscrollKt$StretchOverscrollNonClippingLayer$2$1;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+PLandroidx/compose/foundation/AndroidOverscrollKt$StretchOverscrollNonClippingLayer$2$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/AndroidOverscrollKt$StretchOverscrollNonClippingLayer$2;-><clinit>()V
+PLandroidx/compose/foundation/AndroidOverscrollKt$StretchOverscrollNonClippingLayer$2;-><init>()V
+PLandroidx/compose/foundation/AndroidOverscrollKt$StretchOverscrollNonClippingLayer$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/AndroidOverscrollKt$StretchOverscrollNonClippingLayer$2;->invoke-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult;
+PLandroidx/compose/foundation/AndroidOverscrollKt;-><clinit>()V
+PLandroidx/compose/foundation/AndroidOverscrollKt;->access$getStretchOverscrollNonClippingLayer$p()Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/AndroidOverscrollKt;->rememberOverscrollEffect(Landroidx/compose/runtime/Composer;I)Landroidx/compose/foundation/OverscrollEffect;
+PLandroidx/compose/foundation/Api31Impl;-><clinit>()V
+PLandroidx/compose/foundation/Api31Impl;-><init>()V
+PLandroidx/compose/foundation/Api31Impl;->create(Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/widget/EdgeEffect;
+PLandroidx/compose/foundation/Api31Impl;->getDistance(Landroid/widget/EdgeEffect;)F
+PLandroidx/compose/foundation/CheckScrollableContainerConstraintsKt;->checkScrollableContainerConstraints-K40F9xA(JLandroidx/compose/foundation/gestures/Orientation;)V
+PLandroidx/compose/foundation/ClickableKt$PressedInteractionSourceDisposableEffect$1$invoke$$inlined$onDispose$1;->dispose()V
+PLandroidx/compose/foundation/ClickableKt$clickable$4$1$1$1;->invoke()Ljava/lang/Boolean;
+PLandroidx/compose/foundation/ClickableKt$clickable$4$1$1$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/foundation/ClickableKt$clickable$4$gesture$1$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/ClickableKt$clickable$4$gesture$1$1$1;->invoke-d-4ec7I(Landroidx/compose/foundation/gestures/PressGestureScope;JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/ClickableKt$clickable$4$gesture$1$1$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/ClickableKt$clickable$4$gesture$1$1$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/ClickableKt$clickable$4$gesture$1$1$2;->invoke-k-4lQ0M(J)V
+PLandroidx/compose/foundation/ClickableKt$handlePressInteraction$2$delayJob$1;-><init>(Landroidx/compose/runtime/State;JLandroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/runtime/MutableState;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/ClickableKt$handlePressInteraction$2$delayJob$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/ClickableKt$handlePressInteraction$2$delayJob$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/ClickableKt$handlePressInteraction$2;-><init>(Landroidx/compose/foundation/gestures/PressGestureScope;JLandroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/runtime/MutableState;Landroidx/compose/runtime/State;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/ClickableKt$handlePressInteraction$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/ClickableKt$handlePressInteraction$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/ClickableKt$handlePressInteraction$2;->invoke(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/ClickableKt$handlePressInteraction$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/ClickableKt;->handlePressInteraction-EPk0efs(Landroidx/compose/foundation/gestures/PressGestureScope;JLandroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/runtime/MutableState;Landroidx/compose/runtime/State;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/Clickable_androidKt;-><clinit>()V
+PLandroidx/compose/foundation/Clickable_androidKt;->getTapIndicationDelay()J
+PLandroidx/compose/foundation/ClipScrollableContainerKt$HorizontalScrollableClipModifier$1;-><init>()V
+PLandroidx/compose/foundation/ClipScrollableContainerKt$VerticalScrollableClipModifier$1;-><init>()V
+PLandroidx/compose/foundation/ClipScrollableContainerKt$VerticalScrollableClipModifier$1;->createOutline-Pq9zytI(JLandroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/ui/unit/Density;)Landroidx/compose/ui/graphics/Outline;
+PLandroidx/compose/foundation/ClipScrollableContainerKt;-><clinit>()V
+PLandroidx/compose/foundation/ClipScrollableContainerKt;->clipScrollableContainer(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/gestures/Orientation;)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/ClipScrollableContainerKt;->getMaxSupportedElevation()F
+PLandroidx/compose/foundation/DrawOverscrollModifier;-><init>(Landroidx/compose/foundation/AndroidEdgeEffectOverscrollEffect;Lkotlin/jvm/functions/Function1;)V
+PLandroidx/compose/foundation/DrawOverscrollModifier;->draw(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;)V
+PLandroidx/compose/foundation/DrawOverscrollModifier;->equals(Ljava/lang/Object;)Z
+PLandroidx/compose/foundation/EdgeEffectCompat;-><clinit>()V
+PLandroidx/compose/foundation/EdgeEffectCompat;-><init>()V
+PLandroidx/compose/foundation/EdgeEffectCompat;->create(Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/widget/EdgeEffect;
+PLandroidx/compose/foundation/EdgeEffectCompat;->getDistanceCompat(Landroid/widget/EdgeEffect;)F
+PLandroidx/compose/foundation/FocusableKt$focusGroup$1;-><clinit>()V
+PLandroidx/compose/foundation/FocusableKt$focusGroup$1;-><init>()V
+PLandroidx/compose/foundation/FocusableKt$focusGroup$1;->invoke(Landroidx/compose/ui/focus/FocusProperties;)V
+PLandroidx/compose/foundation/FocusableKt$focusGroup$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/FocusableKt$focusable$2$1$1$invoke$$inlined$onDispose$1;->dispose()V
+PLandroidx/compose/foundation/FocusableKt$focusable$2$2$invoke$$inlined$onDispose$1;->dispose()V
+PLandroidx/compose/foundation/FocusableKt;->focusGroup(Landroidx/compose/ui/Modifier;)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/FocusedBoundsKt$ModifierLocalFocusedBoundsObserver$1;-><clinit>()V
+PLandroidx/compose/foundation/FocusedBoundsKt$ModifierLocalFocusedBoundsObserver$1;-><init>()V
+PLandroidx/compose/foundation/FocusedBoundsKt$ModifierLocalFocusedBoundsObserver$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/foundation/FocusedBoundsKt$ModifierLocalFocusedBoundsObserver$1;->invoke()Lkotlin/jvm/functions/Function1;
+PLandroidx/compose/foundation/FocusedBoundsKt$onFocusedBoundsChanged$2;-><init>(Lkotlin/jvm/functions/Function1;)V
+PLandroidx/compose/foundation/FocusedBoundsKt$onFocusedBoundsChanged$2;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/FocusedBoundsKt$onFocusedBoundsChanged$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/FocusedBoundsKt;-><clinit>()V
+PLandroidx/compose/foundation/FocusedBoundsKt;->getModifierLocalFocusedBoundsObserver()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+PLandroidx/compose/foundation/FocusedBoundsKt;->onFocusedBoundsChanged(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/FocusedBoundsObserverModifier;-><init>(Lkotlin/jvm/functions/Function1;)V
+PLandroidx/compose/foundation/FocusedBoundsObserverModifier;->getKey()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+PLandroidx/compose/foundation/FocusedBoundsObserverModifier;->onModifierLocalsUpdated(Landroidx/compose/ui/modifier/ModifierLocalReadScope;)V
+PLandroidx/compose/foundation/HoverableKt$hoverable$2$1$1$invoke$$inlined$onDispose$1;->dispose()V
+PLandroidx/compose/foundation/HoverableKt$hoverable$2;->access$invoke$tryEmitExit(Landroidx/compose/runtime/MutableState;Landroidx/compose/foundation/interaction/MutableInteractionSource;)V
+PLandroidx/compose/foundation/HoverableKt$hoverable$2;->invoke$lambda$1(Landroidx/compose/runtime/MutableState;)Landroidx/compose/foundation/interaction/HoverInteraction$Enter;
+PLandroidx/compose/foundation/HoverableKt$hoverable$2;->invoke$tryEmitExit(Landroidx/compose/runtime/MutableState;Landroidx/compose/foundation/interaction/MutableInteractionSource;)V
+PLandroidx/compose/foundation/ImageKt$Image$2$measure$1;-><clinit>()V
+PLandroidx/compose/foundation/ImageKt$Image$2$measure$1;-><init>()V
+PLandroidx/compose/foundation/ImageKt$Image$2$measure$1;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+PLandroidx/compose/foundation/ImageKt$Image$2$measure$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/ImageKt$Image$2;-><clinit>()V
+PLandroidx/compose/foundation/ImageKt$Image$2;-><init>()V
+PLandroidx/compose/foundation/ImageKt$Image$2;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Ljava/util/List;J)Landroidx/compose/ui/layout/MeasureResult;
+PLandroidx/compose/foundation/ImageKt$Image$semantics$1$1;-><init>(Ljava/lang/String;)V
+PLandroidx/compose/foundation/ImageKt$Image$semantics$1$1;->invoke(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;)V
+PLandroidx/compose/foundation/ImageKt$Image$semantics$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/ImageKt;->Image-5h-nEew(Landroidx/compose/ui/graphics/ImageBitmap;Ljava/lang/String;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/Alignment;Landroidx/compose/ui/layout/ContentScale;FLandroidx/compose/ui/graphics/ColorFilter;ILandroidx/compose/runtime/Composer;II)V
+PLandroidx/compose/foundation/OverscrollConfiguration;-><init>(JLandroidx/compose/foundation/layout/PaddingValues;)V
+PLandroidx/compose/foundation/OverscrollConfiguration;-><init>(JLandroidx/compose/foundation/layout/PaddingValues;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/OverscrollConfiguration;-><init>(JLandroidx/compose/foundation/layout/PaddingValues;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/OverscrollConfiguration;->equals(Ljava/lang/Object;)Z
+PLandroidx/compose/foundation/OverscrollConfiguration;->getGlowColor-0d7_KjU()J
+PLandroidx/compose/foundation/OverscrollConfigurationKt$LocalOverscrollConfiguration$1;-><clinit>()V
+PLandroidx/compose/foundation/OverscrollConfigurationKt$LocalOverscrollConfiguration$1;-><init>()V
+PLandroidx/compose/foundation/OverscrollConfigurationKt$LocalOverscrollConfiguration$1;->invoke()Landroidx/compose/foundation/OverscrollConfiguration;
+PLandroidx/compose/foundation/OverscrollConfigurationKt$LocalOverscrollConfiguration$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/foundation/OverscrollConfigurationKt;-><clinit>()V
+PLandroidx/compose/foundation/OverscrollConfigurationKt;->getLocalOverscrollConfiguration()Landroidx/compose/runtime/ProvidableCompositionLocal;
+PLandroidx/compose/foundation/OverscrollKt;->overscroll(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/OverscrollEffect;)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/gestures/AndroidConfig;-><clinit>()V
+PLandroidx/compose/foundation/gestures/AndroidConfig;-><init>()V
+PLandroidx/compose/foundation/gestures/AndroidScrollable_androidKt;->platformScrollConfig(Landroidx/compose/runtime/Composer;I)Landroidx/compose/foundation/gestures/ScrollConfig;
+PLandroidx/compose/foundation/gestures/ContentInViewModifier$modifier$1;-><init>(Landroidx/compose/foundation/gestures/ContentInViewModifier;)V
+PLandroidx/compose/foundation/gestures/ContentInViewModifier;-><init>(Lkotlinx/coroutines/CoroutineScope;Landroidx/compose/foundation/gestures/Orientation;Landroidx/compose/foundation/gestures/ScrollableState;Z)V
+PLandroidx/compose/foundation/gestures/ContentInViewModifier;->getModifier()Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/gestures/ContentInViewModifier;->onPlaced(Landroidx/compose/ui/layout/LayoutCoordinates;)V
+PLandroidx/compose/foundation/gestures/ContentInViewModifier;->onRemeasured-ozmzZPI(J)V
+PLandroidx/compose/foundation/gestures/DefaultFlingBehavior$performFling$2$1;-><init>(Lkotlin/jvm/internal/Ref$FloatRef;Landroidx/compose/foundation/gestures/ScrollScope;Lkotlin/jvm/internal/Ref$FloatRef;Landroidx/compose/foundation/gestures/DefaultFlingBehavior;)V
+PLandroidx/compose/foundation/gestures/DefaultFlingBehavior$performFling$2$1;->invoke(Landroidx/compose/animation/core/AnimationScope;)V
+PLandroidx/compose/foundation/gestures/DefaultFlingBehavior$performFling$2$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DefaultFlingBehavior$performFling$2;-><init>(FLandroidx/compose/foundation/gestures/DefaultFlingBehavior;Landroidx/compose/foundation/gestures/ScrollScope;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/DefaultFlingBehavior$performFling$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/gestures/DefaultFlingBehavior$performFling$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DefaultFlingBehavior$performFling$2;->invoke(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DefaultFlingBehavior$performFling$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DefaultFlingBehavior;-><init>(Landroidx/compose/animation/core/DecayAnimationSpec;Landroidx/compose/ui/MotionDurationScale;)V
+PLandroidx/compose/foundation/gestures/DefaultFlingBehavior;-><init>(Landroidx/compose/animation/core/DecayAnimationSpec;Landroidx/compose/ui/MotionDurationScale;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/gestures/DefaultFlingBehavior;->access$getFlingDecay$p(Landroidx/compose/foundation/gestures/DefaultFlingBehavior;)Landroidx/compose/animation/core/DecayAnimationSpec;
+PLandroidx/compose/foundation/gestures/DefaultFlingBehavior;->getLastAnimationCycleCount()I
+PLandroidx/compose/foundation/gestures/DefaultFlingBehavior;->performFling(Landroidx/compose/foundation/gestures/ScrollScope;FLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DefaultFlingBehavior;->setLastAnimationCycleCount(I)V
+PLandroidx/compose/foundation/gestures/DefaultScrollableState$scroll$2$1;-><init>(Landroidx/compose/foundation/gestures/DefaultScrollableState;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/DefaultScrollableState$scroll$2$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/gestures/DefaultScrollableState$scroll$2$1;->invoke(Landroidx/compose/foundation/gestures/ScrollScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DefaultScrollableState$scroll$2$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DefaultScrollableState$scroll$2$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DefaultScrollableState$scroll$2;-><init>(Landroidx/compose/foundation/gestures/DefaultScrollableState;Landroidx/compose/foundation/MutatePriority;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/DefaultScrollableState$scroll$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/gestures/DefaultScrollableState$scroll$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DefaultScrollableState$scroll$2;->invoke(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DefaultScrollableState$scroll$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DefaultScrollableState$scrollScope$1;-><init>(Landroidx/compose/foundation/gestures/DefaultScrollableState;)V
+PLandroidx/compose/foundation/gestures/DefaultScrollableState$scrollScope$1;->scrollBy(F)F
+PLandroidx/compose/foundation/gestures/DefaultScrollableState;-><init>(Lkotlin/jvm/functions/Function1;)V
+PLandroidx/compose/foundation/gestures/DefaultScrollableState;->access$getScrollMutex$p(Landroidx/compose/foundation/gestures/DefaultScrollableState;)Landroidx/compose/foundation/MutatorMutex;
+PLandroidx/compose/foundation/gestures/DefaultScrollableState;->access$getScrollScope$p(Landroidx/compose/foundation/gestures/DefaultScrollableState;)Landroidx/compose/foundation/gestures/ScrollScope;
+PLandroidx/compose/foundation/gestures/DefaultScrollableState;->access$isScrollingState$p(Landroidx/compose/foundation/gestures/DefaultScrollableState;)Landroidx/compose/runtime/MutableState;
+PLandroidx/compose/foundation/gestures/DefaultScrollableState;->getOnDelta()Lkotlin/jvm/functions/Function1;
+PLandroidx/compose/foundation/gestures/DefaultScrollableState;->isScrollInProgress()Z
+PLandroidx/compose/foundation/gestures/DefaultScrollableState;->scroll(Landroidx/compose/foundation/MutatePriority;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DragEvent$DragDelta;-><clinit>()V
+PLandroidx/compose/foundation/gestures/DragEvent$DragDelta;-><init>(J)V
+PLandroidx/compose/foundation/gestures/DragEvent$DragDelta;-><init>(JLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/gestures/DragEvent$DragDelta;->getDelta-F1C5BW0()J
+PLandroidx/compose/foundation/gestures/DragEvent$DragStarted;-><clinit>()V
+PLandroidx/compose/foundation/gestures/DragEvent$DragStarted;-><init>(J)V
+PLandroidx/compose/foundation/gestures/DragEvent$DragStarted;-><init>(JLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/gestures/DragEvent$DragStarted;->getStartPoint-F1C5BW0()J
+PLandroidx/compose/foundation/gestures/DragEvent$DragStopped;-><clinit>()V
+PLandroidx/compose/foundation/gestures/DragEvent$DragStopped;-><init>(J)V
+PLandroidx/compose/foundation/gestures/DragEvent$DragStopped;-><init>(JLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/gestures/DragEvent$DragStopped;->getVelocity-9UxMQ8M()J
+PLandroidx/compose/foundation/gestures/DragEvent;-><init>()V
+PLandroidx/compose/foundation/gestures/DragEvent;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/gestures/DragGestureDetectorKt$HorizontalPointerDirectionConfig$1;-><init>()V
+PLandroidx/compose/foundation/gestures/DragGestureDetectorKt$VerticalPointerDirectionConfig$1;-><init>()V
+PLandroidx/compose/foundation/gestures/DragGestureDetectorKt$VerticalPointerDirectionConfig$1;->crossAxisDelta-k-4lQ0M(J)F
+PLandroidx/compose/foundation/gestures/DragGestureDetectorKt$VerticalPointerDirectionConfig$1;->mainAxisDelta-k-4lQ0M(J)F
+PLandroidx/compose/foundation/gestures/DragGestureDetectorKt$VerticalPointerDirectionConfig$1;->offsetFromChanges-dBAh8RU(FF)J
+PLandroidx/compose/foundation/gestures/DragGestureDetectorKt$verticalDrag$1;-><init>(Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/DragGestureDetectorKt$verticalDrag$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DragGestureDetectorKt;-><clinit>()V
+PLandroidx/compose/foundation/gestures/DragGestureDetectorKt;->access$isPointerUp-DmW0f2w(Landroidx/compose/ui/input/pointer/PointerEvent;J)Z
+PLandroidx/compose/foundation/gestures/DragGestureDetectorKt;->isPointerUp-DmW0f2w(Landroidx/compose/ui/input/pointer/PointerEvent;J)Z
+PLandroidx/compose/foundation/gestures/DragGestureDetectorKt;->pointerSlop-E8SPZFQ(Landroidx/compose/ui/platform/ViewConfiguration;I)F
+PLandroidx/compose/foundation/gestures/DragGestureDetectorKt;->toPointerDirectionConfig(Landroidx/compose/foundation/gestures/Orientation;)Landroidx/compose/foundation/gestures/PointerDirectionConfig;
+PLandroidx/compose/foundation/gestures/DragGestureDetectorKt;->verticalDrag-jO51t88(Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;JLkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DragLogic$processDragStart$1;-><init>(Landroidx/compose/foundation/gestures/DragLogic;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/DragLogic$processDragStop$1;-><init>(Landroidx/compose/foundation/gestures/DragLogic;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/DragLogic;->processDragStart(Lkotlinx/coroutines/CoroutineScope;Landroidx/compose/foundation/gestures/DragEvent$DragStarted;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DragLogic;->processDragStop(Lkotlinx/coroutines/CoroutineScope;Landroidx/compose/foundation/gestures/DragEvent$DragStopped;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt$awaitDownAndSlop$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt$awaitDownAndSlop$postPointerSlop$1;-><init>(Landroidx/compose/ui/input/pointer/util/VelocityTracker;Lkotlin/jvm/internal/Ref$LongRef;)V
+PLandroidx/compose/foundation/gestures/DraggableKt$awaitDownAndSlop$postPointerSlop$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt$awaitDownAndSlop$postPointerSlop$1;->invoke-Uv8p0NA(Landroidx/compose/ui/input/pointer/PointerInputChange;J)V
+PLandroidx/compose/foundation/gestures/DraggableKt$awaitDrag$dragTick$1;-><init>(Landroidx/compose/ui/input/pointer/util/VelocityTracker;Lkotlinx/coroutines/channels/SendChannel;Z)V
+PLandroidx/compose/foundation/gestures/DraggableKt$awaitDrag$dragTick$1;->invoke(Landroidx/compose/ui/input/pointer/PointerInputChange;)V
+PLandroidx/compose/foundation/gestures/DraggableKt$awaitDrag$dragTick$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$1;->invoke-d-4ec7I(Lkotlinx/coroutines/CoroutineScope;JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$3;->invoke(Landroidx/compose/ui/input/pointer/PointerInputChange;)Ljava/lang/Boolean;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$3;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$4;->invoke()Ljava/lang/Boolean;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$4;->invoke()Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$5;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$5;->invoke-LuvzFrg(Lkotlinx/coroutines/CoroutineScope;JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$5;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$6;-><init>(Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$6;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$6;->invoke-d-4ec7I(Lkotlinx/coroutines/CoroutineScope;JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$6;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$1$1$invoke$$inlined$onDispose$1;->dispose()V
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$2$2;-><init>(Lkotlin/jvm/internal/Ref$ObjectRef;Lkotlinx/coroutines/channels/Channel;Landroidx/compose/foundation/gestures/Orientation;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$2$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$2$2;->invoke(Landroidx/compose/foundation/gestures/DragScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$2$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$9$2$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$9;->access$invoke$lambda$3(Landroidx/compose/runtime/State;)Landroidx/compose/foundation/gestures/DragLogic;
+PLandroidx/compose/foundation/gestures/DraggableKt$draggable$9;->invoke$lambda$3(Landroidx/compose/runtime/State;)Landroidx/compose/foundation/gestures/DragLogic;
+PLandroidx/compose/foundation/gestures/DraggableKt;->access$awaitDrag-Su4bsnU(Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;Landroidx/compose/ui/input/pointer/PointerInputChange;JLandroidx/compose/ui/input/pointer/util/VelocityTracker;Lkotlinx/coroutines/channels/SendChannel;ZLandroidx/compose/foundation/gestures/Orientation;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt;->access$toFloat-3MmeM6k(JLandroidx/compose/foundation/gestures/Orientation;)F
+PLandroidx/compose/foundation/gestures/DraggableKt;->access$toFloat-sF-c-tU(JLandroidx/compose/foundation/gestures/Orientation;)F
+PLandroidx/compose/foundation/gestures/DraggableKt;->awaitDrag-Su4bsnU(Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;Landroidx/compose/ui/input/pointer/PointerInputChange;JLandroidx/compose/ui/input/pointer/util/VelocityTracker;Lkotlinx/coroutines/channels/SendChannel;ZLandroidx/compose/foundation/gestures/Orientation;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/DraggableKt;->draggable$default(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/gestures/DraggableState;Lkotlin/jvm/functions/Function1;Landroidx/compose/foundation/gestures/Orientation;ZLandroidx/compose/foundation/interaction/MutableInteractionSource;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;ZILjava/lang/Object;)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/gestures/DraggableKt;->toFloat-3MmeM6k(JLandroidx/compose/foundation/gestures/Orientation;)F
+PLandroidx/compose/foundation/gestures/DraggableKt;->toFloat-sF-c-tU(JLandroidx/compose/foundation/gestures/Orientation;)F
+PLandroidx/compose/foundation/gestures/ForEachGestureKt$awaitAllPointersUp$3;-><init>(Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/ForEachGestureKt$awaitAllPointersUp$3;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ForEachGestureKt;->allPointersUp(Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;)Z
+PLandroidx/compose/foundation/gestures/ForEachGestureKt;->awaitAllPointersUp(Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/PressGestureScopeImpl$reset$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/PressGestureScopeImpl$tryAwaitRelease$1;-><init>(Landroidx/compose/foundation/gestures/PressGestureScopeImpl;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/PressGestureScopeImpl$tryAwaitRelease$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/PressGestureScopeImpl;->cancel()V
+PLandroidx/compose/foundation/gestures/PressGestureScopeImpl;->release()V
+PLandroidx/compose/foundation/gestures/PressGestureScopeImpl;->tryAwaitRelease(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollDraggableState$drag$2;-><init>(Landroidx/compose/foundation/gestures/ScrollDraggableState;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/ScrollDraggableState$drag$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/gestures/ScrollDraggableState$drag$2;->invoke(Landroidx/compose/foundation/gestures/ScrollScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollDraggableState$drag$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollDraggableState$drag$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollDraggableState;-><init>(Landroidx/compose/runtime/State;)V
+PLandroidx/compose/foundation/gestures/ScrollDraggableState;->drag(Landroidx/compose/foundation/MutatePriority;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollDraggableState;->dragBy(F)V
+PLandroidx/compose/foundation/gestures/ScrollDraggableState;->setLatestScrollScope(Landroidx/compose/foundation/gestures/ScrollScope;)V
+PLandroidx/compose/foundation/gestures/ScrollableDefaults;-><clinit>()V
+PLandroidx/compose/foundation/gestures/ScrollableDefaults;-><init>()V
+PLandroidx/compose/foundation/gestures/ScrollableDefaults;->flingBehavior(Landroidx/compose/runtime/Composer;I)Landroidx/compose/foundation/gestures/FlingBehavior;
+PLandroidx/compose/foundation/gestures/ScrollableDefaults;->overscrollEffect(Landroidx/compose/runtime/Composer;I)Landroidx/compose/foundation/OverscrollEffect;
+PLandroidx/compose/foundation/gestures/ScrollableDefaults;->reverseDirection(Landroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/foundation/gestures/Orientation;Z)Z
+PLandroidx/compose/foundation/gestures/ScrollableKt$DefaultScrollMotionDurationScale$1;-><init>()V
+PLandroidx/compose/foundation/gestures/ScrollableKt$DefaultScrollMotionDurationScale$1;->fold(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollableKt$DefaultScrollMotionDurationScale$1;->get(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
+PLandroidx/compose/foundation/gestures/ScrollableKt$DefaultScrollMotionDurationScale$1;->getScaleFactor()F
+PLandroidx/compose/foundation/gestures/ScrollableKt$NoOpScrollScope$1;-><init>()V
+PLandroidx/compose/foundation/gestures/ScrollableKt$awaitScrollEvent$1;-><init>(Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/ScrollableKt$awaitScrollEvent$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollableKt$mouseWheelScroll$1$1;-><init>(Landroidx/compose/foundation/gestures/ScrollConfig;Landroidx/compose/runtime/State;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/ScrollableKt$mouseWheelScroll$1$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/gestures/ScrollableKt$mouseWheelScroll$1$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollableKt$mouseWheelScroll$1;-><init>(Landroidx/compose/foundation/gestures/ScrollConfig;Landroidx/compose/runtime/State;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/ScrollableKt$mouseWheelScroll$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/gestures/ScrollableKt$mouseWheelScroll$1;->invoke(Landroidx/compose/ui/input/pointer/PointerInputScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollableKt$mouseWheelScroll$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollableKt$mouseWheelScroll$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollableKt$pointerScrollable$1;-><clinit>()V
+PLandroidx/compose/foundation/gestures/ScrollableKt$pointerScrollable$1;-><init>()V
+PLandroidx/compose/foundation/gestures/ScrollableKt$pointerScrollable$1;->invoke(Landroidx/compose/ui/input/pointer/PointerInputChange;)Ljava/lang/Boolean;
+PLandroidx/compose/foundation/gestures/ScrollableKt$pointerScrollable$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollableKt$pointerScrollable$2$1;-><init>(Landroidx/compose/runtime/State;)V
+PLandroidx/compose/foundation/gestures/ScrollableKt$pointerScrollable$2$1;->invoke()Ljava/lang/Boolean;
+PLandroidx/compose/foundation/gestures/ScrollableKt$pointerScrollable$2$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollableKt$pointerScrollable$3$1$1;-><init>(Landroidx/compose/runtime/State;JLkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/ScrollableKt$pointerScrollable$3$1$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/gestures/ScrollableKt$pointerScrollable$3$1$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollableKt$pointerScrollable$3$1;-><init>(Landroidx/compose/runtime/MutableState;Landroidx/compose/runtime/State;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/ScrollableKt$pointerScrollable$3$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollableKt$pointerScrollable$3$1;->invoke-LuvzFrg(Lkotlinx/coroutines/CoroutineScope;JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollableKt$pointerScrollable$3$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollableKt$pointerScrollable$scrollContainerInfo$1$1;-><init>(ZLandroidx/compose/foundation/gestures/Orientation;)V
+PLandroidx/compose/foundation/gestures/ScrollableKt$pointerScrollable$scrollContainerInfo$1$1;->canScrollVertically()Z
+PLandroidx/compose/foundation/gestures/ScrollableKt$scrollable$2;-><init>(Landroidx/compose/foundation/gestures/Orientation;Landroidx/compose/foundation/gestures/ScrollableState;ZLandroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/foundation/gestures/FlingBehavior;Landroidx/compose/foundation/OverscrollEffect;Z)V
+PLandroidx/compose/foundation/gestures/ScrollableKt$scrollable$2;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/gestures/ScrollableKt$scrollable$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollableKt$scrollableNestedScrollConnection$1;-><init>(Landroidx/compose/runtime/State;Z)V
+PLandroidx/compose/foundation/gestures/ScrollableKt;-><clinit>()V
+PLandroidx/compose/foundation/gestures/ScrollableKt;->access$awaitScrollEvent(Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollableKt;->access$getNoOpScrollScope$p()Landroidx/compose/foundation/gestures/ScrollScope;
+PLandroidx/compose/foundation/gestures/ScrollableKt;->access$pointerScrollable(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/foundation/gestures/Orientation;ZLandroidx/compose/foundation/gestures/ScrollableState;Landroidx/compose/foundation/gestures/FlingBehavior;Landroidx/compose/foundation/OverscrollEffect;ZLandroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/gestures/ScrollableKt;->access$scrollableNestedScrollConnection(Landroidx/compose/runtime/State;Z)Landroidx/compose/ui/input/nestedscroll/NestedScrollConnection;
+PLandroidx/compose/foundation/gestures/ScrollableKt;->awaitScrollEvent(Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollableKt;->getDefaultScrollMotionDurationScale()Landroidx/compose/ui/MotionDurationScale;
+PLandroidx/compose/foundation/gestures/ScrollableKt;->mouseWheelScroll(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/State;Landroidx/compose/foundation/gestures/ScrollConfig;)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/gestures/ScrollableKt;->pointerScrollable(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/foundation/gestures/Orientation;ZLandroidx/compose/foundation/gestures/ScrollableState;Landroidx/compose/foundation/gestures/FlingBehavior;Landroidx/compose/foundation/OverscrollEffect;ZLandroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/gestures/ScrollableKt;->scrollable(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/gestures/ScrollableState;Landroidx/compose/foundation/gestures/Orientation;Landroidx/compose/foundation/OverscrollEffect;ZZLandroidx/compose/foundation/gestures/FlingBehavior;Landroidx/compose/foundation/interaction/MutableInteractionSource;)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/gestures/ScrollableKt;->scrollableNestedScrollConnection(Landroidx/compose/runtime/State;Z)Landroidx/compose/ui/input/nestedscroll/NestedScrollConnection;
+PLandroidx/compose/foundation/gestures/ScrollableState;->scroll$default(Landroidx/compose/foundation/gestures/ScrollableState;Landroidx/compose/foundation/MutatePriority;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollableStateKt;->ScrollableState(Lkotlin/jvm/functions/Function1;)Landroidx/compose/foundation/gestures/ScrollableState;
+PLandroidx/compose/foundation/gestures/ScrollingLogic$doFlingAnimation$1;-><init>(Landroidx/compose/foundation/gestures/ScrollingLogic;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/ScrollingLogic$doFlingAnimation$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollingLogic$doFlingAnimation$2$outerScopeScroll$1;-><init>(Landroidx/compose/foundation/gestures/ScrollingLogic;Landroidx/compose/foundation/gestures/ScrollScope;)V
+PLandroidx/compose/foundation/gestures/ScrollingLogic$doFlingAnimation$2$outerScopeScroll$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollingLogic$doFlingAnimation$2$outerScopeScroll$1;->invoke-MK-Hz9U(J)J
+PLandroidx/compose/foundation/gestures/ScrollingLogic$doFlingAnimation$2$scope$1;-><init>(Landroidx/compose/foundation/gestures/ScrollingLogic;Lkotlin/jvm/functions/Function1;)V
+PLandroidx/compose/foundation/gestures/ScrollingLogic$doFlingAnimation$2$scope$1;->scrollBy(F)F
+PLandroidx/compose/foundation/gestures/ScrollingLogic$doFlingAnimation$2;-><init>(Landroidx/compose/foundation/gestures/ScrollingLogic;Lkotlin/jvm/internal/Ref$LongRef;JLkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/ScrollingLogic$doFlingAnimation$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/gestures/ScrollingLogic$doFlingAnimation$2;->invoke(Landroidx/compose/foundation/gestures/ScrollScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollingLogic$doFlingAnimation$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollingLogic$doFlingAnimation$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollingLogic$onDragStopped$1;-><init>(Landroidx/compose/foundation/gestures/ScrollingLogic;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/ScrollingLogic$onDragStopped$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollingLogic;-><init>(Landroidx/compose/foundation/gestures/Orientation;ZLandroidx/compose/runtime/State;Landroidx/compose/foundation/gestures/ScrollableState;Landroidx/compose/foundation/gestures/FlingBehavior;Landroidx/compose/foundation/OverscrollEffect;)V
+PLandroidx/compose/foundation/gestures/ScrollingLogic;->dispatchScroll-3eAAhYA(Landroidx/compose/foundation/gestures/ScrollScope;JI)J
+PLandroidx/compose/foundation/gestures/ScrollingLogic;->doFlingAnimation-QWom1Mo(JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollingLogic;->getFlingBehavior()Landroidx/compose/foundation/gestures/FlingBehavior;
+PLandroidx/compose/foundation/gestures/ScrollingLogic;->getScrollableState()Landroidx/compose/foundation/gestures/ScrollableState;
+PLandroidx/compose/foundation/gestures/ScrollingLogic;->getShouldDispatchOverscroll()Z
+PLandroidx/compose/foundation/gestures/ScrollingLogic;->onDragStopped-sF-c-tU(JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/ScrollingLogic;->overscrollPostConsumeDelta-OMhpSzk(JJI)V
+PLandroidx/compose/foundation/gestures/ScrollingLogic;->overscrollPreConsumeDelta-OzD1aCk(JI)J
+PLandroidx/compose/foundation/gestures/ScrollingLogic;->registerNestedFling(Z)V
+PLandroidx/compose/foundation/gestures/ScrollingLogic;->reverseIfNeeded(F)F
+PLandroidx/compose/foundation/gestures/ScrollingLogic;->reverseIfNeeded-MK-Hz9U(J)J
+PLandroidx/compose/foundation/gestures/ScrollingLogic;->shouldScrollImmediately()Z
+PLandroidx/compose/foundation/gestures/ScrollingLogic;->singleAxisOffset-MK-Hz9U(J)J
+PLandroidx/compose/foundation/gestures/ScrollingLogic;->singleAxisVelocity-AH228Gc(J)J
+PLandroidx/compose/foundation/gestures/ScrollingLogic;->toFloat-TH1AsA0(J)F
+PLandroidx/compose/foundation/gestures/ScrollingLogic;->toFloat-k-4lQ0M(J)F
+PLandroidx/compose/foundation/gestures/ScrollingLogic;->toOffset-tuRUvjQ(F)J
+PLandroidx/compose/foundation/gestures/ScrollingLogic;->update-QWom1Mo(JF)J
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1$2;-><init>(Lkotlin/jvm/functions/Function3;Landroidx/compose/foundation/gestures/PressGestureScopeImpl;Landroidx/compose/ui/input/pointer/PointerInputChange;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1$3;-><init>(Landroidx/compose/foundation/gestures/PressGestureScopeImpl;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1$3;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1$3;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1$4;-><init>(Landroidx/compose/foundation/gestures/PressGestureScopeImpl;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1$4;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapAndPress$2$1$4;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$1;-><init>(Landroidx/compose/foundation/gestures/PressGestureScopeImpl;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$3;-><init>(Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$3;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$3;->invoke(Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$3;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$5;-><init>(Landroidx/compose/foundation/gestures/PressGestureScopeImpl;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$5;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$detectTapGestures$2$1$5;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$waitForUpOrCancellation$2;-><init>(Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt$waitForUpOrCancellation$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt;->access$getNoPressGesture$p()Lkotlin/jvm/functions/Function3;
+PLandroidx/compose/foundation/gestures/TapGestureDetectorKt;->waitForUpOrCancellation$default(Landroidx/compose/ui/input/pointer/AwaitPointerEventScope;Landroidx/compose/ui/input/pointer/PointerEventPass;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/interaction/DragInteraction$Start;-><clinit>()V
+PLandroidx/compose/foundation/interaction/DragInteraction$Start;-><init>()V
+PLandroidx/compose/foundation/interaction/DragInteraction$Stop;-><clinit>()V
+PLandroidx/compose/foundation/interaction/DragInteraction$Stop;-><init>(Landroidx/compose/foundation/interaction/DragInteraction$Start;)V
+PLandroidx/compose/foundation/interaction/MutableInteractionSourceImpl;->emit(Landroidx/compose/foundation/interaction/Interaction;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/interaction/PressInteraction$Cancel;-><clinit>()V
+PLandroidx/compose/foundation/interaction/PressInteraction$Cancel;-><init>(Landroidx/compose/foundation/interaction/PressInteraction$Press;)V
+PLandroidx/compose/foundation/interaction/PressInteraction$Cancel;->getPress()Landroidx/compose/foundation/interaction/PressInteraction$Press;
+PLandroidx/compose/foundation/interaction/PressInteraction$Press;->getPressPosition-F1C5BW0()J
+PLandroidx/compose/foundation/interaction/PressInteraction$Release;-><clinit>()V
+PLandroidx/compose/foundation/interaction/PressInteraction$Release;-><init>(Landroidx/compose/foundation/interaction/PressInteraction$Press;)V
+PLandroidx/compose/foundation/interaction/PressInteraction$Release;->getPress()Landroidx/compose/foundation/interaction/PressInteraction$Press;
+PLandroidx/compose/foundation/layout/AndroidWindowInsets;-><init>(ILjava/lang/String;)V
+PLandroidx/compose/foundation/layout/AndroidWindowInsets;->getInsets$foundation_layout_release()Landroidx/core/graphics/Insets;
+PLandroidx/compose/foundation/layout/AndroidWindowInsets;->getLeft(Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/unit/LayoutDirection;)I
+PLandroidx/compose/foundation/layout/AndroidWindowInsets;->getRight(Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/unit/LayoutDirection;)I
+PLandroidx/compose/foundation/layout/AndroidWindowInsets;->getTop(Landroidx/compose/ui/unit/Density;)I
+PLandroidx/compose/foundation/layout/Arrangement$End$1;->arrange(Landroidx/compose/ui/unit/Density;I[ILandroidx/compose/ui/unit/LayoutDirection;[I)V
+PLandroidx/compose/foundation/layout/Arrangement$SpacedAligned;-><init>(FZLkotlin/jvm/functions/Function2;)V
+PLandroidx/compose/foundation/layout/Arrangement$SpacedAligned;-><init>(FZLkotlin/jvm/functions/Function2;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/layout/Arrangement$SpacedAligned;->arrange(Landroidx/compose/ui/unit/Density;I[ILandroidx/compose/ui/unit/LayoutDirection;[I)V
+PLandroidx/compose/foundation/layout/Arrangement$SpacedAligned;->arrange(Landroidx/compose/ui/unit/Density;I[I[I)V
+PLandroidx/compose/foundation/layout/Arrangement$SpacedAligned;->equals(Ljava/lang/Object;)Z
+PLandroidx/compose/foundation/layout/Arrangement$SpacedAligned;->getSpacing-D9Ej5fM()F
+PLandroidx/compose/foundation/layout/Arrangement$spacedBy$1;-><clinit>()V
+PLandroidx/compose/foundation/layout/Arrangement$spacedBy$1;-><init>()V
+PLandroidx/compose/foundation/layout/Arrangement;->getEnd()Landroidx/compose/foundation/layout/Arrangement$Horizontal;
+PLandroidx/compose/foundation/layout/Arrangement;->placeRightOrBottom$foundation_layout_release(I[I[IZ)V
+PLandroidx/compose/foundation/layout/Arrangement;->spacedBy-0680j_4(F)Landroidx/compose/foundation/layout/Arrangement$HorizontalOrVertical;
+PLandroidx/compose/foundation/layout/ColumnKt$columnMeasurePolicy$1$1;-><init>(Landroidx/compose/foundation/layout/Arrangement$Vertical;)V
+PLandroidx/compose/foundation/layout/ColumnKt$columnMeasurePolicy$1$1;->invoke(I[ILandroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/ui/unit/Density;[I)V
+PLandroidx/compose/foundation/layout/ColumnKt$columnMeasurePolicy$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/layout/ExcludeInsets;-><init>(Landroidx/compose/foundation/layout/WindowInsets;Landroidx/compose/foundation/layout/WindowInsets;)V
+PLandroidx/compose/foundation/layout/ExcludeInsets;->equals(Ljava/lang/Object;)Z
+PLandroidx/compose/foundation/layout/ExcludeInsets;->getBottom(Landroidx/compose/ui/unit/Density;)I
+PLandroidx/compose/foundation/layout/ExcludeInsets;->getLeft(Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/unit/LayoutDirection;)I
+PLandroidx/compose/foundation/layout/ExcludeInsets;->getRight(Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/unit/LayoutDirection;)I
+PLandroidx/compose/foundation/layout/ExcludeInsets;->getTop(Landroidx/compose/ui/unit/Density;)I
+PLandroidx/compose/foundation/layout/FixedIntInsets;-><init>(IIII)V
+PLandroidx/compose/foundation/layout/FixedIntInsets;->equals(Ljava/lang/Object;)Z
+PLandroidx/compose/foundation/layout/FixedIntInsets;->getBottom(Landroidx/compose/ui/unit/Density;)I
+PLandroidx/compose/foundation/layout/FixedIntInsets;->getLeft(Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/unit/LayoutDirection;)I
+PLandroidx/compose/foundation/layout/FixedIntInsets;->getRight(Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/unit/LayoutDirection;)I
+PLandroidx/compose/foundation/layout/FixedIntInsets;->getTop(Landroidx/compose/ui/unit/Density;)I
+PLandroidx/compose/foundation/layout/InsetsListener;-><init>(Landroidx/compose/foundation/layout/WindowInsetsHolder;)V
+PLandroidx/compose/foundation/layout/InsetsPaddingModifier$measure$1;-><init>(Landroidx/compose/ui/layout/Placeable;II)V
+PLandroidx/compose/foundation/layout/InsetsPaddingModifier$measure$1;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+PLandroidx/compose/foundation/layout/InsetsPaddingModifier$measure$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/layout/InsetsPaddingModifier;-><init>(Landroidx/compose/foundation/layout/WindowInsets;Lkotlin/jvm/functions/Function1;)V
+PLandroidx/compose/foundation/layout/InsetsPaddingModifier;->getKey()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+PLandroidx/compose/foundation/layout/InsetsPaddingModifier;->getUnconsumedInsets()Landroidx/compose/foundation/layout/WindowInsets;
+PLandroidx/compose/foundation/layout/InsetsPaddingModifier;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult;
+PLandroidx/compose/foundation/layout/InsetsPaddingModifier;->onModifierLocalsUpdated(Landroidx/compose/ui/modifier/ModifierLocalReadScope;)V
+PLandroidx/compose/foundation/layout/InsetsPaddingModifier;->setConsumedInsets(Landroidx/compose/foundation/layout/WindowInsets;)V
+PLandroidx/compose/foundation/layout/InsetsPaddingModifier;->setUnconsumedInsets(Landroidx/compose/foundation/layout/WindowInsets;)V
+PLandroidx/compose/foundation/layout/InsetsValues;-><init>(IIII)V
+PLandroidx/compose/foundation/layout/LimitInsets;-><init>(Landroidx/compose/foundation/layout/WindowInsets;I)V
+PLandroidx/compose/foundation/layout/LimitInsets;-><init>(Landroidx/compose/foundation/layout/WindowInsets;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/layout/LimitInsets;->equals(Ljava/lang/Object;)Z
+PLandroidx/compose/foundation/layout/LimitInsets;->getBottom(Landroidx/compose/ui/unit/Density;)I
+PLandroidx/compose/foundation/layout/LimitInsets;->getLeft(Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/unit/LayoutDirection;)I
+PLandroidx/compose/foundation/layout/LimitInsets;->getRight(Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/unit/LayoutDirection;)I
+PLandroidx/compose/foundation/layout/LimitInsets;->getTop(Landroidx/compose/ui/unit/Density;)I
+PLandroidx/compose/foundation/layout/PaddingKt;->PaddingValues-0680j_4(F)Landroidx/compose/foundation/layout/PaddingValues;
+PLandroidx/compose/foundation/layout/SizeKt$createWrapContentHeightModifier$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/layout/SizeKt$createWrapContentHeightModifier$1;->invoke-5SAbXVA(JLandroidx/compose/ui/unit/LayoutDirection;)J
+PLandroidx/compose/foundation/layout/SizeKt;->wrapContentHeight$default(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/Alignment$Vertical;ZILjava/lang/Object;)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/layout/SizeKt;->wrapContentHeight(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/Alignment$Vertical;Z)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/layout/UnionInsets;-><init>(Landroidx/compose/foundation/layout/WindowInsets;Landroidx/compose/foundation/layout/WindowInsets;)V
+PLandroidx/compose/foundation/layout/UnionInsets;->equals(Ljava/lang/Object;)Z
+PLandroidx/compose/foundation/layout/ValueInsets;-><init>(Landroidx/compose/foundation/layout/InsetsValues;Ljava/lang/String;)V
+PLandroidx/compose/foundation/layout/WindowInsets$Companion;-><clinit>()V
+PLandroidx/compose/foundation/layout/WindowInsets$Companion;-><init>()V
+PLandroidx/compose/foundation/layout/WindowInsets;-><clinit>()V
+PLandroidx/compose/foundation/layout/WindowInsetsHolder$Companion$current$1$invoke$$inlined$onDispose$1;-><init>(Landroidx/compose/foundation/layout/WindowInsetsHolder;Landroid/view/View;)V
+PLandroidx/compose/foundation/layout/WindowInsetsHolder$Companion$current$1$invoke$$inlined$onDispose$1;->dispose()V
+PLandroidx/compose/foundation/layout/WindowInsetsHolder$Companion$current$1;-><init>(Landroidx/compose/foundation/layout/WindowInsetsHolder;Landroid/view/View;)V
+PLandroidx/compose/foundation/layout/WindowInsetsHolder$Companion$current$1;->invoke(Landroidx/compose/runtime/DisposableEffectScope;)Landroidx/compose/runtime/DisposableEffectResult;
+PLandroidx/compose/foundation/layout/WindowInsetsHolder$Companion$current$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/layout/WindowInsetsHolder$Companion;-><init>()V
+PLandroidx/compose/foundation/layout/WindowInsetsHolder$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/layout/WindowInsetsHolder$Companion;->access$systemInsets(Landroidx/compose/foundation/layout/WindowInsetsHolder$Companion;Landroidx/core/view/WindowInsetsCompat;ILjava/lang/String;)Landroidx/compose/foundation/layout/AndroidWindowInsets;
+PLandroidx/compose/foundation/layout/WindowInsetsHolder$Companion;->access$valueInsetsIgnoringVisibility(Landroidx/compose/foundation/layout/WindowInsetsHolder$Companion;Landroidx/core/view/WindowInsetsCompat;ILjava/lang/String;)Landroidx/compose/foundation/layout/ValueInsets;
+PLandroidx/compose/foundation/layout/WindowInsetsHolder$Companion;->current(Landroidx/compose/runtime/Composer;I)Landroidx/compose/foundation/layout/WindowInsetsHolder;
+PLandroidx/compose/foundation/layout/WindowInsetsHolder$Companion;->getOrCreateFor(Landroid/view/View;)Landroidx/compose/foundation/layout/WindowInsetsHolder;
+PLandroidx/compose/foundation/layout/WindowInsetsHolder$Companion;->systemInsets(Landroidx/core/view/WindowInsetsCompat;ILjava/lang/String;)Landroidx/compose/foundation/layout/AndroidWindowInsets;
+PLandroidx/compose/foundation/layout/WindowInsetsHolder$Companion;->valueInsetsIgnoringVisibility(Landroidx/core/view/WindowInsetsCompat;ILjava/lang/String;)Landroidx/compose/foundation/layout/ValueInsets;
+PLandroidx/compose/foundation/layout/WindowInsetsHolder;-><clinit>()V
+PLandroidx/compose/foundation/layout/WindowInsetsHolder;-><init>(Landroidx/core/view/WindowInsetsCompat;Landroid/view/View;)V
+PLandroidx/compose/foundation/layout/WindowInsetsHolder;-><init>(Landroidx/core/view/WindowInsetsCompat;Landroid/view/View;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/layout/WindowInsetsHolder;->access$getViewMap$cp()Ljava/util/WeakHashMap;
+PLandroidx/compose/foundation/layout/WindowInsetsHolder;->decrementAccessors(Landroid/view/View;)V
+PLandroidx/compose/foundation/layout/WindowInsetsHolder;->getConsumes()Z
+PLandroidx/compose/foundation/layout/WindowInsetsHolder;->getSystemBars()Landroidx/compose/foundation/layout/AndroidWindowInsets;
+PLandroidx/compose/foundation/layout/WindowInsetsHolder;->incrementAccessors(Landroid/view/View;)V
+PLandroidx/compose/foundation/layout/WindowInsetsKt;->WindowInsets(IIII)Landroidx/compose/foundation/layout/WindowInsets;
+PLandroidx/compose/foundation/layout/WindowInsetsKt;->exclude(Landroidx/compose/foundation/layout/WindowInsets;Landroidx/compose/foundation/layout/WindowInsets;)Landroidx/compose/foundation/layout/WindowInsets;
+PLandroidx/compose/foundation/layout/WindowInsetsKt;->only-bOOhFvg(Landroidx/compose/foundation/layout/WindowInsets;I)Landroidx/compose/foundation/layout/WindowInsets;
+PLandroidx/compose/foundation/layout/WindowInsetsKt;->union(Landroidx/compose/foundation/layout/WindowInsets;Landroidx/compose/foundation/layout/WindowInsets;)Landroidx/compose/foundation/layout/WindowInsets;
+PLandroidx/compose/foundation/layout/WindowInsetsPaddingKt$ModifierLocalConsumedWindowInsets$1;-><clinit>()V
+PLandroidx/compose/foundation/layout/WindowInsetsPaddingKt$ModifierLocalConsumedWindowInsets$1;-><init>()V
+PLandroidx/compose/foundation/layout/WindowInsetsPaddingKt$ModifierLocalConsumedWindowInsets$1;->invoke()Landroidx/compose/foundation/layout/WindowInsets;
+PLandroidx/compose/foundation/layout/WindowInsetsPaddingKt$ModifierLocalConsumedWindowInsets$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/foundation/layout/WindowInsetsPaddingKt;-><clinit>()V
+PLandroidx/compose/foundation/layout/WindowInsetsPaddingKt;->getModifierLocalConsumedWindowInsets()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+PLandroidx/compose/foundation/layout/WindowInsetsPaddingKt;->windowInsetsPadding(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/layout/WindowInsets;)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/layout/WindowInsetsSides$Companion;-><init>()V
+PLandroidx/compose/foundation/layout/WindowInsetsSides$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/layout/WindowInsetsSides$Companion;->getAllowLeftInLtr-JoeWqyM$foundation_layout_release()I
+PLandroidx/compose/foundation/layout/WindowInsetsSides$Companion;->getAllowRightInLtr-JoeWqyM$foundation_layout_release()I
+PLandroidx/compose/foundation/layout/WindowInsetsSides$Companion;->getBottom-JoeWqyM()I
+PLandroidx/compose/foundation/layout/WindowInsetsSides$Companion;->getHorizontal-JoeWqyM()I
+PLandroidx/compose/foundation/layout/WindowInsetsSides$Companion;->getTop-JoeWqyM()I
+PLandroidx/compose/foundation/layout/WindowInsetsSides;-><clinit>()V
+PLandroidx/compose/foundation/layout/WindowInsetsSides;->access$getAllowLeftInLtr$cp()I
+PLandroidx/compose/foundation/layout/WindowInsetsSides;->access$getAllowRightInLtr$cp()I
+PLandroidx/compose/foundation/layout/WindowInsetsSides;->access$getBottom$cp()I
+PLandroidx/compose/foundation/layout/WindowInsetsSides;->access$getHorizontal$cp()I
+PLandroidx/compose/foundation/layout/WindowInsetsSides;->access$getTop$cp()I
+PLandroidx/compose/foundation/layout/WindowInsetsSides;->constructor-impl(I)I
+PLandroidx/compose/foundation/layout/WindowInsetsSides;->hasAny-bkgdKaI$foundation_layout_release(II)Z
+PLandroidx/compose/foundation/layout/WindowInsetsSides;->plus-gK_yJZ4(II)I
+PLandroidx/compose/foundation/layout/WindowInsets_androidKt;->ValueInsets(Landroidx/core/graphics/Insets;Ljava/lang/String;)Landroidx/compose/foundation/layout/ValueInsets;
+PLandroidx/compose/foundation/layout/WindowInsets_androidKt;->getSystemBars(Landroidx/compose/foundation/layout/WindowInsets$Companion;Landroidx/compose/runtime/Composer;I)Landroidx/compose/foundation/layout/WindowInsets;
+PLandroidx/compose/foundation/layout/WindowInsets_androidKt;->toInsetsValues(Landroidx/core/graphics/Insets;)Landroidx/compose/foundation/layout/InsetsValues;
+PLandroidx/compose/foundation/layout/WrapContentModifier$measure$1;-><init>(Landroidx/compose/foundation/layout/WrapContentModifier;ILandroidx/compose/ui/layout/Placeable;ILandroidx/compose/ui/layout/MeasureScope;)V
+PLandroidx/compose/foundation/layout/WrapContentModifier$measure$1;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+PLandroidx/compose/foundation/layout/WrapContentModifier$measure$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/layout/WrapContentModifier;->access$getAlignmentCallback$p(Landroidx/compose/foundation/layout/WrapContentModifier;)Lkotlin/jvm/functions/Function2;
+PLandroidx/compose/foundation/layout/WrapContentModifier;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult;
+PLandroidx/compose/foundation/lazy/AwaitFirstLayoutModifier$waitForFirstLayout$1;-><init>(Landroidx/compose/foundation/lazy/AwaitFirstLayoutModifier;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/lazy/AwaitFirstLayoutModifier;-><init>()V
+PLandroidx/compose/foundation/lazy/AwaitFirstLayoutModifier;->onGloballyPositioned(Landroidx/compose/ui/layout/LayoutCoordinates;)V
+PLandroidx/compose/foundation/lazy/AwaitFirstLayoutModifier;->waitForFirstLayout(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/DataIndex;-><init>(I)V
+PLandroidx/compose/foundation/lazy/DataIndex;->box-impl(I)Landroidx/compose/foundation/lazy/DataIndex;
+PLandroidx/compose/foundation/lazy/DataIndex;->constructor-impl(I)I
+PLandroidx/compose/foundation/lazy/DataIndex;->equals(Ljava/lang/Object;)Z
+PLandroidx/compose/foundation/lazy/DataIndex;->equals-impl(ILjava/lang/Object;)Z
+PLandroidx/compose/foundation/lazy/DataIndex;->equals-impl0(II)Z
+PLandroidx/compose/foundation/lazy/DataIndex;->unbox-impl()I
+PLandroidx/compose/foundation/lazy/EmptyLazyListLayoutInfo;-><clinit>()V
+PLandroidx/compose/foundation/lazy/EmptyLazyListLayoutInfo;-><init>()V
+PLandroidx/compose/foundation/lazy/LazyBeyondBoundsModifierKt;->lazyListBeyondBoundsModifier(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/lazy/LazyListState;Landroidx/compose/foundation/lazy/LazyListBeyondBoundsInfo;ZLandroidx/compose/foundation/gestures/Orientation;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/lazy/LazyDslKt;->LazyColumn(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/lazy/LazyListState;Landroidx/compose/foundation/layout/PaddingValues;ZLandroidx/compose/foundation/layout/Arrangement$Vertical;Landroidx/compose/ui/Alignment$Horizontal;Landroidx/compose/foundation/gestures/FlingBehavior;ZLkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)V
+PLandroidx/compose/foundation/lazy/LazyItemScopeImpl;-><init>()V
+PLandroidx/compose/foundation/lazy/LazyItemScopeImpl;->setMaxSize(II)V
+PLandroidx/compose/foundation/lazy/LazyListAnimateScrollScope;-><init>(Landroidx/compose/foundation/lazy/LazyListState;)V
+PLandroidx/compose/foundation/lazy/LazyListBeyondBoundsInfo;-><init>()V
+PLandroidx/compose/foundation/lazy/LazyListBeyondBoundsInfo;->hasIntervals()Z
+PLandroidx/compose/foundation/lazy/LazyListBeyondBoundsModifierLocal;-><init>(Landroidx/compose/foundation/lazy/LazyListState;Landroidx/compose/foundation/lazy/LazyListBeyondBoundsInfo;ZLandroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/foundation/gestures/Orientation;)V
+PLandroidx/compose/foundation/lazy/LazyListBeyondBoundsModifierLocal;->getKey()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+PLandroidx/compose/foundation/lazy/LazyListBeyondBoundsModifierLocal;->getValue()Landroidx/compose/ui/layout/BeyondBoundsLayout;
+PLandroidx/compose/foundation/lazy/LazyListBeyondBoundsModifierLocal;->getValue()Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListIntervalContent;-><init>(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function4;)V
+PLandroidx/compose/foundation/lazy/LazyListIntervalContent;->getItem()Lkotlin/jvm/functions/Function4;
+PLandroidx/compose/foundation/lazy/LazyListIntervalContent;->getKey()Lkotlin/jvm/functions/Function1;
+PLandroidx/compose/foundation/lazy/LazyListIntervalContent;->getType()Lkotlin/jvm/functions/Function1;
+PLandroidx/compose/foundation/lazy/LazyListItemPlacementAnimator;-><init>(Lkotlinx/coroutines/CoroutineScope;Z)V
+PLandroidx/compose/foundation/lazy/LazyListItemPlacementAnimator;->onMeasured(IIILjava/util/List;Landroidx/compose/foundation/lazy/LazyMeasuredItemProvider;)V
+PLandroidx/compose/foundation/lazy/LazyListItemPlacementAnimator;->reset()V
+PLandroidx/compose/foundation/lazy/LazyListItemProviderImpl$1;-><init>(Landroidx/compose/foundation/lazy/LazyItemScopeImpl;)V
+PLandroidx/compose/foundation/lazy/LazyListItemProviderImpl$1;->invoke(Landroidx/compose/foundation/lazy/LazyListIntervalContent;ILandroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/foundation/lazy/LazyListItemProviderImpl$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderImpl;-><init>(Landroidx/compose/foundation/lazy/layout/IntervalList;Lkotlin/ranges/IntRange;Ljava/util/List;Landroidx/compose/foundation/lazy/LazyItemScopeImpl;)V
+PLandroidx/compose/foundation/lazy/LazyListItemProviderImpl;->Item(ILandroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/foundation/lazy/LazyListItemProviderImpl;->getContentType(I)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderImpl;->getHeaderIndexes()Ljava/util/List;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderImpl;->getItemCount()I
+PLandroidx/compose/foundation/lazy/LazyListItemProviderImpl;->getItemScope()Landroidx/compose/foundation/lazy/LazyItemScopeImpl;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderImpl;->getKey(I)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderImpl;->getKeyToIndexMap()Ljava/util/Map;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$1$1;-><init>(Landroidx/compose/runtime/State;)V
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$1$1;->Item(ILandroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$1$1;->getContentType(I)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$1$1;->getHeaderIndexes()Ljava/util/List;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$1$1;->getItemCount()I
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$1$1;->getItemScope()Landroidx/compose/foundation/lazy/LazyItemScopeImpl;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$1$1;->getKey(I)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$1$1;->getKeyToIndexMap()Ljava/util/Map;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$1$itemProviderState$1;-><init>(Landroidx/compose/runtime/State;Landroidx/compose/runtime/State;Landroidx/compose/foundation/lazy/LazyItemScopeImpl;)V
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$1$itemProviderState$1;->invoke()Landroidx/compose/foundation/lazy/LazyListItemProviderImpl;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$1$itemProviderState$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$nearestItemsRangeState$1$1;-><init>(Landroidx/compose/foundation/lazy/LazyListState;)V
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$nearestItemsRangeState$1$1;->invoke()Ljava/lang/Integer;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$nearestItemsRangeState$1$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$nearestItemsRangeState$2;-><clinit>()V
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$nearestItemsRangeState$2;-><init>()V
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$nearestItemsRangeState$2;->invoke()Ljava/lang/Integer;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$nearestItemsRangeState$2;->invoke()Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$nearestItemsRangeState$3;-><clinit>()V
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$nearestItemsRangeState$3;-><init>()V
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$nearestItemsRangeState$3;->invoke()Ljava/lang/Integer;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt$rememberLazyListItemProvider$nearestItemsRangeState$3;->invoke()Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListItemProviderKt;->rememberLazyListItemProvider(Landroidx/compose/foundation/lazy/LazyListState;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)Landroidx/compose/foundation/lazy/LazyListItemProvider;
+PLandroidx/compose/foundation/lazy/LazyListKt$ScrollPositionUpdater$1;-><init>(Landroidx/compose/foundation/lazy/LazyListItemProvider;Landroidx/compose/foundation/lazy/LazyListState;I)V
+PLandroidx/compose/foundation/lazy/LazyListKt$rememberLazyListMeasurePolicy$1$1$2;-><init>(Landroidx/compose/foundation/lazy/layout/LazyLayoutMeasureScope;JII)V
+PLandroidx/compose/foundation/lazy/LazyListKt$rememberLazyListMeasurePolicy$1$1$2;->invoke(IILkotlin/jvm/functions/Function1;)Landroidx/compose/ui/layout/MeasureResult;
+PLandroidx/compose/foundation/lazy/LazyListKt$rememberLazyListMeasurePolicy$1$1$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListKt$rememberLazyListMeasurePolicy$1$1$measuredItemProvider$1;-><init>(IILandroidx/compose/foundation/lazy/layout/LazyLayoutMeasureScope;ZLandroidx/compose/ui/Alignment$Horizontal;Landroidx/compose/ui/Alignment$Vertical;ZIILandroidx/compose/foundation/lazy/LazyListItemPlacementAnimator;J)V
+PLandroidx/compose/foundation/lazy/LazyListKt$rememberLazyListMeasurePolicy$1$1;-><init>(ZLandroidx/compose/foundation/layout/PaddingValues;ZLandroidx/compose/foundation/lazy/LazyListState;Landroidx/compose/foundation/lazy/LazyListItemProvider;Landroidx/compose/foundation/layout/Arrangement$Vertical;Landroidx/compose/foundation/layout/Arrangement$Horizontal;Landroidx/compose/foundation/lazy/LazyListItemPlacementAnimator;Landroidx/compose/foundation/lazy/LazyListBeyondBoundsInfo;ILandroidx/compose/ui/Alignment$Horizontal;Landroidx/compose/ui/Alignment$Vertical;)V
+PLandroidx/compose/foundation/lazy/LazyListKt$rememberLazyListMeasurePolicy$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListKt;->LazyList(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/lazy/LazyListState;Landroidx/compose/foundation/layout/PaddingValues;ZZLandroidx/compose/foundation/gestures/FlingBehavior;ZILandroidx/compose/ui/Alignment$Horizontal;Landroidx/compose/foundation/layout/Arrangement$Vertical;Landroidx/compose/ui/Alignment$Vertical;Landroidx/compose/foundation/layout/Arrangement$Horizontal;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;III)V
+PLandroidx/compose/foundation/lazy/LazyListKt;->ScrollPositionUpdater(Landroidx/compose/foundation/lazy/LazyListItemProvider;Landroidx/compose/foundation/lazy/LazyListState;Landroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/foundation/lazy/LazyListKt;->rememberLazyListMeasurePolicy(Landroidx/compose/foundation/lazy/LazyListItemProvider;Landroidx/compose/foundation/lazy/LazyListState;Landroidx/compose/foundation/lazy/LazyListBeyondBoundsInfo;Landroidx/compose/foundation/layout/PaddingValues;ZZILandroidx/compose/ui/Alignment$Horizontal;Landroidx/compose/ui/Alignment$Vertical;Landroidx/compose/foundation/layout/Arrangement$Horizontal;Landroidx/compose/foundation/layout/Arrangement$Vertical;Landroidx/compose/foundation/lazy/LazyListItemPlacementAnimator;Landroidx/compose/runtime/Composer;III)Lkotlin/jvm/functions/Function2;
+PLandroidx/compose/foundation/lazy/LazyListMeasureKt$measureLazyList$5;-><init>(Ljava/util/List;Landroidx/compose/foundation/lazy/LazyListPositionedItem;)V
+PLandroidx/compose/foundation/lazy/LazyListMeasureKt$measureLazyList$5;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+PLandroidx/compose/foundation/lazy/LazyListMeasureKt$measureLazyList$5;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListMeasureKt;-><clinit>()V
+PLandroidx/compose/foundation/lazy/LazyListMeasureKt;->calculateItemsOffsets(Ljava/util/List;Ljava/util/List;Ljava/util/List;IIIIIZLandroidx/compose/foundation/layout/Arrangement$Vertical;Landroidx/compose/foundation/layout/Arrangement$Horizontal;ZLandroidx/compose/ui/unit/Density;)Ljava/util/List;
+PLandroidx/compose/foundation/lazy/LazyListMeasureKt;->createItemsAfterList(Landroidx/compose/foundation/lazy/LazyListBeyondBoundsInfo;Ljava/util/List;Landroidx/compose/foundation/lazy/LazyMeasuredItemProvider;II)Ljava/util/List;
+PLandroidx/compose/foundation/lazy/LazyListMeasureKt;->createItemsBeforeList-aZfr-iw(Landroidx/compose/foundation/lazy/LazyListBeyondBoundsInfo;ILandroidx/compose/foundation/lazy/LazyMeasuredItemProvider;II)Ljava/util/List;
+PLandroidx/compose/foundation/lazy/LazyListMeasureKt;->getNotInEmptyRange(I)Z
+PLandroidx/compose/foundation/lazy/LazyListMeasureResult;-><init>(Landroidx/compose/foundation/lazy/LazyMeasuredItem;IZFLandroidx/compose/ui/layout/MeasureResult;Ljava/util/List;IIIZLandroidx/compose/foundation/gestures/Orientation;I)V
+PLandroidx/compose/foundation/lazy/LazyListMeasureResult;->getAlignmentLines()Ljava/util/Map;
+PLandroidx/compose/foundation/lazy/LazyListMeasureResult;->getCanScrollForward()Z
+PLandroidx/compose/foundation/lazy/LazyListMeasureResult;->getConsumedScroll()F
+PLandroidx/compose/foundation/lazy/LazyListMeasureResult;->getFirstVisibleItem()Landroidx/compose/foundation/lazy/LazyMeasuredItem;
+PLandroidx/compose/foundation/lazy/LazyListMeasureResult;->getFirstVisibleItemScrollOffset()I
+PLandroidx/compose/foundation/lazy/LazyListMeasureResult;->getHeight()I
+PLandroidx/compose/foundation/lazy/LazyListMeasureResult;->getTotalItemsCount()I
+PLandroidx/compose/foundation/lazy/LazyListMeasureResult;->getVisibleItemsInfo()Ljava/util/List;
+PLandroidx/compose/foundation/lazy/LazyListMeasureResult;->getWidth()I
+PLandroidx/compose/foundation/lazy/LazyListMeasureResult;->placeChildren()V
+PLandroidx/compose/foundation/lazy/LazyListPinningModifier$Companion$EmptyPinnedItemsHandle$1;-><init>()V
+PLandroidx/compose/foundation/lazy/LazyListPinningModifier$Companion;-><init>()V
+PLandroidx/compose/foundation/lazy/LazyListPinningModifier$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/lazy/LazyListPinningModifier;-><clinit>()V
+PLandroidx/compose/foundation/lazy/LazyListPinningModifier;-><init>(Landroidx/compose/foundation/lazy/LazyListState;Landroidx/compose/foundation/lazy/LazyListBeyondBoundsInfo;)V
+PLandroidx/compose/foundation/lazy/LazyListPinningModifier;->getKey()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+PLandroidx/compose/foundation/lazy/LazyListPinningModifier;->getValue()Landroidx/compose/foundation/lazy/layout/PinnableParent;
+PLandroidx/compose/foundation/lazy/LazyListPinningModifier;->getValue()Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListPinningModifier;->onModifierLocalsUpdated(Landroidx/compose/ui/modifier/ModifierLocalReadScope;)V
+PLandroidx/compose/foundation/lazy/LazyListPinningModifierKt;->lazyListPinningModifier(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/lazy/LazyListState;Landroidx/compose/foundation/lazy/LazyListBeyondBoundsInfo;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/lazy/LazyListPlaceableWrapper;-><init>(JLandroidx/compose/ui/layout/Placeable;)V
+PLandroidx/compose/foundation/lazy/LazyListPlaceableWrapper;-><init>(JLandroidx/compose/ui/layout/Placeable;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/lazy/LazyListPlaceableWrapper;->getOffset-nOcc-ac()J
+PLandroidx/compose/foundation/lazy/LazyListPlaceableWrapper;->getPlaceable()Landroidx/compose/ui/layout/Placeable;
+PLandroidx/compose/foundation/lazy/LazyListPositionedItem;-><init>(IILjava/lang/Object;IIIZLjava/util/List;Landroidx/compose/foundation/lazy/LazyListItemPlacementAnimator;JZI)V
+PLandroidx/compose/foundation/lazy/LazyListPositionedItem;-><init>(IILjava/lang/Object;IIIZLjava/util/List;Landroidx/compose/foundation/lazy/LazyListItemPlacementAnimator;JZILkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/lazy/LazyListPositionedItem;->getAnimationSpec(I)Landroidx/compose/animation/core/FiniteAnimationSpec;
+PLandroidx/compose/foundation/lazy/LazyListPositionedItem;->getHasAnimations()Z
+PLandroidx/compose/foundation/lazy/LazyListPositionedItem;->getIndex()I
+PLandroidx/compose/foundation/lazy/LazyListPositionedItem;->getMainAxisSize(Landroidx/compose/ui/layout/Placeable;)I
+PLandroidx/compose/foundation/lazy/LazyListPositionedItem;->getOffset-Bjo55l4(I)J
+PLandroidx/compose/foundation/lazy/LazyListPositionedItem;->getPlaceablesCount()I
+PLandroidx/compose/foundation/lazy/LazyListScope;->item$default(Landroidx/compose/foundation/lazy/LazyListScope;Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)V
+PLandroidx/compose/foundation/lazy/LazyListScopeImpl$item$2;-><init>(Ljava/lang/Object;)V
+PLandroidx/compose/foundation/lazy/LazyListScopeImpl$item$2;->invoke(I)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListScopeImpl$item$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListScopeImpl$item$3;-><init>(Lkotlin/jvm/functions/Function3;)V
+PLandroidx/compose/foundation/lazy/LazyListScopeImpl$item$3;->invoke(Landroidx/compose/foundation/lazy/LazyItemScope;ILandroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/foundation/lazy/LazyListScopeImpl$item$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListScopeImpl;-><init>()V
+PLandroidx/compose/foundation/lazy/LazyListScopeImpl;->getHeaderIndexes()Ljava/util/List;
+PLandroidx/compose/foundation/lazy/LazyListScopeImpl;->getIntervals()Landroidx/compose/foundation/lazy/layout/IntervalList;
+PLandroidx/compose/foundation/lazy/LazyListScopeImpl;->item(Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)V
+PLandroidx/compose/foundation/lazy/LazyListScopeImpl;->items(ILkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function4;)V
+PLandroidx/compose/foundation/lazy/LazyListScrollPosition;-><init>(II)V
+PLandroidx/compose/foundation/lazy/LazyListScrollPosition;->getIndex-jQJCoq8()I
+PLandroidx/compose/foundation/lazy/LazyListScrollPosition;->getScrollOffset()I
+PLandroidx/compose/foundation/lazy/LazyListScrollPosition;->setIndex-ZjPyQlc(I)V
+PLandroidx/compose/foundation/lazy/LazyListScrollPosition;->setScrollOffset(I)V
+PLandroidx/compose/foundation/lazy/LazyListScrollPosition;->update-AhXoVpI(II)V
+PLandroidx/compose/foundation/lazy/LazyListScrollPosition;->updateFromMeasureResult(Landroidx/compose/foundation/lazy/LazyListMeasureResult;)V
+PLandroidx/compose/foundation/lazy/LazyListScrollPosition;->updateScrollPositionIfTheFirstItemWasMoved(Landroidx/compose/foundation/lazy/LazyListItemProvider;)V
+PLandroidx/compose/foundation/lazy/LazyListState$Companion$Saver$1;-><clinit>()V
+PLandroidx/compose/foundation/lazy/LazyListState$Companion$Saver$1;-><init>()V
+PLandroidx/compose/foundation/lazy/LazyListState$Companion$Saver$1;->invoke(Landroidx/compose/runtime/saveable/SaverScope;Landroidx/compose/foundation/lazy/LazyListState;)Ljava/util/List;
+PLandroidx/compose/foundation/lazy/LazyListState$Companion$Saver$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListState$Companion$Saver$2;-><clinit>()V
+PLandroidx/compose/foundation/lazy/LazyListState$Companion$Saver$2;-><init>()V
+PLandroidx/compose/foundation/lazy/LazyListState$Companion;-><init>()V
+PLandroidx/compose/foundation/lazy/LazyListState$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/lazy/LazyListState$Companion;->getSaver()Landroidx/compose/runtime/saveable/Saver;
+PLandroidx/compose/foundation/lazy/LazyListState$remeasurementModifier$1;-><init>(Landroidx/compose/foundation/lazy/LazyListState;)V
+PLandroidx/compose/foundation/lazy/LazyListState$remeasurementModifier$1;->onRemeasurementAvailable(Landroidx/compose/ui/layout/Remeasurement;)V
+PLandroidx/compose/foundation/lazy/LazyListState$scroll$1;-><init>(Landroidx/compose/foundation/lazy/LazyListState;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/lazy/LazyListState$scroll$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListState$scrollableState$1;-><init>(Landroidx/compose/foundation/lazy/LazyListState;)V
+PLandroidx/compose/foundation/lazy/LazyListState$scrollableState$1;->invoke(F)Ljava/lang/Float;
+PLandroidx/compose/foundation/lazy/LazyListState$scrollableState$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListState;-><clinit>()V
+PLandroidx/compose/foundation/lazy/LazyListState;-><init>(II)V
+PLandroidx/compose/foundation/lazy/LazyListState;->access$getSaver$cp()Landroidx/compose/runtime/saveable/Saver;
+PLandroidx/compose/foundation/lazy/LazyListState;->access$setRemeasurement(Landroidx/compose/foundation/lazy/LazyListState;Landroidx/compose/ui/layout/Remeasurement;)V
+PLandroidx/compose/foundation/lazy/LazyListState;->applyMeasureResult$foundation_release(Landroidx/compose/foundation/lazy/LazyListMeasureResult;)V
+PLandroidx/compose/foundation/lazy/LazyListState;->cancelPrefetchIfVisibleItemsChanged(Landroidx/compose/foundation/lazy/LazyListLayoutInfo;)V
+PLandroidx/compose/foundation/lazy/LazyListState;->getAwaitLayoutModifier$foundation_release()Landroidx/compose/foundation/lazy/AwaitFirstLayoutModifier;
+PLandroidx/compose/foundation/lazy/LazyListState;->getCanScrollBackward()Z
+PLandroidx/compose/foundation/lazy/LazyListState;->getCanScrollForward()Z
+PLandroidx/compose/foundation/lazy/LazyListState;->getFirstVisibleItemIndex()I
+PLandroidx/compose/foundation/lazy/LazyListState;->getFirstVisibleItemScrollOffset()I
+PLandroidx/compose/foundation/lazy/LazyListState;->getInternalInteractionSource$foundation_release()Landroidx/compose/foundation/interaction/MutableInteractionSource;
+PLandroidx/compose/foundation/lazy/LazyListState;->getLayoutInfo()Landroidx/compose/foundation/lazy/LazyListLayoutInfo;
+PLandroidx/compose/foundation/lazy/LazyListState;->getPrefetchState$foundation_release()Landroidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState;
+PLandroidx/compose/foundation/lazy/LazyListState;->getPremeasureConstraints-msEJaDk$foundation_release()J
+PLandroidx/compose/foundation/lazy/LazyListState;->getRemeasurement$foundation_release()Landroidx/compose/ui/layout/Remeasurement;
+PLandroidx/compose/foundation/lazy/LazyListState;->getRemeasurementModifier$foundation_release()Landroidx/compose/ui/layout/RemeasurementModifier;
+PLandroidx/compose/foundation/lazy/LazyListState;->getScrollToBeConsumed$foundation_release()F
+PLandroidx/compose/foundation/lazy/LazyListState;->isScrollInProgress()Z
+PLandroidx/compose/foundation/lazy/LazyListState;->notifyPrefetch(F)V
+PLandroidx/compose/foundation/lazy/LazyListState;->onScroll$foundation_release(F)F
+PLandroidx/compose/foundation/lazy/LazyListState;->scroll(Landroidx/compose/foundation/MutatePriority;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListState;->setCanScrollBackward(Z)V
+PLandroidx/compose/foundation/lazy/LazyListState;->setCanScrollForward(Z)V
+PLandroidx/compose/foundation/lazy/LazyListState;->setDensity$foundation_release(Landroidx/compose/ui/unit/Density;)V
+PLandroidx/compose/foundation/lazy/LazyListState;->setPlacementAnimator$foundation_release(Landroidx/compose/foundation/lazy/LazyListItemPlacementAnimator;)V
+PLandroidx/compose/foundation/lazy/LazyListState;->setPremeasureConstraints-BRTryo0$foundation_release(J)V
+PLandroidx/compose/foundation/lazy/LazyListState;->setRemeasurement(Landroidx/compose/ui/layout/Remeasurement;)V
+PLandroidx/compose/foundation/lazy/LazyListState;->updateScrollPositionIfTheFirstItemWasMoved$foundation_release(Landroidx/compose/foundation/lazy/LazyListItemProvider;)V
+PLandroidx/compose/foundation/lazy/LazyListStateKt$rememberLazyListState$1$1;-><init>(II)V
+PLandroidx/compose/foundation/lazy/LazyListStateKt$rememberLazyListState$1$1;->invoke()Landroidx/compose/foundation/lazy/LazyListState;
+PLandroidx/compose/foundation/lazy/LazyListStateKt$rememberLazyListState$1$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyListStateKt;->rememberLazyListState(IILandroidx/compose/runtime/Composer;II)Landroidx/compose/foundation/lazy/LazyListState;
+PLandroidx/compose/foundation/lazy/LazyMeasuredItem;-><init>(ILjava/util/List;ZLandroidx/compose/ui/Alignment$Horizontal;Landroidx/compose/ui/Alignment$Vertical;Landroidx/compose/ui/unit/LayoutDirection;ZIILandroidx/compose/foundation/lazy/LazyListItemPlacementAnimator;IJLjava/lang/Object;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/lazy/LazyMeasuredItem;->getCrossAxisSize()I
+PLandroidx/compose/foundation/lazy/LazyMeasuredItem;->getIndex()I
+PLandroidx/compose/foundation/lazy/LazyMeasuredItem;->getKey()Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/LazyMeasuredItem;->getSizeWithSpacings()I
+PLandroidx/compose/foundation/lazy/LazyMeasuredItem;->position(III)Landroidx/compose/foundation/lazy/LazyListPositionedItem;
+PLandroidx/compose/foundation/lazy/LazyMeasuredItemProvider;-><init>(JZLandroidx/compose/foundation/lazy/LazyListItemProvider;Landroidx/compose/foundation/lazy/layout/LazyLayoutMeasureScope;Landroidx/compose/foundation/lazy/MeasuredItemFactory;)V
+PLandroidx/compose/foundation/lazy/LazyMeasuredItemProvider;-><init>(JZLandroidx/compose/foundation/lazy/LazyListItemProvider;Landroidx/compose/foundation/lazy/layout/LazyLayoutMeasureScope;Landroidx/compose/foundation/lazy/MeasuredItemFactory;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/lazy/LazyMeasuredItemProvider;->getAndMeasure-ZjPyQlc(I)Landroidx/compose/foundation/lazy/LazyMeasuredItem;
+PLandroidx/compose/foundation/lazy/LazyMeasuredItemProvider;->getChildConstraints-msEJaDk()J
+PLandroidx/compose/foundation/lazy/LazySemanticsKt$rememberLazyListSemanticState$1$1$scrollAxisRange$1;-><init>(Landroidx/compose/foundation/lazy/LazyListState;)V
+PLandroidx/compose/foundation/lazy/LazySemanticsKt$rememberLazyListSemanticState$1$1$scrollAxisRange$2;-><init>(Landroidx/compose/foundation/lazy/LazyListState;Landroidx/compose/foundation/lazy/layout/LazyLayoutItemProvider;)V
+PLandroidx/compose/foundation/lazy/LazySemanticsKt$rememberLazyListSemanticState$1$1;-><init>(ZLandroidx/compose/foundation/lazy/LazyListState;Landroidx/compose/foundation/lazy/layout/LazyLayoutItemProvider;Z)V
+PLandroidx/compose/foundation/lazy/LazySemanticsKt$rememberLazyListSemanticState$1$1;->collectionInfo()Landroidx/compose/ui/semantics/CollectionInfo;
+PLandroidx/compose/foundation/lazy/LazySemanticsKt$rememberLazyListSemanticState$1$1;->scrollAxisRange()Landroidx/compose/ui/semantics/ScrollAxisRange;
+PLandroidx/compose/foundation/lazy/LazySemanticsKt;->rememberLazyListSemanticState(Landroidx/compose/foundation/lazy/LazyListState;Landroidx/compose/foundation/lazy/layout/LazyLayoutItemProvider;ZZLandroidx/compose/runtime/Composer;I)Landroidx/compose/foundation/lazy/layout/LazyLayoutSemanticState;
+PLandroidx/compose/foundation/lazy/layout/DefaultDelegatingLazyLayoutItemProvider$Item$1;-><init>(Landroidx/compose/foundation/lazy/layout/DefaultDelegatingLazyLayoutItemProvider;II)V
+PLandroidx/compose/foundation/lazy/layout/DefaultDelegatingLazyLayoutItemProvider;-><init>(Landroidx/compose/runtime/State;)V
+PLandroidx/compose/foundation/lazy/layout/DefaultDelegatingLazyLayoutItemProvider;->Item(ILandroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/foundation/lazy/layout/DefaultDelegatingLazyLayoutItemProvider;->getContentType(I)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/DefaultDelegatingLazyLayoutItemProvider;->getItemCount()I
+PLandroidx/compose/foundation/lazy/layout/DefaultDelegatingLazyLayoutItemProvider;->getKey(I)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/DefaultDelegatingLazyLayoutItemProvider;->getKeyToIndexMap()Ljava/util/Map;
+PLandroidx/compose/foundation/lazy/layout/DefaultLazyKey$Companion$CREATOR$1;-><init>()V
+PLandroidx/compose/foundation/lazy/layout/DefaultLazyKey$Companion;-><init>()V
+PLandroidx/compose/foundation/lazy/layout/DefaultLazyKey$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/lazy/layout/DefaultLazyKey;-><clinit>()V
+PLandroidx/compose/foundation/lazy/layout/DefaultLazyKey;-><init>(I)V
+PLandroidx/compose/foundation/lazy/layout/DefaultLazyKey;->equals(Ljava/lang/Object;)Z
+PLandroidx/compose/foundation/lazy/layout/DefaultLazyKey;->hashCode()I
+PLandroidx/compose/foundation/lazy/layout/DefaultLazyLayoutItemsProvider$generateKeyToIndexMap$1$1;-><init>(IILjava/util/HashMap;)V
+PLandroidx/compose/foundation/lazy/layout/DefaultLazyLayoutItemsProvider$generateKeyToIndexMap$1$1;->invoke(Landroidx/compose/foundation/lazy/layout/IntervalList$Interval;)V
+PLandroidx/compose/foundation/lazy/layout/DefaultLazyLayoutItemsProvider$generateKeyToIndexMap$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/DefaultLazyLayoutItemsProvider;-><init>(Lkotlin/jvm/functions/Function4;Landroidx/compose/foundation/lazy/layout/IntervalList;Lkotlin/ranges/IntRange;)V
+PLandroidx/compose/foundation/lazy/layout/DefaultLazyLayoutItemsProvider;->Item(ILandroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/foundation/lazy/layout/DefaultLazyLayoutItemsProvider;->generateKeyToIndexMap(Lkotlin/ranges/IntRange;Landroidx/compose/foundation/lazy/layout/IntervalList;)Ljava/util/Map;
+PLandroidx/compose/foundation/lazy/layout/DefaultLazyLayoutItemsProvider;->getContentType(I)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/DefaultLazyLayoutItemsProvider;->getItemCount()I
+PLandroidx/compose/foundation/lazy/layout/DefaultLazyLayoutItemsProvider;->getKeyToIndexMap()Ljava/util/Map;
+PLandroidx/compose/foundation/lazy/layout/IntervalList$Interval;-><clinit>()V
+PLandroidx/compose/foundation/lazy/layout/IntervalList$Interval;-><init>(IILjava/lang/Object;)V
+PLandroidx/compose/foundation/lazy/layout/IntervalList$Interval;->getSize()I
+PLandroidx/compose/foundation/lazy/layout/IntervalList$Interval;->getStartIndex()I
+PLandroidx/compose/foundation/lazy/layout/IntervalList$Interval;->getValue()Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/IntervalListKt;->access$binarySearch(Landroidx/compose/runtime/collection/MutableVector;I)I
+PLandroidx/compose/foundation/lazy/layout/IntervalListKt;->binarySearch(Landroidx/compose/runtime/collection/MutableVector;I)I
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent$createContentLambda$1$1;-><init>(Landroidx/compose/foundation/lazy/layout/LazyLayoutItemProvider;I)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent$createContentLambda$1$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent$createContentLambda$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent$createContentLambda$1$2$invoke$$inlined$onDispose$1;-><init>(Landroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent$createContentLambda$1$2$invoke$$inlined$onDispose$1;->dispose()V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent$createContentLambda$1$2;-><init>(Landroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent$createContentLambda$1$2;->invoke(Landroidx/compose/runtime/DisposableEffectScope;)Landroidx/compose/runtime/DisposableEffectResult;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent$createContentLambda$1$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent$createContentLambda$1;-><init>(Landroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory;Landroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent$createContentLambda$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent$createContentLambda$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent;-><init>(Landroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory;ILjava/lang/Object;Ljava/lang/Object;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent;->access$set_content$p(Landroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent;Lkotlin/jvm/functions/Function2;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent;->createContentLambda()Lkotlin/jvm/functions/Function2;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent;->getContent()Lkotlin/jvm/functions/Function2;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent;->getKey()Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent;->getLastKnownIndex()I
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory$CachedItemContent;->getType()Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory;-><init>(Landroidx/compose/runtime/saveable/SaveableStateHolder;Lkotlin/jvm/functions/Function0;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory;->access$getSaveableStateHolder$p(Landroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory;)Landroidx/compose/runtime/saveable/SaveableStateHolder;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory;->getContentType(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory;->getItemProvider()Lkotlin/jvm/functions/Function0;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemProviderKt;->DelegatingLazyLayoutItemProvider(Landroidx/compose/runtime/State;)Landroidx/compose/foundation/lazy/layout/LazyLayoutItemProvider;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemProviderKt;->LazyLayoutItemProvider(Landroidx/compose/foundation/lazy/layout/IntervalList;Lkotlin/ranges/IntRange;Lkotlin/jvm/functions/Function4;)Landroidx/compose/foundation/lazy/layout/LazyLayoutItemProvider;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemProviderKt;->findIndexByKey(Landroidx/compose/foundation/lazy/layout/LazyLayoutItemProvider;Ljava/lang/Object;I)I
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemReusePolicy;-><init>(Landroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemReusePolicy;->areCompatible(Ljava/lang/Object;Ljava/lang/Object;)Z
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutItemReusePolicy;->getSlotsToRetain(Landroidx/compose/ui/layout/SubcomposeSlotReusePolicy$SlotIdsSet;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutKt$LazyLayout$1$2$1;-><init>(Landroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory;Lkotlin/jvm/functions/Function2;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutKt$LazyLayout$1$2$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutKt$LazyLayout$1$2$1;->invoke-0kLqBqw(Landroidx/compose/ui/layout/SubcomposeMeasureScope;J)Landroidx/compose/ui/layout/MeasureResult;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutKt$LazyLayout$1$itemContentFactory$1$1;-><init>(Landroidx/compose/runtime/State;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutKt$LazyLayout$1$itemContentFactory$1$1;->invoke()Landroidx/compose/foundation/lazy/layout/LazyLayoutItemProvider;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutKt$LazyLayout$1$itemContentFactory$1$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutKt$LazyLayout$1;-><init>(Landroidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function2;ILandroidx/compose/runtime/State;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutKt$LazyLayout$1;->invoke(Landroidx/compose/runtime/saveable/SaveableStateHolder;Landroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutKt$LazyLayout$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutKt;->LazyLayout(Landroidx/compose/foundation/lazy/layout/LazyLayoutItemProvider;Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutMeasureScopeImpl;-><init>(Landroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory;Landroidx/compose/ui/layout/SubcomposeMeasureScope;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutMeasureScopeImpl;->getLayoutDirection()Landroidx/compose/ui/unit/LayoutDirection;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutMeasureScopeImpl;->layout(IILjava/util/Map;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/layout/MeasureResult;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutMeasureScopeImpl;->roundToPx-0680j_4(F)I
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState;-><init>()V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState;->getPrefetcher$foundation_release()Landroidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState$Prefetcher;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState;->schedulePrefetch-0kLqBqw(IJ)Landroidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState$PrefetchHandle;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState;->setPrefetcher$foundation_release(Landroidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState$Prefetcher;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher$Companion;-><init>()V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher$Companion;->access$calculateFrameIntervalIfNeeded(Landroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher$Companion;Landroid/view/View;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher$Companion;->calculateFrameIntervalIfNeeded(Landroid/view/View;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher$PrefetchRequest;-><init>(IJ)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher$PrefetchRequest;-><init>(IJLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher$PrefetchRequest;->cancel()V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher$PrefetchRequest;->getCanceled()Z
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher$PrefetchRequest;->getConstraints-msEJaDk()J
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher$PrefetchRequest;->getIndex()I
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher$PrefetchRequest;->getMeasured()Z
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher$PrefetchRequest;->getPrecomposeHandle()Landroidx/compose/ui/layout/SubcomposeLayoutState$PrecomposedSlotHandle;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher$PrefetchRequest;->setPrecomposeHandle(Landroidx/compose/ui/layout/SubcomposeLayoutState$PrecomposedSlotHandle;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher;-><clinit>()V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher;-><init>(Landroidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState;Landroidx/compose/ui/layout/SubcomposeLayoutState;Landroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory;Landroid/view/View;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher;->access$getFrameIntervalNs$cp()J
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher;->access$setFrameIntervalNs$cp(J)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher;->calculateAverageTime(JJ)J
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher;->doFrame(J)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher;->enoughTimeLeft(JJJ)Z
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher;->onForgotten()V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher;->onRemembered()V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher;->run()V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher;->schedulePrefetch-0kLqBqw(IJ)Landroidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState$PrefetchHandle;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher_androidKt;->LazyLayoutPrefetcher(Landroidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState;Landroidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory;Landroidx/compose/ui/layout/SubcomposeLayoutState;Landroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutSemanticsKt$lazyLayoutSemantics$1$1;-><init>(Lkotlin/jvm/functions/Function1;ZLandroidx/compose/ui/semantics/ScrollAxisRange;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/semantics/CollectionInfo;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutSemanticsKt$lazyLayoutSemantics$1$1;->invoke(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutSemanticsKt$lazyLayoutSemantics$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutSemanticsKt$lazyLayoutSemantics$1$indexForKeyMapping$1;-><init>(Landroidx/compose/foundation/lazy/layout/LazyLayoutItemProvider;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutSemanticsKt$lazyLayoutSemantics$1$scrollByAction$1;-><init>(ZLkotlinx/coroutines/CoroutineScope;Landroidx/compose/foundation/lazy/layout/LazyLayoutSemanticState;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutSemanticsKt$lazyLayoutSemantics$1$scrollToIndexAction$1;-><init>(Landroidx/compose/foundation/lazy/layout/LazyLayoutItemProvider;Lkotlinx/coroutines/CoroutineScope;Landroidx/compose/foundation/lazy/layout/LazyLayoutSemanticState;)V
+PLandroidx/compose/foundation/lazy/layout/LazyLayoutSemanticsKt;->lazyLayoutSemantics(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/lazy/layout/LazyLayoutItemProvider;Landroidx/compose/foundation/lazy/layout/LazyLayoutSemanticState;Landroidx/compose/foundation/gestures/Orientation;ZLandroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/lazy/layout/LazyNearestItemsRangeKt$rememberLazyNearestItemsRangeState$1$1$1;-><init>(Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
+PLandroidx/compose/foundation/lazy/layout/LazyNearestItemsRangeKt$rememberLazyNearestItemsRangeState$1$1$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazyNearestItemsRangeKt$rememberLazyNearestItemsRangeState$1$1$1;->invoke()Lkotlin/ranges/IntRange;
+PLandroidx/compose/foundation/lazy/layout/LazyNearestItemsRangeKt$rememberLazyNearestItemsRangeState$1$1$2;-><init>(Landroidx/compose/runtime/MutableState;)V
+PLandroidx/compose/foundation/lazy/layout/LazyNearestItemsRangeKt$rememberLazyNearestItemsRangeState$1$1$2;->emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazyNearestItemsRangeKt$rememberLazyNearestItemsRangeState$1$1$2;->emit(Lkotlin/ranges/IntRange;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazyNearestItemsRangeKt$rememberLazyNearestItemsRangeState$1$1;-><init>(Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/MutableState;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/foundation/lazy/layout/LazyNearestItemsRangeKt$rememberLazyNearestItemsRangeState$1$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/foundation/lazy/layout/LazyNearestItemsRangeKt$rememberLazyNearestItemsRangeState$1$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazyNearestItemsRangeKt;->access$calculateNearestItemsRange(III)Lkotlin/ranges/IntRange;
+PLandroidx/compose/foundation/lazy/layout/LazyNearestItemsRangeKt;->calculateNearestItemsRange(III)Lkotlin/ranges/IntRange;
+PLandroidx/compose/foundation/lazy/layout/LazyNearestItemsRangeKt;->rememberLazyNearestItemsRangeState(Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder$1;-><init>(Landroidx/compose/runtime/saveable/SaveableStateRegistry;)V
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder$1;->invoke(Ljava/lang/Object;)Ljava/lang/Boolean;
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder$Companion$saver$1;-><clinit>()V
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder$Companion$saver$1;-><init>()V
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder$Companion$saver$1;->invoke(Landroidx/compose/runtime/saveable/SaverScope;Landroidx/compose/foundation/lazy/layout/LazySaveableStateHolder;)Ljava/util/Map;
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder$Companion$saver$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder$Companion$saver$2;-><init>(Landroidx/compose/runtime/saveable/SaveableStateRegistry;)V
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder$Companion;-><init>()V
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder$Companion;->saver(Landroidx/compose/runtime/saveable/SaveableStateRegistry;)Landroidx/compose/runtime/saveable/Saver;
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder$SaveableStateProvider$1$invoke$$inlined$onDispose$1;-><init>(Landroidx/compose/foundation/lazy/layout/LazySaveableStateHolder;Ljava/lang/Object;)V
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder$SaveableStateProvider$1$invoke$$inlined$onDispose$1;->dispose()V
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder$SaveableStateProvider$1;-><init>(Landroidx/compose/foundation/lazy/layout/LazySaveableStateHolder;Ljava/lang/Object;)V
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder$SaveableStateProvider$1;->invoke(Landroidx/compose/runtime/DisposableEffectScope;)Landroidx/compose/runtime/DisposableEffectResult;
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder$SaveableStateProvider$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder$SaveableStateProvider$2;-><init>(Landroidx/compose/foundation/lazy/layout/LazySaveableStateHolder;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;I)V
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder;-><clinit>()V
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder;-><init>(Landroidx/compose/runtime/saveable/SaveableStateRegistry;)V
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder;-><init>(Landroidx/compose/runtime/saveable/SaveableStateRegistry;Ljava/util/Map;)V
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder;->SaveableStateProvider(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder;->access$getPreviouslyComposedKeys$p(Landroidx/compose/foundation/lazy/layout/LazySaveableStateHolder;)Ljava/util/Set;
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder;->canBeSaved(Ljava/lang/Object;)Z
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder;->consumeRestored(Ljava/lang/String;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder;->getWrappedHolder()Landroidx/compose/runtime/saveable/SaveableStateHolder;
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder;->performSave()Ljava/util/Map;
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder;->registerProvider(Ljava/lang/String;Lkotlin/jvm/functions/Function0;)Landroidx/compose/runtime/saveable/SaveableStateRegistry$Entry;
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolder;->setWrappedHolder(Landroidx/compose/runtime/saveable/SaveableStateHolder;)V
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolderKt$LazySaveableStateHolderProvider$1;-><init>(Landroidx/compose/foundation/lazy/layout/LazySaveableStateHolder;Lkotlin/jvm/functions/Function3;I)V
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolderKt$LazySaveableStateHolderProvider$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolderKt$LazySaveableStateHolderProvider$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolderKt$LazySaveableStateHolderProvider$holder$1;-><init>(Landroidx/compose/runtime/saveable/SaveableStateRegistry;)V
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolderKt$LazySaveableStateHolderProvider$holder$1;->invoke()Landroidx/compose/foundation/lazy/layout/LazySaveableStateHolder;
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolderKt$LazySaveableStateHolderProvider$holder$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/LazySaveableStateHolderKt;->LazySaveableStateHolderProvider(Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/foundation/lazy/layout/Lazy_androidKt;->getDefaultLazyLayoutKey(I)Ljava/lang/Object;
+PLandroidx/compose/foundation/lazy/layout/MutableIntervalList;-><clinit>()V
+PLandroidx/compose/foundation/lazy/layout/MutableIntervalList;-><init>()V
+PLandroidx/compose/foundation/lazy/layout/MutableIntervalList;->addInterval(ILjava/lang/Object;)V
+PLandroidx/compose/foundation/lazy/layout/MutableIntervalList;->checkIndexBounds(I)V
+PLandroidx/compose/foundation/lazy/layout/MutableIntervalList;->contains(Landroidx/compose/foundation/lazy/layout/IntervalList$Interval;I)Z
+PLandroidx/compose/foundation/lazy/layout/MutableIntervalList;->forEach(IILkotlin/jvm/functions/Function1;)V
+PLandroidx/compose/foundation/lazy/layout/MutableIntervalList;->get(I)Landroidx/compose/foundation/lazy/layout/IntervalList$Interval;
+PLandroidx/compose/foundation/lazy/layout/MutableIntervalList;->getIntervalForIndex(I)Landroidx/compose/foundation/lazy/layout/IntervalList$Interval;
+PLandroidx/compose/foundation/lazy/layout/MutableIntervalList;->getSize()I
+PLandroidx/compose/foundation/relocation/BringIntoViewRequesterKt$bringIntoViewRequester$2$1$invoke$$inlined$onDispose$1;->dispose()V
+PLandroidx/compose/foundation/relocation/BringIntoViewResponderKt$bringIntoViewResponder$2;-><init>(Landroidx/compose/foundation/relocation/BringIntoViewResponder;)V
+PLandroidx/compose/foundation/relocation/BringIntoViewResponderKt$bringIntoViewResponder$2;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/relocation/BringIntoViewResponderKt$bringIntoViewResponder$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/foundation/relocation/BringIntoViewResponderKt;->bringIntoViewResponder(Landroidx/compose/ui/Modifier;Landroidx/compose/foundation/relocation/BringIntoViewResponder;)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/foundation/relocation/BringIntoViewResponderModifier;-><init>(Landroidx/compose/foundation/relocation/BringIntoViewParent;)V
+PLandroidx/compose/foundation/relocation/BringIntoViewResponderModifier;->getKey()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+PLandroidx/compose/foundation/relocation/BringIntoViewResponderModifier;->getValue()Landroidx/compose/foundation/relocation/BringIntoViewParent;
+PLandroidx/compose/foundation/relocation/BringIntoViewResponderModifier;->getValue()Ljava/lang/Object;
+PLandroidx/compose/foundation/relocation/BringIntoViewResponderModifier;->setResponder(Landroidx/compose/foundation/relocation/BringIntoViewResponder;)V
+PLandroidx/compose/foundation/text/TextController;->onForgotten()V
+PLandroidx/compose/foundation/text/TextState;->getSelectable()Landroidx/compose/foundation/text/selection/Selectable;
+PLandroidx/compose/material/icons/Icons$Filled;-><clinit>()V
+PLandroidx/compose/material/icons/Icons$Filled;-><init>()V
+PLandroidx/compose/material/icons/Icons$Outlined;-><clinit>()V
+PLandroidx/compose/material/icons/Icons$Outlined;-><init>()V
+PLandroidx/compose/material/icons/filled/AddKt;-><clinit>()V
+PLandroidx/compose/material/icons/filled/AddKt;->getAdd(Landroidx/compose/material/icons/Icons$Filled;)Landroidx/compose/ui/graphics/vector/ImageVector;
+PLandroidx/compose/material/icons/filled/ArrowBackKt;-><clinit>()V
+PLandroidx/compose/material/icons/filled/ArrowBackKt;->getArrowBack(Landroidx/compose/material/icons/Icons$Filled;)Landroidx/compose/ui/graphics/vector/ImageVector;
+PLandroidx/compose/material/icons/outlined/NewReleasesKt;-><clinit>()V
+PLandroidx/compose/material/icons/outlined/NewReleasesKt;->getNewReleases(Landroidx/compose/material/icons/Icons$Outlined;)Landroidx/compose/ui/graphics/vector/ImageVector;
+PLandroidx/compose/material/ripple/AndroidRippleIndicationInstance$onInvalidateRipple$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/material/ripple/AndroidRippleIndicationInstance$onInvalidateRipple$1;->invoke()V
+PLandroidx/compose/material/ripple/AndroidRippleIndicationInstance;->access$getInvalidateTick(Landroidx/compose/material/ripple/AndroidRippleIndicationInstance;)Z
+PLandroidx/compose/material/ripple/AndroidRippleIndicationInstance;->access$setInvalidateTick(Landroidx/compose/material/ripple/AndroidRippleIndicationInstance;Z)V
+PLandroidx/compose/material/ripple/AndroidRippleIndicationInstance;->addRipple(Landroidx/compose/foundation/interaction/PressInteraction$Press;Lkotlinx/coroutines/CoroutineScope;)V
+PLandroidx/compose/material/ripple/AndroidRippleIndicationInstance;->dispose()V
+PLandroidx/compose/material/ripple/AndroidRippleIndicationInstance;->onForgotten()V
+PLandroidx/compose/material/ripple/AndroidRippleIndicationInstance;->removeRipple(Landroidx/compose/foundation/interaction/PressInteraction$Press;)V
+PLandroidx/compose/material/ripple/AndroidRippleIndicationInstance;->resetHostView()V
+PLandroidx/compose/material/ripple/AndroidRippleIndicationInstance;->setInvalidateTick(Z)V
+PLandroidx/compose/material/ripple/AndroidRippleIndicationInstance;->setRippleHostView(Landroidx/compose/material/ripple/RippleHostView;)V
+PLandroidx/compose/material/ripple/Ripple$rememberUpdatedInstance$1$1;->emit(Landroidx/compose/foundation/interaction/Interaction;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/material/ripple/Ripple$rememberUpdatedInstance$1$1;->emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/material/ripple/RippleContainer;->disposeRippleIfNeeded(Landroidx/compose/material/ripple/AndroidRippleIndicationInstance;)V
+PLandroidx/compose/material/ripple/RippleContainer;->getRippleHostView(Landroidx/compose/material/ripple/AndroidRippleIndicationInstance;)Landroidx/compose/material/ripple/RippleHostView;
+PLandroidx/compose/material/ripple/RippleHostMap;->get(Landroidx/compose/material/ripple/AndroidRippleIndicationInstance;)Landroidx/compose/material/ripple/RippleHostView;
+PLandroidx/compose/material/ripple/RippleHostMap;->remove(Landroidx/compose/material/ripple/AndroidRippleIndicationInstance;)V
+PLandroidx/compose/material/ripple/RippleHostMap;->set(Landroidx/compose/material/ripple/AndroidRippleIndicationInstance;Landroidx/compose/material/ripple/RippleHostView;)V
+PLandroidx/compose/material/ripple/RippleHostView$$ExternalSyntheticLambda0;-><init>(Landroidx/compose/material/ripple/RippleHostView;)V
+PLandroidx/compose/material/ripple/RippleHostView$$ExternalSyntheticLambda0;->run()V
+PLandroidx/compose/material/ripple/RippleHostView;->$r8$lambda$4nztiuYeQHklB-09QfMAnp7Ay8E(Landroidx/compose/material/ripple/RippleHostView;)V
+PLandroidx/compose/material/ripple/RippleHostView;->addRipple-KOepWvA(Landroidx/compose/foundation/interaction/PressInteraction$Press;ZJIJFLkotlin/jvm/functions/Function0;)V
+PLandroidx/compose/material/ripple/RippleHostView;->createRipple(Z)V
+PLandroidx/compose/material/ripple/RippleHostView;->disposeRipple()V
+PLandroidx/compose/material/ripple/RippleHostView;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
+PLandroidx/compose/material/ripple/RippleHostView;->removeRipple()V
+PLandroidx/compose/material/ripple/RippleHostView;->setRippleState$lambda$2(Landroidx/compose/material/ripple/RippleHostView;)V
+PLandroidx/compose/material/ripple/RippleHostView;->setRippleState(Z)V
+PLandroidx/compose/material/ripple/RippleHostView;->updateRippleProperties-biQXAtU(JIJF)V
+PLandroidx/compose/material/ripple/UnprojectedRipple$Companion;-><init>()V
+PLandroidx/compose/material/ripple/UnprojectedRipple$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/material/ripple/UnprojectedRipple$MRadiusHelper;-><clinit>()V
+PLandroidx/compose/material/ripple/UnprojectedRipple$MRadiusHelper;-><init>()V
+PLandroidx/compose/material/ripple/UnprojectedRipple$MRadiusHelper;->setRadius(Landroid/graphics/drawable/RippleDrawable;I)V
+PLandroidx/compose/material/ripple/UnprojectedRipple;-><clinit>()V
+PLandroidx/compose/material/ripple/UnprojectedRipple;-><init>(Z)V
+PLandroidx/compose/material/ripple/UnprojectedRipple;->calculateRippleColor-5vOe2sY(JF)J
+PLandroidx/compose/material/ripple/UnprojectedRipple;->getDirtyBounds()Landroid/graphics/Rect;
+PLandroidx/compose/material/ripple/UnprojectedRipple;->isProjected()Z
+PLandroidx/compose/material/ripple/UnprojectedRipple;->setColor-DxMtmZc(JF)V
+PLandroidx/compose/material/ripple/UnprojectedRipple;->trySetRadius(I)V
+PLandroidx/compose/material3/AppBarKt$SingleRowTopAppBar$1$1;-><init>(Landroidx/compose/material3/TopAppBarScrollBehavior;F)V
+PLandroidx/compose/material3/AppBarKt$SingleRowTopAppBar$1$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/material3/AppBarKt$SingleRowTopAppBar$1$1;->invoke()V
+PLandroidx/compose/material3/AppBarKt$SingleRowTopAppBar$2;-><init>(Landroidx/compose/foundation/layout/WindowInsets;Landroidx/compose/material3/TopAppBarColors;Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/text/TextStyle;ZLkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;ILandroidx/compose/material3/TopAppBarScrollBehavior;)V
+PLandroidx/compose/material3/AppBarKt$SingleRowTopAppBar$2;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/material3/AppBarKt$SingleRowTopAppBar$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/material3/AppBarKt$SingleRowTopAppBar$3;-><init>(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/text/TextStyle;ZLkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Landroidx/compose/foundation/layout/WindowInsets;Landroidx/compose/material3/TopAppBarColors;Landroidx/compose/material3/TopAppBarScrollBehavior;II)V
+PLandroidx/compose/material3/AppBarKt$SingleRowTopAppBar$actionsRow$1;-><init>(Lkotlin/jvm/functions/Function3;I)V
+PLandroidx/compose/material3/AppBarKt$SingleRowTopAppBar$actionsRow$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/material3/AppBarKt$SingleRowTopAppBar$actionsRow$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/material3/AppBarKt$TopAppBarLayout$1$3$1;-><init>(JLkotlin/jvm/functions/Function2;I)V
+PLandroidx/compose/material3/AppBarKt$TopAppBarLayout$1$3$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/material3/AppBarKt$TopAppBarLayout$1$3$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/material3/AppBarKt$TopAppBarLayout$2$measure$1;-><init>(Landroidx/compose/ui/layout/Placeable;ILandroidx/compose/ui/layout/Placeable;Landroidx/compose/foundation/layout/Arrangement$Horizontal;JLandroidx/compose/ui/layout/Placeable;Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/foundation/layout/Arrangement$Vertical;II)V
+PLandroidx/compose/material3/AppBarKt$TopAppBarLayout$2$measure$1;->invoke(Landroidx/compose/ui/layout/Placeable$PlacementScope;)V
+PLandroidx/compose/material3/AppBarKt$TopAppBarLayout$2$measure$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/material3/AppBarKt$TopAppBarLayout$2;-><init>(FLandroidx/compose/foundation/layout/Arrangement$Horizontal;Landroidx/compose/foundation/layout/Arrangement$Vertical;I)V
+PLandroidx/compose/material3/AppBarKt$TopAppBarLayout$2;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Ljava/util/List;J)Landroidx/compose/ui/layout/MeasureResult;
+PLandroidx/compose/material3/AppBarKt;-><clinit>()V
+PLandroidx/compose/material3/AppBarKt;->SingleRowTopAppBar$lambda$3(Landroidx/compose/runtime/State;)J
+PLandroidx/compose/material3/AppBarKt;->SingleRowTopAppBar(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/text/TextStyle;ZLkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Landroidx/compose/foundation/layout/WindowInsets;Landroidx/compose/material3/TopAppBarColors;Landroidx/compose/material3/TopAppBarScrollBehavior;Landroidx/compose/runtime/Composer;II)V
+PLandroidx/compose/material3/AppBarKt;->TopAppBar(Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Landroidx/compose/foundation/layout/WindowInsets;Landroidx/compose/material3/TopAppBarColors;Landroidx/compose/material3/TopAppBarScrollBehavior;Landroidx/compose/runtime/Composer;II)V
+PLandroidx/compose/material3/AppBarKt;->TopAppBarLayout-kXwM9vE(Landroidx/compose/ui/Modifier;FJJJLkotlin/jvm/functions/Function2;Landroidx/compose/ui/text/TextStyle;FLandroidx/compose/foundation/layout/Arrangement$Vertical;Landroidx/compose/foundation/layout/Arrangement$Horizontal;IZLkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V
+PLandroidx/compose/material3/AppBarKt;->access$TopAppBarLayout-kXwM9vE(Landroidx/compose/ui/Modifier;FJJJLkotlin/jvm/functions/Function2;Landroidx/compose/ui/text/TextStyle;FLandroidx/compose/foundation/layout/Arrangement$Vertical;Landroidx/compose/foundation/layout/Arrangement$Horizontal;IZLkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V
+PLandroidx/compose/material3/AppBarKt;->access$getTopAppBarTitleInset$p()F
+PLandroidx/compose/material3/ButtonElevation$animateElevation$1$1$1;->emit(Landroidx/compose/foundation/interaction/Interaction;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/material3/ButtonElevation$animateElevation$1$1$1;->emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/material3/ButtonKt$Button$3;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/material3/ButtonKt$Button$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/material3/ChipElevation$animateElevation$1$1$1;->emit(Landroidx/compose/foundation/interaction/Interaction;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/material3/ChipElevation$animateElevation$1$1$1;->emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/material3/ChipKt$Chip$2;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/material3/ChipKt$Chip$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/material3/ChipKt;->access$Chip-nkUnTEs(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function0;ZLkotlin/jvm/functions/Function2;Landroidx/compose/ui/text/TextStyle;JLkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/graphics/Shape;Landroidx/compose/material3/ChipColors;Landroidx/compose/material3/ChipElevation;Landroidx/compose/foundation/BorderStroke;FLandroidx/compose/foundation/layout/PaddingValues;Landroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/runtime/Composer;II)V
+PLandroidx/compose/material3/ColorSchemeKt;->applyTonalElevation-Hht5A8o(Landroidx/compose/material3/ColorScheme;JF)J
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-1$1;-><clinit>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-1$1;-><init>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-10$1;-><clinit>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-10$1;-><init>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-11$1;-><clinit>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-11$1;-><init>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-12$1;-><clinit>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-12$1;-><init>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-2$1;-><clinit>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-2$1;-><init>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-2$1;->invoke(Landroidx/compose/foundation/layout/RowScope;Landroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-2$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-3$1;-><clinit>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-3$1;-><init>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-4$1;-><clinit>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-4$1;-><init>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-5$1;-><clinit>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-5$1;-><init>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-6$1;-><clinit>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-6$1;-><init>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-7$1;-><clinit>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-7$1;-><init>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-8$1;-><clinit>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-8$1;-><init>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-9$1;-><clinit>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt$lambda-9$1;-><init>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt;-><clinit>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt;-><init>()V
+PLandroidx/compose/material3/ComposableSingletons$AppBarKt;->getLambda-2$material3_release()Lkotlin/jvm/functions/Function3;
+PLandroidx/compose/material3/IconButtonColors;-><init>(JJJJ)V
+PLandroidx/compose/material3/IconButtonColors;-><init>(JJJJLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/material3/IconButtonColors;->containerColor$material3_release(ZLandroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+PLandroidx/compose/material3/IconButtonColors;->contentColor$material3_release(ZLandroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/State;
+PLandroidx/compose/material3/IconButtonDefaults;-><clinit>()V
+PLandroidx/compose/material3/IconButtonDefaults;-><init>()V
+PLandroidx/compose/material3/IconButtonDefaults;->iconButtonColors-ro_MJ88(JJJJLandroidx/compose/runtime/Composer;II)Landroidx/compose/material3/IconButtonColors;
+PLandroidx/compose/material3/IconButtonKt$IconButton$3;-><init>(Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/Modifier;ZLandroidx/compose/material3/IconButtonColors;Landroidx/compose/foundation/interaction/MutableInteractionSource;Lkotlin/jvm/functions/Function2;II)V
+PLandroidx/compose/material3/IconButtonKt;->IconButton(Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/Modifier;ZLandroidx/compose/material3/IconButtonColors;Landroidx/compose/foundation/interaction/MutableInteractionSource;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V
+PLandroidx/compose/material3/IconKt$Icon$1;-><init>(Landroidx/compose/ui/graphics/vector/ImageVector;Ljava/lang/String;Landroidx/compose/ui/Modifier;JII)V
+PLandroidx/compose/material3/IconKt$Icon$3;-><init>(Landroidx/compose/ui/graphics/painter/Painter;Ljava/lang/String;Landroidx/compose/ui/Modifier;JII)V
+PLandroidx/compose/material3/IconKt$Icon$semantics$1$1;-><init>(Ljava/lang/String;)V
+PLandroidx/compose/material3/IconKt$Icon$semantics$1$1;->invoke(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;)V
+PLandroidx/compose/material3/IconKt$Icon$semantics$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/material3/IconKt;->Icon-ww6aTOc(Landroidx/compose/ui/graphics/vector/ImageVector;Ljava/lang/String;Landroidx/compose/ui/Modifier;JLandroidx/compose/runtime/Composer;II)V
+PLandroidx/compose/material3/Shapes;->getLarge()Landroidx/compose/foundation/shape/CornerBasedShape;
+PLandroidx/compose/material3/Shapes;->getSmall()Landroidx/compose/foundation/shape/CornerBasedShape;
+PLandroidx/compose/material3/SuggestionChipDefaults;->getShape(Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/graphics/Shape;
+PLandroidx/compose/material3/SystemBarsDefaultInsets_androidKt;->getSystemBarsForVisualComponents(Landroidx/compose/foundation/layout/WindowInsets$Companion;Landroidx/compose/runtime/Composer;I)Landroidx/compose/foundation/layout/WindowInsets;
+PLandroidx/compose/material3/TopAppBarColors;-><init>(JJJJJ)V
+PLandroidx/compose/material3/TopAppBarColors;-><init>(JJJJJLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/material3/TopAppBarColors;->containerColor-XeAY9LY$material3_release(FLandroidx/compose/runtime/Composer;I)J
+PLandroidx/compose/material3/TopAppBarColors;->equals(Ljava/lang/Object;)Z
+PLandroidx/compose/material3/TopAppBarColors;->getActionIconContentColor-0d7_KjU$material3_release()J
+PLandroidx/compose/material3/TopAppBarColors;->getNavigationIconContentColor-0d7_KjU$material3_release()J
+PLandroidx/compose/material3/TopAppBarColors;->getTitleContentColor-0d7_KjU$material3_release()J
+PLandroidx/compose/material3/TopAppBarDefaults;-><clinit>()V
+PLandroidx/compose/material3/TopAppBarDefaults;-><init>()V
+PLandroidx/compose/material3/TopAppBarDefaults;->getWindowInsets(Landroidx/compose/runtime/Composer;I)Landroidx/compose/foundation/layout/WindowInsets;
+PLandroidx/compose/material3/TopAppBarDefaults;->smallTopAppBarColors-zjMxDiM(JJJJJLandroidx/compose/runtime/Composer;II)Landroidx/compose/material3/TopAppBarColors;
+PLandroidx/compose/material3/TopAppBarDefaults;->topAppBarColors-zjMxDiM(JJJJJLandroidx/compose/runtime/Composer;II)Landroidx/compose/material3/TopAppBarColors;
+PLandroidx/compose/material3/Typography;->getHeadlineSmall()Landroidx/compose/ui/text/TextStyle;
+PLandroidx/compose/material3/tokens/IconButtonTokens;->getStateLayerShape()Landroidx/compose/material3/tokens/ShapeKeyTokens;
+PLandroidx/compose/material3/tokens/IconButtonTokens;->getStateLayerSize-D9Ej5fM()F
+PLandroidx/compose/material3/tokens/SuggestionChipTokens;->getContainerShape()Landroidx/compose/material3/tokens/ShapeKeyTokens;
+PLandroidx/compose/material3/tokens/SuggestionChipTokens;->getLabelTextColor()Landroidx/compose/material3/tokens/ColorSchemeKeyTokens;
+PLandroidx/compose/material3/tokens/SuggestionChipTokens;->getLeadingIconColor()Landroidx/compose/material3/tokens/ColorSchemeKeyTokens;
+PLandroidx/compose/material3/tokens/TopAppBarSmallTokens;-><clinit>()V
+PLandroidx/compose/material3/tokens/TopAppBarSmallTokens;-><init>()V
+PLandroidx/compose/material3/tokens/TopAppBarSmallTokens;->getContainerHeight-D9Ej5fM()F
+PLandroidx/compose/material3/tokens/TopAppBarSmallTokens;->getHeadlineColor()Landroidx/compose/material3/tokens/ColorSchemeKeyTokens;
+PLandroidx/compose/material3/tokens/TopAppBarSmallTokens;->getHeadlineFont()Landroidx/compose/material3/tokens/TypographyKeyTokens;
+PLandroidx/compose/material3/tokens/TopAppBarSmallTokens;->getLeadingIconColor()Landroidx/compose/material3/tokens/ColorSchemeKeyTokens;
+PLandroidx/compose/material3/tokens/TopAppBarSmallTokens;->getOnScrollContainerElevation-D9Ej5fM()F
+PLandroidx/compose/material3/tokens/TopAppBarSmallTokens;->getTrailingIconColor()Landroidx/compose/material3/tokens/ColorSchemeKeyTokens;
+PLandroidx/compose/runtime/AbstractApplier;->clear()V
+PLandroidx/compose/runtime/BroadcastFrameClock;->minusKey(Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
+PLandroidx/compose/runtime/ComposableSingletons$CompositionKt;->getLambda-2$runtime_release()Lkotlin/jvm/functions/Function2;
+PLandroidx/compose/runtime/ComposerImpl$CompositionContextHolder;->onForgotten()V
+PLandroidx/compose/runtime/ComposerImpl$CompositionContextImpl;->dispose()V
+PLandroidx/compose/runtime/ComposerImpl$CompositionContextImpl;->getComposers()Ljava/util/Set;
+PLandroidx/compose/runtime/ComposerImpl$CompositionContextImpl;->unregisterComposer$runtime_release(Landroidx/compose/runtime/Composer;)V
+PLandroidx/compose/runtime/ComposerImpl$CompositionContextImpl;->unregisterComposition$runtime_release(Landroidx/compose/runtime/ControlledComposition;)V
+PLandroidx/compose/runtime/ComposerImpl$deactivateToEndGroup$2$1;-><init>(Ljava/lang/Object;II)V
+PLandroidx/compose/runtime/ComposerImpl$deactivateToEndGroup$2$1;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+PLandroidx/compose/runtime/ComposerImpl$deactivateToEndGroup$2$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/ComposerImpl$deactivateToEndGroup$2$2;-><init>(Ljava/lang/Object;II)V
+PLandroidx/compose/runtime/ComposerImpl$deactivateToEndGroup$2$2;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+PLandroidx/compose/runtime/ComposerImpl$deactivateToEndGroup$2$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/ComposerImpl$deactivateToEndGroup$2;-><init>(Landroidx/compose/runtime/ComposerImpl;I)V
+PLandroidx/compose/runtime/ComposerImpl$deactivateToEndGroup$2;->invoke(ILjava/lang/Object;)V
+PLandroidx/compose/runtime/ComposerImpl$deactivateToEndGroup$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/ComposerImpl$doCompose$2$3;->invoke(Landroidx/compose/runtime/State;)V
+PLandroidx/compose/runtime/ComposerImpl$doCompose$2$3;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/ComposerImpl$doCompose$2$4;->invoke(Landroidx/compose/runtime/State;)V
+PLandroidx/compose/runtime/ComposerImpl$doCompose$2$4;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/ComposerImpl$realizeMovement$1;-><init>(II)V
+PLandroidx/compose/runtime/ComposerImpl$realizeMovement$1;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+PLandroidx/compose/runtime/ComposerImpl$realizeMovement$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/ComposerImpl$start$2;-><init>(I)V
+PLandroidx/compose/runtime/ComposerImpl$start$2;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+PLandroidx/compose/runtime/ComposerImpl$start$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/ComposerImpl;->access$getChanges$p(Landroidx/compose/runtime/ComposerImpl;)Ljava/util/List;
+PLandroidx/compose/runtime/ComposerImpl;->access$getReader$p(Landroidx/compose/runtime/ComposerImpl;)Landroidx/compose/runtime/SlotReader;
+PLandroidx/compose/runtime/ComposerImpl;->access$setChanges$p(Landroidx/compose/runtime/ComposerImpl;Ljava/util/List;)V
+PLandroidx/compose/runtime/ComposerImpl;->changed(F)Z
+PLandroidx/compose/runtime/ComposerImpl;->changed(I)Z
+PLandroidx/compose/runtime/ComposerImpl;->deactivateToEndGroup(Z)V
+PLandroidx/compose/runtime/ComposerImpl;->dispose$runtime_release()V
+PLandroidx/compose/runtime/ComposerImpl;->getDeferredChanges$runtime_release()Ljava/util/List;
+PLandroidx/compose/runtime/ComposerImpl;->nodeAt(Landroidx/compose/runtime/SlotReader;I)Ljava/lang/Object;
+PLandroidx/compose/runtime/ComposerImpl;->recordDelete()V
+PLandroidx/compose/runtime/ComposerImpl;->recordRemoveNode(II)V
+PLandroidx/compose/runtime/ComposerImpl;->reportAllMovableContent()V
+PLandroidx/compose/runtime/ComposerImpl;->reportFreeMovableContent$reportGroup(Landroidx/compose/runtime/ComposerImpl;IZI)I
+PLandroidx/compose/runtime/ComposerImpl;->reportFreeMovableContent(I)V
+PLandroidx/compose/runtime/ComposerKt$removeCurrentGroupInstance$1;->invoke(Landroidx/compose/runtime/Applier;Landroidx/compose/runtime/SlotWriter;Landroidx/compose/runtime/RememberManager;)V
+PLandroidx/compose/runtime/ComposerKt$removeCurrentGroupInstance$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/ComposerKt;->access$getRemoveCurrentGroupInstance$p()Lkotlin/jvm/functions/Function3;
+PLandroidx/compose/runtime/ComposerKt;->access$removeRange(Ljava/util/List;II)V
+PLandroidx/compose/runtime/ComposerKt;->distanceFrom(Landroidx/compose/runtime/SlotReader;II)I
+PLandroidx/compose/runtime/ComposerKt;->removeRange(Ljava/util/List;II)V
+PLandroidx/compose/runtime/CompositionContext;->unregisterComposer$runtime_release(Landroidx/compose/runtime/Composer;)V
+PLandroidx/compose/runtime/CompositionImpl;->dispose()V
+PLandroidx/compose/runtime/CompositionImpl;->observesAnyOf(Ljava/util/Set;)Z
+PLandroidx/compose/runtime/CompositionImpl;->setPendingInvalidScopes$runtime_release(Z)V
+PLandroidx/compose/runtime/CompositionScopedCoroutineScopeCanceller;->onForgotten()V
+PLandroidx/compose/runtime/DerivedSnapshotState$ResultRecord$Companion;-><init>()V
+PLandroidx/compose/runtime/DerivedSnapshotState$ResultRecord$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/runtime/DerivedSnapshotState$ResultRecord$Companion;->getUnset()Ljava/lang/Object;
+PLandroidx/compose/runtime/DerivedSnapshotState$ResultRecord;-><clinit>()V
+PLandroidx/compose/runtime/DerivedSnapshotState$ResultRecord;-><init>()V
+PLandroidx/compose/runtime/DerivedSnapshotState$ResultRecord;->access$getUnset$cp()Ljava/lang/Object;
+PLandroidx/compose/runtime/DerivedSnapshotState$ResultRecord;->assign(Landroidx/compose/runtime/snapshots/StateRecord;)V
+PLandroidx/compose/runtime/DerivedSnapshotState$ResultRecord;->create()Landroidx/compose/runtime/snapshots/StateRecord;
+PLandroidx/compose/runtime/DerivedSnapshotState$ResultRecord;->getDependencies()Landroidx/compose/runtime/collection/IdentityArrayMap;
+PLandroidx/compose/runtime/DerivedSnapshotState$ResultRecord;->getResult()Ljava/lang/Object;
+PLandroidx/compose/runtime/DerivedSnapshotState$ResultRecord;->setDependencies(Landroidx/compose/runtime/collection/IdentityArrayMap;)V
+PLandroidx/compose/runtime/DerivedSnapshotState$ResultRecord;->setResult(Ljava/lang/Object;)V
+PLandroidx/compose/runtime/DerivedSnapshotState$ResultRecord;->setResultHash(I)V
+PLandroidx/compose/runtime/DerivedSnapshotState$currentRecord$result$1$result$1;-><init>(Landroidx/compose/runtime/DerivedSnapshotState;Landroidx/compose/runtime/collection/IdentityArrayMap;I)V
+PLandroidx/compose/runtime/DerivedSnapshotState$currentRecord$result$1$result$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/DerivedSnapshotState$currentRecord$result$1$result$1;->invoke(Ljava/lang/Object;)V
+PLandroidx/compose/runtime/DerivedSnapshotState;-><init>(Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/SnapshotMutationPolicy;)V
+PLandroidx/compose/runtime/DerivedSnapshotState;->getCurrentValue()Ljava/lang/Object;
+PLandroidx/compose/runtime/DerivedSnapshotState;->getDependencies()[Ljava/lang/Object;
+PLandroidx/compose/runtime/DerivedSnapshotState;->getFirstStateRecord()Landroidx/compose/runtime/snapshots/StateRecord;
+PLandroidx/compose/runtime/DerivedSnapshotState;->getPolicy()Landroidx/compose/runtime/SnapshotMutationPolicy;
+PLandroidx/compose/runtime/DerivedSnapshotState;->prependStateRecord(Landroidx/compose/runtime/snapshots/StateRecord;)V
+PLandroidx/compose/runtime/GroupInfo;->setNodeCount(I)V
+PLandroidx/compose/runtime/GroupInfo;->setNodeIndex(I)V
+PLandroidx/compose/runtime/GroupInfo;->setSlotIndex(I)V
+PLandroidx/compose/runtime/Pending;->updateNodeCount(II)Z
+PLandroidx/compose/runtime/PrioritySet;->peek()I
+PLandroidx/compose/runtime/RecomposeScopeImpl;->access$setTrackedInstances$p(Landroidx/compose/runtime/RecomposeScopeImpl;Landroidx/compose/runtime/collection/IdentityArrayIntMap;)V
+PLandroidx/compose/runtime/RecomposeScopeImpl;->getComposition()Landroidx/compose/runtime/CompositionImpl;
+PLandroidx/compose/runtime/RecomposeScopeImpl;->release()V
+PLandroidx/compose/runtime/RecomposeScopeImpl;->rereadTrackedInstances()V
+PLandroidx/compose/runtime/RecomposeScopeImpl;->setRereading(Z)V
+PLandroidx/compose/runtime/Recomposer$Companion;->access$removeRunning(Landroidx/compose/runtime/Recomposer$Companion;Landroidx/compose/runtime/Recomposer$RecomposerInfoImpl;)V
+PLandroidx/compose/runtime/Recomposer$Companion;->removeRunning(Landroidx/compose/runtime/Recomposer$RecomposerInfoImpl;)V
+PLandroidx/compose/runtime/Recomposer$effectJob$1$1$1$1;-><init>(Landroidx/compose/runtime/Recomposer;Ljava/lang/Throwable;)V
+PLandroidx/compose/runtime/Recomposer$effectJob$1$1$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/Recomposer$effectJob$1$1$1$1;->invoke(Ljava/lang/Throwable;)V
+PLandroidx/compose/runtime/Recomposer$effectJob$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/Recomposer$effectJob$1$1;->invoke(Ljava/lang/Throwable;)V
+PLandroidx/compose/runtime/Recomposer;->access$getRunnerJob$p(Landroidx/compose/runtime/Recomposer;)Lkotlinx/coroutines/Job;
+PLandroidx/compose/runtime/Recomposer;->access$isClosed$p(Landroidx/compose/runtime/Recomposer;)Z
+PLandroidx/compose/runtime/Recomposer;->access$setCloseCause$p(Landroidx/compose/runtime/Recomposer;Ljava/lang/Throwable;)V
+PLandroidx/compose/runtime/Recomposer;->access$setRunnerJob$p(Landroidx/compose/runtime/Recomposer;Lkotlinx/coroutines/Job;)V
+PLandroidx/compose/runtime/Recomposer;->cancel()V
+PLandroidx/compose/runtime/Recomposer;->unregisterComposition$runtime_release(Landroidx/compose/runtime/ControlledComposition;)V
+PLandroidx/compose/runtime/SlotReader;->containsMark(I)Z
+PLandroidx/compose/runtime/SlotReader;->forEachData$runtime_release(ILkotlin/jvm/functions/Function2;)V
+PLandroidx/compose/runtime/SlotReader;->getCurrentEnd()I
+PLandroidx/compose/runtime/SlotReader;->getGroupSize()I
+PLandroidx/compose/runtime/SlotReader;->hasMark(I)Z
+PLandroidx/compose/runtime/SlotTable;->containsMark()Z
+PLandroidx/compose/runtime/SlotWriter$groupSlots$1;-><init>(IILandroidx/compose/runtime/SlotWriter;)V
+PLandroidx/compose/runtime/SlotWriter;->access$updateContainsMark(Landroidx/compose/runtime/SlotWriter;I)V
+PLandroidx/compose/runtime/SlotWriter;->fixParentAnchorsFor(III)V
+PLandroidx/compose/runtime/SlotWriter;->groupSlots()Ljava/util/Iterator;
+PLandroidx/compose/runtime/SlotWriter;->moveAnchors(III)V
+PLandroidx/compose/runtime/SlotWriter;->moveGroup(I)V
+PLandroidx/compose/runtime/SlotWriter;->slot(II)Ljava/lang/Object;
+PLandroidx/compose/runtime/SlotWriter;->updateDataIndex([III)V
+PLandroidx/compose/runtime/SnapshotStateKt;->derivedStateOf(Lkotlin/jvm/functions/Function0;)Landroidx/compose/runtime/State;
+PLandroidx/compose/runtime/SnapshotStateKt__DerivedStateKt;->access$getCalculationBlockNestedLevel$p()Landroidx/compose/runtime/SnapshotThreadLocal;
+PLandroidx/compose/runtime/SnapshotStateKt__DerivedStateKt;->access$getDerivedStateObservers$p()Landroidx/compose/runtime/SnapshotThreadLocal;
+PLandroidx/compose/runtime/SnapshotStateKt__DerivedStateKt;->derivedStateOf(Lkotlin/jvm/functions/Function0;)Landroidx/compose/runtime/State;
+PLandroidx/compose/runtime/SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1$readObserver$1;-><init>(Ljava/util/Set;)V
+PLandroidx/compose/runtime/SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1$readObserver$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1$readObserver$1;->invoke(Ljava/lang/Object;)V
+PLandroidx/compose/runtime/SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1$unregisterApplyObserver$1;-><init>(Lkotlinx/coroutines/channels/Channel;)V
+PLandroidx/compose/runtime/SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/runtime/SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/SnapshotStateKt__SnapshotFlowKt$snapshotFlow$1;->invoke(Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/runtime/SnapshotStateKt__SnapshotFlowKt;->access$intersects(Ljava/util/Set;Ljava/util/Set;)Z
+PLandroidx/compose/runtime/Stack;->peek(I)Ljava/lang/Object;
+PLandroidx/compose/runtime/collection/IdentityArrayMap;->clear()V
+PLandroidx/compose/runtime/collection/IdentityArrayMap;->setSize$runtime_release(I)V
+PLandroidx/compose/runtime/collection/IdentityArraySet$iterator$1;-><init>(Landroidx/compose/runtime/collection/IdentityArraySet;)V
+PLandroidx/compose/runtime/collection/IdentityArraySet$iterator$1;->hasNext()Z
+PLandroidx/compose/runtime/collection/IdentityArraySet$iterator$1;->next()Ljava/lang/Object;
+PLandroidx/compose/runtime/collection/IdentityArraySet;->isEmpty()Z
+PLandroidx/compose/runtime/collection/IdentityArraySet;->iterator()Ljava/util/Iterator;
+PLandroidx/compose/runtime/collection/IdentityScopeMap;->clear()V
+PLandroidx/compose/runtime/collection/IdentityScopeMap;->removeScope(Ljava/lang/Object;)V
+PLandroidx/compose/runtime/collection/MutableVector$MutableVectorList;->iterator()Ljava/util/Iterator;
+PLandroidx/compose/runtime/collection/MutableVector$VectorListIterator;-><init>(Ljava/util/List;I)V
+PLandroidx/compose/runtime/collection/MutableVector$VectorListIterator;->hasNext()Z
+PLandroidx/compose/runtime/collection/MutableVector$VectorListIterator;->next()Ljava/lang/Object;
+PLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/AbstractPersistentList;->remove(Ljava/lang/Object;)Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentList;
+PLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/SmallPersistentVector;->add(Ljava/lang/Object;)Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentList;
+PLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/SmallPersistentVector;->get(I)Ljava/lang/Object;
+PLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/SmallPersistentVector;->indexOf(Ljava/lang/Object;)I
+PLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableList/SmallPersistentVector;->removeAt(I)Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentList;
+PLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;->remove(Ljava/lang/Object;)Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMap;
+PLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->remove(ILjava/lang/Object;I)Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;
+PLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;->removeEntryAtIndex(II)Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode;
+PLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeBaseIterator;->moveToNextNode()V
+PLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/Links;->getHasNext()Z
+PLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/Links;->getHasPrevious()Z
+PLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/Links;->getNext()Ljava/lang/Object;
+PLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/Links;->getPrevious()Ljava/lang/Object;
+PLandroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/persistentOrderedSet/PersistentOrderedSet;->remove(Ljava/lang/Object;)Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentSet;
+PLandroidx/compose/runtime/external/kotlinx/collections/immutable/internal/ListImplementation;-><clinit>()V
+PLandroidx/compose/runtime/external/kotlinx/collections/immutable/internal/ListImplementation;-><init>()V
+PLandroidx/compose/runtime/external/kotlinx/collections/immutable/internal/ListImplementation;->checkElementIndex$runtime_release(II)V
+PLandroidx/compose/runtime/internal/ComposableLambdaImpl$invoke$2;-><init>(Landroidx/compose/runtime/internal/ComposableLambdaImpl;Ljava/lang/Object;Ljava/lang/Object;I)V
+PLandroidx/compose/runtime/internal/ComposableLambdaImpl;->invoke(Ljava/lang/Object;Ljava/lang/Object;Landroidx/compose/runtime/Composer;I)Ljava/lang/Object;
+PLandroidx/compose/runtime/internal/ComposableLambdaImpl;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/saveable/ListSaverKt$listSaver$1;-><init>(Lkotlin/jvm/functions/Function2;)V
+PLandroidx/compose/runtime/saveable/ListSaverKt$listSaver$1;->invoke(Landroidx/compose/runtime/saveable/SaverScope;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/saveable/ListSaverKt$listSaver$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/saveable/ListSaverKt;->listSaver(Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)Landroidx/compose/runtime/saveable/Saver;
+PLandroidx/compose/runtime/saveable/RememberSaveableKt$rememberSaveable$1$invoke$$inlined$onDispose$1;->dispose()V
+PLandroidx/compose/runtime/saveable/RememberSaveableKt$rememberSaveable$1$valueProvider$1$1$1;->canBeSaved(Ljava/lang/Object;)Z
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl$Companion$Saver$1;-><clinit>()V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl$Companion$Saver$1;-><init>()V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl$Companion$Saver$1;->invoke(Landroidx/compose/runtime/saveable/SaverScope;Landroidx/compose/runtime/saveable/SaveableStateHolderImpl;)Ljava/util/Map;
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl$Companion$Saver$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl$Companion$Saver$2;-><clinit>()V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl$Companion$Saver$2;-><init>()V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl$Companion;-><init>()V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl$Companion;->getSaver()Landroidx/compose/runtime/saveable/Saver;
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl$RegistryHolder$registry$1;-><init>(Landroidx/compose/runtime/saveable/SaveableStateHolderImpl;)V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl$RegistryHolder;-><init>(Landroidx/compose/runtime/saveable/SaveableStateHolderImpl;Ljava/lang/Object;)V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl$RegistryHolder;->getRegistry()Landroidx/compose/runtime/saveable/SaveableStateRegistry;
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl$RegistryHolder;->saveTo(Ljava/util/Map;)V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl$SaveableStateProvider$1$1$invoke$$inlined$onDispose$1;-><init>(Landroidx/compose/runtime/saveable/SaveableStateHolderImpl$RegistryHolder;Landroidx/compose/runtime/saveable/SaveableStateHolderImpl;Ljava/lang/Object;)V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl$SaveableStateProvider$1$1$invoke$$inlined$onDispose$1;->dispose()V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl$SaveableStateProvider$1$1;-><init>(Landroidx/compose/runtime/saveable/SaveableStateHolderImpl;Ljava/lang/Object;Landroidx/compose/runtime/saveable/SaveableStateHolderImpl$RegistryHolder;)V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl$SaveableStateProvider$1$1;->invoke(Landroidx/compose/runtime/DisposableEffectScope;)Landroidx/compose/runtime/DisposableEffectResult;
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl$SaveableStateProvider$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl;-><clinit>()V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl;-><init>(Ljava/util/Map;)V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl;-><init>(Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl;->SaveableStateProvider(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl;->access$getRegistryHolders$p(Landroidx/compose/runtime/saveable/SaveableStateHolderImpl;)Ljava/util/Map;
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl;->access$getSavedStates$p(Landroidx/compose/runtime/saveable/SaveableStateHolderImpl;)Ljava/util/Map;
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl;->access$getSaver$cp()Landroidx/compose/runtime/saveable/Saver;
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl;->access$saveAll(Landroidx/compose/runtime/saveable/SaveableStateHolderImpl;)Ljava/util/Map;
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl;->getParentSaveableStateRegistry()Landroidx/compose/runtime/saveable/SaveableStateRegistry;
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl;->removeState(Ljava/lang/Object;)V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl;->saveAll()Ljava/util/Map;
+PLandroidx/compose/runtime/saveable/SaveableStateHolderImpl;->setParentSaveableStateRegistry(Landroidx/compose/runtime/saveable/SaveableStateRegistry;)V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderKt$rememberSaveableStateHolder$1;-><clinit>()V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderKt$rememberSaveableStateHolder$1;-><init>()V
+PLandroidx/compose/runtime/saveable/SaveableStateHolderKt$rememberSaveableStateHolder$1;->invoke()Landroidx/compose/runtime/saveable/SaveableStateHolderImpl;
+PLandroidx/compose/runtime/saveable/SaveableStateHolderKt$rememberSaveableStateHolder$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/runtime/saveable/SaveableStateHolderKt;->rememberSaveableStateHolder(Landroidx/compose/runtime/Composer;I)Landroidx/compose/runtime/saveable/SaveableStateHolder;
+PLandroidx/compose/runtime/saveable/SaveableStateRegistryImpl$registerProvider$3;->unregister()V
+PLandroidx/compose/runtime/saveable/SaveableStateRegistryImpl;->access$getValueProviders$p(Landroidx/compose/runtime/saveable/SaveableStateRegistryImpl;)Ljava/util/Map;
+PLandroidx/compose/runtime/saveable/SaveableStateRegistryImpl;->performSave()Ljava/util/Map;
+PLandroidx/compose/runtime/snapshots/GlobalSnapshot$takeNestedSnapshot$1;-><init>(Lkotlin/jvm/functions/Function1;)V
+PLandroidx/compose/runtime/snapshots/GlobalSnapshot$takeNestedSnapshot$1;->invoke(Landroidx/compose/runtime/snapshots/SnapshotIdSet;)Landroidx/compose/runtime/snapshots/ReadonlySnapshot;
+PLandroidx/compose/runtime/snapshots/GlobalSnapshot$takeNestedSnapshot$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/snapshots/GlobalSnapshot;->takeNestedSnapshot(Lkotlin/jvm/functions/Function1;)Landroidx/compose/runtime/snapshots/Snapshot;
+PLandroidx/compose/runtime/snapshots/MutableSnapshot;->advance$runtime_release()V
+PLandroidx/compose/runtime/snapshots/MutableSnapshot;->getApplied$runtime_release()Z
+PLandroidx/compose/runtime/snapshots/MutableSnapshot;->getPreviousPinnedSnapshots$runtime_release()[I
+PLandroidx/compose/runtime/snapshots/MutableSnapshot;->nestedActivated$runtime_release(Landroidx/compose/runtime/snapshots/Snapshot;)V
+PLandroidx/compose/runtime/snapshots/MutableSnapshot;->notifyObjectsInitialized$runtime_release()V
+PLandroidx/compose/runtime/snapshots/MutableSnapshot;->recordPrevious$runtime_release(I)V
+PLandroidx/compose/runtime/snapshots/MutableSnapshot;->recordPreviousList$runtime_release(Landroidx/compose/runtime/snapshots/SnapshotIdSet;)V
+PLandroidx/compose/runtime/snapshots/MutableSnapshot;->recordPreviousPinnedSnapshot$runtime_release(I)V
+PLandroidx/compose/runtime/snapshots/MutableSnapshot;->recordPreviousPinnedSnapshots$runtime_release([I)V
+PLandroidx/compose/runtime/snapshots/MutableSnapshot;->setApplied$runtime_release(Z)V
+PLandroidx/compose/runtime/snapshots/MutableSnapshot;->takeNestedMutableSnapshot(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Landroidx/compose/runtime/snapshots/MutableSnapshot;
+PLandroidx/compose/runtime/snapshots/MutableSnapshot;->validateNotAppliedOrPinned$runtime_release()V
+PLandroidx/compose/runtime/snapshots/NestedMutableSnapshot;-><init>(ILandroidx/compose/runtime/snapshots/SnapshotIdSet;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/snapshots/MutableSnapshot;)V
+PLandroidx/compose/runtime/snapshots/NestedMutableSnapshot;->apply()Landroidx/compose/runtime/snapshots/SnapshotApplyResult;
+PLandroidx/compose/runtime/snapshots/NestedMutableSnapshot;->deactivate()V
+PLandroidx/compose/runtime/snapshots/NestedMutableSnapshot;->dispose()V
+PLandroidx/compose/runtime/snapshots/ReadonlySnapshot;-><init>(ILandroidx/compose/runtime/snapshots/SnapshotIdSet;Lkotlin/jvm/functions/Function1;)V
+PLandroidx/compose/runtime/snapshots/ReadonlySnapshot;->dispose()V
+PLandroidx/compose/runtime/snapshots/ReadonlySnapshot;->getReadObserver$runtime_release()Lkotlin/jvm/functions/Function1;
+PLandroidx/compose/runtime/snapshots/ReadonlySnapshot;->nestedDeactivated$runtime_release(Landroidx/compose/runtime/snapshots/Snapshot;)V
+PLandroidx/compose/runtime/snapshots/Snapshot$Companion$registerApplyObserver$2;->dispose()V
+PLandroidx/compose/runtime/snapshots/Snapshot$Companion;->takeSnapshot(Lkotlin/jvm/functions/Function1;)Landroidx/compose/runtime/snapshots/Snapshot;
+PLandroidx/compose/runtime/snapshots/Snapshot;->closeAndReleasePinning$runtime_release()V
+PLandroidx/compose/runtime/snapshots/Snapshot;->closeLocked$runtime_release()V
+PLandroidx/compose/runtime/snapshots/Snapshot;->setId$runtime_release(I)V
+PLandroidx/compose/runtime/snapshots/Snapshot;->setInvalid$runtime_release(Landroidx/compose/runtime/snapshots/SnapshotIdSet;)V
+PLandroidx/compose/runtime/snapshots/Snapshot;->takeoverPinnedSnapshot$runtime_release()I
+PLandroidx/compose/runtime/snapshots/Snapshot;->validateNotDisposed$runtime_release()V
+PLandroidx/compose/runtime/snapshots/SnapshotIdSet$iterator$1;-><init>(Landroidx/compose/runtime/snapshots/SnapshotIdSet;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/runtime/snapshots/SnapshotIdSet$iterator$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/runtime/snapshots/SnapshotIdSet$iterator$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/snapshots/SnapshotIdSet;->access$getBelowBound$p(Landroidx/compose/runtime/snapshots/SnapshotIdSet;)[I
+PLandroidx/compose/runtime/snapshots/SnapshotIdSet;->access$getLowerBound$p(Landroidx/compose/runtime/snapshots/SnapshotIdSet;)I
+PLandroidx/compose/runtime/snapshots/SnapshotIdSet;->access$getLowerSet$p(Landroidx/compose/runtime/snapshots/SnapshotIdSet;)J
+PLandroidx/compose/runtime/snapshots/SnapshotIdSet;->access$getUpperSet$p(Landroidx/compose/runtime/snapshots/SnapshotIdSet;)J
+PLandroidx/compose/runtime/snapshots/SnapshotIdSet;->iterator()Ljava/util/Iterator;
+PLandroidx/compose/runtime/snapshots/SnapshotIdSetKt;->binarySearch([II)I
+PLandroidx/compose/runtime/snapshots/SnapshotKt$mergedReadObserver$1;-><init>(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)V
+PLandroidx/compose/runtime/snapshots/SnapshotKt$mergedReadObserver$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/snapshots/SnapshotKt$mergedReadObserver$1;->invoke(Ljava/lang/Object;)V
+PLandroidx/compose/runtime/snapshots/SnapshotKt;->addRange(Landroidx/compose/runtime/snapshots/SnapshotIdSet;II)Landroidx/compose/runtime/snapshots/SnapshotIdSet;
+PLandroidx/compose/runtime/snapshots/SnapshotKt;->newWritableRecord(Landroidx/compose/runtime/snapshots/StateRecord;Landroidx/compose/runtime/snapshots/StateObject;Landroidx/compose/runtime/snapshots/Snapshot;)Landroidx/compose/runtime/snapshots/StateRecord;
+PLandroidx/compose/runtime/snapshots/SnapshotKt;->writableRecord(Landroidx/compose/runtime/snapshots/StateRecord;Landroidx/compose/runtime/snapshots/StateObject;Landroidx/compose/runtime/snapshots/Snapshot;)Landroidx/compose/runtime/snapshots/StateRecord;
+PLandroidx/compose/runtime/snapshots/SnapshotStateList$StateListStateRecord;->assign(Landroidx/compose/runtime/snapshots/StateRecord;)V
+PLandroidx/compose/runtime/snapshots/SnapshotStateList$StateListStateRecord;->create()Landroidx/compose/runtime/snapshots/StateRecord;
+PLandroidx/compose/runtime/snapshots/SnapshotStateList$StateListStateRecord;->getModification$runtime_release()I
+PLandroidx/compose/runtime/snapshots/SnapshotStateList$StateListStateRecord;->setList$runtime_release(Landroidx/compose/runtime/external/kotlinx/collections/immutable/PersistentList;)V
+PLandroidx/compose/runtime/snapshots/SnapshotStateList$StateListStateRecord;->setModification$runtime_release(I)V
+PLandroidx/compose/runtime/snapshots/SnapshotStateList;->add(Ljava/lang/Object;)Z
+PLandroidx/compose/runtime/snapshots/SnapshotStateList;->get(I)Ljava/lang/Object;
+PLandroidx/compose/runtime/snapshots/SnapshotStateList;->getSize()I
+PLandroidx/compose/runtime/snapshots/SnapshotStateList;->prependStateRecord(Landroidx/compose/runtime/snapshots/StateRecord;)V
+PLandroidx/compose/runtime/snapshots/SnapshotStateList;->remove(Ljava/lang/Object;)Z
+PLandroidx/compose/runtime/snapshots/SnapshotStateList;->size()I
+PLandroidx/compose/runtime/snapshots/SnapshotStateListKt;-><clinit>()V
+PLandroidx/compose/runtime/snapshots/SnapshotStateListKt;->access$getSync$p()Ljava/lang/Object;
+PLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap$derivedStateEnterObserver$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->access$setDeriveStateScopeCount$p(Landroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;I)V
+PLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->clear()V
+PLandroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;->removeScopeIf(Lkotlin/jvm/functions/Function1;)V
+PLandroidx/compose/runtime/snapshots/SnapshotStateObserver;->clear()V
+PLandroidx/compose/runtime/snapshots/SnapshotStateObserver;->clearIf(Lkotlin/jvm/functions/Function1;)V
+PLandroidx/compose/runtime/snapshots/SnapshotStateObserver;->stop()V
+PLandroidx/compose/ui/Modifier$Node;->onDetach()V
+PLandroidx/compose/ui/autofill/AutofillCallback;->unregister(Landroidx/compose/ui/autofill/AndroidAutofill;)V
+PLandroidx/compose/ui/draw/ClipKt;->clipToBounds(Landroidx/compose/ui/Modifier;)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/ui/draw/PainterModifier;->calculateScaledSize-E7KxVPU(J)J
+PLandroidx/compose/ui/focus/FocusModifier$WhenMappings;-><clinit>()V
+PLandroidx/compose/ui/focus/FocusModifier;->isValid()Z
+PLandroidx/compose/ui/focus/FocusRequesterModifierLocal;->removeFocusModifier(Landroidx/compose/ui/focus/FocusModifier;)V
+PLandroidx/compose/ui/geometry/Offset;->copy-dBAh8RU$default(JFFILjava/lang/Object;)J
+PLandroidx/compose/ui/geometry/Offset;->copy-dBAh8RU(JFF)J
+PLandroidx/compose/ui/geometry/Offset;->equals-impl0(JJ)Z
+PLandroidx/compose/ui/geometry/Offset;->getDistanceSquared-impl(J)F
+PLandroidx/compose/ui/geometry/Offset;->minus-MK-Hz9U(JJ)J
+PLandroidx/compose/ui/geometry/Offset;->plus-MK-Hz9U(JJ)J
+PLandroidx/compose/ui/geometry/Offset;->times-tuRUvjQ(JF)J
+PLandroidx/compose/ui/geometry/Rect;->getHeight()F
+PLandroidx/compose/ui/geometry/Rect;->getWidth()F
+PLandroidx/compose/ui/geometry/Size;->equals(Ljava/lang/Object;)Z
+PLandroidx/compose/ui/geometry/Size;->isEmpty-impl(J)Z
+PLandroidx/compose/ui/geometry/SizeKt;->getCenter-uvyYCjk(J)J
+PLandroidx/compose/ui/graphics/AndroidCanvas;->concat-58bKbWc([F)V
+PLandroidx/compose/ui/graphics/AndroidCanvas_androidKt;->ActualCanvas(Landroidx/compose/ui/graphics/ImageBitmap;)Landroidx/compose/ui/graphics/Canvas;
+PLandroidx/compose/ui/graphics/AndroidImageBitmap;->prepareToDraw()V
+PLandroidx/compose/ui/graphics/AndroidImageBitmap_androidKt;->ActualImageBitmap-x__-hDU(IIIZLandroidx/compose/ui/graphics/colorspace/ColorSpace;)Landroidx/compose/ui/graphics/ImageBitmap;
+PLandroidx/compose/ui/graphics/AndroidImageBitmap_androidKt;->toBitmapConfig-1JJdX4A(I)Landroid/graphics/Bitmap$Config;
+PLandroidx/compose/ui/graphics/AndroidMatrixConversions_androidKt;->setFrom-EL8BTi8(Landroid/graphics/Matrix;[F)V
+PLandroidx/compose/ui/graphics/AndroidMatrixConversions_androidKt;->setFrom-tU-YjHk([FLandroid/graphics/Matrix;)V
+PLandroidx/compose/ui/graphics/AndroidPaint;->setBlendMode-s9anfk8(I)V
+PLandroidx/compose/ui/graphics/AndroidPaint_androidKt;->setNativeBlendMode-GB0RdKg(Landroid/graphics/Paint;I)V
+PLandroidx/compose/ui/graphics/AndroidPath;->addPath-Uv8p0NA(Landroidx/compose/ui/graphics/Path;J)V
+PLandroidx/compose/ui/graphics/AndroidPath;->close()V
+PLandroidx/compose/ui/graphics/AndroidPath;->lineTo(FF)V
+PLandroidx/compose/ui/graphics/AndroidPath;->moveTo(FF)V
+PLandroidx/compose/ui/graphics/AndroidPath;->relativeLineTo(FF)V
+PLandroidx/compose/ui/graphics/AndroidPath;->setFillType-oQ8Xj4U(I)V
+PLandroidx/compose/ui/graphics/Api26Bitmap;-><clinit>()V
+PLandroidx/compose/ui/graphics/Api26Bitmap;-><init>()V
+PLandroidx/compose/ui/graphics/Api26Bitmap;->createBitmap-x__-hDU$ui_graphics_release(IIIZLandroidx/compose/ui/graphics/colorspace/ColorSpace;)Landroid/graphics/Bitmap;
+PLandroidx/compose/ui/graphics/Api26Bitmap;->toFrameworkColorSpace$ui_graphics_release(Landroidx/compose/ui/graphics/colorspace/ColorSpace;)Landroid/graphics/ColorSpace;
+PLandroidx/compose/ui/graphics/BlendMode;-><init>(I)V
+PLandroidx/compose/ui/graphics/BlendMode;->box-impl(I)Landroidx/compose/ui/graphics/BlendMode;
+PLandroidx/compose/ui/graphics/Brush$Companion;-><init>()V
+PLandroidx/compose/ui/graphics/Brush$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/Brush;-><clinit>()V
+PLandroidx/compose/ui/graphics/Brush;-><init>()V
+PLandroidx/compose/ui/graphics/Brush;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/CanvasKt;->Canvas(Landroidx/compose/ui/graphics/ImageBitmap;)Landroidx/compose/ui/graphics/Canvas;
+PLandroidx/compose/ui/graphics/ColorKt;->access$getComponents-8_81llA(J)[F
+PLandroidx/compose/ui/graphics/ColorKt;->getComponents-8_81llA(J)[F
+PLandroidx/compose/ui/graphics/ColorKt;->lerp-jxsXWHM(JJF)J
+PLandroidx/compose/ui/graphics/Float16;->toFloat-impl(S)F
+PLandroidx/compose/ui/graphics/ImageBitmapConfig$Companion;-><init>()V
+PLandroidx/compose/ui/graphics/ImageBitmapConfig$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/ImageBitmapConfig$Companion;->getArgb8888-_sVssgQ()I
+PLandroidx/compose/ui/graphics/ImageBitmapConfig;-><clinit>()V
+PLandroidx/compose/ui/graphics/ImageBitmapConfig;->access$getArgb8888$cp()I
+PLandroidx/compose/ui/graphics/ImageBitmapConfig;->constructor-impl(I)I
+PLandroidx/compose/ui/graphics/ImageBitmapConfig;->equals-impl0(II)Z
+PLandroidx/compose/ui/graphics/ImageBitmapKt;->ImageBitmap-x__-hDU$default(IIIZLandroidx/compose/ui/graphics/colorspace/ColorSpace;ILjava/lang/Object;)Landroidx/compose/ui/graphics/ImageBitmap;
+PLandroidx/compose/ui/graphics/ImageBitmapKt;->ImageBitmap-x__-hDU(IIIZLandroidx/compose/ui/graphics/colorspace/ColorSpace;)Landroidx/compose/ui/graphics/ImageBitmap;
+PLandroidx/compose/ui/graphics/Matrix;-><init>([F)V
+PLandroidx/compose/ui/graphics/Matrix;->box-impl([F)Landroidx/compose/ui/graphics/Matrix;
+PLandroidx/compose/ui/graphics/Matrix;->rotateZ-impl([FF)V
+PLandroidx/compose/ui/graphics/Matrix;->scale-impl([FFFF)V
+PLandroidx/compose/ui/graphics/Matrix;->translate-impl$default([FFFFILjava/lang/Object;)V
+PLandroidx/compose/ui/graphics/Matrix;->translate-impl([FFFF)V
+PLandroidx/compose/ui/graphics/Matrix;->unbox-impl()[F
+PLandroidx/compose/ui/graphics/MatrixKt;->isIdentity-58bKbWc([F)Z
+PLandroidx/compose/ui/graphics/Outline$Rectangle;-><init>(Landroidx/compose/ui/geometry/Rect;)V
+PLandroidx/compose/ui/graphics/Outline$Rectangle;->getRect()Landroidx/compose/ui/geometry/Rect;
+PLandroidx/compose/ui/graphics/OutlineKt;->size(Landroidx/compose/ui/geometry/Rect;)J
+PLandroidx/compose/ui/graphics/OutlineKt;->topLeft(Landroidx/compose/ui/geometry/Rect;)J
+PLandroidx/compose/ui/graphics/Path$Companion;-><clinit>()V
+PLandroidx/compose/ui/graphics/Path$Companion;-><init>()V
+PLandroidx/compose/ui/graphics/Path;-><clinit>()V
+PLandroidx/compose/ui/graphics/Path;->addPath-Uv8p0NA$default(Landroidx/compose/ui/graphics/Path;Landroidx/compose/ui/graphics/Path;JILjava/lang/Object;)V
+PLandroidx/compose/ui/graphics/PathFillType$Companion;-><init>()V
+PLandroidx/compose/ui/graphics/PathFillType$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/PathFillType$Companion;->getEvenOdd-Rg-k1Os()I
+PLandroidx/compose/ui/graphics/PathFillType$Companion;->getNonZero-Rg-k1Os()I
+PLandroidx/compose/ui/graphics/PathFillType;-><clinit>()V
+PLandroidx/compose/ui/graphics/PathFillType;-><init>(I)V
+PLandroidx/compose/ui/graphics/PathFillType;->access$getEvenOdd$cp()I
+PLandroidx/compose/ui/graphics/PathFillType;->access$getNonZero$cp()I
+PLandroidx/compose/ui/graphics/PathFillType;->box-impl(I)Landroidx/compose/ui/graphics/PathFillType;
+PLandroidx/compose/ui/graphics/PathFillType;->constructor-impl(I)I
+PLandroidx/compose/ui/graphics/PathFillType;->equals-impl0(II)Z
+PLandroidx/compose/ui/graphics/PathFillType;->unbox-impl()I
+PLandroidx/compose/ui/graphics/RectHelper_androidKt;->toAndroidRect(Landroidx/compose/ui/geometry/Rect;)Landroid/graphics/Rect;
+PLandroidx/compose/ui/graphics/SolidColor;-><init>(J)V
+PLandroidx/compose/ui/graphics/SolidColor;-><init>(JLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/SolidColor;->applyTo-Pq9zytI(JLandroidx/compose/ui/graphics/Paint;F)V
+PLandroidx/compose/ui/graphics/StrokeCap$Companion;-><init>()V
+PLandroidx/compose/ui/graphics/StrokeCap$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/StrokeCap$Companion;->getButt-KaPHkGw()I
+PLandroidx/compose/ui/graphics/StrokeCap;-><clinit>()V
+PLandroidx/compose/ui/graphics/StrokeCap;-><init>(I)V
+PLandroidx/compose/ui/graphics/StrokeCap;->access$getButt$cp()I
+PLandroidx/compose/ui/graphics/StrokeCap;->box-impl(I)Landroidx/compose/ui/graphics/StrokeCap;
+PLandroidx/compose/ui/graphics/StrokeCap;->constructor-impl(I)I
+PLandroidx/compose/ui/graphics/StrokeCap;->unbox-impl()I
+PLandroidx/compose/ui/graphics/StrokeJoin$Companion;-><init>()V
+PLandroidx/compose/ui/graphics/StrokeJoin$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/StrokeJoin$Companion;->getBevel-LxFBmk8()I
+PLandroidx/compose/ui/graphics/StrokeJoin$Companion;->getMiter-LxFBmk8()I
+PLandroidx/compose/ui/graphics/StrokeJoin;-><clinit>()V
+PLandroidx/compose/ui/graphics/StrokeJoin;-><init>(I)V
+PLandroidx/compose/ui/graphics/StrokeJoin;->access$getBevel$cp()I
+PLandroidx/compose/ui/graphics/StrokeJoin;->access$getMiter$cp()I
+PLandroidx/compose/ui/graphics/StrokeJoin;->box-impl(I)Landroidx/compose/ui/graphics/StrokeJoin;
+PLandroidx/compose/ui/graphics/StrokeJoin;->constructor-impl(I)I
+PLandroidx/compose/ui/graphics/StrokeJoin;->unbox-impl()I
+PLandroidx/compose/ui/graphics/WrapperVerificationHelperMethods;-><clinit>()V
+PLandroidx/compose/ui/graphics/WrapperVerificationHelperMethods;-><init>()V
+PLandroidx/compose/ui/graphics/WrapperVerificationHelperMethods;->setBlendMode-GB0RdKg(Landroid/graphics/Paint;I)V
+PLandroidx/compose/ui/graphics/colorspace/ColorModel;->equals-impl0(JJ)Z
+PLandroidx/compose/ui/graphics/colorspace/ColorSpace;->equals(Ljava/lang/Object;)Z
+PLandroidx/compose/ui/graphics/colorspace/ColorSpace;->getModel-xdoWZVw()J
+PLandroidx/compose/ui/graphics/colorspace/ColorSpace;->getName()Ljava/lang/String;
+PLandroidx/compose/ui/graphics/colorspace/ColorSpace;->isSrgb()Z
+PLandroidx/compose/ui/graphics/colorspace/ColorSpaceKt;->adapt$default(Landroidx/compose/ui/graphics/colorspace/ColorSpace;Landroidx/compose/ui/graphics/colorspace/WhitePoint;Landroidx/compose/ui/graphics/colorspace/Adaptation;ILjava/lang/Object;)Landroidx/compose/ui/graphics/colorspace/ColorSpace;
+PLandroidx/compose/ui/graphics/colorspace/ColorSpaceKt;->adapt(Landroidx/compose/ui/graphics/colorspace/ColorSpace;Landroidx/compose/ui/graphics/colorspace/WhitePoint;Landroidx/compose/ui/graphics/colorspace/Adaptation;)Landroidx/compose/ui/graphics/colorspace/ColorSpace;
+PLandroidx/compose/ui/graphics/colorspace/ColorSpaceKt;->connect-YBCOT_4$default(Landroidx/compose/ui/graphics/colorspace/ColorSpace;Landroidx/compose/ui/graphics/colorspace/ColorSpace;IILjava/lang/Object;)Landroidx/compose/ui/graphics/colorspace/Connector;
+PLandroidx/compose/ui/graphics/colorspace/ColorSpaceKt;->connect-YBCOT_4(Landroidx/compose/ui/graphics/colorspace/ColorSpace;Landroidx/compose/ui/graphics/colorspace/ColorSpace;I)Landroidx/compose/ui/graphics/colorspace/Connector;
+PLandroidx/compose/ui/graphics/colorspace/ColorSpaces;->getCieXyz()Landroidx/compose/ui/graphics/colorspace/ColorSpace;
+PLandroidx/compose/ui/graphics/colorspace/ColorSpaces;->getOklab()Landroidx/compose/ui/graphics/colorspace/ColorSpace;
+PLandroidx/compose/ui/graphics/colorspace/Connector$Companion;-><init>()V
+PLandroidx/compose/ui/graphics/colorspace/Connector$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/colorspace/Connector$Companion;->access$computeTransform-YBCOT_4(Landroidx/compose/ui/graphics/colorspace/Connector$Companion;Landroidx/compose/ui/graphics/colorspace/ColorSpace;Landroidx/compose/ui/graphics/colorspace/ColorSpace;I)[F
+PLandroidx/compose/ui/graphics/colorspace/Connector$Companion;->computeTransform-YBCOT_4(Landroidx/compose/ui/graphics/colorspace/ColorSpace;Landroidx/compose/ui/graphics/colorspace/ColorSpace;I)[F
+PLandroidx/compose/ui/graphics/colorspace/Connector;-><clinit>()V
+PLandroidx/compose/ui/graphics/colorspace/Connector;-><init>(Landroidx/compose/ui/graphics/colorspace/ColorSpace;Landroidx/compose/ui/graphics/colorspace/ColorSpace;I)V
+PLandroidx/compose/ui/graphics/colorspace/Connector;-><init>(Landroidx/compose/ui/graphics/colorspace/ColorSpace;Landroidx/compose/ui/graphics/colorspace/ColorSpace;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/colorspace/Connector;-><init>(Landroidx/compose/ui/graphics/colorspace/ColorSpace;Landroidx/compose/ui/graphics/colorspace/ColorSpace;Landroidx/compose/ui/graphics/colorspace/ColorSpace;Landroidx/compose/ui/graphics/colorspace/ColorSpace;I[F)V
+PLandroidx/compose/ui/graphics/colorspace/Connector;-><init>(Landroidx/compose/ui/graphics/colorspace/ColorSpace;Landroidx/compose/ui/graphics/colorspace/ColorSpace;Landroidx/compose/ui/graphics/colorspace/ColorSpace;Landroidx/compose/ui/graphics/colorspace/ColorSpace;I[FLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/colorspace/Connector;->transform([F)[F
+PLandroidx/compose/ui/graphics/colorspace/Oklab;->fromXyz([F)[F
+PLandroidx/compose/ui/graphics/colorspace/Oklab;->getMaxValue(I)F
+PLandroidx/compose/ui/graphics/colorspace/Oklab;->getMinValue(I)F
+PLandroidx/compose/ui/graphics/colorspace/Oklab;->toXyz([F)[F
+PLandroidx/compose/ui/graphics/colorspace/RenderIntent$Companion;-><init>()V
+PLandroidx/compose/ui/graphics/colorspace/RenderIntent$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/colorspace/RenderIntent$Companion;->getAbsolute-uksYyKA()I
+PLandroidx/compose/ui/graphics/colorspace/RenderIntent$Companion;->getPerceptual-uksYyKA()I
+PLandroidx/compose/ui/graphics/colorspace/RenderIntent;-><clinit>()V
+PLandroidx/compose/ui/graphics/colorspace/RenderIntent;->access$getAbsolute$cp()I
+PLandroidx/compose/ui/graphics/colorspace/RenderIntent;->access$getPerceptual$cp()I
+PLandroidx/compose/ui/graphics/colorspace/RenderIntent;->constructor-impl(I)I
+PLandroidx/compose/ui/graphics/colorspace/RenderIntent;->equals-impl0(II)Z
+PLandroidx/compose/ui/graphics/colorspace/Rgb$eotf$1;->invoke(D)Ljava/lang/Double;
+PLandroidx/compose/ui/graphics/colorspace/Rgb$eotf$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/colorspace/Rgb$oetf$1;->invoke(D)Ljava/lang/Double;
+PLandroidx/compose/ui/graphics/colorspace/Rgb$oetf$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/colorspace/Rgb;-><init>(Landroidx/compose/ui/graphics/colorspace/Rgb;[FLandroidx/compose/ui/graphics/colorspace/WhitePoint;)V
+PLandroidx/compose/ui/graphics/colorspace/Rgb;->access$getMax$p(Landroidx/compose/ui/graphics/colorspace/Rgb;)F
+PLandroidx/compose/ui/graphics/colorspace/Rgb;->access$getMin$p(Landroidx/compose/ui/graphics/colorspace/Rgb;)F
+PLandroidx/compose/ui/graphics/colorspace/Rgb;->fromXyz([F)[F
+PLandroidx/compose/ui/graphics/colorspace/Rgb;->getTransform$ui_graphics_release()[F
+PLandroidx/compose/ui/graphics/colorspace/Rgb;->getWhitePoint()Landroidx/compose/ui/graphics/colorspace/WhitePoint;
+PLandroidx/compose/ui/graphics/colorspace/Rgb;->toXyz([F)[F
+PLandroidx/compose/ui/graphics/colorspace/Xyz;->clamp(F)F
+PLandroidx/compose/ui/graphics/colorspace/Xyz;->fromXyz([F)[F
+PLandroidx/compose/ui/graphics/colorspace/Xyz;->getMaxValue(I)F
+PLandroidx/compose/ui/graphics/colorspace/Xyz;->getMinValue(I)F
+PLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope;->configurePaint-swdJneE$default(Landroidx/compose/ui/graphics/drawscope/CanvasDrawScope;Landroidx/compose/ui/graphics/Brush;Landroidx/compose/ui/graphics/drawscope/DrawStyle;FLandroidx/compose/ui/graphics/ColorFilter;IIILjava/lang/Object;)Landroidx/compose/ui/graphics/Paint;
+PLandroidx/compose/ui/graphics/drawscope/CanvasDrawScope;->drawPath-GBMwjPU(Landroidx/compose/ui/graphics/Path;Landroidx/compose/ui/graphics/Brush;FLandroidx/compose/ui/graphics/drawscope/DrawStyle;Landroidx/compose/ui/graphics/ColorFilter;I)V
+PLandroidx/compose/ui/graphics/drawscope/CanvasDrawScopeKt$asDrawTransform$1;->transform-58bKbWc([F)V
+PLandroidx/compose/ui/graphics/drawscope/DrawScope;->drawPath-GBMwjPU$default(Landroidx/compose/ui/graphics/drawscope/DrawScope;Landroidx/compose/ui/graphics/Path;Landroidx/compose/ui/graphics/Brush;FLandroidx/compose/ui/graphics/drawscope/DrawStyle;Landroidx/compose/ui/graphics/ColorFilter;IILjava/lang/Object;)V
+PLandroidx/compose/ui/graphics/painter/BitmapPainter;->setFilterQuality-vDHp3xo$ui_graphics_release(I)V
+PLandroidx/compose/ui/graphics/painter/BitmapPainterKt;->BitmapPainter-QZhYCtY$default(Landroidx/compose/ui/graphics/ImageBitmap;JJIILjava/lang/Object;)Landroidx/compose/ui/graphics/painter/BitmapPainter;
+PLandroidx/compose/ui/graphics/painter/BitmapPainterKt;->BitmapPainter-QZhYCtY(Landroidx/compose/ui/graphics/ImageBitmap;JJI)Landroidx/compose/ui/graphics/painter/BitmapPainter;
+PLandroidx/compose/ui/graphics/vector/DrawCache;-><init>()V
+PLandroidx/compose/ui/graphics/vector/DrawCache;->clear(Landroidx/compose/ui/graphics/drawscope/DrawScope;)V
+PLandroidx/compose/ui/graphics/vector/DrawCache;->drawCachedImage-CJJAR-o(JLandroidx/compose/ui/unit/Density;Landroidx/compose/ui/unit/LayoutDirection;Lkotlin/jvm/functions/Function1;)V
+PLandroidx/compose/ui/graphics/vector/DrawCache;->drawInto(Landroidx/compose/ui/graphics/drawscope/DrawScope;FLandroidx/compose/ui/graphics/ColorFilter;)V
+PLandroidx/compose/ui/graphics/vector/GroupComponent;-><init>()V
+PLandroidx/compose/ui/graphics/vector/GroupComponent;->draw(Landroidx/compose/ui/graphics/drawscope/DrawScope;)V
+PLandroidx/compose/ui/graphics/vector/GroupComponent;->getInvalidateListener$ui_release()Lkotlin/jvm/functions/Function0;
+PLandroidx/compose/ui/graphics/vector/GroupComponent;->getNumChildren()I
+PLandroidx/compose/ui/graphics/vector/GroupComponent;->getWillClipPath()Z
+PLandroidx/compose/ui/graphics/vector/GroupComponent;->insertAt(ILandroidx/compose/ui/graphics/vector/VNode;)V
+PLandroidx/compose/ui/graphics/vector/GroupComponent;->remove(II)V
+PLandroidx/compose/ui/graphics/vector/GroupComponent;->setInvalidateListener$ui_release(Lkotlin/jvm/functions/Function0;)V
+PLandroidx/compose/ui/graphics/vector/GroupComponent;->setName(Ljava/lang/String;)V
+PLandroidx/compose/ui/graphics/vector/GroupComponent;->setPivotX(F)V
+PLandroidx/compose/ui/graphics/vector/GroupComponent;->setPivotY(F)V
+PLandroidx/compose/ui/graphics/vector/GroupComponent;->setScaleX(F)V
+PLandroidx/compose/ui/graphics/vector/GroupComponent;->setScaleY(F)V
+PLandroidx/compose/ui/graphics/vector/GroupComponent;->updateClipPath()V
+PLandroidx/compose/ui/graphics/vector/GroupComponent;->updateMatrix()V
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder$GroupParams;-><init>(Ljava/lang/String;FFFFFFFLjava/util/List;Ljava/util/List;)V
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder$GroupParams;-><init>(Ljava/lang/String;FFFFFFFLjava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder$GroupParams;->getChildren()Ljava/util/List;
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder$GroupParams;->getClipPathData()Ljava/util/List;
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder$GroupParams;->getName()Ljava/lang/String;
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder$GroupParams;->getPivotX()F
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder$GroupParams;->getPivotY()F
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder$GroupParams;->getRotate()F
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder$GroupParams;->getScaleX()F
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder$GroupParams;->getScaleY()F
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder$GroupParams;->getTranslationX()F
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder$GroupParams;->getTranslationY()F
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder;-><init>(Ljava/lang/String;FFFFJIZ)V
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder;-><init>(Ljava/lang/String;FFFFJIZILkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder;-><init>(Ljava/lang/String;FFFFJIZLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder;->addPath-oIyEayM$default(Landroidx/compose/ui/graphics/vector/ImageVector$Builder;Ljava/util/List;ILjava/lang/String;Landroidx/compose/ui/graphics/Brush;FLandroidx/compose/ui/graphics/Brush;FFIIFFFFILjava/lang/Object;)Landroidx/compose/ui/graphics/vector/ImageVector$Builder;
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder;->addPath-oIyEayM(Ljava/util/List;ILjava/lang/String;Landroidx/compose/ui/graphics/Brush;FLandroidx/compose/ui/graphics/Brush;FFIIFFFF)Landroidx/compose/ui/graphics/vector/ImageVector$Builder;
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder;->asVectorGroup(Landroidx/compose/ui/graphics/vector/ImageVector$Builder$GroupParams;)Landroidx/compose/ui/graphics/vector/VectorGroup;
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder;->build()Landroidx/compose/ui/graphics/vector/ImageVector;
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder;->ensureNotConsumed()V
+PLandroidx/compose/ui/graphics/vector/ImageVector$Builder;->getCurrentGroup()Landroidx/compose/ui/graphics/vector/ImageVector$Builder$GroupParams;
+PLandroidx/compose/ui/graphics/vector/ImageVector$Companion;-><init>()V
+PLandroidx/compose/ui/graphics/vector/ImageVector$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/vector/ImageVector;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/ImageVector;-><init>(Ljava/lang/String;FFFFLandroidx/compose/ui/graphics/vector/VectorGroup;JIZ)V
+PLandroidx/compose/ui/graphics/vector/ImageVector;-><init>(Ljava/lang/String;FFFFLandroidx/compose/ui/graphics/vector/VectorGroup;JIZLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/vector/ImageVector;->equals(Ljava/lang/Object;)Z
+PLandroidx/compose/ui/graphics/vector/ImageVector;->getAutoMirror()Z
+PLandroidx/compose/ui/graphics/vector/ImageVector;->getDefaultHeight-D9Ej5fM()F
+PLandroidx/compose/ui/graphics/vector/ImageVector;->getDefaultWidth-D9Ej5fM()F
+PLandroidx/compose/ui/graphics/vector/ImageVector;->getName()Ljava/lang/String;
+PLandroidx/compose/ui/graphics/vector/ImageVector;->getRoot()Landroidx/compose/ui/graphics/vector/VectorGroup;
+PLandroidx/compose/ui/graphics/vector/ImageVector;->getTintBlendMode-0nO6VwU()I
+PLandroidx/compose/ui/graphics/vector/ImageVector;->getTintColor-0d7_KjU()J
+PLandroidx/compose/ui/graphics/vector/ImageVector;->getViewportHeight()F
+PLandroidx/compose/ui/graphics/vector/ImageVector;->getViewportWidth()F
+PLandroidx/compose/ui/graphics/vector/ImageVectorKt;->access$peek(Ljava/util/ArrayList;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/ImageVectorKt;->access$push(Ljava/util/ArrayList;Ljava/lang/Object;)Z
+PLandroidx/compose/ui/graphics/vector/ImageVectorKt;->peek(Ljava/util/ArrayList;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/ImageVectorKt;->push(Ljava/util/ArrayList;Ljava/lang/Object;)Z
+PLandroidx/compose/ui/graphics/vector/PathBuilder;-><init>()V
+PLandroidx/compose/ui/graphics/vector/PathBuilder;->addNode(Landroidx/compose/ui/graphics/vector/PathNode;)Landroidx/compose/ui/graphics/vector/PathBuilder;
+PLandroidx/compose/ui/graphics/vector/PathBuilder;->close()Landroidx/compose/ui/graphics/vector/PathBuilder;
+PLandroidx/compose/ui/graphics/vector/PathBuilder;->getNodes()Ljava/util/List;
+PLandroidx/compose/ui/graphics/vector/PathBuilder;->horizontalLineTo(F)Landroidx/compose/ui/graphics/vector/PathBuilder;
+PLandroidx/compose/ui/graphics/vector/PathBuilder;->horizontalLineToRelative(F)Landroidx/compose/ui/graphics/vector/PathBuilder;
+PLandroidx/compose/ui/graphics/vector/PathBuilder;->lineTo(FF)Landroidx/compose/ui/graphics/vector/PathBuilder;
+PLandroidx/compose/ui/graphics/vector/PathBuilder;->lineToRelative(FF)Landroidx/compose/ui/graphics/vector/PathBuilder;
+PLandroidx/compose/ui/graphics/vector/PathBuilder;->moveTo(FF)Landroidx/compose/ui/graphics/vector/PathBuilder;
+PLandroidx/compose/ui/graphics/vector/PathBuilder;->verticalLineTo(F)Landroidx/compose/ui/graphics/vector/PathBuilder;
+PLandroidx/compose/ui/graphics/vector/PathBuilder;->verticalLineToRelative(F)Landroidx/compose/ui/graphics/vector/PathBuilder;
+PLandroidx/compose/ui/graphics/vector/PathComponent$pathMeasure$2;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/PathComponent$pathMeasure$2;-><init>()V
+PLandroidx/compose/ui/graphics/vector/PathComponent;-><init>()V
+PLandroidx/compose/ui/graphics/vector/PathComponent;->draw(Landroidx/compose/ui/graphics/drawscope/DrawScope;)V
+PLandroidx/compose/ui/graphics/vector/PathComponent;->setFill(Landroidx/compose/ui/graphics/Brush;)V
+PLandroidx/compose/ui/graphics/vector/PathComponent;->setFillAlpha(F)V
+PLandroidx/compose/ui/graphics/vector/PathComponent;->setName(Ljava/lang/String;)V
+PLandroidx/compose/ui/graphics/vector/PathComponent;->setPathData(Ljava/util/List;)V
+PLandroidx/compose/ui/graphics/vector/PathComponent;->setPathFillType-oQ8Xj4U(I)V
+PLandroidx/compose/ui/graphics/vector/PathComponent;->setStroke(Landroidx/compose/ui/graphics/Brush;)V
+PLandroidx/compose/ui/graphics/vector/PathComponent;->setStrokeAlpha(F)V
+PLandroidx/compose/ui/graphics/vector/PathComponent;->setStrokeLineCap-BeK7IIE(I)V
+PLandroidx/compose/ui/graphics/vector/PathComponent;->setStrokeLineJoin-Ww9F2mQ(I)V
+PLandroidx/compose/ui/graphics/vector/PathComponent;->setStrokeLineMiter(F)V
+PLandroidx/compose/ui/graphics/vector/PathComponent;->setStrokeLineWidth(F)V
+PLandroidx/compose/ui/graphics/vector/PathComponent;->setTrimPathEnd(F)V
+PLandroidx/compose/ui/graphics/vector/PathComponent;->setTrimPathOffset(F)V
+PLandroidx/compose/ui/graphics/vector/PathComponent;->setTrimPathStart(F)V
+PLandroidx/compose/ui/graphics/vector/PathComponent;->updatePath()V
+PLandroidx/compose/ui/graphics/vector/PathComponent;->updateRenderPath()V
+PLandroidx/compose/ui/graphics/vector/PathNode$Close;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/PathNode$Close;-><init>()V
+PLandroidx/compose/ui/graphics/vector/PathNode$HorizontalTo;-><init>(F)V
+PLandroidx/compose/ui/graphics/vector/PathNode$HorizontalTo;->getX()F
+PLandroidx/compose/ui/graphics/vector/PathNode$LineTo;-><init>(FF)V
+PLandroidx/compose/ui/graphics/vector/PathNode$LineTo;->getX()F
+PLandroidx/compose/ui/graphics/vector/PathNode$LineTo;->getY()F
+PLandroidx/compose/ui/graphics/vector/PathNode$MoveTo;-><init>(FF)V
+PLandroidx/compose/ui/graphics/vector/PathNode$MoveTo;->getX()F
+PLandroidx/compose/ui/graphics/vector/PathNode$MoveTo;->getY()F
+PLandroidx/compose/ui/graphics/vector/PathNode$RelativeHorizontalTo;-><init>(F)V
+PLandroidx/compose/ui/graphics/vector/PathNode$RelativeHorizontalTo;->getDx()F
+PLandroidx/compose/ui/graphics/vector/PathNode$RelativeLineTo;-><init>(FF)V
+PLandroidx/compose/ui/graphics/vector/PathNode$RelativeLineTo;->getDx()F
+PLandroidx/compose/ui/graphics/vector/PathNode$RelativeLineTo;->getDy()F
+PLandroidx/compose/ui/graphics/vector/PathNode$RelativeVerticalTo;-><init>(F)V
+PLandroidx/compose/ui/graphics/vector/PathNode$RelativeVerticalTo;->getDy()F
+PLandroidx/compose/ui/graphics/vector/PathNode$VerticalTo;-><init>(F)V
+PLandroidx/compose/ui/graphics/vector/PathNode$VerticalTo;->getY()F
+PLandroidx/compose/ui/graphics/vector/PathNode;-><init>(ZZ)V
+PLandroidx/compose/ui/graphics/vector/PathNode;-><init>(ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/vector/PathNode;-><init>(ZZLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/vector/PathParser$PathPoint;-><init>(FF)V
+PLandroidx/compose/ui/graphics/vector/PathParser$PathPoint;-><init>(FFILkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/vector/PathParser$PathPoint;->getX()F
+PLandroidx/compose/ui/graphics/vector/PathParser$PathPoint;->getY()F
+PLandroidx/compose/ui/graphics/vector/PathParser$PathPoint;->reset()V
+PLandroidx/compose/ui/graphics/vector/PathParser$PathPoint;->setX(F)V
+PLandroidx/compose/ui/graphics/vector/PathParser$PathPoint;->setY(F)V
+PLandroidx/compose/ui/graphics/vector/PathParser;-><init>()V
+PLandroidx/compose/ui/graphics/vector/PathParser;->addPathNodes(Ljava/util/List;)Landroidx/compose/ui/graphics/vector/PathParser;
+PLandroidx/compose/ui/graphics/vector/PathParser;->clear()V
+PLandroidx/compose/ui/graphics/vector/PathParser;->close(Landroidx/compose/ui/graphics/Path;)V
+PLandroidx/compose/ui/graphics/vector/PathParser;->horizontalTo(Landroidx/compose/ui/graphics/vector/PathNode$HorizontalTo;Landroidx/compose/ui/graphics/Path;)V
+PLandroidx/compose/ui/graphics/vector/PathParser;->lineTo(Landroidx/compose/ui/graphics/vector/PathNode$LineTo;Landroidx/compose/ui/graphics/Path;)V
+PLandroidx/compose/ui/graphics/vector/PathParser;->moveTo(Landroidx/compose/ui/graphics/vector/PathNode$MoveTo;Landroidx/compose/ui/graphics/Path;)V
+PLandroidx/compose/ui/graphics/vector/PathParser;->relativeHorizontalTo(Landroidx/compose/ui/graphics/vector/PathNode$RelativeHorizontalTo;Landroidx/compose/ui/graphics/Path;)V
+PLandroidx/compose/ui/graphics/vector/PathParser;->relativeLineTo(Landroidx/compose/ui/graphics/vector/PathNode$RelativeLineTo;Landroidx/compose/ui/graphics/Path;)V
+PLandroidx/compose/ui/graphics/vector/PathParser;->relativeVerticalTo(Landroidx/compose/ui/graphics/vector/PathNode$RelativeVerticalTo;Landroidx/compose/ui/graphics/Path;)V
+PLandroidx/compose/ui/graphics/vector/PathParser;->toPath(Landroidx/compose/ui/graphics/Path;)Landroidx/compose/ui/graphics/Path;
+PLandroidx/compose/ui/graphics/vector/PathParser;->verticalTo(Landroidx/compose/ui/graphics/vector/PathNode$VerticalTo;Landroidx/compose/ui/graphics/Path;)V
+PLandroidx/compose/ui/graphics/vector/VNode;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VNode;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VNode;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/vector/VNode;->getInvalidateListener$ui_release()Lkotlin/jvm/functions/Function0;
+PLandroidx/compose/ui/graphics/vector/VNode;->invalidate()V
+PLandroidx/compose/ui/graphics/vector/VNode;->setInvalidateListener$ui_release(Lkotlin/jvm/functions/Function0;)V
+PLandroidx/compose/ui/graphics/vector/VectorApplier;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorApplier;-><init>(Landroidx/compose/ui/graphics/vector/VNode;)V
+PLandroidx/compose/ui/graphics/vector/VectorApplier;->asGroup(Landroidx/compose/ui/graphics/vector/VNode;)Landroidx/compose/ui/graphics/vector/GroupComponent;
+PLandroidx/compose/ui/graphics/vector/VectorApplier;->insertBottomUp(ILandroidx/compose/ui/graphics/vector/VNode;)V
+PLandroidx/compose/ui/graphics/vector/VectorApplier;->insertBottomUp(ILjava/lang/Object;)V
+PLandroidx/compose/ui/graphics/vector/VectorApplier;->insertTopDown(ILandroidx/compose/ui/graphics/vector/VNode;)V
+PLandroidx/compose/ui/graphics/vector/VectorApplier;->insertTopDown(ILjava/lang/Object;)V
+PLandroidx/compose/ui/graphics/vector/VectorApplier;->onClear()V
+PLandroidx/compose/ui/graphics/vector/VectorComponent$drawVectorBlock$1;-><init>(Landroidx/compose/ui/graphics/vector/VectorComponent;)V
+PLandroidx/compose/ui/graphics/vector/VectorComponent$drawVectorBlock$1;->invoke(Landroidx/compose/ui/graphics/drawscope/DrawScope;)V
+PLandroidx/compose/ui/graphics/vector/VectorComponent$drawVectorBlock$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorComponent$invalidateCallback$1;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorComponent$invalidateCallback$1;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorComponent$root$1$1;-><init>(Landroidx/compose/ui/graphics/vector/VectorComponent;)V
+PLandroidx/compose/ui/graphics/vector/VectorComponent$root$1$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorComponent$root$1$1;->invoke()V
+PLandroidx/compose/ui/graphics/vector/VectorComponent;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorComponent;->access$doInvalidate(Landroidx/compose/ui/graphics/vector/VectorComponent;)V
+PLandroidx/compose/ui/graphics/vector/VectorComponent;->doInvalidate()V
+PLandroidx/compose/ui/graphics/vector/VectorComponent;->draw(Landroidx/compose/ui/graphics/drawscope/DrawScope;FLandroidx/compose/ui/graphics/ColorFilter;)V
+PLandroidx/compose/ui/graphics/vector/VectorComponent;->getRoot()Landroidx/compose/ui/graphics/vector/GroupComponent;
+PLandroidx/compose/ui/graphics/vector/VectorComponent;->getViewportHeight()F
+PLandroidx/compose/ui/graphics/vector/VectorComponent;->getViewportWidth()F
+PLandroidx/compose/ui/graphics/vector/VectorComponent;->setIntrinsicColorFilter$ui_release(Landroidx/compose/ui/graphics/ColorFilter;)V
+PLandroidx/compose/ui/graphics/vector/VectorComponent;->setInvalidateCallback$ui_release(Lkotlin/jvm/functions/Function0;)V
+PLandroidx/compose/ui/graphics/vector/VectorComponent;->setName(Ljava/lang/String;)V
+PLandroidx/compose/ui/graphics/vector/VectorComponent;->setViewportHeight(F)V
+PLandroidx/compose/ui/graphics/vector/VectorComponent;->setViewportWidth(F)V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$1;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$1;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$1;->invoke()Landroidx/compose/ui/graphics/vector/PathComponent;
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$10;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$10;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$10;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$10;->invoke-CSYIeUk(Landroidx/compose/ui/graphics/vector/PathComponent;I)V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$11;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$11;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$11;->invoke(Landroidx/compose/ui/graphics/vector/PathComponent;F)V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$11;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$12;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$12;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$12;->invoke(Landroidx/compose/ui/graphics/vector/PathComponent;F)V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$12;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$13;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$13;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$13;->invoke(Landroidx/compose/ui/graphics/vector/PathComponent;F)V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$13;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$14;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$14;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$14;->invoke(Landroidx/compose/ui/graphics/vector/PathComponent;F)V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$14;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$1;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$1;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$1;->invoke(Landroidx/compose/ui/graphics/vector/PathComponent;Ljava/lang/String;)V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$2;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$2;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$2;->invoke(Landroidx/compose/ui/graphics/vector/PathComponent;Ljava/util/List;)V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$3;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$3;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$3;->invoke-pweu1eQ(Landroidx/compose/ui/graphics/vector/PathComponent;I)V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$4;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$4;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$4;->invoke(Landroidx/compose/ui/graphics/vector/PathComponent;Landroidx/compose/ui/graphics/Brush;)V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$4;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$5;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$5;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$5;->invoke(Landroidx/compose/ui/graphics/vector/PathComponent;F)V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$5;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$6;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$6;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$6;->invoke(Landroidx/compose/ui/graphics/vector/PathComponent;Landroidx/compose/ui/graphics/Brush;)V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$6;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$7;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$7;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$7;->invoke(Landroidx/compose/ui/graphics/vector/PathComponent;F)V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$7;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$8;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$8;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$8;->invoke(Landroidx/compose/ui/graphics/vector/PathComponent;F)V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$8;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$9;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$9;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$9;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path$2$9;->invoke-kLtJ_vA(Landroidx/compose/ui/graphics/vector/PathComponent;I)V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path-9cdaXJ4$$inlined$ComposeNode$1;-><init>(Lkotlin/jvm/functions/Function0;)V
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt$Path-9cdaXJ4$$inlined$ComposeNode$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorComposeKt;->Path-9cdaXJ4(Ljava/util/List;ILjava/lang/String;Landroidx/compose/ui/graphics/Brush;FLandroidx/compose/ui/graphics/Brush;FFIIFFFFLandroidx/compose/runtime/Composer;III)V
+PLandroidx/compose/ui/graphics/vector/VectorConfig;->getOrDefault(Landroidx/compose/ui/graphics/vector/VectorProperty;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorGroup$iterator$1;-><init>(Landroidx/compose/ui/graphics/vector/VectorGroup;)V
+PLandroidx/compose/ui/graphics/vector/VectorGroup$iterator$1;->hasNext()Z
+PLandroidx/compose/ui/graphics/vector/VectorGroup$iterator$1;->next()Landroidx/compose/ui/graphics/vector/VectorNode;
+PLandroidx/compose/ui/graphics/vector/VectorGroup$iterator$1;->next()Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorGroup;-><init>(Ljava/lang/String;FFFFFFFLjava/util/List;Ljava/util/List;)V
+PLandroidx/compose/ui/graphics/vector/VectorGroup;->access$getChildren$p(Landroidx/compose/ui/graphics/vector/VectorGroup;)Ljava/util/List;
+PLandroidx/compose/ui/graphics/vector/VectorGroup;->iterator()Ljava/util/Iterator;
+PLandroidx/compose/ui/graphics/vector/VectorKt;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorKt;->getDefaultFillType()I
+PLandroidx/compose/ui/graphics/vector/VectorKt;->getDefaultStrokeLineCap()I
+PLandroidx/compose/ui/graphics/vector/VectorKt;->getDefaultStrokeLineJoin()I
+PLandroidx/compose/ui/graphics/vector/VectorKt;->getEmptyPath()Ljava/util/List;
+PLandroidx/compose/ui/graphics/vector/VectorNode;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorNode;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorNode;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/vector/VectorPainter$RenderVector$2$invoke$$inlined$onDispose$1;-><init>(Landroidx/compose/runtime/Composition;)V
+PLandroidx/compose/ui/graphics/vector/VectorPainter$RenderVector$2$invoke$$inlined$onDispose$1;->dispose()V
+PLandroidx/compose/ui/graphics/vector/VectorPainter$RenderVector$2;-><init>(Landroidx/compose/runtime/Composition;)V
+PLandroidx/compose/ui/graphics/vector/VectorPainter$RenderVector$2;->invoke(Landroidx/compose/runtime/DisposableEffectScope;)Landroidx/compose/runtime/DisposableEffectResult;
+PLandroidx/compose/ui/graphics/vector/VectorPainter$RenderVector$2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorPainter$composeVector$1;-><init>(Lkotlin/jvm/functions/Function4;Landroidx/compose/ui/graphics/vector/VectorPainter;)V
+PLandroidx/compose/ui/graphics/vector/VectorPainter$composeVector$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/ui/graphics/vector/VectorPainter$composeVector$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorPainter$vector$1$1;-><init>(Landroidx/compose/ui/graphics/vector/VectorPainter;)V
+PLandroidx/compose/ui/graphics/vector/VectorPainter$vector$1$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorPainter$vector$1$1;->invoke()V
+PLandroidx/compose/ui/graphics/vector/VectorPainter;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorPainter;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorPainter;->RenderVector$ui_release(Ljava/lang/String;FFLkotlin/jvm/functions/Function4;Landroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/ui/graphics/vector/VectorPainter;->access$getVector$p(Landroidx/compose/ui/graphics/vector/VectorPainter;)Landroidx/compose/ui/graphics/vector/VectorComponent;
+PLandroidx/compose/ui/graphics/vector/VectorPainter;->access$setDirty(Landroidx/compose/ui/graphics/vector/VectorPainter;Z)V
+PLandroidx/compose/ui/graphics/vector/VectorPainter;->applyColorFilter(Landroidx/compose/ui/graphics/ColorFilter;)Z
+PLandroidx/compose/ui/graphics/vector/VectorPainter;->composeVector(Landroidx/compose/runtime/CompositionContext;Lkotlin/jvm/functions/Function4;)Landroidx/compose/runtime/Composition;
+PLandroidx/compose/ui/graphics/vector/VectorPainter;->getAutoMirror$ui_release()Z
+PLandroidx/compose/ui/graphics/vector/VectorPainter;->getIntrinsicSize-NH-jbRc()J
+PLandroidx/compose/ui/graphics/vector/VectorPainter;->getSize-NH-jbRc$ui_release()J
+PLandroidx/compose/ui/graphics/vector/VectorPainter;->isDirty()Z
+PLandroidx/compose/ui/graphics/vector/VectorPainter;->onDraw(Landroidx/compose/ui/graphics/drawscope/DrawScope;)V
+PLandroidx/compose/ui/graphics/vector/VectorPainter;->setAutoMirror$ui_release(Z)V
+PLandroidx/compose/ui/graphics/vector/VectorPainter;->setDirty(Z)V
+PLandroidx/compose/ui/graphics/vector/VectorPainter;->setIntrinsicColorFilter$ui_release(Landroidx/compose/ui/graphics/ColorFilter;)V
+PLandroidx/compose/ui/graphics/vector/VectorPainter;->setSize-uvyYCjk$ui_release(J)V
+PLandroidx/compose/ui/graphics/vector/VectorPainterKt$RenderVectorGroup$config$1;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorPainterKt$rememberVectorPainter$3;-><init>(Landroidx/compose/ui/graphics/vector/ImageVector;)V
+PLandroidx/compose/ui/graphics/vector/VectorPainterKt$rememberVectorPainter$3;->invoke(FFLandroidx/compose/runtime/Composer;I)V
+PLandroidx/compose/ui/graphics/vector/VectorPainterKt$rememberVectorPainter$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/graphics/vector/VectorPainterKt;->RenderVectorGroup(Landroidx/compose/ui/graphics/vector/VectorGroup;Ljava/util/Map;Landroidx/compose/runtime/Composer;II)V
+PLandroidx/compose/ui/graphics/vector/VectorPainterKt;->rememberVectorPainter(Landroidx/compose/ui/graphics/vector/ImageVector;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/graphics/vector/VectorPainter;
+PLandroidx/compose/ui/graphics/vector/VectorPainterKt;->rememberVectorPainter-vIP8VLU(FFFFLjava/lang/String;JIZLkotlin/jvm/functions/Function4;Landroidx/compose/runtime/Composer;II)Landroidx/compose/ui/graphics/vector/VectorPainter;
+PLandroidx/compose/ui/graphics/vector/VectorPath;-><init>(Ljava/lang/String;Ljava/util/List;ILandroidx/compose/ui/graphics/Brush;FLandroidx/compose/ui/graphics/Brush;FFIIFFFF)V
+PLandroidx/compose/ui/graphics/vector/VectorPath;-><init>(Ljava/lang/String;Ljava/util/List;ILandroidx/compose/ui/graphics/Brush;FLandroidx/compose/ui/graphics/Brush;FFIIFFFFLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/graphics/vector/VectorPath;->getFill()Landroidx/compose/ui/graphics/Brush;
+PLandroidx/compose/ui/graphics/vector/VectorPath;->getFillAlpha()F
+PLandroidx/compose/ui/graphics/vector/VectorPath;->getName()Ljava/lang/String;
+PLandroidx/compose/ui/graphics/vector/VectorPath;->getPathData()Ljava/util/List;
+PLandroidx/compose/ui/graphics/vector/VectorPath;->getPathFillType-Rg-k1Os()I
+PLandroidx/compose/ui/graphics/vector/VectorPath;->getStroke()Landroidx/compose/ui/graphics/Brush;
+PLandroidx/compose/ui/graphics/vector/VectorPath;->getStrokeAlpha()F
+PLandroidx/compose/ui/graphics/vector/VectorPath;->getStrokeLineCap-KaPHkGw()I
+PLandroidx/compose/ui/graphics/vector/VectorPath;->getStrokeLineJoin-LxFBmk8()I
+PLandroidx/compose/ui/graphics/vector/VectorPath;->getStrokeLineMiter()F
+PLandroidx/compose/ui/graphics/vector/VectorPath;->getStrokeLineWidth()F
+PLandroidx/compose/ui/graphics/vector/VectorPath;->getTrimPathEnd()F
+PLandroidx/compose/ui/graphics/vector/VectorPath;->getTrimPathOffset()F
+PLandroidx/compose/ui/graphics/vector/VectorPath;->getTrimPathStart()F
+PLandroidx/compose/ui/graphics/vector/VectorProperty$Fill;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty$Fill;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty$FillAlpha;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty$FillAlpha;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty$PathData;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty$PathData;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty$Stroke;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty$Stroke;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty$StrokeAlpha;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty$StrokeAlpha;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty$StrokeLineWidth;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty$StrokeLineWidth;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty$TrimPathEnd;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty$TrimPathEnd;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty$TrimPathOffset;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty$TrimPathOffset;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty$TrimPathStart;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty$TrimPathStart;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty;-><clinit>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty;-><init>()V
+PLandroidx/compose/ui/graphics/vector/VectorProperty;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/input/ScrollContainerInfoKt$provideScrollContainerInfo$2;-><init>(Landroidx/compose/ui/input/ScrollContainerInfo;)V
+PLandroidx/compose/ui/input/ScrollContainerInfoKt$provideScrollContainerInfo$2;->invoke(Landroidx/compose/ui/Modifier;Landroidx/compose/runtime/Composer;I)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/ui/input/ScrollContainerInfoKt$provideScrollContainerInfo$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/input/ScrollContainerInfoKt;->canScroll(Landroidx/compose/ui/input/ScrollContainerInfo;)Z
+PLandroidx/compose/ui/input/ScrollContainerInfoKt;->provideScrollContainerInfo(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/input/ScrollContainerInfo;)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/ui/input/ScrollContainerInfoModifierLocal;-><init>(Landroidx/compose/ui/input/ScrollContainerInfo;)V
+PLandroidx/compose/ui/input/ScrollContainerInfoModifierLocal;->canScrollVertically()Z
+PLandroidx/compose/ui/input/ScrollContainerInfoModifierLocal;->getKey()Landroidx/compose/ui/modifier/ProvidableModifierLocal;
+PLandroidx/compose/ui/input/ScrollContainerInfoModifierLocal;->getValue()Landroidx/compose/ui/input/ScrollContainerInfoModifierLocal;
+PLandroidx/compose/ui/input/ScrollContainerInfoModifierLocal;->getValue()Ljava/lang/Object;
+PLandroidx/compose/ui/input/ScrollContainerInfoModifierLocal;->onModifierLocalsUpdated(Landroidx/compose/ui/modifier/ModifierLocalReadScope;)V
+PLandroidx/compose/ui/input/ScrollContainerInfoModifierLocal;->setParent(Landroidx/compose/ui/input/ScrollContainerInfo;)V
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher$dispatchPostFling$1;-><init>(Landroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher$dispatchPostFling$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher$dispatchPreFling$1;-><init>(Landroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;->dispatchPostFling-RZ2iAVY(JJLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;->dispatchPostScroll-DzOQY0M(JJI)J
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;->dispatchPreFling-QWom1Mo(JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;->dispatchPreScroll-OzD1aCk(JI)J
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;->getCoroutineScope()Lkotlinx/coroutines/CoroutineScope;
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollDispatcher;->getOriginNestedScrollScope$ui_release()Lkotlinx/coroutines/CoroutineScope;
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal$1;->invoke()Lkotlinx/coroutines/CoroutineScope;
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal$onPostFling$1;-><init>(Landroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal$onPostFling$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal$onPreFling$1;-><init>(Landroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;->access$getNestedCoroutineScope(Landroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;)Lkotlinx/coroutines/CoroutineScope;
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;->getNestedCoroutineScope()Lkotlinx/coroutines/CoroutineScope;
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;->getValue()Landroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;->getValue()Ljava/lang/Object;
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;->onPostFling-RZ2iAVY(JJLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;->onPostScroll-DzOQY0M(JJI)J
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;->onPreFling-QWom1Mo(JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollModifierLocal;->onPreScroll-OzD1aCk(JI)J
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollSource$Companion;-><init>()V
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollSource$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollSource$Companion;->getDrag-WNlRxjI()I
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollSource$Companion;->getFling-WNlRxjI()I
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollSource;-><clinit>()V
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollSource;->access$getDrag$cp()I
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollSource;->access$getFling$cp()I
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollSource;->constructor-impl(I)I
+PLandroidx/compose/ui/input/nestedscroll/NestedScrollSource;->equals-impl0(II)Z
+PLandroidx/compose/ui/input/pointer/ConsumedData;-><clinit>()V
+PLandroidx/compose/ui/input/pointer/ConsumedData;-><init>(ZZ)V
+PLandroidx/compose/ui/input/pointer/ConsumedData;->getDownChange()Z
+PLandroidx/compose/ui/input/pointer/ConsumedData;->getPositionChange()Z
+PLandroidx/compose/ui/input/pointer/ConsumedData;->setDownChange(Z)V
+PLandroidx/compose/ui/input/pointer/ConsumedData;->setPositionChange(Z)V
+PLandroidx/compose/ui/input/pointer/HistoricalChange;-><init>(JJ)V
+PLandroidx/compose/ui/input/pointer/HistoricalChange;-><init>(JJLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/input/pointer/HistoricalChange;->getPosition-F1C5BW0()J
+PLandroidx/compose/ui/input/pointer/HistoricalChange;->getUptimeMillis()J
+PLandroidx/compose/ui/input/pointer/HitPathTracker;->addHitPath-KNwqfcY(JLjava/util/List;)V
+PLandroidx/compose/ui/input/pointer/HitPathTracker;->dispatchChanges(Landroidx/compose/ui/input/pointer/InternalPointerEvent;Z)Z
+PLandroidx/compose/ui/input/pointer/HitPathTracker;->processCancel()V
+PLandroidx/compose/ui/input/pointer/HitPathTracker;->removeDetachedPointerInputFilters()V
+PLandroidx/compose/ui/input/pointer/InternalPointerEvent;-><init>(Ljava/util/Map;Landroidx/compose/ui/input/pointer/PointerInputEvent;)V
+PLandroidx/compose/ui/input/pointer/InternalPointerEvent;->getChanges()Ljava/util/Map;
+PLandroidx/compose/ui/input/pointer/InternalPointerEvent;->getMotionEvent()Landroid/view/MotionEvent;
+PLandroidx/compose/ui/input/pointer/InternalPointerEvent;->getSuppressMovementConsumption()Z
+PLandroidx/compose/ui/input/pointer/MotionEventAdapter;->addFreshIds(Landroid/view/MotionEvent;)V
+PLandroidx/compose/ui/input/pointer/MotionEventAdapter;->clearOnDeviceChange(Landroid/view/MotionEvent;)V
+PLandroidx/compose/ui/input/pointer/MotionEventAdapter;->endStream(I)V
+PLandroidx/compose/ui/input/pointer/MotionEventAdapter;->getComposePointerId-_I2yYro(I)J
+PLandroidx/compose/ui/input/pointer/MotionEventAdapter;->removeStaleIds(Landroid/view/MotionEvent;)V
+PLandroidx/compose/ui/input/pointer/Node;-><init>(Landroidx/compose/ui/node/PointerInputModifierNode;)V
+PLandroidx/compose/ui/input/pointer/Node;->clearCache()V
+PLandroidx/compose/ui/input/pointer/Node;->dispatchCancel()V
+PLandroidx/compose/ui/input/pointer/Node;->getPointerIds()Landroidx/compose/runtime/collection/MutableVector;
+PLandroidx/compose/ui/input/pointer/Node;->getPointerInputNode()Landroidx/compose/ui/node/PointerInputModifierNode;
+PLandroidx/compose/ui/input/pointer/Node;->hasPositionChanged(Landroidx/compose/ui/input/pointer/PointerEvent;Landroidx/compose/ui/input/pointer/PointerEvent;)Z
+PLandroidx/compose/ui/input/pointer/NodeParent;->buildCache(Ljava/util/Map;Landroidx/compose/ui/layout/LayoutCoordinates;Landroidx/compose/ui/input/pointer/InternalPointerEvent;Z)Z
+PLandroidx/compose/ui/input/pointer/NodeParent;->cleanUpHits(Landroidx/compose/ui/input/pointer/InternalPointerEvent;)V
+PLandroidx/compose/ui/input/pointer/NodeParent;->clear()V
+PLandroidx/compose/ui/input/pointer/NodeParent;->dispatchCancel()V
+PLandroidx/compose/ui/input/pointer/NodeParent;->dispatchFinalEventPass(Landroidx/compose/ui/input/pointer/InternalPointerEvent;)Z
+PLandroidx/compose/ui/input/pointer/NodeParent;->dispatchMainEventPass(Ljava/util/Map;Landroidx/compose/ui/layout/LayoutCoordinates;Landroidx/compose/ui/input/pointer/InternalPointerEvent;Z)Z
+PLandroidx/compose/ui/input/pointer/NodeParent;->getChildren()Landroidx/compose/runtime/collection/MutableVector;
+PLandroidx/compose/ui/input/pointer/NodeParent;->removeDetachedPointerInputFilters()V
+PLandroidx/compose/ui/input/pointer/PointerEvent;->getChanges()Ljava/util/List;
+PLandroidx/compose/ui/input/pointer/PointerEvent;->getType-7fucELk()I
+PLandroidx/compose/ui/input/pointer/PointerEventKt;->changedToDown(Landroidx/compose/ui/input/pointer/PointerInputChange;)Z
+PLandroidx/compose/ui/input/pointer/PointerEventKt;->changedToDownIgnoreConsumed(Landroidx/compose/ui/input/pointer/PointerInputChange;)Z
+PLandroidx/compose/ui/input/pointer/PointerEventKt;->changedToUp(Landroidx/compose/ui/input/pointer/PointerInputChange;)Z
+PLandroidx/compose/ui/input/pointer/PointerEventKt;->changedToUpIgnoreConsumed(Landroidx/compose/ui/input/pointer/PointerInputChange;)Z
+PLandroidx/compose/ui/input/pointer/PointerEventKt;->isOutOfBounds-jwHxaWs(Landroidx/compose/ui/input/pointer/PointerInputChange;JJ)Z
+PLandroidx/compose/ui/input/pointer/PointerEventKt;->positionChange(Landroidx/compose/ui/input/pointer/PointerInputChange;)J
+PLandroidx/compose/ui/input/pointer/PointerEventKt;->positionChangeIgnoreConsumed(Landroidx/compose/ui/input/pointer/PointerInputChange;)J
+PLandroidx/compose/ui/input/pointer/PointerEventKt;->positionChangeInternal(Landroidx/compose/ui/input/pointer/PointerInputChange;Z)J
+PLandroidx/compose/ui/input/pointer/PointerEventKt;->positionChangedIgnoreConsumed(Landroidx/compose/ui/input/pointer/PointerInputChange;)Z
+PLandroidx/compose/ui/input/pointer/PointerEventPass;->values()[Landroidx/compose/ui/input/pointer/PointerEventPass;
+PLandroidx/compose/ui/input/pointer/PointerEventType$Companion;->getEnter-7fucELk()I
+PLandroidx/compose/ui/input/pointer/PointerEventType$Companion;->getExit-7fucELk()I
+PLandroidx/compose/ui/input/pointer/PointerEventType$Companion;->getPress-7fucELk()I
+PLandroidx/compose/ui/input/pointer/PointerEventType$Companion;->getRelease-7fucELk()I
+PLandroidx/compose/ui/input/pointer/PointerEventType$Companion;->getScroll-7fucELk()I
+PLandroidx/compose/ui/input/pointer/PointerEventType;->access$getEnter$cp()I
+PLandroidx/compose/ui/input/pointer/PointerEventType;->access$getExit$cp()I
+PLandroidx/compose/ui/input/pointer/PointerEventType;->access$getPress$cp()I
+PLandroidx/compose/ui/input/pointer/PointerEventType;->access$getRelease$cp()I
+PLandroidx/compose/ui/input/pointer/PointerEventType;->access$getScroll$cp()I
+PLandroidx/compose/ui/input/pointer/PointerEventType;->equals-impl0(II)Z
+PLandroidx/compose/ui/input/pointer/PointerId;->box-impl(J)Landroidx/compose/ui/input/pointer/PointerId;
+PLandroidx/compose/ui/input/pointer/PointerId;->constructor-impl(J)J
+PLandroidx/compose/ui/input/pointer/PointerId;->equals(Ljava/lang/Object;)Z
+PLandroidx/compose/ui/input/pointer/PointerId;->equals-impl0(JJ)Z
+PLandroidx/compose/ui/input/pointer/PointerId;->hashCode()I
+PLandroidx/compose/ui/input/pointer/PointerId;->hashCode-impl(J)I
+PLandroidx/compose/ui/input/pointer/PointerId;->unbox-impl()J
+PLandroidx/compose/ui/input/pointer/PointerInputChange;-><init>(JJJZFJJZZIJ)V
+PLandroidx/compose/ui/input/pointer/PointerInputChange;-><init>(JJJZFJJZZIJILkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/input/pointer/PointerInputChange;-><init>(JJJZFJJZZIJLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/input/pointer/PointerInputChange;-><init>(JJJZFJJZZILjava/util/List;J)V
+PLandroidx/compose/ui/input/pointer/PointerInputChange;-><init>(JJJZFJJZZILjava/util/List;JLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/input/pointer/PointerInputChange;-><init>(JJJZJJZZIJLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/input/pointer/PointerInputChange;->consume()V
+PLandroidx/compose/ui/input/pointer/PointerInputChange;->getHistorical()Ljava/util/List;
+PLandroidx/compose/ui/input/pointer/PointerInputChange;->getId-J3iCeTQ()J
+PLandroidx/compose/ui/input/pointer/PointerInputChange;->getPosition-F1C5BW0()J
+PLandroidx/compose/ui/input/pointer/PointerInputChange;->getPressed()Z
+PLandroidx/compose/ui/input/pointer/PointerInputChange;->getPressure()F
+PLandroidx/compose/ui/input/pointer/PointerInputChange;->getPreviousPosition-F1C5BW0()J
+PLandroidx/compose/ui/input/pointer/PointerInputChange;->getPreviousPressed()Z
+PLandroidx/compose/ui/input/pointer/PointerInputChange;->getType-T8wyACA()I
+PLandroidx/compose/ui/input/pointer/PointerInputChange;->getUptimeMillis()J
+PLandroidx/compose/ui/input/pointer/PointerInputChange;->isConsumed()Z
+PLandroidx/compose/ui/input/pointer/PointerInputChangeEventProducer$PointerInputData;-><init>(JJZI)V
+PLandroidx/compose/ui/input/pointer/PointerInputChangeEventProducer$PointerInputData;-><init>(JJZILkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/input/pointer/PointerInputChangeEventProducer$PointerInputData;->getDown()Z
+PLandroidx/compose/ui/input/pointer/PointerInputChangeEventProducer$PointerInputData;->getPositionOnScreen-F1C5BW0()J
+PLandroidx/compose/ui/input/pointer/PointerInputChangeEventProducer$PointerInputData;->getUptime()J
+PLandroidx/compose/ui/input/pointer/PointerInputChangeEventProducer;->clear()V
+PLandroidx/compose/ui/input/pointer/PointerInputEvent;-><init>(JLjava/util/List;Landroid/view/MotionEvent;)V
+PLandroidx/compose/ui/input/pointer/PointerInputEvent;->getMotionEvent()Landroid/view/MotionEvent;
+PLandroidx/compose/ui/input/pointer/PointerInputEvent;->getPointers()Ljava/util/List;
+PLandroidx/compose/ui/input/pointer/PointerInputEventData;-><init>(JJJJZFIZLjava/util/List;J)V
+PLandroidx/compose/ui/input/pointer/PointerInputEventData;-><init>(JJJJZFIZLjava/util/List;JLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/input/pointer/PointerInputEventData;->getDown()Z
+PLandroidx/compose/ui/input/pointer/PointerInputEventData;->getHistorical()Ljava/util/List;
+PLandroidx/compose/ui/input/pointer/PointerInputEventData;->getId-J3iCeTQ()J
+PLandroidx/compose/ui/input/pointer/PointerInputEventData;->getIssuesEnterExit()Z
+PLandroidx/compose/ui/input/pointer/PointerInputEventData;->getPosition-F1C5BW0()J
+PLandroidx/compose/ui/input/pointer/PointerInputEventData;->getPositionOnScreen-F1C5BW0()J
+PLandroidx/compose/ui/input/pointer/PointerInputEventData;->getPressure()F
+PLandroidx/compose/ui/input/pointer/PointerInputEventData;->getScrollDelta-F1C5BW0()J
+PLandroidx/compose/ui/input/pointer/PointerInputEventData;->getType-T8wyACA()I
+PLandroidx/compose/ui/input/pointer/PointerInputEventData;->getUptime()J
+PLandroidx/compose/ui/input/pointer/PointerInputEventProcessor;->processCancel()V
+PLandroidx/compose/ui/input/pointer/PointerInputEventProcessorKt;->ProcessResult(ZZ)I
+PLandroidx/compose/ui/input/pointer/PointerInputFilter;->getShareWithSiblings()Z
+PLandroidx/compose/ui/input/pointer/PointerKeyboardModifiers;->equals(Ljava/lang/Object;)Z
+PLandroidx/compose/ui/input/pointer/PointerKeyboardModifiers;->equals-impl(ILjava/lang/Object;)Z
+PLandroidx/compose/ui/input/pointer/PointerKeyboardModifiers;->unbox-impl()I
+PLandroidx/compose/ui/input/pointer/PointerType$Companion;-><init>()V
+PLandroidx/compose/ui/input/pointer/PointerType$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/input/pointer/PointerType$Companion;->getMouse-T8wyACA()I
+PLandroidx/compose/ui/input/pointer/PointerType$Companion;->getTouch-T8wyACA()I
+PLandroidx/compose/ui/input/pointer/PointerType;-><clinit>()V
+PLandroidx/compose/ui/input/pointer/PointerType;->access$getMouse$cp()I
+PLandroidx/compose/ui/input/pointer/PointerType;->access$getTouch$cp()I
+PLandroidx/compose/ui/input/pointer/PointerType;->constructor-impl(I)I
+PLandroidx/compose/ui/input/pointer/PointerType;->equals-impl0(II)Z
+PLandroidx/compose/ui/input/pointer/ProcessResult;->constructor-impl(I)I
+PLandroidx/compose/ui/input/pointer/ProcessResult;->getAnyMovementConsumed-impl(I)Z
+PLandroidx/compose/ui/input/pointer/ProcessResult;->getDispatchedToAPointerInputModifier-impl(I)Z
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine$withTimeout$1;-><init>(Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine$withTimeout$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine$withTimeout$job$1;-><init>(JLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;Lkotlin/coroutines/Continuation;)V
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine$withTimeout$job$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine$withTimeout$job$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;->getCurrentEvent()Landroidx/compose/ui/input/pointer/PointerEvent;
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;->getExtendedTouchPadding-NH-jbRc()J
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;->getSize-YbymL2g()J
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;->getViewConfiguration()Landroidx/compose/ui/platform/ViewConfiguration;
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;->withTimeout(JLkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$WhenMappings;-><clinit>()V
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;->access$getBoundsSize$p(Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;)J
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;->access$getCurrentEvent$p(Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;)Landroidx/compose/ui/input/pointer/PointerEvent;
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;->getCoroutineScope()Lkotlinx/coroutines/CoroutineScope;
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;->getExtendedTouchPadding-NH-jbRc()J
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;->getInterceptOutOfBoundsChildEvents()Z
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;->getViewConfiguration()Landroidx/compose/ui/platform/ViewConfiguration;
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;->onCancel()V
+PLandroidx/compose/ui/input/pointer/SuspendingPointerInputFilter;->toSize-XkaWNTQ(J)J
+PLandroidx/compose/ui/input/pointer/util/Matrix;-><init>(II)V
+PLandroidx/compose/ui/input/pointer/util/Matrix;->get(II)F
+PLandroidx/compose/ui/input/pointer/util/Matrix;->getRow(I)Landroidx/compose/ui/input/pointer/util/Vector;
+PLandroidx/compose/ui/input/pointer/util/Matrix;->set(IIF)V
+PLandroidx/compose/ui/input/pointer/util/PointAtTime;-><init>(JJ)V
+PLandroidx/compose/ui/input/pointer/util/PointAtTime;-><init>(JJLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/input/pointer/util/PointAtTime;->getPoint-F1C5BW0()J
+PLandroidx/compose/ui/input/pointer/util/PointAtTime;->getTime()J
+PLandroidx/compose/ui/input/pointer/util/PolynomialFit;-><init>(Ljava/util/List;F)V
+PLandroidx/compose/ui/input/pointer/util/PolynomialFit;->getCoefficients()Ljava/util/List;
+PLandroidx/compose/ui/input/pointer/util/PolynomialFit;->getConfidence()F
+PLandroidx/compose/ui/input/pointer/util/Vector;-><init>(I)V
+PLandroidx/compose/ui/input/pointer/util/Vector;->get(I)F
+PLandroidx/compose/ui/input/pointer/util/Vector;->norm()F
+PLandroidx/compose/ui/input/pointer/util/Vector;->set(IF)V
+PLandroidx/compose/ui/input/pointer/util/Vector;->times(Landroidx/compose/ui/input/pointer/util/Vector;)F
+PLandroidx/compose/ui/input/pointer/util/VelocityEstimate$Companion;-><init>()V
+PLandroidx/compose/ui/input/pointer/util/VelocityEstimate$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/input/pointer/util/VelocityEstimate;-><clinit>()V
+PLandroidx/compose/ui/input/pointer/util/VelocityEstimate;-><init>(JFJJ)V
+PLandroidx/compose/ui/input/pointer/util/VelocityEstimate;-><init>(JFJJLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/input/pointer/util/VelocityEstimate;->getPixelsPerSecond-F1C5BW0()J
+PLandroidx/compose/ui/input/pointer/util/VelocityTracker;->addPosition-Uv8p0NA(JJ)V
+PLandroidx/compose/ui/input/pointer/util/VelocityTracker;->calculateVelocity-9UxMQ8M()J
+PLandroidx/compose/ui/input/pointer/util/VelocityTracker;->getCurrentPointerPositionAccumulator-F1C5BW0$ui_release()J
+PLandroidx/compose/ui/input/pointer/util/VelocityTracker;->getVelocityEstimate()Landroidx/compose/ui/input/pointer/util/VelocityEstimate;
+PLandroidx/compose/ui/input/pointer/util/VelocityTracker;->resetTracking()V
+PLandroidx/compose/ui/input/pointer/util/VelocityTracker;->setCurrentPointerPositionAccumulator-k-4lQ0M$ui_release(J)V
+PLandroidx/compose/ui/input/pointer/util/VelocityTrackerKt;->addPointerInputChange(Landroidx/compose/ui/input/pointer/util/VelocityTracker;Landroidx/compose/ui/input/pointer/PointerInputChange;)V
+PLandroidx/compose/ui/input/pointer/util/VelocityTrackerKt;->polyFitLeastSquares(Ljava/util/List;Ljava/util/List;I)Landroidx/compose/ui/input/pointer/util/PolynomialFit;
+PLandroidx/compose/ui/layout/LayoutId;-><init>(Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
+PLandroidx/compose/ui/layout/LayoutId;->getLayoutId()Ljava/lang/Object;
+PLandroidx/compose/ui/layout/LayoutId;->modifyParentData(Landroidx/compose/ui/unit/Density;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/layout/LayoutIdKt;->getLayoutId(Landroidx/compose/ui/layout/Measurable;)Ljava/lang/Object;
+PLandroidx/compose/ui/layout/LayoutIdKt;->layoutId(Landroidx/compose/ui/Modifier;Ljava/lang/Object;)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/ui/layout/LayoutModifierImpl;-><init>(Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;)V
+PLandroidx/compose/ui/layout/LayoutModifierImpl;->equals(Ljava/lang/Object;)Z
+PLandroidx/compose/ui/layout/LayoutModifierImpl;->measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult;
+PLandroidx/compose/ui/layout/LayoutModifierKt;->layout(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function3;)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$NodeState;->getForceRecompose()Z
+PLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$NodeState;->getSlotId()Ljava/lang/Object;
+PLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$NodeState;->setActive(Z)V
+PLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$NodeState;->setSlotId(Ljava/lang/Object;)V
+PLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$Scope;->getDensity()F
+PLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$precompose$1;-><init>(Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState;Ljava/lang/Object;)V
+PLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$precompose$1;->dispose()V
+PLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$precompose$1;->getPlaceablesCount()I
+PLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState$precompose$1;->premeasure-0kLqBqw(IJ)V
+PLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->access$getPrecomposeMap$p(Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState;)Ljava/util/Map;
+PLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->access$getRoot$p(Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState;)Landroidx/compose/ui/node/LayoutNode;
+PLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->disposeCurrentNodes()V
+PLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->getSlotIdAtIndex(I)Ljava/lang/Object;
+PLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->move$default(Landroidx/compose/ui/layout/LayoutNodeSubcompositionsState;IIIILjava/lang/Object;)V
+PLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->move(III)V
+PLandroidx/compose/ui/layout/LayoutNodeSubcompositionsState;->precompose(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Landroidx/compose/ui/layout/SubcomposeLayoutState$PrecomposedSlotHandle;
+PLandroidx/compose/ui/layout/OnRemeasuredModifierKt;->onSizeChanged(Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/Modifier;
+PLandroidx/compose/ui/layout/OnSizeChangedModifier;-><init>(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)V
+PLandroidx/compose/ui/layout/OnSizeChangedModifier;->equals(Ljava/lang/Object;)Z
+PLandroidx/compose/ui/layout/OnSizeChangedModifier;->onRemeasured-ozmzZPI(J)V
+PLandroidx/compose/ui/layout/Placeable$PlacementScope;->placeWithLayer-aW-9-wM$default(Landroidx/compose/ui/layout/Placeable$PlacementScope;Landroidx/compose/ui/layout/Placeable;JFLkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
+PLandroidx/compose/ui/layout/Placeable;->getMeasuredHeight()I
+PLandroidx/compose/ui/layout/SubcomposeLayoutKt$SubcomposeLayout$5$1$invoke$$inlined$onDispose$1;->dispose()V
+PLandroidx/compose/ui/layout/SubcomposeLayoutKt$SubcomposeLayout$6;-><init>(Landroidx/compose/ui/layout/SubcomposeLayoutState;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function2;II)V
+PLandroidx/compose/ui/layout/SubcomposeLayoutState;->disposeCurrentNodes$ui_release()V
+PLandroidx/compose/ui/layout/SubcomposeLayoutState;->precompose(Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Landroidx/compose/ui/layout/SubcomposeLayoutState$PrecomposedSlotHandle;
+PLandroidx/compose/ui/layout/SubcomposeSlotReusePolicy$SlotIdsSet;->add$ui_release(Ljava/lang/Object;)Z
+PLandroidx/compose/ui/layout/SubcomposeSlotReusePolicy$SlotIdsSet;->clear()V
+PLandroidx/compose/ui/layout/SubcomposeSlotReusePolicy$SlotIdsSet;->contains(Ljava/lang/Object;)Z
+PLandroidx/compose/ui/layout/SubcomposeSlotReusePolicy$SlotIdsSet;->iterator()Ljava/util/Iterator;
+PLandroidx/compose/ui/node/AlignmentLines$recalculate$1;-><init>(Landroidx/compose/ui/node/AlignmentLines;)V
+PLandroidx/compose/ui/node/AlignmentLines$recalculate$1;->invoke(Landroidx/compose/ui/node/AlignmentLinesOwner;)V
+PLandroidx/compose/ui/node/AlignmentLines$recalculate$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/node/AlignmentLines;->access$addAlignmentLine(Landroidx/compose/ui/node/AlignmentLines;Landroidx/compose/ui/layout/AlignmentLine;ILandroidx/compose/ui/node/NodeCoordinator;)V
+PLandroidx/compose/ui/node/AlignmentLines;->access$getAlignmentLineMap$p(Landroidx/compose/ui/node/AlignmentLines;)Ljava/util/Map;
+PLandroidx/compose/ui/node/AlignmentLines;->addAlignmentLine(Landroidx/compose/ui/layout/AlignmentLine;ILandroidx/compose/ui/node/NodeCoordinator;)V
+PLandroidx/compose/ui/node/AlignmentLines;->getAlignmentLinesOwner()Landroidx/compose/ui/node/AlignmentLinesOwner;
+PLandroidx/compose/ui/node/AlignmentLines;->getLastCalculation()Ljava/util/Map;
+PLandroidx/compose/ui/node/AlignmentLines;->recalculate()V
+PLandroidx/compose/ui/node/BackwardsCompatNode;->interceptOutOfBoundsChildEvents()Z
+PLandroidx/compose/ui/node/BackwardsCompatNode;->isValid()Z
+PLandroidx/compose/ui/node/BackwardsCompatNode;->onCancelPointerInput()V
+PLandroidx/compose/ui/node/BackwardsCompatNode;->onDetach()V
+PLandroidx/compose/ui/node/BackwardsCompatNode;->sharePointerInputWithSiblings()Z
+PLandroidx/compose/ui/node/BackwardsCompatNodeKt$updateModifierLocalConsumer$1;->invoke(Landroidx/compose/ui/node/BackwardsCompatNode;)V
+PLandroidx/compose/ui/node/BackwardsCompatNodeKt$updateModifierLocalConsumer$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/node/DistanceAndInLayer;->compareTo-S_HNhKs(JJ)I
+PLandroidx/compose/ui/node/DistanceAndInLayer;->constructor-impl(J)J
+PLandroidx/compose/ui/node/DistanceAndInLayer;->getDistance-impl(J)F
+PLandroidx/compose/ui/node/DistanceAndInLayer;->isInLayer-impl(J)Z
+PLandroidx/compose/ui/node/HitTestResult;->access$getHitDepth$p(Landroidx/compose/ui/node/HitTestResult;)I
+PLandroidx/compose/ui/node/HitTestResult;->access$setHitDepth$p(Landroidx/compose/ui/node/HitTestResult;I)V
+PLandroidx/compose/ui/node/HitTestResult;->clear()V
+PLandroidx/compose/ui/node/HitTestResult;->ensureContainerSize()V
+PLandroidx/compose/ui/node/HitTestResult;->findBestHitDistance-ptXAw2c()J
+PLandroidx/compose/ui/node/HitTestResult;->get(I)Ljava/lang/Object;
+PLandroidx/compose/ui/node/HitTestResult;->getSize()I
+PLandroidx/compose/ui/node/HitTestResult;->hasHit()Z
+PLandroidx/compose/ui/node/HitTestResult;->hit(Ljava/lang/Object;ZLkotlin/jvm/functions/Function0;)V
+PLandroidx/compose/ui/node/HitTestResult;->hitInMinimumTouchTarget(Ljava/lang/Object;FZLkotlin/jvm/functions/Function0;)V
+PLandroidx/compose/ui/node/HitTestResult;->isEmpty()Z
+PLandroidx/compose/ui/node/HitTestResult;->isHitInMinimumTouchTargetBetter(FZ)Z
+PLandroidx/compose/ui/node/HitTestResult;->resizeToHitDepth()V
+PLandroidx/compose/ui/node/HitTestResult;->size()I
+PLandroidx/compose/ui/node/HitTestResultKt;->DistanceAndInLayer(FZ)J
+PLandroidx/compose/ui/node/HitTestResultKt;->access$DistanceAndInLayer(FZ)J
+PLandroidx/compose/ui/node/InnerNodeCoordinator;->calculateAlignmentLine(Landroidx/compose/ui/layout/AlignmentLine;)I
+PLandroidx/compose/ui/node/LayoutModifierNode;->forceRemeasure()V
+PLandroidx/compose/ui/node/LayoutModifierNodeCoordinator;->calculateAlignmentLine(Landroidx/compose/ui/layout/AlignmentLine;)I
+PLandroidx/compose/ui/node/LayoutModifierNodeCoordinatorKt;->access$calculateAlignmentAndPlaceChildAsNeeded(Landroidx/compose/ui/node/LookaheadCapablePlaceable;Landroidx/compose/ui/layout/AlignmentLine;)I
+PLandroidx/compose/ui/node/LayoutModifierNodeCoordinatorKt;->calculateAlignmentAndPlaceChildAsNeeded(Landroidx/compose/ui/node/LookaheadCapablePlaceable;Landroidx/compose/ui/layout/AlignmentLine;)I
+PLandroidx/compose/ui/node/LayoutNode$WhenMappings;-><clinit>()V
+PLandroidx/compose/ui/node/LayoutNode;->forceRemeasure()V
+PLandroidx/compose/ui/node/LayoutNode;->getViewConfiguration()Landroidx/compose/ui/platform/ViewConfiguration;
+PLandroidx/compose/ui/node/LayoutNode;->hitTest-M_7yMNQ$ui_release$default(Landroidx/compose/ui/node/LayoutNode;JLandroidx/compose/ui/node/HitTestResult;ZZILjava/lang/Object;)V
+PLandroidx/compose/ui/node/LayoutNode;->hitTest-M_7yMNQ$ui_release(JLandroidx/compose/ui/node/HitTestResult;ZZ)V
+PLandroidx/compose/ui/node/LayoutNode;->markSubtreeAsNotPlaced()V
+PLandroidx/compose/ui/node/LayoutNode;->move$ui_release(III)V
+PLandroidx/compose/ui/node/LayoutNode;->onChildRemoved(Landroidx/compose/ui/node/LayoutNode;)V
+PLandroidx/compose/ui/node/LayoutNode;->removeAll$ui_release()V
+PLandroidx/compose/ui/node/LayoutNode;->removeAt$ui_release(II)V
+PLandroidx/compose/ui/node/LayoutNode;->rescheduleRemeasureOrRelayout$ui_release(Landroidx/compose/ui/node/LayoutNode;)V
+PLandroidx/compose/ui/node/LayoutNodeAlignmentLines;->calculatePositionInParent-R5De75A(Landroidx/compose/ui/node/NodeCoordinator;J)J
+PLandroidx/compose/ui/node/LayoutNodeAlignmentLines;->getAlignmentLinesMap(Landroidx/compose/ui/node/NodeCoordinator;)Ljava/util/Map;
+PLandroidx/compose/ui/node/LayoutNodeDrawScope;->performDraw(Landroidx/compose/ui/node/DrawModifierNode;Landroidx/compose/ui/graphics/Canvas;)V
+PLandroidx/compose/ui/node/LayoutNodeDrawScope;->roundToPx-0680j_4(F)I
+PLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->calculateAlignmentLines()Ljava/util/Map;
+PLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->get(Landroidx/compose/ui/layout/AlignmentLine;)I
+PLandroidx/compose/ui/node/LayoutNodeLayoutDelegate$MeasurePassDelegate;->isPlaced()Z
+PLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->getCoordinatesAccessedDuringPlacement()Z
+PLandroidx/compose/ui/node/LayoutNodeLayoutDelegate;->resetAlignmentLines()V
+PLandroidx/compose/ui/node/LookaheadCapablePlaceable;->get(Landroidx/compose/ui/layout/AlignmentLine;)I
+PLandroidx/compose/ui/node/LookaheadCapablePlaceable;->setShallowPlacing$ui_release(Z)V
+PLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->doLookaheadRemeasure-sdFAvZA(Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/ui/unit/Constraints;)Z
+PLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->measureAndLayout-0kLqBqw(Landroidx/compose/ui/node/LayoutNode;J)V
+PLandroidx/compose/ui/node/MeasureAndLayoutDelegate;->onNodeDetached(Landroidx/compose/ui/node/LayoutNode;)V
+PLandroidx/compose/ui/node/MutableVectorWithMutationTracking;->clear()V
+PLandroidx/compose/ui/node/MutableVectorWithMutationTracking;->get(I)Ljava/lang/Object;
+PLandroidx/compose/ui/node/MutableVectorWithMutationTracking;->getSize()I
+PLandroidx/compose/ui/node/MutableVectorWithMutationTracking;->removeAt(I)Ljava/lang/Object;
+PLandroidx/compose/ui/node/NodeChain$Differ;->remove(I)V
+PLandroidx/compose/ui/node/NodeChain;->access$disposeAndRemoveNode(Landroidx/compose/ui/node/NodeChain;Landroidx/compose/ui/Modifier$Node;)Landroidx/compose/ui/Modifier$Node;
+PLandroidx/compose/ui/node/NodeChain;->disposeAndRemoveNode(Landroidx/compose/ui/Modifier$Node;)Landroidx/compose/ui/Modifier$Node;
+PLandroidx/compose/ui/node/NodeChain;->removeNode(Landroidx/compose/ui/Modifier$Node;)Landroidx/compose/ui/Modifier$Node;
+PLandroidx/compose/ui/node/NodeCoordinator$Companion$PointerInputSource$1;->childHitTest-YqVAtuI(Landroidx/compose/ui/node/LayoutNode;JLandroidx/compose/ui/node/HitTestResult;ZZ)V
+PLandroidx/compose/ui/node/NodeCoordinator$Companion$PointerInputSource$1;->entityType-OLwlOKw()I
+PLandroidx/compose/ui/node/NodeCoordinator$Companion$PointerInputSource$1;->interceptOutOfBoundsChildEvents(Landroidx/compose/ui/node/DelegatableNode;)Z
+PLandroidx/compose/ui/node/NodeCoordinator$Companion$PointerInputSource$1;->interceptOutOfBoundsChildEvents(Landroidx/compose/ui/node/PointerInputModifierNode;)Z
+PLandroidx/compose/ui/node/NodeCoordinator$Companion$PointerInputSource$1;->shouldHitTestChildren(Landroidx/compose/ui/node/LayoutNode;)Z
+PLandroidx/compose/ui/node/NodeCoordinator$Companion;->getPointerInputSource()Landroidx/compose/ui/node/NodeCoordinator$HitTestSource;
+PLandroidx/compose/ui/node/NodeCoordinator$hit$1;-><init>(Landroidx/compose/ui/node/NodeCoordinator;Landroidx/compose/ui/node/DelegatableNode;Landroidx/compose/ui/node/NodeCoordinator$HitTestSource;JLandroidx/compose/ui/node/HitTestResult;ZZ)V
+PLandroidx/compose/ui/node/NodeCoordinator$hit$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/ui/node/NodeCoordinator$hit$1;->invoke()V
+PLandroidx/compose/ui/node/NodeCoordinator$hitNear$1;-><init>(Landroidx/compose/ui/node/NodeCoordinator;Landroidx/compose/ui/node/DelegatableNode;Landroidx/compose/ui/node/NodeCoordinator$HitTestSource;JLandroidx/compose/ui/node/HitTestResult;ZZF)V
+PLandroidx/compose/ui/node/NodeCoordinator$hitNear$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/ui/node/NodeCoordinator$hitNear$1;->invoke()V
+PLandroidx/compose/ui/node/NodeCoordinator;->access$getPointerInputSource$cp()Landroidx/compose/ui/node/NodeCoordinator$HitTestSource;
+PLandroidx/compose/ui/node/NodeCoordinator;->access$hit-1hIXUjU(Landroidx/compose/ui/node/NodeCoordinator;Landroidx/compose/ui/node/DelegatableNode;Landroidx/compose/ui/node/NodeCoordinator$HitTestSource;JLandroidx/compose/ui/node/HitTestResult;ZZ)V
+PLandroidx/compose/ui/node/NodeCoordinator;->access$hitNear-JHbHoSQ(Landroidx/compose/ui/node/NodeCoordinator;Landroidx/compose/ui/node/DelegatableNode;Landroidx/compose/ui/node/NodeCoordinator$HitTestSource;JLandroidx/compose/ui/node/HitTestResult;ZZF)V
+PLandroidx/compose/ui/node/NodeCoordinator;->calculateMinimumTouchTargetPadding-E7KxVPU(J)J
+PLandroidx/compose/ui/node/NodeCoordinator;->distanceInMinimumTouchTarget-tz77jQw(JJ)F
+PLandroidx/compose/ui/node/NodeCoordinator;->getChild()Landroidx/compose/ui/node/LookaheadCapablePlaceable;
+PLandroidx/compose/ui/node/NodeCoordinator;->getHasMeasureResult()Z
+PLandroidx/compose/ui/node/NodeCoordinator;->getMinimumTouchTargetSize-NH-jbRc()J
+PLandroidx/compose/ui/node/NodeCoordinator;->headUnchecked-H91voCI(I)Ljava/lang/Object;
+PLandroidx/compose/ui/node/NodeCoordinator;->hit-1hIXUjU(Landroidx/compose/ui/node/DelegatableNode;Landroidx/compose/ui/node/NodeCoordinator$HitTestSource;JLandroidx/compose/ui/node/HitTestResult;ZZ)V
+PLandroidx/compose/ui/node/NodeCoordinator;->hitNear-JHbHoSQ(Landroidx/compose/ui/node/DelegatableNode;Landroidx/compose/ui/node/NodeCoordinator$HitTestSource;JLandroidx/compose/ui/node/HitTestResult;ZZF)V
+PLandroidx/compose/ui/node/NodeCoordinator;->hitTest-YqVAtuI(Landroidx/compose/ui/node/NodeCoordinator$HitTestSource;JLandroidx/compose/ui/node/HitTestResult;ZZ)V
+PLandroidx/compose/ui/node/NodeCoordinator;->isPointerInBounds-k-4lQ0M(J)Z
+PLandroidx/compose/ui/node/NodeCoordinator;->isValid()Z
+PLandroidx/compose/ui/node/NodeCoordinator;->offsetFromEdge-MK-Hz9U(J)J
+PLandroidx/compose/ui/node/NodeCoordinator;->replace$ui_release()V
+PLandroidx/compose/ui/node/NodeCoordinator;->shouldSharePointerInputWithSiblings()Z
+PLandroidx/compose/ui/node/NodeCoordinator;->speculativeHit-JHbHoSQ(Landroidx/compose/ui/node/DelegatableNode;Landroidx/compose/ui/node/NodeCoordinator$HitTestSource;JLandroidx/compose/ui/node/HitTestResult;ZZF)V
+PLandroidx/compose/ui/node/NodeCoordinator;->toCoordinator(Landroidx/compose/ui/layout/LayoutCoordinates;)Landroidx/compose/ui/node/NodeCoordinator;
+PLandroidx/compose/ui/node/NodeCoordinator;->toParentPosition-MK-Hz9U(J)J
+PLandroidx/compose/ui/node/NodeCoordinator;->withinLayerBounds-k-4lQ0M(J)Z
+PLandroidx/compose/ui/node/NodeCoordinatorKt;->access$nextUncheckedUntil-hw7D004(Landroidx/compose/ui/node/DelegatableNode;II)Ljava/lang/Object;
+PLandroidx/compose/ui/node/NodeCoordinatorKt;->nextUncheckedUntil-hw7D004(Landroidx/compose/ui/node/DelegatableNode;II)Ljava/lang/Object;
+PLandroidx/compose/ui/node/NodeKindKt;->autoInvalidateRemovedNode(Landroidx/compose/ui/Modifier$Node;)V
+PLandroidx/compose/ui/node/OwnerSnapshotObserver$clearInvalidObservations$1;-><clinit>()V
+PLandroidx/compose/ui/node/OwnerSnapshotObserver$clearInvalidObservations$1;-><init>()V
+PLandroidx/compose/ui/node/OwnerSnapshotObserver$clearInvalidObservations$1;->invoke(Ljava/lang/Object;)Ljava/lang/Boolean;
+PLandroidx/compose/ui/node/OwnerSnapshotObserver$clearInvalidObservations$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/node/OwnerSnapshotObserver;->clearInvalidObservations$ui_release()V
+PLandroidx/compose/ui/node/OwnerSnapshotObserver;->stopObserving$ui_release()V
+PLandroidx/compose/ui/node/PointerInputModifierNodeKt;->getLayoutCoordinates(Landroidx/compose/ui/node/PointerInputModifierNode;)Landroidx/compose/ui/layout/LayoutCoordinates;
+PLandroidx/compose/ui/node/UiApplier;->onClear()V
+PLandroidx/compose/ui/node/UiApplier;->remove(II)V
+PLandroidx/compose/ui/platform/AbstractComposeView;->disposeComposition()V
+PLandroidx/compose/ui/platform/AbstractComposeView;->shouldDelayChildPressedState()Z
+PLandroidx/compose/ui/platform/AndroidComposeView$scrollContainerInfo$1$value$1;->canScrollHorizontally()Z
+PLandroidx/compose/ui/platform/AndroidComposeView$scrollContainerInfo$1$value$1;->canScrollVertically()Z
+PLandroidx/compose/ui/platform/AndroidComposeView$scrollContainerInfo$1$value$1;->isInScrollableViewGroup(Landroid/view/View;)Z
+PLandroidx/compose/ui/platform/AndroidComposeView;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z
+PLandroidx/compose/ui/platform/AndroidComposeView;->hasChangedDevices(Landroid/view/MotionEvent;Landroid/view/MotionEvent;)Z
+PLandroidx/compose/ui/platform/AndroidComposeView;->isBadMotionEvent(Landroid/view/MotionEvent;)Z
+PLandroidx/compose/ui/platform/AndroidComposeView;->isInBounds(Landroid/view/MotionEvent;)Z
+PLandroidx/compose/ui/platform/AndroidComposeView;->isPositionChanged(Landroid/view/MotionEvent;)Z
+PLandroidx/compose/ui/platform/AndroidComposeView;->measureAndLayout-0kLqBqw(Landroidx/compose/ui/node/LayoutNode;J)V
+PLandroidx/compose/ui/platform/AndroidComposeView;->onDetach(Landroidx/compose/ui/node/LayoutNode;)V
+PLandroidx/compose/ui/platform/AndroidComposeView;->onDetachedFromWindow()V
+PLandroidx/compose/ui/platform/AndroidComposeView;->recalculateWindowPosition()V
+PLandroidx/compose/ui/platform/AndroidComposeView;->recalculateWindowPosition(Landroid/view/MotionEvent;)V
+PLandroidx/compose/ui/platform/AndroidComposeView;->recalculateWindowViewTransforms()V
+PLandroidx/compose/ui/platform/AndroidComposeView;->requestClearInvalidObservations()V
+PLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$1;->onViewDetachedFromWindow(Landroid/view/View;)V
+PLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat$boundsUpdatesEventLoop$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;->access$getHandler$p(Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;)Landroid/os/Handler;
+PLandroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;->access$getSemanticsChangeChecker$p(Landroidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat;)Ljava/lang/Runnable;
+PLandroidx/compose/ui/platform/AndroidComposeViewVerificationHelperMethodsN;-><clinit>()V
+PLandroidx/compose/ui/platform/AndroidComposeViewVerificationHelperMethodsN;-><init>()V
+PLandroidx/compose/ui/platform/AndroidComposeViewVerificationHelperMethodsN;->setPointerIcon(Landroid/view/View;Landroidx/compose/ui/input/pointer/PointerIcon;)V
+PLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$2$invoke$$inlined$onDispose$1;->dispose()V
+PLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$obtainImageVectorCache$1$invoke$$inlined$onDispose$1;->dispose()V
+PLandroidx/compose/ui/platform/AndroidCompositionLocals_androidKt$obtainImageVectorCache$callbacks$1$1;->onTrimMemory(I)V
+PLandroidx/compose/ui/platform/AndroidViewConfiguration;->getTouchSlop()F
+PLandroidx/compose/ui/platform/DisposableSaveableStateRegistry;->dispose()V
+PLandroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt$DisposableSaveableStateRegistry$1;->invoke()Ljava/lang/Object;
+PLandroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt$DisposableSaveableStateRegistry$1;->invoke()V
+PLandroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt$DisposableSaveableStateRegistry$registered$1;->saveState()Landroid/os/Bundle;
+PLandroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt;->access$toBundle(Ljava/util/Map;)Landroid/os/Bundle;
+PLandroidx/compose/ui/platform/DisposableSaveableStateRegistry_androidKt;->toBundle(Ljava/util/Map;)Landroid/os/Bundle;
+PLandroidx/compose/ui/platform/InvertMatrixKt;->invertTo-JiSxe2E([F[F)Z
+PLandroidx/compose/ui/platform/OutlineResolver;->isInOutline-k-4lQ0M(J)Z
+PLandroidx/compose/ui/platform/OutlineResolver;->updateCacheWithRect(Landroidx/compose/ui/geometry/Rect;)V
+PLandroidx/compose/ui/platform/RenderNodeApi29;->getClipToBounds()Z
+PLandroidx/compose/ui/platform/RenderNodeApi29;->getMatrix(Landroid/graphics/Matrix;)V
+PLandroidx/compose/ui/platform/RenderNodeLayer$Companion$getMatrix$1;->invoke(Landroidx/compose/ui/platform/DeviceRenderNode;Landroid/graphics/Matrix;)V
+PLandroidx/compose/ui/platform/RenderNodeLayer$Companion$getMatrix$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/platform/RenderNodeLayer;->isInLayer-k-4lQ0M(J)Z
+PLandroidx/compose/ui/platform/ShapeContainingUtilKt;->isInOutline(Landroidx/compose/ui/graphics/Outline;FFLandroidx/compose/ui/graphics/Path;Landroidx/compose/ui/graphics/Path;)Z
+PLandroidx/compose/ui/platform/ShapeContainingUtilKt;->isInRectangle(Landroidx/compose/ui/geometry/Rect;FF)Z
+PLandroidx/compose/ui/platform/ShapeContainingUtilKt;->isWithinEllipse-VE1yxkc(FFJFF)Z
+PLandroidx/compose/ui/platform/ViewCompositionStrategy$DisposeOnDetachedFromWindowOrReleasedFromPool$installFor$listener$1;->onViewDetachedFromWindow(Landroid/view/View;)V
+PLandroidx/compose/ui/platform/WindowInfoImpl;->setKeyboardModifiers-5xRPYO0(I)V
+PLandroidx/compose/ui/platform/WindowRecomposerPolicy$createAndInstallWindowRecomposer$1;->onViewDetachedFromWindow(Landroid/view/View;)V
+PLandroidx/compose/ui/platform/WindowRecomposer_androidKt$createLifecycleAwareWindowRecomposer$1;->onViewDetachedFromWindow(Landroid/view/View;)V
+PLandroidx/compose/ui/platform/WrappedComposition;->dispose()V
+PLandroidx/compose/ui/res/ImageVectorCache;->clear()V
+PLandroidx/compose/ui/semantics/CollectionInfo;-><clinit>()V
+PLandroidx/compose/ui/semantics/CollectionInfo;-><init>(II)V
+PLandroidx/compose/ui/semantics/Role$Companion;->getImage-o7Vup1c()I
+PLandroidx/compose/ui/semantics/Role;->access$getImage$cp()I
+PLandroidx/compose/ui/semantics/ScrollAxisRange;-><clinit>()V
+PLandroidx/compose/ui/semantics/ScrollAxisRange;-><init>(Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Z)V
+PLandroidx/compose/ui/semantics/SemanticsActions;->getScrollBy()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+PLandroidx/compose/ui/semantics/SemanticsActions;->getScrollToIndex()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+PLandroidx/compose/ui/semantics/SemanticsProperties;->getIndexForKey()Landroidx/compose/ui/semantics/SemanticsPropertyKey;
+PLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->indexForKey(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Lkotlin/jvm/functions/Function1;)V
+PLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->scrollBy$default(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V
+PLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->scrollBy(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)V
+PLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->scrollToIndex$default(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
+PLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->scrollToIndex(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
+PLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->setCollectionInfo(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Landroidx/compose/ui/semantics/CollectionInfo;)V
+PLandroidx/compose/ui/semantics/SemanticsPropertiesKt;->setVerticalScrollAxisRange(Landroidx/compose/ui/semantics/SemanticsPropertyReceiver;Landroidx/compose/ui/semantics/ScrollAxisRange;)V
+PLandroidx/compose/ui/text/font/GenericFontFamily;->getName()Ljava/lang/String;
+PLandroidx/compose/ui/text/font/PlatformTypefacesApi28;->createNamed-RetOiIg(Landroidx/compose/ui/text/font/GenericFontFamily;Landroidx/compose/ui/text/font/FontWeight;I)Landroid/graphics/Typeface;
+PLandroidx/compose/ui/text/input/TextInputServiceAndroid$textInputCommandEventLoop$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/compose/ui/unit/Constraints;->equals(Ljava/lang/Object;)Z
+PLandroidx/compose/ui/unit/Constraints;->equals-impl(JLjava/lang/Object;)Z
+PLandroidx/compose/ui/unit/Density;->toSize-XkaWNTQ(J)J
+PLandroidx/compose/ui/unit/DpSize$Companion;->getUnspecified-MYxV2XQ()J
+PLandroidx/compose/ui/unit/DpSize;->access$getUnspecified$cp()J
+PLandroidx/compose/ui/unit/IntOffsetKt;->plus-Nv-tHpc(JJ)J
+PLandroidx/compose/ui/unit/IntSize;->unbox-impl()J
+PLandroidx/compose/ui/unit/Velocity$Companion;-><init>()V
+PLandroidx/compose/ui/unit/Velocity$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLandroidx/compose/ui/unit/Velocity$Companion;->getZero-9UxMQ8M()J
+PLandroidx/compose/ui/unit/Velocity;-><clinit>()V
+PLandroidx/compose/ui/unit/Velocity;-><init>(J)V
+PLandroidx/compose/ui/unit/Velocity;->access$getZero$cp()J
+PLandroidx/compose/ui/unit/Velocity;->box-impl(J)Landroidx/compose/ui/unit/Velocity;
+PLandroidx/compose/ui/unit/Velocity;->constructor-impl(J)J
+PLandroidx/compose/ui/unit/Velocity;->copy-OhffZ5M$default(JFFILjava/lang/Object;)J
+PLandroidx/compose/ui/unit/Velocity;->copy-OhffZ5M(JFF)J
+PLandroidx/compose/ui/unit/Velocity;->equals-impl0(JJ)Z
+PLandroidx/compose/ui/unit/Velocity;->getX-impl(J)F
+PLandroidx/compose/ui/unit/Velocity;->getY-impl(J)F
+PLandroidx/compose/ui/unit/Velocity;->minus-AH228Gc(JJ)J
+PLandroidx/compose/ui/unit/Velocity;->plus-AH228Gc(JJ)J
+PLandroidx/compose/ui/unit/Velocity;->times-adjELrA(JF)J
+PLandroidx/compose/ui/unit/Velocity;->unbox-impl()J
+PLandroidx/compose/ui/unit/VelocityKt;->Velocity(FF)J
+PLandroidx/compose/ui/util/MathHelpersKt;->lerp(FFF)F
+PLandroidx/concurrent/futures/AbstractResolvableFuture$AtomicHelper;-><init>()V
+PLandroidx/concurrent/futures/AbstractResolvableFuture$AtomicHelper;-><init>(Landroidx/concurrent/futures/AbstractResolvableFuture$1;)V
+PLandroidx/concurrent/futures/AbstractResolvableFuture$Listener;-><clinit>()V
+PLandroidx/concurrent/futures/AbstractResolvableFuture$Listener;-><init>(Ljava/lang/Runnable;Ljava/util/concurrent/Executor;)V
+PLandroidx/concurrent/futures/AbstractResolvableFuture$SafeAtomicHelper;-><init>(Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater;Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater;Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater;Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater;Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater;)V
+PLandroidx/concurrent/futures/AbstractResolvableFuture$SafeAtomicHelper;->casListeners(Landroidx/concurrent/futures/AbstractResolvableFuture;Landroidx/concurrent/futures/AbstractResolvableFuture$Listener;Landroidx/concurrent/futures/AbstractResolvableFuture$Listener;)Z
+PLandroidx/concurrent/futures/AbstractResolvableFuture$SafeAtomicHelper;->casValue(Landroidx/concurrent/futures/AbstractResolvableFuture;Ljava/lang/Object;Ljava/lang/Object;)Z
+PLandroidx/concurrent/futures/AbstractResolvableFuture$SafeAtomicHelper;->casWaiters(Landroidx/concurrent/futures/AbstractResolvableFuture;Landroidx/concurrent/futures/AbstractResolvableFuture$Waiter;Landroidx/concurrent/futures/AbstractResolvableFuture$Waiter;)Z
+PLandroidx/concurrent/futures/AbstractResolvableFuture$Waiter;-><clinit>()V
+PLandroidx/concurrent/futures/AbstractResolvableFuture$Waiter;-><init>(Z)V
+PLandroidx/concurrent/futures/AbstractResolvableFuture;-><clinit>()V
+PLandroidx/concurrent/futures/AbstractResolvableFuture;-><init>()V
+PLandroidx/concurrent/futures/AbstractResolvableFuture;->afterDone()V
+PLandroidx/concurrent/futures/AbstractResolvableFuture;->clearListeners(Landroidx/concurrent/futures/AbstractResolvableFuture$Listener;)Landroidx/concurrent/futures/AbstractResolvableFuture$Listener;
+PLandroidx/concurrent/futures/AbstractResolvableFuture;->complete(Landroidx/concurrent/futures/AbstractResolvableFuture;)V
+PLandroidx/concurrent/futures/AbstractResolvableFuture;->releaseWaiters()V
+PLandroidx/concurrent/futures/AbstractResolvableFuture;->set(Ljava/lang/Object;)Z
+PLandroidx/concurrent/futures/ResolvableFuture;-><init>()V
+PLandroidx/concurrent/futures/ResolvableFuture;->create()Landroidx/concurrent/futures/ResolvableFuture;
+PLandroidx/concurrent/futures/ResolvableFuture;->set(Ljava/lang/Object;)Z
+PLandroidx/core/app/ActivityCompat$Api16Impl;->startIntentSenderForResult(Landroid/app/Activity;Landroid/content/IntentSender;ILandroid/content/Intent;IIILandroid/os/Bundle;)V
+PLandroidx/core/app/ActivityCompat;->startIntentSenderForResult(Landroid/app/Activity;Landroid/content/IntentSender;ILandroid/content/Intent;IIILandroid/os/Bundle;)V
+PLandroidx/core/app/ComponentActivity;->dispatchKeyEvent(Landroid/view/KeyEvent;)Z
+PLandroidx/core/app/ComponentActivity;->onSaveInstanceState(Landroid/os/Bundle;)V
+PLandroidx/core/app/ComponentActivity;->superDispatchKeyEvent(Landroid/view/KeyEvent;)Z
+PLandroidx/core/content/ContextCompat;-><clinit>()V
+PLandroidx/core/graphics/Insets;-><clinit>()V
+PLandroidx/core/graphics/Insets;-><init>(IIII)V
+PLandroidx/core/view/KeyEventDispatcher;-><clinit>()V
+PLandroidx/core/view/KeyEventDispatcher;->dispatchBeforeHierarchy(Landroid/view/View;Landroid/view/KeyEvent;)Z
+PLandroidx/core/view/KeyEventDispatcher;->dispatchKeyEvent(Landroidx/core/view/KeyEventDispatcher$Component;Landroid/view/View;Landroid/view/Window$Callback;Landroid/view/KeyEvent;)Z
+PLandroidx/core/view/ViewCompat$Api21Impl$1;-><init>(Landroid/view/View;Landroidx/core/view/OnApplyWindowInsetsListener;)V
+PLandroidx/core/view/ViewCompat$Api21Impl;->setOnApplyWindowInsetsListener(Landroid/view/View;Landroidx/core/view/OnApplyWindowInsetsListener;)V
+PLandroidx/core/view/ViewCompat;->dispatchUnhandledKeyEventBeforeHierarchy(Landroid/view/View;Landroid/view/KeyEvent;)Z
+PLandroidx/core/view/ViewCompat;->setOnApplyWindowInsetsListener(Landroid/view/View;Landroidx/core/view/OnApplyWindowInsetsListener;)V
+PLandroidx/core/view/ViewCompat;->setWindowInsetsAnimationCallback(Landroid/view/View;Landroidx/core/view/WindowInsetsAnimationCompat$Callback;)V
+PLandroidx/core/view/ViewKt$ancestors$1;-><clinit>()V
+PLandroidx/core/view/ViewKt$ancestors$1;-><init>()V
+PLandroidx/core/view/ViewKt$ancestors$1;->invoke(Landroid/view/ViewParent;)Landroid/view/ViewParent;
+PLandroidx/core/view/ViewKt$ancestors$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLandroidx/core/view/ViewKt;->getAncestors(Landroid/view/View;)Lkotlin/sequences/Sequence;
+PLandroidx/core/view/WindowInsetsAnimationCompat$Callback;-><init>(I)V
+PLandroidx/core/view/WindowInsetsAnimationCompat$Callback;->getDispatchMode()I
+PLandroidx/core/view/WindowInsetsAnimationCompat$Impl30$ProxyCallback;-><init>(Landroidx/core/view/WindowInsetsAnimationCompat$Callback;)V
+PLandroidx/core/view/WindowInsetsAnimationCompat$Impl30;->setCallback(Landroid/view/View;Landroidx/core/view/WindowInsetsAnimationCompat$Callback;)V
+PLandroidx/core/view/WindowInsetsAnimationCompat;->setCallback(Landroid/view/View;Landroidx/core/view/WindowInsetsAnimationCompat$Callback;)V
+PLandroidx/core/view/WindowInsetsCompat$Type;->captionBar()I
+PLandroidx/core/view/WindowInsetsCompat$Type;->displayCutout()I
+PLandroidx/core/view/WindowInsetsCompat$Type;->ime()I
+PLandroidx/core/view/WindowInsetsCompat$Type;->mandatorySystemGestures()I
+PLandroidx/core/view/WindowInsetsCompat$Type;->navigationBars()I
+PLandroidx/core/view/WindowInsetsCompat$Type;->statusBars()I
+PLandroidx/core/view/WindowInsetsCompat$Type;->systemBars()I
+PLandroidx/core/view/WindowInsetsCompat$Type;->systemGestures()I
+PLandroidx/core/view/WindowInsetsCompat$Type;->tappableElement()I
+PLandroidx/customview/poolingcontainer/PoolingContainer;->isPoolingContainer(Landroid/view/View;)Z
+PLandroidx/customview/poolingcontainer/PoolingContainer;->isWithinPoolingContainer(Landroid/view/View;)Z
+PLandroidx/emoji2/text/EmojiMetadata;->isDefaultEmoji()Z
+PLandroidx/emoji2/text/EmojiProcessor$ProcessorSm;->isEmojiStyle(I)Z
+PLandroidx/emoji2/text/EmojiProcessor$ProcessorSm;->isTextStyle(I)Z
+PLandroidx/emoji2/text/EmojiProcessor$ProcessorSm;->shouldUseEmojiPresentationStyleForSingleCodepoint()Z
+PLandroidx/emoji2/text/MetadataRepo$Node;->getData()Landroidx/emoji2/text/EmojiMetadata;
+PLandroidx/emoji2/text/flatbuffer/MetadataItem;->emojiStyle()Z
+PLandroidx/lifecycle/DefaultLifecycleObserver;->onDestroy(Landroidx/lifecycle/LifecycleOwner;)V
+PLandroidx/lifecycle/DefaultLifecycleObserver;->onPause(Landroidx/lifecycle/LifecycleOwner;)V
+PLandroidx/lifecycle/DefaultLifecycleObserver;->onStop(Landroidx/lifecycle/LifecycleOwner;)V
+PLandroidx/lifecycle/EmptyActivityLifecycleCallbacks;->onActivityDestroyed(Landroid/app/Activity;)V
+PLandroidx/lifecycle/EmptyActivityLifecycleCallbacks;->onActivityPaused(Landroid/app/Activity;)V
+PLandroidx/lifecycle/EmptyActivityLifecycleCallbacks;->onActivitySaveInstanceState(Landroid/app/Activity;Landroid/os/Bundle;)V
+PLandroidx/lifecycle/EmptyActivityLifecycleCallbacks;->onActivityStopped(Landroid/app/Activity;)V
+PLandroidx/lifecycle/Lifecycle$Event;->downFrom(Landroidx/lifecycle/Lifecycle$State;)Landroidx/lifecycle/Lifecycle$Event;
+PLandroidx/lifecycle/LifecycleDispatcher$DispatcherActivityCallback;->onActivitySaveInstanceState(Landroid/app/Activity;Landroid/os/Bundle;)V
+PLandroidx/lifecycle/LifecycleDispatcher$DispatcherActivityCallback;->onActivityStopped(Landroid/app/Activity;)V
+PLandroidx/lifecycle/LifecycleRegistry;->backwardPass(Landroidx/lifecycle/LifecycleOwner;)V
+PLandroidx/lifecycle/LifecycleRegistry;->markState(Landroidx/lifecycle/Lifecycle$State;)V
+PLandroidx/lifecycle/LifecycleRegistry;->setCurrentState(Landroidx/lifecycle/Lifecycle$State;)V
+PLandroidx/lifecycle/LiveData$LifecycleBoundObserver;->detachObserver()V
+PLandroidx/lifecycle/LiveData;->onInactive()V
+PLandroidx/lifecycle/LiveData;->removeObserver(Landroidx/lifecycle/Observer;)V
+PLandroidx/lifecycle/LiveData;->setValue(Ljava/lang/Object;)V
+PLandroidx/lifecycle/MutableLiveData;->setValue(Ljava/lang/Object;)V
+PLandroidx/lifecycle/ProcessLifecycleOwner$1;->run()V
+PLandroidx/lifecycle/ProcessLifecycleOwner$3;->onActivityPaused(Landroid/app/Activity;)V
+PLandroidx/lifecycle/ProcessLifecycleOwner$3;->onActivityStopped(Landroid/app/Activity;)V
+PLandroidx/lifecycle/ProcessLifecycleOwner;->activityPaused()V
+PLandroidx/lifecycle/ProcessLifecycleOwner;->activityStopped()V
+PLandroidx/lifecycle/ProcessLifecycleOwner;->dispatchPauseIfNeeded()V
+PLandroidx/lifecycle/ProcessLifecycleOwner;->dispatchStopIfNeeded()V
+PLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityDestroyed(Landroid/app/Activity;)V
+PLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityPaused(Landroid/app/Activity;)V
+PLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityPreDestroyed(Landroid/app/Activity;)V
+PLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityPrePaused(Landroid/app/Activity;)V
+PLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityPreStopped(Landroid/app/Activity;)V
+PLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivitySaveInstanceState(Landroid/app/Activity;Landroid/os/Bundle;)V
+PLandroidx/lifecycle/ReportFragment$LifecycleCallbacks;->onActivityStopped(Landroid/app/Activity;)V
+PLandroidx/lifecycle/ReportFragment;->onDestroy()V
+PLandroidx/lifecycle/ReportFragment;->onPause()V
+PLandroidx/lifecycle/ReportFragment;->onStop()V
+PLandroidx/lifecycle/SavedStateHandlesProvider;->saveState()Landroid/os/Bundle;
+PLandroidx/lifecycle/SavedStateHandlesVM;->getHandles()Ljava/util/Map;
+PLandroidx/lifecycle/ViewModel;->clear()V
+PLandroidx/lifecycle/ViewModel;->onCleared()V
+PLandroidx/lifecycle/ViewModelStore;->clear()V
+PLandroidx/profileinstaller/DeviceProfileWriter$$ExternalSyntheticLambda0;-><init>(Landroidx/profileinstaller/DeviceProfileWriter;ILjava/lang/Object;)V
+PLandroidx/profileinstaller/DeviceProfileWriter$$ExternalSyntheticLambda0;->run()V
+PLandroidx/profileinstaller/DeviceProfileWriter;->$r8$lambda$ERhlvXCSfTRq-n5iULYjO-Ntn-w(Landroidx/profileinstaller/DeviceProfileWriter;ILjava/lang/Object;)V
+PLandroidx/profileinstaller/DeviceProfileWriter;-><init>(Landroid/content/res/AssetManager;Ljava/util/concurrent/Executor;Landroidx/profileinstaller/ProfileInstaller$DiagnosticsCallback;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/io/File;)V
+PLandroidx/profileinstaller/DeviceProfileWriter;->desiredVersion()[B
+PLandroidx/profileinstaller/DeviceProfileWriter;->deviceAllowsProfileInstallerAotWrites()Z
+PLandroidx/profileinstaller/DeviceProfileWriter;->lambda$result$0(ILjava/lang/Object;)V
+PLandroidx/profileinstaller/DeviceProfileWriter;->result(ILjava/lang/Object;)V
+PLandroidx/profileinstaller/ProfileInstallReceiver$$ExternalSyntheticLambda0;-><init>()V
+PLandroidx/profileinstaller/ProfileInstallReceiver$$ExternalSyntheticLambda0;->execute(Ljava/lang/Runnable;)V
+PLandroidx/profileinstaller/ProfileInstaller$1;-><init>()V
+PLandroidx/profileinstaller/ProfileInstaller$1;->onResultReceived(ILjava/lang/Object;)V
+PLandroidx/profileinstaller/ProfileInstaller$2;-><init>()V
+PLandroidx/profileinstaller/ProfileInstaller;-><clinit>()V
+PLandroidx/profileinstaller/ProfileInstaller;->hasAlreadyWrittenProfileForThisInstall(Landroid/content/pm/PackageInfo;Ljava/io/File;Landroidx/profileinstaller/ProfileInstaller$DiagnosticsCallback;)Z
+PLandroidx/profileinstaller/ProfileInstaller;->transcodeAndWrite(Landroid/content/res/AssetManager;Ljava/lang/String;Landroid/content/pm/PackageInfo;Ljava/io/File;Ljava/lang/String;Ljava/util/concurrent/Executor;Landroidx/profileinstaller/ProfileInstaller$DiagnosticsCallback;)Z
+PLandroidx/profileinstaller/ProfileInstaller;->writeProfile(Landroid/content/Context;)V
+PLandroidx/profileinstaller/ProfileInstaller;->writeProfile(Landroid/content/Context;Ljava/util/concurrent/Executor;Landroidx/profileinstaller/ProfileInstaller$DiagnosticsCallback;)V
+PLandroidx/profileinstaller/ProfileInstaller;->writeProfile(Landroid/content/Context;Ljava/util/concurrent/Executor;Landroidx/profileinstaller/ProfileInstaller$DiagnosticsCallback;Z)V
+PLandroidx/profileinstaller/ProfileInstallerInitializer$$ExternalSyntheticLambda1;->run()V
+PLandroidx/profileinstaller/ProfileInstallerInitializer$$ExternalSyntheticLambda2;-><init>(Landroid/content/Context;)V
+PLandroidx/profileinstaller/ProfileInstallerInitializer$$ExternalSyntheticLambda2;->run()V
+PLandroidx/profileinstaller/ProfileInstallerInitializer;->$r8$lambda$nkOIpN4NfyreWbcXjHv0xCvwgTY(Landroid/content/Context;)V
+PLandroidx/profileinstaller/ProfileInstallerInitializer;->$r8$lambda$nvFqT5BztGB-MvszW9GUTUoI9rw(Landroid/content/Context;)V
+PLandroidx/profileinstaller/ProfileInstallerInitializer;->lambda$installAfterDelay$1(Landroid/content/Context;)V
+PLandroidx/profileinstaller/ProfileInstallerInitializer;->lambda$writeInBackground$2(Landroid/content/Context;)V
+PLandroidx/profileinstaller/ProfileInstallerInitializer;->writeInBackground(Landroid/content/Context;)V
+PLandroidx/profileinstaller/ProfileVerifier$Api33Impl;->getPackageInfo(Landroid/content/pm/PackageManager;Landroid/content/Context;)Landroid/content/pm/PackageInfo;
+PLandroidx/profileinstaller/ProfileVerifier$Cache;-><init>(IIJJ)V
+PLandroidx/profileinstaller/ProfileVerifier$Cache;->equals(Ljava/lang/Object;)Z
+PLandroidx/profileinstaller/ProfileVerifier$Cache;->readFromFile(Ljava/io/File;)Landroidx/profileinstaller/ProfileVerifier$Cache;
+PLandroidx/profileinstaller/ProfileVerifier$Cache;->writeOnFile(Ljava/io/File;)V
+PLandroidx/profileinstaller/ProfileVerifier$CompilationStatus;-><init>(IZZ)V
+PLandroidx/profileinstaller/ProfileVerifier;-><clinit>()V
+PLandroidx/profileinstaller/ProfileVerifier;->getPackageLastUpdateTime(Landroid/content/Context;)J
+PLandroidx/profileinstaller/ProfileVerifier;->setCompilationStatus(IZZ)Landroidx/profileinstaller/ProfileVerifier$CompilationStatus;
+PLandroidx/profileinstaller/ProfileVerifier;->writeProfileVerification(Landroid/content/Context;Z)Landroidx/profileinstaller/ProfileVerifier$CompilationStatus;
+PLandroidx/savedstate/SavedStateRegistry;->performSave(Landroid/os/Bundle;)V
+PLandroidx/savedstate/SavedStateRegistry;->unregisterSavedStateProvider(Ljava/lang/String;)V
+PLandroidx/savedstate/SavedStateRegistryController;->performSave(Landroid/os/Bundle;)V
+PLcom/android/credentialmanager/CredentialManagerRepo;->getCredentialInitialUiState()Lcom/android/credentialmanager/getflow/GetCredentialUiState;
+PLcom/android/credentialmanager/CredentialManagerRepo;->onCancel()V
+PLcom/android/credentialmanager/CredentialManagerRepo;->onOptionSelected(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Landroid/content/Intent;)V
+PLcom/android/credentialmanager/CredentialSelectorActivity$CredentialManagerBottomSheet$3;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/CredentialSelectorActivity$CredentialManagerBottomSheet$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/CredentialSelectorActivity$CredentialManagerBottomSheet$launcher$1$1;->invoke(Landroidx/activity/result/ActivityResult;)V
+PLcom/android/credentialmanager/CredentialSelectorActivity$CredentialManagerBottomSheet$launcher$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/CredentialSelectorActivity$onCancel$1;->onChanged(Lcom/android/credentialmanager/common/DialogResult;)V
+PLcom/android/credentialmanager/CredentialSelectorActivity$onCancel$1;->onChanged(Ljava/lang/Object;)V
+PLcom/android/credentialmanager/GetFlowUtils$Companion;-><init>()V
+PLcom/android/credentialmanager/GetFlowUtils$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLcom/android/credentialmanager/GetFlowUtils$Companion;->getActionEntryList(Ljava/lang/String;Ljava/util/List;Landroid/graphics/drawable/Drawable;)Ljava/util/List;
+PLcom/android/credentialmanager/GetFlowUtils$Companion;->getAuthenticationEntry(Ljava/lang/String;Ljava/lang/String;Landroid/graphics/drawable/Drawable;Landroid/credentials/ui/Entry;)Lcom/android/credentialmanager/getflow/AuthenticationEntryInfo;
+PLcom/android/credentialmanager/GetFlowUtils$Companion;->getCredentialOptionInfoList(Ljava/lang/String;Ljava/util/List;Landroid/content/Context;)Ljava/util/List;
+PLcom/android/credentialmanager/GetFlowUtils$Companion;->getRemoteEntry(Ljava/lang/String;Landroid/credentials/ui/Entry;)Lcom/android/credentialmanager/getflow/RemoteEntryInfo;
+PLcom/android/credentialmanager/GetFlowUtils$Companion;->toProviderList(Ljava/util/List;Landroid/content/Context;)Ljava/util/List;
+PLcom/android/credentialmanager/GetFlowUtils$Companion;->toRequestDisplayInfo(Landroid/credentials/ui/RequestInfo;Landroid/content/Context;)Lcom/android/credentialmanager/getflow/RequestDisplayInfo;
+PLcom/android/credentialmanager/GetFlowUtils;-><clinit>()V
+PLcom/android/credentialmanager/UserConfigRepo;->setDefaultProvider(Ljava/lang/String;)V
+PLcom/android/credentialmanager/common/DialogResult;-><clinit>()V
+PLcom/android/credentialmanager/common/DialogResult;-><init>(Lcom/android/credentialmanager/common/ResultState;)V
+PLcom/android/credentialmanager/common/DialogResult;->getResultState()Lcom/android/credentialmanager/common/ResultState;
+PLcom/android/credentialmanager/common/ProviderActivityResult;-><clinit>()V
+PLcom/android/credentialmanager/common/ProviderActivityResult;-><init>(ILandroid/content/Intent;)V
+PLcom/android/credentialmanager/common/ProviderActivityResult;->equals(Ljava/lang/Object;)Z
+PLcom/android/credentialmanager/common/ProviderActivityResult;->getData()Landroid/content/Intent;
+PLcom/android/credentialmanager/common/ProviderActivityResult;->getResultCode()I
+PLcom/android/credentialmanager/common/ResultState;->$values()[Lcom/android/credentialmanager/common/ResultState;
+PLcom/android/credentialmanager/common/ResultState;-><clinit>()V
+PLcom/android/credentialmanager/common/ResultState;-><init>(Ljava/lang/String;I)V
+PLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$1$1$1;-><init>(Lcom/android/credentialmanager/common/material/ModalBottomSheetState;Lkotlin/coroutines/Continuation;)V
+PLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$1$1$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$1$1$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$1$1;->invoke()Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/ModalBottomSheetKt$ModalBottomSheetLayout$1$1$1;->invoke()V
+PLcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$dismissModifier$1$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/ModalBottomSheetKt$Scrim$dismissModifier$1$1$1;->invoke-k-4lQ0M(J)V
+PLcom/android/credentialmanager/common/material/ModalBottomSheetKt$rememberModalBottomSheetState$1;->invoke(Lcom/android/credentialmanager/common/material/ModalBottomSheetValue;)Ljava/lang/Boolean;
+PLcom/android/credentialmanager/common/material/ModalBottomSheetKt$rememberModalBottomSheetState$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/ModalBottomSheetState;->hide(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableKt$PreUpPostDownNestedScrollConnection$1$onPostFling$1;-><init>(Lcom/android/credentialmanager/common/material/SwipeableKt$PreUpPostDownNestedScrollConnection$1;Lkotlin/coroutines/Continuation;)V
+PLcom/android/credentialmanager/common/material/SwipeableKt$PreUpPostDownNestedScrollConnection$1$onPostFling$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableKt$PreUpPostDownNestedScrollConnection$1$onPreFling$1;-><init>(Lcom/android/credentialmanager/common/material/SwipeableKt$PreUpPostDownNestedScrollConnection$1;Lkotlin/coroutines/Continuation;)V
+PLcom/android/credentialmanager/common/material/SwipeableKt$PreUpPostDownNestedScrollConnection$1;->onPostFling-RZ2iAVY(JJLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableKt$PreUpPostDownNestedScrollConnection$1;->onPostScroll-DzOQY0M(JJI)J
+PLcom/android/credentialmanager/common/material/SwipeableKt$PreUpPostDownNestedScrollConnection$1;->onPreFling-QWom1Mo(JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableKt$PreUpPostDownNestedScrollConnection$1;->onPreScroll-OzD1aCk(JI)J
+PLcom/android/credentialmanager/common/material/SwipeableKt$PreUpPostDownNestedScrollConnection$1;->toFloat(J)F
+PLcom/android/credentialmanager/common/material/SwipeableKt$PreUpPostDownNestedScrollConnection$1;->toOffset(F)J
+PLcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3$4$1$1;-><init>(Lcom/android/credentialmanager/common/material/SwipeableState;FLkotlin/coroutines/Continuation;)V
+PLcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3$4$1$1;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3$4$1$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3$4$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3$4$1;->invoke(Lkotlinx/coroutines/CoroutineScope;FLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableKt$swipeable$3$4$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState$animateInternalToOffset$2$1;-><init>(Landroidx/compose/foundation/gestures/DragScope;Lkotlin/jvm/internal/Ref$FloatRef;)V
+PLcom/android/credentialmanager/common/material/SwipeableState$animateInternalToOffset$2$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState$animateInternalToOffset$2;-><init>(Lcom/android/credentialmanager/common/material/SwipeableState;FLandroidx/compose/animation/core/AnimationSpec;Lkotlin/coroutines/Continuation;)V
+PLcom/android/credentialmanager/common/material/SwipeableState$animateInternalToOffset$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLcom/android/credentialmanager/common/material/SwipeableState$animateInternalToOffset$2;->invoke(Landroidx/compose/foundation/gestures/DragScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState$animateInternalToOffset$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState$animateInternalToOffset$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState$animateTo$2$emit$1;-><init>(Lcom/android/credentialmanager/common/material/SwipeableState$animateTo$2;Lkotlin/coroutines/Continuation;)V
+PLcom/android/credentialmanager/common/material/SwipeableState$animateTo$2$emit$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState$animateTo$2;-><init>(Ljava/lang/Object;Lcom/android/credentialmanager/common/material/SwipeableState;Landroidx/compose/animation/core/AnimationSpec;)V
+PLcom/android/credentialmanager/common/material/SwipeableState$animateTo$2;->emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState$animateTo$2;->emit(Ljava/util/Map;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState$latestNonEmptyAnchorsFlow$1;->invoke()Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState$latestNonEmptyAnchorsFlow$1;->invoke()Ljava/util/Map;
+PLcom/android/credentialmanager/common/material/SwipeableState$performFling$2;-><init>(Lcom/android/credentialmanager/common/material/SwipeableState;F)V
+PLcom/android/credentialmanager/common/material/SwipeableState$performFling$2;->emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState$performFling$2;->emit(Ljava/util/Map;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState$processNewAnchors$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState$special$$inlined$filter$1$2$1;-><init>(Lcom/android/credentialmanager/common/material/SwipeableState$special$$inlined$filter$1$2;Lkotlin/coroutines/Continuation;)V
+PLcom/android/credentialmanager/common/material/SwipeableState$special$$inlined$filter$1$2$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState$special$$inlined$filter$1$2;-><init>(Lkotlinx/coroutines/flow/FlowCollector;)V
+PLcom/android/credentialmanager/common/material/SwipeableState$special$$inlined$filter$1$2;->emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState$special$$inlined$filter$1;->collect(Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState;->access$animateInternalToOffset(Lcom/android/credentialmanager/common/material/SwipeableState;FLandroidx/compose/animation/core/AnimationSpec;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState;->access$getAnimationTarget$p(Lcom/android/credentialmanager/common/material/SwipeableState;)Landroidx/compose/runtime/MutableState;
+PLcom/android/credentialmanager/common/material/SwipeableState;->access$setAnimationRunning(Lcom/android/credentialmanager/common/material/SwipeableState;Z)V
+PLcom/android/credentialmanager/common/material/SwipeableState;->access$setCurrentValue(Lcom/android/credentialmanager/common/material/SwipeableState;Ljava/lang/Object;)V
+PLcom/android/credentialmanager/common/material/SwipeableState;->animateInternalToOffset(FLandroidx/compose/animation/core/AnimationSpec;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState;->animateTo$default(Lcom/android/credentialmanager/common/material/SwipeableState;Ljava/lang/Object;Landroidx/compose/animation/core/AnimationSpec;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState;->animateTo(Ljava/lang/Object;Landroidx/compose/animation/core/AnimationSpec;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState;->getConfirmStateChange$frameworks__base__packages__CredentialManager__android_common__CredentialManager()Lkotlin/jvm/functions/Function1;
+PLcom/android/credentialmanager/common/material/SwipeableState;->getVelocityThreshold$frameworks__base__packages__CredentialManager__android_common__CredentialManager()F
+PLcom/android/credentialmanager/common/material/SwipeableState;->performDrag(F)F
+PLcom/android/credentialmanager/common/material/SwipeableState;->performFling(FLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLcom/android/credentialmanager/common/material/SwipeableState;->setAnimationRunning(Z)V
+PLcom/android/credentialmanager/common/material/SwipeableState;->setCurrentValue(Ljava/lang/Object;)V
+PLcom/android/credentialmanager/common/ui/EntryKt$TransparentBackgroundEntry$1;-><init>(Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function2;II)V
+PLcom/android/credentialmanager/common/ui/EntryKt;->TransparentBackgroundEntry(Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function2;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V
+PLcom/android/credentialmanager/createflow/ActiveEntry;->equals(Ljava/lang/Object;)Z
+PLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-2$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-2$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-3$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt$lambda-3$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt;->getLambda-2$frameworks__base__packages__CredentialManager__android_common__CredentialManager()Lkotlin/jvm/functions/Function2;
+PLcom/android/credentialmanager/createflow/ComposableSingletons$CreateCredentialComponentsKt;->getLambda-3$frameworks__base__packages__CredentialManager__android_common__CredentialManager()Lkotlin/jvm/functions/Function2;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$10;-><init>(Ljava/lang/Object;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$10;->invoke()Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$10;->invoke()V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$11;-><init>(Ljava/lang/Object;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$11;->invoke(Lcom/android/credentialmanager/createflow/ActiveEntry;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$11;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$12;-><init>(Ljava/lang/Object;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$12;->invoke()Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$12;->invoke()V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$13;-><init>(Ljava/lang/Object;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$14;-><init>(Ljava/lang/Object;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$14;->invoke()Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$14;->invoke()V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$15;-><init>(Ljava/lang/Object;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$15;->invoke()Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$15;->invoke()V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$6;->invoke(Lcom/android/credentialmanager/createflow/EntryInfo;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$6;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$7;->invoke()Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$7;->invoke()V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$8;->invoke()Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$8;->invoke()V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$1$9;-><init>(Ljava/lang/Object;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$3;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$CreateCredentialScreen$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsDisabledProvidersRow$1$1$1;-><clinit>()V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsDisabledProvidersRow$1$1$1;-><init>()V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsDisabledProvidersRow$1$1$1;->invoke(Lcom/android/credentialmanager/createflow/ProviderInfo;)Ljava/lang/CharSequence;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsDisabledProvidersRow$1$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsDisabledProvidersRow$1;-><init>(Ljava/util/List;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsDisabledProvidersRow$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsDisabledProvidersRow$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsInfoRow$1;-><init>(Lcom/android/credentialmanager/createflow/EnabledProviderInfo;Lcom/android/credentialmanager/createflow/CreateOptionInfo;Lcom/android/credentialmanager/createflow/RequestDisplayInfo;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsInfoRow$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsInfoRow$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsInfoRow$2;-><init>(Lcom/android/credentialmanager/createflow/EnabledProviderInfo;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsInfoRow$2;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsInfoRow$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsRowIntroCard$1;-><init>(Lcom/android/credentialmanager/createflow/EnabledProviderInfo;Lkotlin/jvm/functions/Function0;ILkotlin/jvm/functions/Function0;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsRowIntroCard$1;->invoke(Landroidx/compose/foundation/layout/ColumnScope;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsRowIntroCard$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$1;-><init>(Lcom/android/credentialmanager/createflow/RequestDisplayInfo;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$2;-><init>(ZLkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$2;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$3$1$1$1$1;-><init>(Lkotlin/jvm/functions/Function1;Lkotlin/Pair;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$3$1$1$1$1;->invoke()Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$3$1$1$1$1;->invoke()V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$3$1$1$1;-><init>(Lcom/android/credentialmanager/createflow/RequestDisplayInfo;Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$3$1$1$1;->invoke(Landroidx/compose/foundation/lazy/LazyItemScope;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$3$1$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$3$1$2;-><init>(Ljava/util/List;Lkotlin/jvm/functions/Function0;I)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$3$1$2;->invoke(Landroidx/compose/foundation/lazy/LazyItemScope;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$3$1$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$3$1;-><init>(ZLjava/util/List;Ljava/util/List;Lcom/android/credentialmanager/createflow/RequestDisplayInfo;Lkotlin/jvm/functions/Function1;Ljava/util/List;Lkotlin/jvm/functions/Function0;ILkotlin/jvm/functions/Function1;I)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$3$1;->invoke(Landroidx/compose/foundation/lazy/LazyListScope;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$3$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$3;-><init>(ZLjava/util/List;Ljava/util/List;Lcom/android/credentialmanager/createflow/RequestDisplayInfo;Lkotlin/jvm/functions/Function1;Ljava/util/List;Lkotlin/jvm/functions/Function0;ILkotlin/jvm/functions/Function1;I)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$3;->invoke(Landroidx/compose/foundation/layout/ColumnScope;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1$1$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1;-><init>(Lcom/android/credentialmanager/createflow/RequestDisplayInfo;ZLkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;ZLjava/util/List;Ljava/util/List;Lkotlin/jvm/functions/Function1;Ljava/util/List;Lkotlin/jvm/functions/Function0;ILkotlin/jvm/functions/Function1;I)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1;->invoke(Landroidx/compose/foundation/layout/ColumnScope;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$MoreOptionsSelectionCard$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$PrimaryCreateOptionRow$1;->invoke()Ljava/lang/Object;
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt$PrimaryCreateOptionRow$1;->invoke()V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt;->MoreOptionsDisabledProvidersRow(Ljava/util/List;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt;->MoreOptionsInfoRow(Lcom/android/credentialmanager/createflow/RequestDisplayInfo;Lcom/android/credentialmanager/createflow/EnabledProviderInfo;Lcom/android/credentialmanager/createflow/CreateOptionInfo;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt;->MoreOptionsRowIntroCard(Lcom/android/credentialmanager/createflow/EnabledProviderInfo;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/createflow/CreateCredentialComponentsKt;->MoreOptionsSelectionCard(Lcom/android/credentialmanager/createflow/RequestDisplayInfo;Ljava/util/List;Ljava/util/List;Ljava/util/List;ZZLkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)V
+PLcom/android/credentialmanager/createflow/CreateCredentialUiState;->copy$default(Lcom/android/credentialmanager/createflow/CreateCredentialUiState;Ljava/util/List;Ljava/util/List;Lcom/android/credentialmanager/createflow/CreateScreenState;Lcom/android/credentialmanager/createflow/RequestDisplayInfo;Ljava/util/List;ZLcom/android/credentialmanager/createflow/ActiveEntry;Lcom/android/credentialmanager/createflow/EntryInfo;ZZLjava/lang/Boolean;ILjava/lang/Object;)Lcom/android/credentialmanager/createflow/CreateCredentialUiState;
+PLcom/android/credentialmanager/createflow/CreateCredentialUiState;->copy(Ljava/util/List;Ljava/util/List;Lcom/android/credentialmanager/createflow/CreateScreenState;Lcom/android/credentialmanager/createflow/RequestDisplayInfo;Ljava/util/List;ZLcom/android/credentialmanager/createflow/ActiveEntry;Lcom/android/credentialmanager/createflow/EntryInfo;ZZLjava/lang/Boolean;)Lcom/android/credentialmanager/createflow/CreateCredentialUiState;
+PLcom/android/credentialmanager/createflow/CreateCredentialUiState;->equals(Ljava/lang/Object;)Z
+PLcom/android/credentialmanager/createflow/CreateCredentialUiState;->getDisabledProviders()Ljava/util/List;
+PLcom/android/credentialmanager/createflow/CreateCredentialUiState;->getHasDefaultProvider()Z
+PLcom/android/credentialmanager/createflow/CreateCredentialUiState;->getProviderActivityPending()Z
+PLcom/android/credentialmanager/createflow/CreateCredentialUiState;->getSelectedEntry()Lcom/android/credentialmanager/createflow/EntryInfo;
+PLcom/android/credentialmanager/createflow/CreateCredentialUiState;->getSortedCreateOptionsPairs()Ljava/util/List;
+PLcom/android/credentialmanager/createflow/CreateCredentialUiState;->isFromProviderSelection()Ljava/lang/Boolean;
+PLcom/android/credentialmanager/createflow/CreateCredentialViewModel;->launchProviderUi(Landroidx/activity/compose/ManagedActivityResultLauncher;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialViewModel;->onBackCreationSelectionButtonSelected()V
+PLcom/android/credentialmanager/createflow/CreateCredentialViewModel;->onCancel()V
+PLcom/android/credentialmanager/createflow/CreateCredentialViewModel;->onChangeDefaultSelected()V
+PLcom/android/credentialmanager/createflow/CreateCredentialViewModel;->onConfirmEntrySelected()V
+PLcom/android/credentialmanager/createflow/CreateCredentialViewModel;->onDefaultChanged(Ljava/lang/String;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialViewModel;->onDisabledPasswordManagerSelected()V
+PLcom/android/credentialmanager/createflow/CreateCredentialViewModel;->onEntrySelected(Lcom/android/credentialmanager/createflow/EntryInfo;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialViewModel;->onEntrySelectedFromMoreOptionScreen(Lcom/android/credentialmanager/createflow/ActiveEntry;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialViewModel;->onMoreOptionsSelectedOnCreationSelection()V
+PLcom/android/credentialmanager/createflow/CreateCredentialViewModel;->onProviderActivityResult(Lcom/android/credentialmanager/common/ProviderActivityResult;)V
+PLcom/android/credentialmanager/createflow/CreateCredentialViewModel;->onUseOnceSelected()V
+PLcom/android/credentialmanager/createflow/CreateCredentialViewModel;->setUiState(Lcom/android/credentialmanager/createflow/CreateCredentialUiState;)V
+PLcom/android/credentialmanager/createflow/CreateOptionInfo;->getPasskeyCount()Ljava/lang/Integer;
+PLcom/android/credentialmanager/createflow/CreateOptionInfo;->getPasswordCount()Ljava/lang/Integer;
+PLcom/android/credentialmanager/createflow/EntryInfo;->getEntryKey()Ljava/lang/String;
+PLcom/android/credentialmanager/createflow/EntryInfo;->getEntrySubkey()Ljava/lang/String;
+PLcom/android/credentialmanager/createflow/EntryInfo;->getFillInIntent()Landroid/content/Intent;
+PLcom/android/credentialmanager/createflow/EntryInfo;->getPendingIntent()Landroid/app/PendingIntent;
+PLcom/android/credentialmanager/createflow/EntryInfo;->getProviderId()Ljava/lang/String;
+PLcom/android/credentialmanager/createflow/RequestDisplayInfo;->equals(Ljava/lang/Object;)Z
+PLcom/android/credentialmanager/getflow/ActionEntryInfo;-><clinit>()V
+PLcom/android/credentialmanager/getflow/ActionEntryInfo;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/content/Intent;Ljava/lang/String;Landroid/graphics/drawable/Drawable;Ljava/lang/String;)V
+PLcom/android/credentialmanager/getflow/ActionEntryInfo;->getIcon()Landroid/graphics/drawable/Drawable;
+PLcom/android/credentialmanager/getflow/ActionEntryInfo;->getSubTitle()Ljava/lang/String;
+PLcom/android/credentialmanager/getflow/ActionEntryInfo;->getTitle()Ljava/lang/String;
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-1$1;-><clinit>()V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-1$1;-><init>()V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-1$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-2$1;-><clinit>()V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-2$1;-><init>()V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-2$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-2$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-3$1;-><clinit>()V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-3$1;-><init>()V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-3$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-3$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-4$1;-><clinit>()V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-4$1;-><init>()V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-5$1;-><clinit>()V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-5$1;-><init>()V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-6$1;-><clinit>()V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-6$1;-><init>()V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-7$1;-><clinit>()V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt$lambda-7$1;-><init>()V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt;-><clinit>()V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt;-><init>()V
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt;->getLambda-1$frameworks__base__packages__CredentialManager__android_common__CredentialManager()Lkotlin/jvm/functions/Function2;
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt;->getLambda-2$frameworks__base__packages__CredentialManager__android_common__CredentialManager()Lkotlin/jvm/functions/Function2;
+PLcom/android/credentialmanager/getflow/ComposableSingletons$GetCredentialComponentsKt;->getLambda-3$frameworks__base__packages__CredentialManager__android_common__CredentialManager()Lkotlin/jvm/functions/Function2;
+PLcom/android/credentialmanager/getflow/CredentialEntryInfo;-><clinit>()V
+PLcom/android/credentialmanager/getflow/CredentialEntryInfo;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/content/Intent;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/graphics/drawable/Drawable;Ljava/lang/Long;)V
+PLcom/android/credentialmanager/getflow/CredentialEntryInfo;->getCredentialType()Ljava/lang/String;
+PLcom/android/credentialmanager/getflow/CredentialEntryInfo;->getCredentialTypeDisplayName()Ljava/lang/String;
+PLcom/android/credentialmanager/getflow/CredentialEntryInfo;->getDisplayName()Ljava/lang/String;
+PLcom/android/credentialmanager/getflow/CredentialEntryInfo;->getIcon()Landroid/graphics/drawable/Drawable;
+PLcom/android/credentialmanager/getflow/CredentialEntryInfo;->getLastUsedTimeMillis()Ljava/lang/Long;
+PLcom/android/credentialmanager/getflow/CredentialEntryInfo;->getUserName()Ljava/lang/String;
+PLcom/android/credentialmanager/getflow/CredentialEntryInfoComparatorByTypeThenTimestamp;-><init>()V
+PLcom/android/credentialmanager/getflow/CredentialEntryInfoComparatorByTypeThenTimestamp;->compare(Lcom/android/credentialmanager/getflow/CredentialEntryInfo;Lcom/android/credentialmanager/getflow/CredentialEntryInfo;)I
+PLcom/android/credentialmanager/getflow/CredentialEntryInfoComparatorByTypeThenTimestamp;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
+PLcom/android/credentialmanager/getflow/EntryInfo;-><clinit>()V
+PLcom/android/credentialmanager/getflow/EntryInfo;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/content/Intent;)V
+PLcom/android/credentialmanager/getflow/EntryInfo;->getEntryKey()Ljava/lang/String;
+PLcom/android/credentialmanager/getflow/EntryInfo;->getEntrySubkey()Ljava/lang/String;
+PLcom/android/credentialmanager/getflow/EntryInfo;->getFillInIntent()Landroid/content/Intent;
+PLcom/android/credentialmanager/getflow/EntryInfo;->getPendingIntent()Landroid/app/PendingIntent;
+PLcom/android/credentialmanager/getflow/EntryInfo;->getProviderId()Ljava/lang/String;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$ActionChips$2;-><init>(Ljava/util/List;Lkotlin/jvm/functions/Function1;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$ActionChips$2;->invoke(Landroidx/compose/foundation/layout/ColumnScope;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$ActionChips$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$ActionChips$3;-><init>(Ljava/util/List;Lkotlin/jvm/functions/Function1;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$ActionEntryRow$1;-><init>(Lkotlin/jvm/functions/Function1;Lcom/android/credentialmanager/getflow/ActionEntryInfo;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$ActionEntryRow$1;->invoke()Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$ActionEntryRow$1;->invoke()V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$ActionEntryRow$2;-><init>(Lcom/android/credentialmanager/getflow/ActionEntryInfo;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$ActionEntryRow$2;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$ActionEntryRow$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$ActionEntryRow$3;-><init>(Lcom/android/credentialmanager/getflow/ActionEntryInfo;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$ActionEntryRow$3;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$ActionEntryRow$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$1;-><init>(ZLkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$1;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2$1$4;-><init>(Ljava/util/List;Lkotlin/jvm/functions/Function1;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2$1$4;->invoke(Landroidx/compose/foundation/lazy/LazyItemScope;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2$1$4;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2$1$invoke$$inlined$items$default$1;-><clinit>()V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2$1$invoke$$inlined$items$default$1;-><init>()V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2$1$invoke$$inlined$items$default$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2$1$invoke$$inlined$items$default$1;->invoke(Ljava/lang/Object;)Ljava/lang/Void;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2$1$invoke$$inlined$items$default$3;-><init>(Lkotlin/jvm/functions/Function1;Ljava/util/List;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2$1$invoke$$inlined$items$default$3;->invoke(I)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2$1$invoke$$inlined$items$default$3;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2$1$invoke$$inlined$items$default$4;-><init>(Ljava/util/List;Lkotlin/jvm/functions/Function1;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2$1$invoke$$inlined$items$default$4;->invoke(Landroidx/compose/foundation/lazy/LazyItemScope;ILandroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2$1$invoke$$inlined$items$default$4;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2$1;-><init>(Ljava/util/List;Ljava/util/List;Lcom/android/credentialmanager/getflow/ProviderDisplayInfo;Lkotlin/jvm/functions/Function1;ILjava/util/List;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2$1;->invoke(Landroidx/compose/foundation/lazy/LazyListScope;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2;-><init>(Ljava/util/List;Ljava/util/List;Lcom/android/credentialmanager/getflow/ProviderDisplayInfo;Lkotlin/jvm/functions/Function1;ILjava/util/List;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2;->invoke(Landroidx/compose/foundation/layout/ColumnScope;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1$1$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1;-><init>(ZLkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Ljava/util/List;Ljava/util/List;Lcom/android/credentialmanager/getflow/ProviderDisplayInfo;Lkotlin/jvm/functions/Function1;ILjava/util/List;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1;->invoke(Landroidx/compose/foundation/layout/ColumnScope;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$AllSignInOptionCard$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$CredentialEntryRow$1;-><init>(Lkotlin/jvm/functions/Function1;Lcom/android/credentialmanager/getflow/CredentialEntryInfo;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$CredentialEntryRow$1;->invoke()Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$CredentialEntryRow$1;->invoke()V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$CredentialEntryRow$2;-><init>(Lcom/android/credentialmanager/getflow/CredentialEntryInfo;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$CredentialEntryRow$2;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$CredentialEntryRow$3;-><init>(Lcom/android/credentialmanager/getflow/CredentialEntryInfo;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$CredentialEntryRow$3;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$CredentialEntryRow$3;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$GetCredentialScreen$1$1;-><init>(Ljava/lang/Object;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$GetCredentialScreen$1$2;-><init>(Ljava/lang/Object;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$GetCredentialScreen$1$2;->invoke()Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$GetCredentialScreen$1$2;->invoke()V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$GetCredentialScreen$1$3;-><init>(Ljava/lang/Object;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$GetCredentialScreen$1$3;->invoke(Lcom/android/credentialmanager/getflow/EntryInfo;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$GetCredentialScreen$1$3;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$GetCredentialScreen$1$4;-><init>(Ljava/lang/Object;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$GetCredentialScreen$1$5;-><init>(Ljava/lang/Object;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$GetCredentialScreen$1;-><init>(Lcom/android/credentialmanager/getflow/GetCredentialUiState;Lcom/android/credentialmanager/getflow/GetCredentialViewModel;Landroidx/activity/compose/ManagedActivityResultLauncher;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$GetCredentialScreen$1;->invoke(Landroidx/compose/foundation/layout/ColumnScope;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$GetCredentialScreen$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$GetCredentialScreen$2;-><init>(Lcom/android/credentialmanager/common/material/ModalBottomSheetState;Lcom/android/credentialmanager/getflow/GetCredentialViewModel;Lkotlin/coroutines/Continuation;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$GetCredentialScreen$2;->create(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$GetCredentialScreen$2;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$GetCredentialScreen$5;-><init>(Lcom/android/credentialmanager/getflow/GetCredentialViewModel;Landroidx/activity/compose/ManagedActivityResultLauncher;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$GetCredentialScreen$5;->invoke(Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$GetCredentialScreen$5;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PerUserNameCredentials$1;-><init>(Lcom/android/credentialmanager/getflow/PerUserNameCredentialEntryList;Lkotlin/jvm/functions/Function1;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PerUserNameCredentials$1;->invoke(Landroidx/compose/foundation/layout/ColumnScope;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PerUserNameCredentials$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PerUserNameCredentials$2;-><init>(Lcom/android/credentialmanager/getflow/PerUserNameCredentialEntryList;Lkotlin/jvm/functions/Function1;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$17;-><clinit>()V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$17;-><init>()V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$17;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$17;->invoke(Ljava/lang/Object;)Ljava/lang/Void;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$19;-><init>(Lkotlin/jvm/functions/Function1;Ljava/util/List;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$19;->invoke(I)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$19;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$1;-><clinit>()V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$1;-><init>()V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$1;->invoke(Ljava/lang/Object;)Ljava/lang/Void;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$20;-><init>(Ljava/util/List;Lkotlin/jvm/functions/Function1;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$20;->invoke(Landroidx/compose/foundation/lazy/LazyItemScope;ILandroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$20;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$3;-><init>(Lkotlin/jvm/functions/Function1;Ljava/util/List;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$3;->invoke(I)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$3;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$4;-><init>(Ljava/util/List;Lkotlin/jvm/functions/Function1;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$4;->invoke(Landroidx/compose/foundation/lazy/LazyItemScope;ILandroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$4;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$5;-><clinit>()V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$5;-><init>()V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$7;-><init>(Lkotlin/jvm/functions/Function1;Ljava/util/List;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1$invoke$$inlined$items$default$8;-><init>(Ljava/util/List;Lkotlin/jvm/functions/Function1;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1;-><init>(IILjava/util/List;Ljava/util/List;Lkotlin/jvm/functions/Function1;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1;->invoke(Landroidx/compose/foundation/lazy/LazyListScope;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1$1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1;-><init>(Ljava/util/List;Ljava/util/List;Lkotlin/jvm/functions/Function1;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1;->invoke(Landroidx/compose/foundation/layout/ColumnScope;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1$1$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1;-><init>(Ljava/util/List;Ljava/util/List;Lcom/android/credentialmanager/getflow/RequestDisplayInfo;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/functions/Function0;)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1;->invoke(Landroidx/compose/foundation/layout/ColumnScope;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt$PrimarySelectionCard$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt;->ActionChips(Ljava/util/List;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt;->ActionEntryRow(Lcom/android/credentialmanager/getflow/ActionEntryInfo;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt;->AllSignInOptionCard(Ljava/util/List;Lcom/android/credentialmanager/getflow/ProviderDisplayInfo;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;ZLandroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt;->CredentialEntryRow(Lcom/android/credentialmanager/getflow/CredentialEntryInfo;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt;->GetCredentialScreen(Lcom/android/credentialmanager/getflow/GetCredentialViewModel;Landroidx/activity/compose/ManagedActivityResultLauncher;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt;->PerUserNameCredentials(Lcom/android/credentialmanager/getflow/PerUserNameCredentialEntryList;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialComponentsKt;->PrimarySelectionCard(Lcom/android/credentialmanager/getflow/RequestDisplayInfo;Lcom/android/credentialmanager/getflow/ProviderDisplayInfo;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;I)V
+PLcom/android/credentialmanager/getflow/GetCredentialUiState;-><clinit>()V
+PLcom/android/credentialmanager/getflow/GetCredentialUiState;-><init>(Ljava/util/List;Lcom/android/credentialmanager/getflow/RequestDisplayInfo;Lcom/android/credentialmanager/getflow/GetScreenState;Lcom/android/credentialmanager/getflow/ProviderDisplayInfo;Lcom/android/credentialmanager/getflow/EntryInfo;ZZZ)V
+PLcom/android/credentialmanager/getflow/GetCredentialUiState;-><init>(Ljava/util/List;Lcom/android/credentialmanager/getflow/RequestDisplayInfo;Lcom/android/credentialmanager/getflow/GetScreenState;Lcom/android/credentialmanager/getflow/ProviderDisplayInfo;Lcom/android/credentialmanager/getflow/EntryInfo;ZZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLcom/android/credentialmanager/getflow/GetCredentialUiState;->copy$default(Lcom/android/credentialmanager/getflow/GetCredentialUiState;Ljava/util/List;Lcom/android/credentialmanager/getflow/RequestDisplayInfo;Lcom/android/credentialmanager/getflow/GetScreenState;Lcom/android/credentialmanager/getflow/ProviderDisplayInfo;Lcom/android/credentialmanager/getflow/EntryInfo;ZZZILjava/lang/Object;)Lcom/android/credentialmanager/getflow/GetCredentialUiState;
+PLcom/android/credentialmanager/getflow/GetCredentialUiState;->copy(Ljava/util/List;Lcom/android/credentialmanager/getflow/RequestDisplayInfo;Lcom/android/credentialmanager/getflow/GetScreenState;Lcom/android/credentialmanager/getflow/ProviderDisplayInfo;Lcom/android/credentialmanager/getflow/EntryInfo;ZZZ)Lcom/android/credentialmanager/getflow/GetCredentialUiState;
+PLcom/android/credentialmanager/getflow/GetCredentialUiState;->equals(Ljava/lang/Object;)Z
+PLcom/android/credentialmanager/getflow/GetCredentialUiState;->getCurrentScreenState()Lcom/android/credentialmanager/getflow/GetScreenState;
+PLcom/android/credentialmanager/getflow/GetCredentialUiState;->getHidden()Z
+PLcom/android/credentialmanager/getflow/GetCredentialUiState;->getProviderActivityPending()Z
+PLcom/android/credentialmanager/getflow/GetCredentialUiState;->getProviderDisplayInfo()Lcom/android/credentialmanager/getflow/ProviderDisplayInfo;
+PLcom/android/credentialmanager/getflow/GetCredentialUiState;->getProviderInfoList()Ljava/util/List;
+PLcom/android/credentialmanager/getflow/GetCredentialUiState;->getRequestDisplayInfo()Lcom/android/credentialmanager/getflow/RequestDisplayInfo;
+PLcom/android/credentialmanager/getflow/GetCredentialUiState;->getSelectedEntry()Lcom/android/credentialmanager/getflow/EntryInfo;
+PLcom/android/credentialmanager/getflow/GetCredentialUiState;->isNoAccount()Z
+PLcom/android/credentialmanager/getflow/GetCredentialViewModel$dialogResult$2;-><clinit>()V
+PLcom/android/credentialmanager/getflow/GetCredentialViewModel$dialogResult$2;-><init>()V
+PLcom/android/credentialmanager/getflow/GetCredentialViewModel$dialogResult$2;->invoke()Landroidx/lifecycle/MutableLiveData;
+PLcom/android/credentialmanager/getflow/GetCredentialViewModel$dialogResult$2;->invoke()Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialViewModel;-><clinit>()V
+PLcom/android/credentialmanager/getflow/GetCredentialViewModel;-><init>()V
+PLcom/android/credentialmanager/getflow/GetCredentialViewModel;-><init>(Lcom/android/credentialmanager/CredentialManagerRepo;)V
+PLcom/android/credentialmanager/getflow/GetCredentialViewModel;-><init>(Lcom/android/credentialmanager/CredentialManagerRepo;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLcom/android/credentialmanager/getflow/GetCredentialViewModel;->getDialogResult()Landroidx/lifecycle/MutableLiveData;
+PLcom/android/credentialmanager/getflow/GetCredentialViewModel;->getUiState()Lcom/android/credentialmanager/getflow/GetCredentialUiState;
+PLcom/android/credentialmanager/getflow/GetCredentialViewModel;->launchProviderUi(Landroidx/activity/compose/ManagedActivityResultLauncher;)V
+PLcom/android/credentialmanager/getflow/GetCredentialViewModel;->observeDialogResult()Landroidx/lifecycle/LiveData;
+PLcom/android/credentialmanager/getflow/GetCredentialViewModel;->onCancel()V
+PLcom/android/credentialmanager/getflow/GetCredentialViewModel;->onEntrySelected(Lcom/android/credentialmanager/getflow/EntryInfo;)V
+PLcom/android/credentialmanager/getflow/GetCredentialViewModel;->onMoreOptionSelected()V
+PLcom/android/credentialmanager/getflow/GetCredentialViewModel;->onProviderActivityResult(Lcom/android/credentialmanager/common/ProviderActivityResult;)V
+PLcom/android/credentialmanager/getflow/GetCredentialViewModel;->setUiState(Lcom/android/credentialmanager/getflow/GetCredentialUiState;)V
+PLcom/android/credentialmanager/getflow/GetCredentialViewModelKt$toProviderDisplayInfo$$inlined$compareByDescending$1;-><init>()V
+PLcom/android/credentialmanager/getflow/GetCredentialViewModelKt$toProviderDisplayInfo$$inlined$compareByDescending$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
+PLcom/android/credentialmanager/getflow/GetCredentialViewModelKt$toProviderDisplayInfo$1$1$1;-><init>(Lcom/android/credentialmanager/getflow/CredentialEntryInfo;)V
+PLcom/android/credentialmanager/getflow/GetCredentialViewModelKt$toProviderDisplayInfo$1$1$1;->apply(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLcom/android/credentialmanager/getflow/GetCredentialViewModelKt$toProviderDisplayInfo$1$1$1;->apply(Ljava/lang/String;Ljava/util/List;)Ljava/util/List;
+PLcom/android/credentialmanager/getflow/GetCredentialViewModelKt;->access$toGetScreenState(Ljava/util/List;)Lcom/android/credentialmanager/getflow/GetScreenState;
+PLcom/android/credentialmanager/getflow/GetCredentialViewModelKt;->access$toProviderDisplayInfo(Ljava/util/List;)Lcom/android/credentialmanager/getflow/ProviderDisplayInfo;
+PLcom/android/credentialmanager/getflow/GetCredentialViewModelKt;->toGetScreenState(Ljava/util/List;)Lcom/android/credentialmanager/getflow/GetScreenState;
+PLcom/android/credentialmanager/getflow/GetCredentialViewModelKt;->toProviderDisplayInfo(Ljava/util/List;)Lcom/android/credentialmanager/getflow/ProviderDisplayInfo;
+PLcom/android/credentialmanager/getflow/GetScreenState;->$values()[Lcom/android/credentialmanager/getflow/GetScreenState;
+PLcom/android/credentialmanager/getflow/GetScreenState;-><clinit>()V
+PLcom/android/credentialmanager/getflow/GetScreenState;-><init>(Ljava/lang/String;I)V
+PLcom/android/credentialmanager/getflow/PerUserNameCredentialEntryList;-><clinit>()V
+PLcom/android/credentialmanager/getflow/PerUserNameCredentialEntryList;-><init>(Ljava/lang/String;Ljava/util/List;)V
+PLcom/android/credentialmanager/getflow/PerUserNameCredentialEntryList;->getSortedCredentialEntryList()Ljava/util/List;
+PLcom/android/credentialmanager/getflow/PerUserNameCredentialEntryList;->getUserName()Ljava/lang/String;
+PLcom/android/credentialmanager/getflow/ProviderDisplayInfo;-><clinit>()V
+PLcom/android/credentialmanager/getflow/ProviderDisplayInfo;-><init>(Ljava/util/List;Ljava/util/List;Lcom/android/credentialmanager/getflow/RemoteEntryInfo;)V
+PLcom/android/credentialmanager/getflow/ProviderDisplayInfo;->equals(Ljava/lang/Object;)Z
+PLcom/android/credentialmanager/getflow/ProviderDisplayInfo;->getAuthenticationEntryList()Ljava/util/List;
+PLcom/android/credentialmanager/getflow/ProviderDisplayInfo;->getRemoteEntry()Lcom/android/credentialmanager/getflow/RemoteEntryInfo;
+PLcom/android/credentialmanager/getflow/ProviderDisplayInfo;->getSortedUserNameToCredentialEntryList()Ljava/util/List;
+PLcom/android/credentialmanager/getflow/ProviderInfo;-><clinit>()V
+PLcom/android/credentialmanager/getflow/ProviderInfo;-><init>(Ljava/lang/String;Landroid/graphics/drawable/Drawable;Ljava/lang/String;Ljava/util/List;Lcom/android/credentialmanager/getflow/AuthenticationEntryInfo;Lcom/android/credentialmanager/getflow/RemoteEntryInfo;Ljava/util/List;)V
+PLcom/android/credentialmanager/getflow/ProviderInfo;->getActionEntryList()Ljava/util/List;
+PLcom/android/credentialmanager/getflow/ProviderInfo;->getAuthenticationEntry()Lcom/android/credentialmanager/getflow/AuthenticationEntryInfo;
+PLcom/android/credentialmanager/getflow/ProviderInfo;->getCredentialEntryList()Ljava/util/List;
+PLcom/android/credentialmanager/getflow/ProviderInfo;->getRemoteEntry()Lcom/android/credentialmanager/getflow/RemoteEntryInfo;
+PLcom/android/credentialmanager/getflow/RequestDisplayInfo;-><clinit>()V
+PLcom/android/credentialmanager/getflow/RequestDisplayInfo;-><init>(Ljava/lang/String;)V
+PLcom/android/credentialmanager/getflow/RequestDisplayInfo;->equals(Ljava/lang/Object;)Z
+PLcom/android/credentialmanager/getflow/RequestDisplayInfo;->getAppName()Ljava/lang/String;
+PLcom/android/credentialmanager/jetpack/provider/Action$Companion;-><init>()V
+PLcom/android/credentialmanager/jetpack/provider/Action$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLcom/android/credentialmanager/jetpack/provider/Action$Companion;->fromSlice(Landroid/app/slice/Slice;)Lcom/android/credentialmanager/jetpack/provider/Action;
+PLcom/android/credentialmanager/jetpack/provider/Action;-><clinit>()V
+PLcom/android/credentialmanager/jetpack/provider/Action;-><init>(Ljava/lang/CharSequence;Ljava/lang/CharSequence;Landroid/app/PendingIntent;)V
+PLcom/android/credentialmanager/jetpack/provider/Action;->getPendingIntent()Landroid/app/PendingIntent;
+PLcom/android/credentialmanager/jetpack/provider/Action;->getSubTitle()Ljava/lang/CharSequence;
+PLcom/android/credentialmanager/jetpack/provider/Action;->getTitle()Ljava/lang/CharSequence;
+PLcom/android/credentialmanager/jetpack/provider/CredentialEntry$Companion;-><init>()V
+PLcom/android/credentialmanager/jetpack/provider/CredentialEntry$Companion;-><init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLcom/android/credentialmanager/jetpack/provider/CredentialEntry$Companion;->fromSlice(Landroid/app/slice/Slice;)Lcom/android/credentialmanager/jetpack/provider/CredentialEntry;
+PLcom/android/credentialmanager/jetpack/provider/CredentialEntry;-><clinit>()V
+PLcom/android/credentialmanager/jetpack/provider/CredentialEntry;-><init>(Ljava/lang/String;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Landroid/app/PendingIntent;JLandroid/graphics/drawable/Icon;Z)V
+PLcom/android/credentialmanager/jetpack/provider/CredentialEntry;->getDisplayName()Ljava/lang/CharSequence;
+PLcom/android/credentialmanager/jetpack/provider/CredentialEntry;->getIcon()Landroid/graphics/drawable/Icon;
+PLcom/android/credentialmanager/jetpack/provider/CredentialEntry;->getLastUsedTimeMillis()J
+PLcom/android/credentialmanager/jetpack/provider/CredentialEntry;->getPendingIntent()Landroid/app/PendingIntent;
+PLcom/android/credentialmanager/jetpack/provider/CredentialEntry;->getType()Ljava/lang/String;
+PLcom/android/credentialmanager/jetpack/provider/CredentialEntry;->getTypeDisplayName()Ljava/lang/CharSequence;
+PLcom/android/credentialmanager/jetpack/provider/CredentialEntry;->getUsername()Ljava/lang/CharSequence;
+PLkotlin/collections/AbstractList$Companion;->orderedEquals$kotlin_stdlib(Ljava/util/Collection;Ljava/util/Collection;)Z
+PLkotlin/collections/AbstractList;->equals(Ljava/lang/Object;)Z
+PLkotlin/collections/ArraysKt;->fill$default([IIIIILjava/lang/Object;)V
+PLkotlin/collections/ArraysKt;->fill([IIII)V
+PLkotlin/collections/ArraysKt;->indexOf([Ljava/lang/Object;Ljava/lang/Object;)I
+PLkotlin/collections/ArraysKt___ArraysJvmKt;->fill$default([IIIIILjava/lang/Object;)V
+PLkotlin/collections/ArraysKt___ArraysJvmKt;->fill([IIII)V
+PLkotlin/collections/ArraysKt___ArraysKt;->indexOf([Ljava/lang/Object;Ljava/lang/Object;)I
+PLkotlin/collections/CollectionsKt;->arrayListOf([Ljava/lang/Object;)Ljava/util/ArrayList;
+PLkotlin/collections/CollectionsKt;->firstOrNull(Ljava/util/List;)Ljava/lang/Object;
+PLkotlin/collections/CollectionsKt;->getOrNull(Ljava/util/List;I)Ljava/lang/Object;
+PLkotlin/collections/CollectionsKt;->joinToString$default(Ljava/lang/Iterable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
+PLkotlin/collections/CollectionsKt;->mutableListOf([Ljava/lang/Object;)Ljava/util/List;
+PLkotlin/collections/CollectionsKt;->optimizeReadOnlyList(Ljava/util/List;)Ljava/util/List;
+PLkotlin/collections/CollectionsKt;->removeFirstOrNull(Ljava/util/List;)Ljava/lang/Object;
+PLkotlin/collections/CollectionsKt;->take(Ljava/lang/Iterable;I)Ljava/util/List;
+PLkotlin/collections/CollectionsKt;->toIntArray(Ljava/util/Collection;)[I
+PLkotlin/collections/CollectionsKt__CollectionsKt;->arrayListOf([Ljava/lang/Object;)Ljava/util/ArrayList;
+PLkotlin/collections/CollectionsKt__CollectionsKt;->mutableListOf([Ljava/lang/Object;)Ljava/util/List;
+PLkotlin/collections/CollectionsKt__CollectionsKt;->optimizeReadOnlyList(Ljava/util/List;)Ljava/util/List;
+PLkotlin/collections/CollectionsKt__MutableCollectionsKt;->removeFirstOrNull(Ljava/util/List;)Ljava/lang/Object;
+PLkotlin/collections/CollectionsKt___CollectionsKt;->firstOrNull(Ljava/util/List;)Ljava/lang/Object;
+PLkotlin/collections/CollectionsKt___CollectionsKt;->getOrNull(Ljava/util/List;I)Ljava/lang/Object;
+PLkotlin/collections/CollectionsKt___CollectionsKt;->joinTo(Ljava/lang/Iterable;Ljava/lang/Appendable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;)Ljava/lang/Appendable;
+PLkotlin/collections/CollectionsKt___CollectionsKt;->joinToString$default(Ljava/lang/Iterable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/String;
+PLkotlin/collections/CollectionsKt___CollectionsKt;->joinToString(Ljava/lang/Iterable;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;ILjava/lang/CharSequence;Lkotlin/jvm/functions/Function1;)Ljava/lang/String;
+PLkotlin/collections/CollectionsKt___CollectionsKt;->take(Ljava/lang/Iterable;I)Ljava/util/List;
+PLkotlin/collections/CollectionsKt___CollectionsKt;->toIntArray(Ljava/util/Collection;)[I
+PLkotlin/collections/EmptyMap;->containsKey(Ljava/lang/Object;)Z
+PLkotlin/collections/EmptyMap;->getSize()I
+PLkotlin/collections/EmptyMap;->size()I
+PLkotlin/collections/MapsKt;->getValue(Ljava/util/Map;Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlin/collections/MapsKt;->toMutableMap(Ljava/util/Map;)Ljava/util/Map;
+PLkotlin/collections/MapsKt__MapWithDefaultKt;->getOrImplicitDefaultNullable(Ljava/util/Map;Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlin/collections/MapsKt__MapsKt;->getValue(Ljava/util/Map;Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlin/collections/MapsKt__MapsKt;->toMutableMap(Ljava/util/Map;)Ljava/util/Map;
+PLkotlin/coroutines/jvm/internal/Boxing;->boxFloat(F)Ljava/lang/Float;
+PLkotlin/coroutines/jvm/internal/Boxing;->boxInt(I)Ljava/lang/Integer;
+PLkotlin/jvm/internal/FunctionReference;->getArity()I
+PLkotlin/jvm/internal/Intrinsics;->areEqual(Ljava/lang/Float;F)Z
+PLkotlin/jvm/internal/Ref$FloatRef;-><init>()V
+PLkotlin/jvm/internal/Ref$LongRef;-><init>()V
+PLkotlin/jvm/internal/TypeIntrinsics;->asMutableCollection(Ljava/lang/Object;)Ljava/util/Collection;
+PLkotlin/jvm/internal/TypeIntrinsics;->castToCollection(Ljava/lang/Object;)Ljava/util/Collection;
+PLkotlin/math/MathKt;->getSign(I)I
+PLkotlin/math/MathKt__MathJVMKt;->getSign(I)I
+PLkotlin/ranges/IntRange;->equals(Ljava/lang/Object;)Z
+PLkotlin/ranges/IntRange;->isEmpty()Z
+PLkotlin/ranges/RangesKt;->coerceAtLeast(JJ)J
+PLkotlin/ranges/RangesKt;->coerceAtMost(FF)F
+PLkotlin/ranges/RangesKt;->coerceAtMost(JJ)J
+PLkotlin/ranges/RangesKt;->coerceIn(DDD)D
+PLkotlin/ranges/RangesKt;->until(II)Lkotlin/ranges/IntRange;
+PLkotlin/ranges/RangesKt___RangesKt;->coerceAtLeast(JJ)J
+PLkotlin/ranges/RangesKt___RangesKt;->coerceAtMost(FF)F
+PLkotlin/ranges/RangesKt___RangesKt;->coerceAtMost(JJ)J
+PLkotlin/ranges/RangesKt___RangesKt;->coerceIn(DDD)D
+PLkotlin/ranges/RangesKt___RangesKt;->until(II)Lkotlin/ranges/IntRange;
+PLkotlin/sequences/SequenceBuilderIterator;-><init>()V
+PLkotlin/sequences/SequenceBuilderIterator;->getContext()Lkotlin/coroutines/CoroutineContext;
+PLkotlin/sequences/SequenceBuilderIterator;->hasNext()Z
+PLkotlin/sequences/SequenceBuilderIterator;->next()Ljava/lang/Object;
+PLkotlin/sequences/SequenceBuilderIterator;->resumeWith(Ljava/lang/Object;)V
+PLkotlin/sequences/SequenceBuilderIterator;->setNextStep(Lkotlin/coroutines/Continuation;)V
+PLkotlin/sequences/SequenceBuilderIterator;->yield(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLkotlin/sequences/SequenceScope;-><init>()V
+PLkotlin/sequences/SequencesKt;->sequence(Lkotlin/jvm/functions/Function2;)Lkotlin/sequences/Sequence;
+PLkotlin/sequences/SequencesKt__SequenceBuilderKt$sequence$$inlined$Sequence$1;-><init>(Lkotlin/jvm/functions/Function2;)V
+PLkotlin/sequences/SequencesKt__SequenceBuilderKt$sequence$$inlined$Sequence$1;->iterator()Ljava/util/Iterator;
+PLkotlin/sequences/SequencesKt__SequenceBuilderKt;->iterator(Lkotlin/jvm/functions/Function2;)Ljava/util/Iterator;
+PLkotlin/sequences/SequencesKt__SequenceBuilderKt;->sequence(Lkotlin/jvm/functions/Function2;)Lkotlin/sequences/Sequence;
+PLkotlin/text/StringsKt;->appendElement(Ljava/lang/Appendable;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
+PLkotlin/text/StringsKt__AppendableKt;->appendElement(Ljava/lang/Appendable;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
+PLkotlinx/coroutines/AbstractTimeSourceKt;-><clinit>()V
+PLkotlinx/coroutines/AbstractTimeSourceKt;->getTimeSource()Lkotlinx/coroutines/AbstractTimeSource;
+PLkotlinx/coroutines/CancellableContinuationImpl;->cancelCompletedResult$external__kotlinx_coroutines__android_common__kotlinx_coroutines(Ljava/lang/Object;Ljava/lang/Throwable;)V
+PLkotlinx/coroutines/CancellableContinuationKt;->disposeOnCancellation(Lkotlinx/coroutines/CancellableContinuation;Lkotlinx/coroutines/DisposableHandle;)V
+PLkotlinx/coroutines/CancellableContinuationKt;->removeOnCancellation(Lkotlinx/coroutines/CancellableContinuation;Lkotlinx/coroutines/internal/LockFreeLinkedListNode;)V
+PLkotlinx/coroutines/CoroutineScopeKt;->cancel$default(Lkotlinx/coroutines/CoroutineScope;Ljava/util/concurrent/CancellationException;ILjava/lang/Object;)V
+PLkotlinx/coroutines/CoroutineScopeKt;->cancel(Lkotlinx/coroutines/CoroutineScope;Ljava/util/concurrent/CancellationException;)V
+PLkotlinx/coroutines/DefaultExecutor;->acknowledgeShutdownIfNeeded()V
+PLkotlinx/coroutines/DefaultExecutor;->createThreadSync()Ljava/lang/Thread;
+PLkotlinx/coroutines/DefaultExecutor;->getThread()Ljava/lang/Thread;
+PLkotlinx/coroutines/DefaultExecutor;->isShutdownRequested()Z
+PLkotlinx/coroutines/DefaultExecutor;->notifyStartup()Z
+PLkotlinx/coroutines/DefaultExecutor;->run()V
+PLkotlinx/coroutines/DelayKt;->delay(JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLkotlinx/coroutines/DelayKt;->getDelay(Lkotlin/coroutines/CoroutineContext;)Lkotlinx/coroutines/Delay;
+PLkotlinx/coroutines/DisposeOnCancel;-><init>(Lkotlinx/coroutines/DisposableHandle;)V
+PLkotlinx/coroutines/DisposeOnCancel;->invoke(Ljava/lang/Throwable;)V
+PLkotlinx/coroutines/EventLoop;->getNextTime()J
+PLkotlinx/coroutines/EventLoop;->isUnconfinedQueueEmpty()Z
+PLkotlinx/coroutines/EventLoopImplBase$DelayedResumeTask;-><init>(Lkotlinx/coroutines/EventLoopImplBase;JLkotlinx/coroutines/CancellableContinuation;)V
+PLkotlinx/coroutines/EventLoopImplBase$DelayedTask;-><init>(J)V
+PLkotlinx/coroutines/EventLoopImplBase$DelayedTask;->dispose()V
+PLkotlinx/coroutines/EventLoopImplBase$DelayedTask;->getHeap()Lkotlinx/coroutines/internal/ThreadSafeHeap;
+PLkotlinx/coroutines/EventLoopImplBase$DelayedTask;->getIndex()I
+PLkotlinx/coroutines/EventLoopImplBase$DelayedTask;->scheduleTask(JLkotlinx/coroutines/EventLoopImplBase$DelayedTaskQueue;Lkotlinx/coroutines/EventLoopImplBase;)I
+PLkotlinx/coroutines/EventLoopImplBase$DelayedTask;->setHeap(Lkotlinx/coroutines/internal/ThreadSafeHeap;)V
+PLkotlinx/coroutines/EventLoopImplBase$DelayedTask;->setIndex(I)V
+PLkotlinx/coroutines/EventLoopImplBase$DelayedTask;->timeToExecute(J)Z
+PLkotlinx/coroutines/EventLoopImplBase$DelayedTaskQueue;-><init>(J)V
+PLkotlinx/coroutines/EventLoopImplBase;->access$isCompleted(Lkotlinx/coroutines/EventLoopImplBase;)Z
+PLkotlinx/coroutines/EventLoopImplBase;->dequeue()Ljava/lang/Runnable;
+PLkotlinx/coroutines/EventLoopImplBase;->getNextTime()J
+PLkotlinx/coroutines/EventLoopImplBase;->isCompleted()Z
+PLkotlinx/coroutines/EventLoopImplBase;->isEmpty()Z
+PLkotlinx/coroutines/EventLoopImplBase;->processNextEvent()J
+PLkotlinx/coroutines/EventLoopImplBase;->schedule(JLkotlinx/coroutines/EventLoopImplBase$DelayedTask;)V
+PLkotlinx/coroutines/EventLoopImplBase;->scheduleImpl(JLkotlinx/coroutines/EventLoopImplBase$DelayedTask;)I
+PLkotlinx/coroutines/EventLoopImplBase;->scheduleResumeAfterDelay(JLkotlinx/coroutines/CancellableContinuation;)V
+PLkotlinx/coroutines/EventLoopImplBase;->shouldUnpark(Lkotlinx/coroutines/EventLoopImplBase$DelayedTask;)Z
+PLkotlinx/coroutines/EventLoopImplPlatform;->unpark()V
+PLkotlinx/coroutines/EventLoop_commonKt;-><clinit>()V
+PLkotlinx/coroutines/EventLoop_commonKt;->access$getDISPOSED_TASK$p()Lkotlinx/coroutines/internal/Symbol;
+PLkotlinx/coroutines/EventLoop_commonKt;->delayToNanos(J)J
+PLkotlinx/coroutines/ExceptionsKt;->CancellationException(Ljava/lang/String;Ljava/lang/Throwable;)Ljava/util/concurrent/CancellationException;
+PLkotlinx/coroutines/InvokeOnCompletion;->invoke(Ljava/lang/Throwable;)V
+PLkotlinx/coroutines/JobImpl;->getOnCancelComplete$external__kotlinx_coroutines__android_common__kotlinx_coroutines()Z
+PLkotlinx/coroutines/JobKt;->cancelAndJoin(Lkotlinx/coroutines/Job;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLkotlinx/coroutines/JobKt__JobKt;->cancelAndJoin(Lkotlinx/coroutines/Job;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLkotlinx/coroutines/JobSupport$ChildCompletion;-><init>(Lkotlinx/coroutines/JobSupport;Lkotlinx/coroutines/JobSupport$Finishing;Lkotlinx/coroutines/ChildHandleNode;Ljava/lang/Object;)V
+PLkotlinx/coroutines/JobSupport$ChildCompletion;->invoke(Ljava/lang/Throwable;)V
+PLkotlinx/coroutines/JobSupport$Finishing;->isSealed()Z
+PLkotlinx/coroutines/JobSupport$Finishing;->setRootCause(Ljava/lang/Throwable;)V
+PLkotlinx/coroutines/JobSupport;->access$continueCompleting(Lkotlinx/coroutines/JobSupport;Lkotlinx/coroutines/JobSupport$Finishing;Lkotlinx/coroutines/ChildHandleNode;Ljava/lang/Object;)V
+PLkotlinx/coroutines/JobSupport;->cancellationExceptionMessage()Ljava/lang/String;
+PLkotlinx/coroutines/JobSupport;->continueCompleting(Lkotlinx/coroutines/JobSupport$Finishing;Lkotlinx/coroutines/ChildHandleNode;Ljava/lang/Object;)V
+PLkotlinx/coroutines/JobSupport;->join(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLkotlinx/coroutines/JobSupport;->joinInternal()Z
+PLkotlinx/coroutines/JobSupport;->joinSuspend(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLkotlinx/coroutines/JobSupport;->onCompletionInternal(Ljava/lang/Object;)V
+PLkotlinx/coroutines/JobSupport;->tryWaitForChild(Lkotlinx/coroutines/JobSupport$Finishing;Lkotlinx/coroutines/ChildHandleNode;Ljava/lang/Object;)Z
+PLkotlinx/coroutines/JobSupportKt;->access$getTOO_LATE_TO_CANCEL$p()Lkotlinx/coroutines/internal/Symbol;
+PLkotlinx/coroutines/RemoveOnCancel;-><init>(Lkotlinx/coroutines/internal/LockFreeLinkedListNode;)V
+PLkotlinx/coroutines/ResumeOnCompletion;-><init>(Lkotlin/coroutines/Continuation;)V
+PLkotlinx/coroutines/ResumeOnCompletion;->invoke(Ljava/lang/Throwable;)V
+PLkotlinx/coroutines/ThreadLocalEventLoop;->setEventLoop$external__kotlinx_coroutines__android_common__kotlinx_coroutines(Lkotlinx/coroutines/EventLoop;)V
+PLkotlinx/coroutines/UndispatchedCoroutine;->afterResume(Ljava/lang/Object;)V
+PLkotlinx/coroutines/channels/AbstractChannel$RemoveReceiveOnCancel;->invoke(Ljava/lang/Throwable;)V
+PLkotlinx/coroutines/channels/AbstractSendChannel$SendBuffered;-><init>(Ljava/lang/Object;)V
+PLkotlinx/coroutines/channels/AbstractSendChannel$SendBuffered;->completeResumeSend()V
+PLkotlinx/coroutines/channels/AbstractSendChannel$SendBuffered;->getPollResult()Ljava/lang/Object;
+PLkotlinx/coroutines/channels/AbstractSendChannel$SendBuffered;->tryResumeSend(Lkotlinx/coroutines/internal/LockFreeLinkedListNode$PrepareOp;)Lkotlinx/coroutines/internal/Symbol;
+PLkotlinx/coroutines/channels/AbstractSendChannel;->sendBuffered(Ljava/lang/Object;)Lkotlinx/coroutines/channels/ReceiveOrClosed;
+PLkotlinx/coroutines/channels/LinkedListChannel;->offerInternal(Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlinx/coroutines/channels/Send;-><init>()V
+PLkotlinx/coroutines/flow/AbstractFlow$collect$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/DistinctFlowImpl$collect$2$emit$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/FlowKt__DistinctKt$defaultAreEquivalent$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Boolean;
+PLkotlinx/coroutines/flow/FlowKt__DistinctKt$defaultAreEquivalent$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/FlowKt__LimitKt$dropWhile$1$1$emit$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/FlowKt__LimitKt$emitAbort$1;-><init>(Lkotlin/coroutines/Continuation;)V
+PLkotlinx/coroutines/flow/FlowKt__LimitKt$emitAbort$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/FlowKt__LimitKt$take$$inlined$unsafeFlow$1$1;-><init>(Lkotlinx/coroutines/flow/FlowKt__LimitKt$take$$inlined$unsafeFlow$1;Lkotlin/coroutines/Continuation;)V
+PLkotlinx/coroutines/flow/FlowKt__LimitKt$take$$inlined$unsafeFlow$1$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/FlowKt__LimitKt$take$$inlined$unsafeFlow$1;->collect(Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/FlowKt__LimitKt$take$2$1$emit$1;-><init>(Lkotlinx/coroutines/flow/FlowKt__LimitKt$take$2$1;Lkotlin/coroutines/Continuation;)V
+PLkotlinx/coroutines/flow/FlowKt__LimitKt$take$2$1$emit$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/FlowKt__LimitKt$take$2$1;-><init>(Lkotlin/jvm/internal/Ref$IntRef;ILkotlinx/coroutines/flow/FlowCollector;)V
+PLkotlinx/coroutines/flow/FlowKt__LimitKt$take$2$1;->emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/FlowKt__LimitKt;->access$emitAbort$FlowKt__LimitKt(Lkotlinx/coroutines/flow/FlowCollector;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/FlowKt__LimitKt;->emitAbort$FlowKt__LimitKt(Lkotlinx/coroutines/flow/FlowCollector;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/FlowKt__ReduceKt$first$3;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/SharedFlowImpl$collect$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/SharedFlowImpl;->emit$suspendImpl(Lkotlinx/coroutines/flow/SharedFlowImpl;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/SharedFlowImpl;->emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/SharedFlowImpl;->getQueueEndIndex()J
+PLkotlinx/coroutines/flow/SharedFlowSlot;->freeLocked(Ljava/lang/Object;)[Lkotlin/coroutines/Continuation;
+PLkotlinx/coroutines/flow/SharedFlowSlot;->freeLocked(Lkotlinx/coroutines/flow/SharedFlowImpl;)[Lkotlin/coroutines/Continuation;
+PLkotlinx/coroutines/flow/StartedWhileSubscribed;->access$getReplayExpiration$p(Lkotlinx/coroutines/flow/StartedWhileSubscribed;)J
+PLkotlinx/coroutines/flow/StartedWhileSubscribed;->access$getStopTimeout$p(Lkotlinx/coroutines/flow/StartedWhileSubscribed;)J
+PLkotlinx/coroutines/flow/StateFlowSlot;->freeLocked(Ljava/lang/Object;)[Lkotlin/coroutines/Continuation;
+PLkotlinx/coroutines/flow/StateFlowSlot;->freeLocked(Lkotlinx/coroutines/flow/StateFlowImpl;)[Lkotlin/coroutines/Continuation;
+PLkotlinx/coroutines/flow/internal/AbortFlowException;-><init>(Lkotlinx/coroutines/flow/FlowCollector;)V
+PLkotlinx/coroutines/flow/internal/AbortFlowException;->fillInStackTrace()Ljava/lang/Throwable;
+PLkotlinx/coroutines/flow/internal/AbstractSharedFlow;->freeSlot(Lkotlinx/coroutines/flow/internal/AbstractSharedFlowSlot;)V
+PLkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest$flowCollect$3$1$emit$1;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/internal/ChildCancelledException;-><init>()V
+PLkotlinx/coroutines/flow/internal/ChildCancelledException;->fillInStackTrace()Ljava/lang/Throwable;
+PLkotlinx/coroutines/flow/internal/DownstreamExceptionContext;-><init>(Ljava/lang/Throwable;Lkotlin/coroutines/CoroutineContext;)V
+PLkotlinx/coroutines/flow/internal/FlowExceptions_commonKt;->checkOwnership(Lkotlinx/coroutines/flow/internal/AbortFlowException;Lkotlinx/coroutines/flow/FlowCollector;)V
+PLkotlinx/coroutines/flow/internal/NopCollector;->emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/internal/SafeCollector;->checkContext(Lkotlin/coroutines/CoroutineContext;Lkotlin/coroutines/CoroutineContext;Ljava/lang/Object;)V
+PLkotlinx/coroutines/flow/internal/SafeCollector;->emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/internal/SafeCollector;->emit(Lkotlin/coroutines/Continuation;Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/internal/SafeCollector;->getContext()Lkotlin/coroutines/CoroutineContext;
+PLkotlinx/coroutines/flow/internal/SafeCollector;->invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/internal/SafeCollector;->releaseIntercepted()V
+PLkotlinx/coroutines/flow/internal/SafeCollectorKt$emitFun$1;-><clinit>()V
+PLkotlinx/coroutines/flow/internal/SafeCollectorKt$emitFun$1;-><init>()V
+PLkotlinx/coroutines/flow/internal/SafeCollectorKt$emitFun$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/internal/SafeCollectorKt$emitFun$1;->invoke(Lkotlinx/coroutines/flow/FlowCollector;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/internal/SafeCollectorKt;-><clinit>()V
+PLkotlinx/coroutines/flow/internal/SafeCollectorKt;->access$getEmitFun$p()Lkotlin/jvm/functions/Function3;
+PLkotlinx/coroutines/flow/internal/SafeCollector_commonKt$checkContext$result$1;-><init>(Lkotlinx/coroutines/flow/internal/SafeCollector;)V
+PLkotlinx/coroutines/flow/internal/SafeCollector_commonKt$checkContext$result$1;->invoke(ILkotlin/coroutines/CoroutineContext$Element;)Ljava/lang/Integer;
+PLkotlinx/coroutines/flow/internal/SafeCollector_commonKt$checkContext$result$1;->invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlinx/coroutines/flow/internal/SafeCollector_commonKt;->checkContext(Lkotlinx/coroutines/flow/internal/SafeCollector;Lkotlin/coroutines/CoroutineContext;)V
+PLkotlinx/coroutines/flow/internal/SafeCollector_commonKt;->transitiveCoroutineParent(Lkotlinx/coroutines/Job;Lkotlinx/coroutines/Job;)Lkotlinx/coroutines/Job;
+PLkotlinx/coroutines/internal/DispatchedContinuation;->postponeCancellation(Ljava/lang/Throwable;)Z
+PLkotlinx/coroutines/internal/LockFreeLinkedListHead;->isEmpty()Z
+PLkotlinx/coroutines/internal/LockFreeLinkedListNode;->addLast(Lkotlinx/coroutines/internal/LockFreeLinkedListNode;)V
+PLkotlinx/coroutines/internal/LockFreeLinkedListNode;->findPrevNonRemoved(Lkotlinx/coroutines/internal/LockFreeLinkedListNode;)Lkotlinx/coroutines/internal/LockFreeLinkedListNode;
+PLkotlinx/coroutines/internal/LockFreeLinkedListNode;->removeFirstOrNull()Lkotlinx/coroutines/internal/LockFreeLinkedListNode;
+PLkotlinx/coroutines/internal/ThreadSafeHeap;-><init>()V
+PLkotlinx/coroutines/internal/ThreadSafeHeap;->addImpl(Lkotlinx/coroutines/internal/ThreadSafeHeapNode;)V
+PLkotlinx/coroutines/internal/ThreadSafeHeap;->firstImpl()Lkotlinx/coroutines/internal/ThreadSafeHeapNode;
+PLkotlinx/coroutines/internal/ThreadSafeHeap;->getSize()I
+PLkotlinx/coroutines/internal/ThreadSafeHeap;->isEmpty()Z
+PLkotlinx/coroutines/internal/ThreadSafeHeap;->peek()Lkotlinx/coroutines/internal/ThreadSafeHeapNode;
+PLkotlinx/coroutines/internal/ThreadSafeHeap;->realloc()[Lkotlinx/coroutines/internal/ThreadSafeHeapNode;
+PLkotlinx/coroutines/internal/ThreadSafeHeap;->remove(Lkotlinx/coroutines/internal/ThreadSafeHeapNode;)Z
+PLkotlinx/coroutines/internal/ThreadSafeHeap;->removeAtImpl(I)Lkotlinx/coroutines/internal/ThreadSafeHeapNode;
+PLkotlinx/coroutines/internal/ThreadSafeHeap;->setSize(I)V
+PLkotlinx/coroutines/internal/ThreadSafeHeap;->siftUpFrom(I)V
+PLkotlinx/coroutines/sync/Mutex$DefaultImpls;->unlock$default(Lkotlinx/coroutines/sync/Mutex;Ljava/lang/Object;ILjava/lang/Object;)V
+PLkotlinx/coroutines/sync/MutexImpl$LockCont$tryResumeLockWaiter$1;-><init>(Lkotlinx/coroutines/sync/MutexImpl;Lkotlinx/coroutines/sync/MutexImpl$LockCont;)V
+PLkotlinx/coroutines/sync/MutexImpl$LockCont;-><init>(Lkotlinx/coroutines/sync/MutexImpl;Ljava/lang/Object;Lkotlinx/coroutines/CancellableContinuation;)V
+PLkotlinx/coroutines/sync/MutexImpl$LockCont;->completeResumeLockWaiter()V
+PLkotlinx/coroutines/sync/MutexImpl$LockCont;->tryResumeLockWaiter()Z
+PLkotlinx/coroutines/sync/MutexImpl$LockWaiter;-><init>(Lkotlinx/coroutines/sync/MutexImpl;Ljava/lang/Object;)V
+PLkotlinx/coroutines/sync/MutexImpl$LockWaiter;->take()Z
+PLkotlinx/coroutines/sync/MutexImpl$LockedQueue;-><init>(Ljava/lang/Object;)V
+PLkotlinx/coroutines/sync/MutexImpl$UnlockOp;-><init>(Lkotlinx/coroutines/sync/MutexImpl$LockedQueue;)V
+PLkotlinx/coroutines/sync/MutexImpl$UnlockOp;->complete(Ljava/lang/Object;Ljava/lang/Object;)V
+PLkotlinx/coroutines/sync/MutexImpl$UnlockOp;->complete(Lkotlinx/coroutines/sync/MutexImpl;Ljava/lang/Object;)V
+PLkotlinx/coroutines/sync/MutexImpl$UnlockOp;->prepare(Ljava/lang/Object;)Ljava/lang/Object;
+PLkotlinx/coroutines/sync/MutexImpl$UnlockOp;->prepare(Lkotlinx/coroutines/sync/MutexImpl;)Ljava/lang/Object;
+PLkotlinx/coroutines/sync/MutexImpl;->access$get_state$p(Lkotlinx/coroutines/sync/MutexImpl;)Lkotlinx/atomicfu/AtomicRef;
+PLkotlinx/coroutines/sync/MutexImpl;->lockSuspend(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+PLkotlinx/coroutines/sync/MutexKt;->access$getLOCKED$p()Lkotlinx/coroutines/internal/Symbol;
+[Landroidx/compose/animation/core/AnimationEndReason;
+[Landroidx/compose/animation/core/MutatePriority;
+[Landroidx/compose/foundation/MutatePriority;
+[Landroidx/compose/foundation/gestures/Orientation;
+[Landroidx/compose/foundation/layout/Direction;
+[Landroidx/compose/foundation/layout/LayoutOrientation;
+[Landroidx/compose/foundation/layout/RowColumnParentData;
+[Landroidx/compose/foundation/layout/SizeMode;
+[Landroidx/compose/foundation/relocation/BringIntoViewRequesterModifier;
+[Landroidx/compose/material3/tokens/ColorSchemeKeyTokens;
+[Landroidx/compose/material3/tokens/ShapeKeyTokens;
+[Landroidx/compose/material3/tokens/TypographyKeyTokens;
+[Landroidx/compose/runtime/InvalidationResult;
+[Landroidx/compose/runtime/ParcelableSnapshotMutableState;
+[Landroidx/compose/runtime/ProvidedValue;
+[Landroidx/compose/runtime/Recomposer$State;
+[Landroidx/compose/runtime/collection/IdentityArraySet;
+[Landroidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNodeBaseIterator;
+[Landroidx/compose/runtime/snapshots/SnapshotStateObserver$ObservedScopeMap;
+[Landroidx/compose/ui/Modifier$Element;
+[Landroidx/compose/ui/Modifier$Node;
+[Landroidx/compose/ui/Modifier;
+[Landroidx/compose/ui/focus/FocusEventModifierLocal;
+[Landroidx/compose/ui/focus/FocusModifier;
+[Landroidx/compose/ui/focus/FocusRequesterModifierLocal;
+[Landroidx/compose/ui/focus/FocusStateImpl;
+[Landroidx/compose/ui/graphics/colorspace/ColorSpace;
+[Landroidx/compose/ui/input/key/KeyInputModifier;
+[Landroidx/compose/ui/input/pointer/Node;
+[Landroidx/compose/ui/input/pointer/PointerEventPass;
+[Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilter$PointerEventHandlerCoroutine;
+[Landroidx/compose/ui/input/pointer/util/PointAtTime;
+[Landroidx/compose/ui/layout/Measurable;
+[Landroidx/compose/ui/layout/Placeable;
+[Landroidx/compose/ui/modifier/ModifierLocal;
+[Landroidx/compose/ui/node/BackwardsCompatNode;
+[Landroidx/compose/ui/node/LayoutNode$LayoutState;
+[Landroidx/compose/ui/node/LayoutNode$UsageByParent;
+[Landroidx/compose/ui/node/LayoutNode;
+[Landroidx/compose/ui/node/MeasureAndLayoutDelegate$PostponedRequest;
+[Landroidx/compose/ui/node/Owner$OnLayoutCompletedListener;
+[Landroidx/compose/ui/platform/TextToolbarStatus;
+[Landroidx/compose/ui/text/android/style/LineHeightStyleSpan;
+[Landroidx/compose/ui/text/android/style/PlaceholderSpan;
+[Landroidx/compose/ui/text/font/FontWeight;
+[Landroidx/compose/ui/text/platform/style/ShaderBrushSpan;
+[Landroidx/compose/ui/unit/LayoutDirection;
+[Landroidx/compose/ui/unit/TextUnitType;
+[Landroidx/core/content/res/FontResourcesParserCompat$FontFileResourceEntry;
+[Landroidx/core/provider/FontsContractCompat$FontInfo;
+[Landroidx/emoji2/text/EmojiCompat$InitCallback;
+[Landroidx/emoji2/text/EmojiSpan;
+[Landroidx/lifecycle/GeneratedAdapter;
+[Landroidx/lifecycle/Lifecycle$Event;
+[Landroidx/lifecycle/Lifecycle$State;
+[Landroidx/lifecycle/viewmodel/ViewModelInitializer;
+[Lcom/android/credentialmanager/common/DialogType;
+[Lcom/android/credentialmanager/common/material/ModalBottomSheetValue;
+[Lcom/android/credentialmanager/createflow/CreateScreenState;
+[Lcom/android/credentialmanager/jetpack/provider/CredentialCountInformation;
+[Lkotlin/LazyThreadSafetyMode;
+[Lkotlin/Pair;
+[Lkotlin/coroutines/Continuation;
+[Lkotlin/coroutines/CoroutineContext;
+[Lkotlin/coroutines/intrinsics/CoroutineSingletons;
+[Lkotlin/jvm/functions/Function0;
+[Lkotlin/reflect/KClass;
+[Lkotlin/reflect/KProperty;
+[Lkotlinx/atomicfu/AtomicRef;
+[Lkotlinx/coroutines/CoroutineStart;
+[Lkotlinx/coroutines/channels/BufferOverflow;
+[Lkotlinx/coroutines/flow/SharedFlowSlot;
+[Lkotlinx/coroutines/flow/SharingCommand;
+[Lkotlinx/coroutines/flow/StateFlowSlot;
+[Lkotlinx/coroutines/flow/internal/AbstractSharedFlowSlot;
diff --git a/packages/CredentialManager/res/values/strings.xml b/packages/CredentialManager/res/values/strings.xml
index 91ffc44..81505e1 100644
--- a/packages/CredentialManager/res/values/strings.xml
+++ b/packages/CredentialManager/res/values/strings.xml
@@ -5,63 +5,49 @@
<string name="app_name">Credential Manager</string>
<!-- Strings for the create flow. -->
- <!-- Button label to close the dialog when the user does not want to create the credential. [CHAR LIMIT=40] -->
+ <!-- Button label to close the dialog when the user does not want to create the credential. [CHAR LIMIT=20] -->
<string name="string_cancel">Cancel</string>
- <!-- Button label to confirm choosing the default dialog information and continue. [CHAR LIMIT=40] -->
+ <!-- This is a label for a button that takes user to the next screen. [CHAR LIMIT=20] -->
<string name="string_continue">Continue</string>
- <!-- Button label to create this credential in other available places. [CHAR LIMIT=40] -->
+ <!-- This is a label for a button that links to different places where the user can save their passkeys. [CHAR LIMIT=20] -->
<string name="string_more_options">More options</string>
- <!-- This appears as a text button where users can click to create this passkey in other available places. [CHAR LIMIT=80] -->
- <string name="string_create_in_another_place">Create in another place</string>
- <!-- This appears as a text button where users can click to create this password or other credential types in other available places. [CHAR LIMIT=80] -->
- <string name="string_save_to_another_place">Save to another place</string>
- <!-- This appears as a text button where users can click to use another device to create this credential. [CHAR LIMIT=80] -->
- <string name="string_use_another_device">Use another device</string>
- <!-- This appears as a text button where users can click to save this credential to another device. [CHAR LIMIT=80] -->
- <string name="string_save_to_another_device">Save to another device</string>
- <!-- This appears as the title of the modal bottom sheet introducing what is passkey to users. [CHAR LIMIT=200] -->
+ <!-- This string introduces passkeys to the users for the first time they use this method. Tip: to avoid gendered language patterns, this header could be translated as if the original string were "More safety with passkeys". [CHAR LIMIT=200] -->
<string name="passkey_creation_intro_title">Safer with passkeys</string>
- <!-- This appears as the description body of the modal bottom sheet introducing why passkey beneficial on the passwords side. [CHAR LIMIT=200] -->
+ <!-- These strings highlight passkey benefits. [CHAR LIMIT=200] -->
<string name="passkey_creation_intro_body_password">With passkeys, you don’t need to create or remember complex passwords</string>
- <!-- This appears as the description body of the modal bottom sheet introducing why passkey beneficial on the safety side. [CHAR LIMIT=200] -->
<string name="passkey_creation_intro_body_fingerprint">Passkeys are encrypted digital keys you create using your fingerprint, face, or screen lock</string>
- <!-- This appears as the description body of the modal bottom sheet introducing why passkey beneficial on the using other devices side. [CHAR LIMIT=200] -->
<string name="passkey_creation_intro_body_device">They are saved to a password manager, so you can sign in on other devices</string>
- <!-- This appears as the title of the modal bottom sheet which provides all available providers for users to choose. [CHAR LIMIT=200] -->
- <string name="choose_provider_title">Choose where to <xliff:g id="createTypes" example="create your passkeys">%1$s</xliff:g></string>
- <!-- Create types which are inserted as a placeholder for string choose_provider_title. [CHAR LIMIT=200] -->
- <string name="create_your_passkeys">create your passkeys</string>
- <string name="save_your_password">save your password</string>
- <string name="save_your_sign_in_info">save your sign-in info</string>
+ <!-- This appears as the title of the modal bottom sheet which provides all available providers for users to choose. [CHAR LIMIT=200] -->
+ <string name="choose_provider_title">Choose where to save your <xliff:g id="createTypes" example="passkeys">%1$s</xliff:g></string>
<!-- This appears as the description body of the modal bottom sheet which provides all available providers for users to choose. [CHAR LIMIT=200] -->
- <string name="choose_provider_body">Select a password manager to save your info and sign in faster next time.</string>
+ <string name="choose_provider_body">Select a password manager to save your info and sign in faster next time</string>
<!-- This appears as the title of the modal bottom sheet for users to choose the create option inside a provider when the credential type is passkey. [CHAR LIMIT=200] -->
<string name="choose_create_option_passkey_title">Create passkey for <xliff:g id="appName" example="Tribank">%1$s</xliff:g>?</string>
<!-- This appears as the title of the modal bottom sheet for users to choose the create option inside a provider when the credential type is password. [CHAR LIMIT=200] -->
<string name="choose_create_option_password_title">Save password for <xliff:g id="appName" example="Tribank">%1$s</xliff:g>?</string>
<!-- This appears as the title of the modal bottom sheet for users to choose the create option inside a provider when the credential type is others. [CHAR LIMIT=200] -->
<string name="choose_create_option_sign_in_title">Save sign-in info for <xliff:g id="appName" example="Tribank">%1$s</xliff:g>?</string>
- <!-- This appears as the description body of the modal bottom sheet for users to choose the create option inside a provider. [CHAR LIMIT=200] -->
- <string name="choose_create_option_description">You can use your <xliff:g id="appDomainName" example="Tribank">%1$s</xliff:g> <xliff:g id="credentialTypes" example="passkey">%2$s</xliff:g> on any device. It is saved to <xliff:g id="providerInfoDisplayName" example="Google Password Manager">%3$s</xliff:g> for <xliff:g id="createInfoDisplayName" example="elisa.beckett@gmail.com">%4$s</xliff:g>.</string>
<!-- Types which are inserted as a placeholder as credentialTypes for other strings. [CHAR LIMIT=200] -->
<string name="passkey">passkey</string>
<string name="password">password</string>
+ <string name="passkeys">passkeys</string>
+ <string name="passwords">passwords</string>
<string name="sign_ins">sign-ins</string>
<string name="sign_in_info">sign-in info</string>
- <!-- This appears as the title of the modal bottom sheet for users to choose other available places the created password can be saved to. [CHAR LIMIT=200] -->
+ <!-- This text is followed by a list of one or more options. [CHAR LIMIT=200] -->
<string name="save_credential_to_title">Save <xliff:g id="credentialTypes" example="passkey">%1$s</xliff:g> to</string>
<!-- This appears as the title of the modal bottom sheet for users to choose to create a passkey on another device. [CHAR LIMIT=200] -->
- <string name="create_passkey_in_other_device_title">Create a passkey in another device?</string>
+ <string name="create_passkey_in_other_device_title">Create passkey in another device?</string>
<!-- This appears as the title of the modal bottom sheet for users to confirm whether they should use the selected provider as default or not. [CHAR LIMIT=200] -->
<string name="use_provider_for_all_title">Use <xliff:g id="providerInfoDisplayName" example="Google Password Manager">%1$s</xliff:g> for all your sign-ins?</string>
<!-- TODO: Check the wording here. -->
<!-- This appears as the description body of the modal bottom sheet for users to confirm whether they should use the selected provider as default or not. [CHAR LIMIT=200] -->
- <string name="use_provider_for_all_description">This password manager will store your passwords and passkeys to help you easily sign in.</string>
- <!-- Button label to set the selected provider on the modal bottom sheet as default. [CHAR LIMIT=40] -->
+ <string name="use_provider_for_all_description">This password manager will store your passwords and passkeys to help you easily sign in</string>
+ <!-- This is a label for a button that sets this password manager as the default. [CHAR LIMIT=20] -->
<string name="set_as_default">Set as default</string>
- <!-- Button label to set the selected provider on the modal bottom sheet not as default but just use once. [CHAR LIMIT=40] -->
+ <!-- This is a label for a button that makes this password manager be used just in this specific case. [CHAR LIMIT=20] -->
<string name="use_once">Use once</string>
<!-- Appears as an option row subtitle to show how many passwords and passkeys are saved in this option when there are passwords and passkeys. [CHAR LIMIT=80] -->
<string name="more_options_usage_passwords_passkeys"><xliff:g id="passwordsNumber" example="1">%1$s</xliff:g> passwords • <xliff:g id="passkeysNumber" example="2">%2$s</xliff:g> passkeys</string>
@@ -73,7 +59,7 @@
<string name="more_options_usage_credentials"><xliff:g id="totalCredentialsNumber" example="5">%1$s</xliff:g> credentials</string>
<!-- Appears before a request display name when the credential type is passkey . [CHAR LIMIT=80] -->
<string name="passkey_before_subtitle">Passkey</string>
- <!-- Appears as an option row title that users can choose to use another device for this creation. [CHAR LIMIT=80] -->
+ <!-- This is a label for a button that lets users save their passkey to a different device. [CHAR LIMIT=80] -->
<string name="another_device">Another device</string>
<!-- Appears as an option row title that users can choose to view other disabled providers. [CHAR LIMIT=80] -->
<string name="other_password_manager">Other password managers</string>
@@ -91,15 +77,15 @@
<string name="get_dialog_title_use_sign_in_for">Use your saved sign-in for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g>?</string>
<!-- This appears as the title of the dialog asking for user to make a choice from various previously saved credentials to sign in to the app. [CHAR LIMIT=200] -->
<string name="get_dialog_title_choose_sign_in_for">Choose a saved sign-in for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g></string>
- <!-- Appears as an option row for viewing all the available sign-in options. [CHAR LIMIT=80] -->
+ <!-- This is a label for a button that links the user to different sign-in methods . [CHAR LIMIT=80] -->
<string name="get_dialog_use_saved_passkey_for">Sign in another way</string>
- <!-- Appears as a text button in the snackbar for users to click to view all options. [CHAR LIMIT=80] -->
+ <!-- This is a label for a button that links the user to different sign-in methods. [CHAR LIMIT=80] -->
<string name="snackbar_action">View options</string>
- <!-- Button label to continue with the selected sign-in. [CHAR LIMIT=40] -->
+ <!-- This is a label for a button that takes user to the next screen. [CHAR LIMIT=20] -->
<string name="get_dialog_button_label_continue">Continue</string>
<!-- Separator for sign-in type and username in a sign-in entry. -->
<string name="get_dialog_sign_in_type_username_separator" translatable="false">" - "</string>
- <!-- Modal bottom sheet title for displaying all the available sign-in options. [CHAR LIMIT=80] -->
+ <!-- This text is followed by a list of one or more options. [CHAR LIMIT=80] -->
<string name="get_dialog_title_sign_in_options">Sign-in options</string>
<!-- Column heading for displaying sign-ins for a specific username. [CHAR LIMIT=80] -->
<string name="get_dialog_heading_for_username">For <xliff:g id="username" example="becket@gmail.com">%1$s</xliff:g></string>
@@ -111,6 +97,6 @@
<string name="get_dialog_heading_manage_sign_ins">Manage sign-ins</string>
<!-- Column heading for displaying option to use sign-ins saved on a different device. [CHAR LIMIT=80] -->
<string name="get_dialog_heading_from_another_device">From another device</string>
- <!-- Headline text for an option to use sign-ins saved on a different device. [CHAR LIMIT=120] -->
+ <!-- This is a label for a button that takes the user to other available devices. [CHAR LIMIT=120] -->
<string name="get_dialog_option_headline_use_a_different_device">Use a different device</string>
</resources>
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
index 86b4711..1e5bd7b 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
@@ -45,7 +45,7 @@
import com.android.credentialmanager.createflow.EnabledProviderInfo
import com.android.credentialmanager.createflow.RequestDisplayInfo
import com.android.credentialmanager.getflow.GetCredentialUiState
-import com.android.credentialmanager.jetpack.developer.CreatePasswordRequest.Companion.toBundle
+import com.android.credentialmanager.jetpack.developer.CreatePasswordRequest.Companion.toCredentialDataBundle
import com.android.credentialmanager.jetpack.developer.CreatePublicKeyCredentialRequest
import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
import com.android.credentialmanager.jetpack.provider.Action
@@ -176,9 +176,11 @@
.setSaveEntries(
listOf<Entry>(
newCreateEntry("key1", "subkey-1", "elisa.beckett@gmail.com",
- 20, 7, 27, 10L),
+ 20, 7, 27, 10L,
+ "Optional footer description"),
newCreateEntry("key1", "subkey-2", "elisa.work@google.com",
- 20, 7, 27, 12L),
+ 20, 7, 27, 12L,
+ null),
)
)
.setRemoteEntry(
@@ -190,9 +192,11 @@
.setSaveEntries(
listOf<Entry>(
newCreateEntry("key1", "subkey-3", "elisa.beckett@dashlane.com",
- 20, 7, 27, 11L),
+ 20, 7, 27, 11L,
+ null),
newCreateEntry("key1", "subkey-4", "elisa.work@dashlane.com",
- 20, 7, 27, 14L),
+ 20, 7, 27, 14L,
+ null),
)
)
.build(),
@@ -325,7 +329,7 @@
key,
subkey,
CredentialEntry.toSlice(credentialEntry),
- null
+ Intent()
)
}
@@ -337,6 +341,7 @@
passkeyCount: Int,
totalCredentialCount: Int,
lastUsedTimeMillis: Long,
+ footerDescription: String?,
): Entry {
val intent = Intent("com.androidauth.androidvault.CONFIRM_PASSWORD")
.setPackage("com.androidauth.androidvault")
@@ -348,7 +353,7 @@
android.service.credentials.CallingAppInfo(
context.applicationInfo.packageName, SigningInfo()),
TYPE_PASSWORD_CREDENTIAL,
- toBundle("beckett-bakert@gmail.com", "password123")
+ toCredentialDataBundle("beckett-bakert@gmail.com", "password123")
)
val fillInIntent = Intent().putExtra(
CredentialProviderService.EXTRA_CREATE_CREDENTIAL_REQUEST,
@@ -360,7 +365,7 @@
listOf(
CredentialCountInformation.createPasswordCountInformation(passwordCount),
CredentialCountInformation.createPublicKeyCountInformation(passkeyCount),
- ))
+ ), footerDescription)
return Entry(
key,
subkey,
@@ -417,7 +422,7 @@
" \"residentKey\": \"required\",\n" +
" \"requireResidentKey\": true\n" +
" }}")
- val credentialData = request.data
+ val credentialData = request.credentialData
return RequestInfo.newCreateRequestInfo(
Binder(),
CreateCredentialRequest(
@@ -432,7 +437,7 @@
}
private fun testCreatePasswordRequestInfo(): RequestInfo {
- val data = toBundle("beckett-bakert@gmail.com", "password123")
+ val data = toCredentialDataBundle("beckett-bakert@gmail.com", "password123")
return RequestInfo.newCreateRequestInfo(
Binder(),
CreateCredentialRequest(
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
index cdff2d4..686415f 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
@@ -16,7 +16,9 @@
package com.android.credentialmanager
+import android.content.Intent
import android.os.Bundle
+import android.provider.Settings
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult
@@ -26,7 +28,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
-import androidx.lifecycle.Observer
+import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewmodel.compose.viewModel
import com.android.credentialmanager.common.DialogType
import com.android.credentialmanager.common.DialogResult
@@ -37,6 +39,7 @@
import com.android.credentialmanager.getflow.GetCredentialScreen
import com.android.credentialmanager.getflow.GetCredentialViewModel
import com.android.credentialmanager.ui.theme.CredentialSelectorTheme
+import kotlinx.coroutines.launch
@ExperimentalMaterialApi
class CredentialSelectorActivity : ComponentActivity() {
@@ -64,10 +67,11 @@
when (dialogType) {
DialogType.CREATE_PASSKEY -> {
val viewModel: CreateCredentialViewModel = viewModel()
- viewModel.observeDialogResult().observe(
- this@CredentialSelectorActivity,
- onCancel
- )
+ lifecycleScope.launch {
+ viewModel.observeDialogResult().collect{ dialogResult ->
+ onCancel(dialogResult)
+ }
+ }
providerActivityResult.value?.let {
viewModel.onProviderActivityResult(it)
providerActivityResult.value = null
@@ -76,10 +80,11 @@
}
DialogType.GET_CREDENTIALS -> {
val viewModel: GetCredentialViewModel = viewModel()
- viewModel.observeDialogResult().observe(
- this@CredentialSelectorActivity,
- onCancel
- )
+ lifecycleScope.launch {
+ viewModel.observeDialogResult().collect{ dialogResult ->
+ onCancel(dialogResult)
+ }
+ }
providerActivityResult.value?.let {
viewModel.onProviderActivityResult(it)
providerActivityResult.value = null
@@ -93,8 +98,12 @@
}
}
- private val onCancel = Observer<DialogResult> {
- if (it.resultState == ResultState.COMPLETE || it.resultState == ResultState.CANCELED) {
+ private fun onCancel(dialogResut: DialogResult) {
+ if (dialogResut.resultState == ResultState
+ .COMPLETE || dialogResut.resultState == ResultState.NORMAL_CANCELED) {
+ this@CredentialSelectorActivity.finish()
+ } else if (dialogResut.resultState == ResultState.LAUNCH_SETTING_CANCELED) {
+ this@CredentialSelectorActivity.startActivity(Intent(Settings.ACTION_SYNC_SETTINGS))
this@CredentialSelectorActivity.finish()
}
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
index 9108f57..09f9b5e 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
@@ -44,6 +44,7 @@
import com.android.credentialmanager.jetpack.developer.CreatePublicKeyCredentialRequest
import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
import com.android.credentialmanager.jetpack.provider.Action
+import com.android.credentialmanager.jetpack.provider.AuthenticationAction
import com.android.credentialmanager.jetpack.provider.CredentialCountInformation
import com.android.credentialmanager.jetpack.provider.CredentialEntry
import com.android.credentialmanager.jetpack.provider.CreateEntry
@@ -140,16 +141,20 @@
providerIcon: Drawable,
authEntry: Entry?,
): AuthenticationEntryInfo? {
- // TODO: should also call fromSlice after getting the official jetpack code.
-
if (authEntry == null) {
return null
}
+ val authStructuredEntry = AuthenticationAction.fromSlice(
+ authEntry!!.slice)
+ if (authStructuredEntry == null) {
+ return null
+ }
+
return AuthenticationEntryInfo(
providerId = providerId,
entryKey = authEntry.key,
entrySubkey = authEntry.subkey,
- pendingIntent = authEntry.pendingIntent,
+ pendingIntent = authStructuredEntry.pendingIntent,
fillInIntent = authEntry.frameworkExtrasIntent,
title = providerDisplayName,
icon = providerIcon,
@@ -242,7 +247,7 @@
packageName = it.providerFlattenedComponentName
}
val pkgInfo = packageManager
- .getPackageInfo(packageName,
+ .getPackageInfo(packageName!!,
PackageManager.PackageInfoFlags.of(0))
DisabledProviderInfo(
icon = pkgInfo.applicationInfo.loadIcon(packageManager)!!,
@@ -264,7 +269,7 @@
val createCredentialRequest = requestInfo.createCredentialRequest
val createCredentialRequestJetpack = createCredentialRequest?.let {
CreateCredentialRequest.createFrom(
- it
+ it.type, it.credentialData, it.candidateQueryData, it.requireSystemProvider()
)
}
when (createCredentialRequestJetpack) {
@@ -431,6 +436,7 @@
totalCredentialCount = CredentialCountInformation.getTotalCount(
createEntry.credentialCountInformationList) ?: 0,
lastUsedTimeMillis = createEntry.lastUsedTimeMillis ?: 0,
+ footerDescription = createEntry.footerDescription?.toString()
)
}
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/DialogResult.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/DialogResult.kt
index b751663..743f49b 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/DialogResult.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/DialogResult.kt
@@ -18,7 +18,8 @@
enum class ResultState {
COMPLETE,
- CANCELED,
+ NORMAL_CANCELED,
+ LAUNCH_SETTING_CANCELED
}
data class DialogResult(
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
index ea305a4..498f0a1 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
@@ -78,8 +78,7 @@
disabledProviderList = uiState.disabledProviders,
sortedCreateOptionsPairs = uiState.sortedCreateOptionsPairs,
onOptionSelected = viewModel::onEntrySelectedFromFirstUseScreen,
- onDisabledPasswordManagerSelected =
- viewModel::onDisabledPasswordManagerSelected,
+ onDisabledProvidersSelected = viewModel::onDisabledProvidersSelected,
onMoreOptionsSelected = viewModel::onMoreOptionsSelectedOnProviderSelection,
)
CreateScreenState.CREATION_OPTION_SELECTION -> CreationSelectionCard(
@@ -103,8 +102,7 @@
onBackCreationSelectionButtonSelected =
viewModel::onBackCreationSelectionButtonSelected,
onOptionSelected = viewModel::onEntrySelectedFromMoreOptionScreen,
- onDisabledPasswordManagerSelected =
- viewModel::onDisabledPasswordManagerSelected,
+ onDisabledProvidersSelected = viewModel::onDisabledProvidersSelected,
onRemoteEntrySelected = viewModel::onEntrySelected,
)
CreateScreenState.MORE_OPTIONS_ROW_INTRO -> MoreOptionsRowIntroCard(
@@ -250,7 +248,7 @@
disabledProviderList: List<DisabledProviderInfo>?,
sortedCreateOptionsPairs: List<Pair<CreateOptionInfo, EnabledProviderInfo>>,
onOptionSelected: (ActiveEntry) -> Unit,
- onDisabledPasswordManagerSelected: () -> Unit,
+ onDisabledProvidersSelected: () -> Unit,
onMoreOptionsSelected: () -> Unit,
) {
ContainerCard() {
@@ -266,11 +264,12 @@
text = stringResource(
R.string.choose_provider_title,
when (requestDisplayInfo.type) {
- TYPE_PUBLIC_KEY_CREDENTIAL -> stringResource(R.string.create_your_passkeys)
- TYPE_PASSWORD_CREDENTIAL -> stringResource(R.string.save_your_password)
- else -> stringResource(R.string.save_your_sign_in_info)
- },
- ),
+ TYPE_PUBLIC_KEY_CREDENTIAL ->
+ stringResource(R.string.passkeys)
+ TYPE_PASSWORD_CREDENTIAL ->
+ stringResource(R.string.passwords)
+ else -> stringResource(R.string.sign_in_info)
+ }),
style = MaterialTheme.typography.titleMedium,
modifier = Modifier.padding(horizontal = 24.dp)
.align(alignment = Alignment.CenterHorizontally),
@@ -318,8 +317,8 @@
item {
MoreOptionsDisabledProvidersRow(
disabledProviders = disabledProviderList,
- onDisabledPasswordManagerSelected =
- onDisabledPasswordManagerSelected,
+ onDisabledProvidersSelected =
+ onDisabledProvidersSelected,
)
}
}
@@ -363,7 +362,7 @@
onBackProviderSelectionButtonSelected: () -> Unit,
onBackCreationSelectionButtonSelected: () -> Unit,
onOptionSelected: (ActiveEntry) -> Unit,
- onDisabledPasswordManagerSelected: () -> Unit,
+ onDisabledProvidersSelected: () -> Unit,
onRemoteEntrySelected: (EntryInfo) -> Unit,
) {
ContainerCard() {
@@ -436,8 +435,8 @@
item {
MoreOptionsDisabledProvidersRow(
disabledProviders = disabledProviderList,
- onDisabledPasswordManagerSelected =
- onDisabledPasswordManagerSelected,
+ onDisabledProvidersSelected =
+ onDisabledProvidersSelected,
)
}
}
@@ -606,27 +605,17 @@
onClick = onConfirm
)
}
- Divider(
- thickness = 1.dp,
- color = Color.LightGray,
- modifier = Modifier.padding(start = 24.dp, end = 24.dp, top = 18.dp)
- )
- if (createOptionInfo.userProviderDisplayName != null) {
+ if (createOptionInfo.footerDescription != null) {
+ Divider(
+ thickness = 1.dp,
+ color = Color.LightGray,
+ modifier = Modifier.padding(start = 24.dp, end = 24.dp, top = 18.dp)
+ )
TextSecondary(
- text = stringResource(
- R.string.choose_create_option_description,
- requestDisplayInfo.appName,
- when (requestDisplayInfo.type) {
- TYPE_PUBLIC_KEY_CREDENTIAL -> stringResource(R.string.passkey)
- TYPE_PASSWORD_CREDENTIAL -> stringResource(R.string.password)
- else -> stringResource(R.string.sign_ins)
- },
- providerInfo.displayName,
- createOptionInfo.userProviderDisplayName
- ),
+ text = createOptionInfo.footerDescription,
style = MaterialTheme.typography.bodyLarge,
modifier = Modifier.padding(
- start = 24.dp, top = 8.dp, bottom = 18.dp, end = 24.dp)
+ start = 29.dp, top = 8.dp, bottom = 18.dp, end = 28.dp)
)
}
Divider(
@@ -891,11 +880,11 @@
@Composable
fun MoreOptionsDisabledProvidersRow(
disabledProviders: List<ProviderInfo>?,
- onDisabledPasswordManagerSelected: () -> Unit,
+ onDisabledProvidersSelected: () -> Unit,
) {
if (disabledProviders != null && disabledProviders.isNotEmpty()) {
Entry(
- onClick = onDisabledPasswordManagerSelected,
+ onClick = onDisabledProvidersSelected,
icon = {
Icon(
Icons.Filled.Add,
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt
index 55e14a9..3e1137d 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt
@@ -24,8 +24,6 @@
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.android.credentialmanager.CreateFlowUtils
import com.android.credentialmanager.CredentialManagerRepo
@@ -33,6 +31,9 @@
import com.android.credentialmanager.common.DialogResult
import com.android.credentialmanager.common.ProviderActivityResult
import com.android.credentialmanager.common.ResultState
+import kotlinx.coroutines.channels.BufferOverflow
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.SharedFlow
data class CreateCredentialUiState(
val enabledProviders: List<EnabledProviderInfo>,
@@ -75,11 +76,11 @@
isPasskeyFirstUse))
private set
- val dialogResult: MutableLiveData<DialogResult> by lazy {
- MutableLiveData<DialogResult>()
- }
+ val dialogResult: MutableSharedFlow<DialogResult> =
+ MutableSharedFlow(replay = 0, extraBufferCapacity = 1,
+ onBufferOverflow = BufferOverflow.DROP_OLDEST)
- fun observeDialogResult(): LiveData<DialogResult> {
+ fun observeDialogResult(): SharedFlow<DialogResult> {
return dialogResult
}
@@ -124,7 +125,9 @@
fun onEntrySelectedFromMoreOptionScreen(activeEntry: ActiveEntry) {
uiState = uiState.copy(
- currentScreenState = CreateScreenState.MORE_OPTIONS_ROW_INTRO,
+ currentScreenState = if (
+ activeEntry.activeProvider.id == UserConfigRepo.getInstance().getDefaultProviderId()
+ ) CreateScreenState.CREATION_OPTION_SELECTION else CreateScreenState.MORE_OPTIONS_ROW_INTRO,
activeEntry = activeEntry
)
}
@@ -138,13 +141,14 @@
onDefaultChanged(providerId)
}
- fun onDisabledPasswordManagerSelected() {
- // TODO: Complete this function
+ fun onDisabledProvidersSelected() {
+ CredentialManagerRepo.getInstance().onCancel()
+ dialogResult.tryEmit(DialogResult(ResultState.LAUNCH_SETTING_CANCELED))
}
fun onCancel() {
CredentialManagerRepo.getInstance().onCancel()
- dialogResult.value = DialogResult(ResultState.CANCELED)
+ dialogResult.tryEmit(DialogResult(ResultState.NORMAL_CANCELED))
}
fun onChangeDefaultSelected() {
@@ -190,9 +194,7 @@
entryKey,
entrySubkey
)
- dialogResult.value = DialogResult(
- ResultState.COMPLETE,
- )
+ dialogResult.tryEmit(DialogResult(ResultState.COMPLETE))
}
}
@@ -219,9 +221,7 @@
} else {
Log.w("Account Selector",
"Illegal state: confirm is pressed but activeEntry isn't set.")
- dialogResult.value = DialogResult(
- ResultState.COMPLETE,
- )
+ dialogResult.tryEmit(DialogResult(ResultState.COMPLETE))
}
}
@@ -250,9 +250,7 @@
Log.w("Account Selector",
"Illegal state: received a provider result but found no matching entry.")
}
- dialogResult.value = DialogResult(
- ResultState.COMPLETE,
- )
+ dialogResult.tryEmit(DialogResult(ResultState.COMPLETE))
}
}
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
index 04cd26b..97477a7 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
@@ -60,6 +60,7 @@
val passkeyCount: Int?,
val totalCredentialCount: Int?,
val lastUsedTimeMillis: Long?,
+ val footerDescription: String?,
) : EntryInfo(providerId, entryKey, entrySubkey, pendingIntent, fillInIntent)
class RemoteInfo(
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt
index 294e468..af59a0a 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt
@@ -24,8 +24,6 @@
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.android.credentialmanager.CredentialManagerRepo
import com.android.credentialmanager.common.DialogResult
@@ -33,6 +31,9 @@
import com.android.credentialmanager.common.ResultState
import com.android.credentialmanager.jetpack.developer.PublicKeyCredential
import com.android.internal.util.Preconditions
+import kotlinx.coroutines.channels.BufferOverflow
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.SharedFlow
data class GetCredentialUiState(
val providerInfoList: List<ProviderInfo>,
@@ -52,11 +53,11 @@
var uiState by mutableStateOf(credManRepo.getCredentialInitialUiState())
private set
- val dialogResult: MutableLiveData<DialogResult> by lazy {
- MutableLiveData<DialogResult>()
- }
+ val dialogResult: MutableSharedFlow<DialogResult> =
+ MutableSharedFlow(replay = 0, extraBufferCapacity = 1,
+ onBufferOverflow = BufferOverflow.DROP_OLDEST)
- fun observeDialogResult(): LiveData<DialogResult> {
+ fun observeDialogResult(): SharedFlow<DialogResult> {
return dialogResult
}
@@ -72,7 +73,7 @@
CredentialManagerRepo.getInstance().onOptionSelected(
entry.providerId, entry.entryKey, entry.entrySubkey,
)
- dialogResult.value = DialogResult(ResultState.COMPLETE)
+ dialogResult.tryEmit(DialogResult(ResultState.COMPLETE))
}
}
@@ -117,7 +118,7 @@
Log.w("Account Selector",
"Illegal state: received a provider result but found no matching entry.")
}
- dialogResult.value = DialogResult(ResultState.COMPLETE)
+ dialogResult.tryEmit(DialogResult(ResultState.COMPLETE))
}
}
@@ -144,7 +145,7 @@
fun onCancel() {
CredentialManagerRepo.getInstance().onCancel()
- dialogResult.value = DialogResult(ResultState.CANCELED)
+ dialogResult.tryEmit(DialogResult(ResultState.NORMAL_CANCELED))
}
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCredentialRequest.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCredentialRequest.kt
index 008e1b6..eaa2ad4 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCredentialRequest.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCredentialRequest.kt
@@ -18,6 +18,7 @@
import android.credentials.Credential
import android.os.Bundle
+import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.BUNDLE_KEY_SUBTYPE
/**
* Base request class for registering a credential.
@@ -28,27 +29,44 @@
* otherwise
*/
open class CreateCredentialRequest(
- val type: String,
- val data: Bundle,
- val requireSystemProvider: Boolean,
+ open val type: String,
+ open val credentialData: Bundle,
+ open val candidateQueryData: Bundle,
+ open val requireSystemProvider: Boolean
) {
companion object {
@JvmStatic
- fun createFrom(from: android.credentials.CreateCredentialRequest): CreateCredentialRequest {
+ fun createFrom(
+ type: String,
+ credentialData: Bundle,
+ candidateQueryData: Bundle,
+ requireSystemProvider: Boolean
+ ): CreateCredentialRequest {
return try {
- when (from.type) {
+ when (type) {
Credential.TYPE_PASSWORD_CREDENTIAL ->
- CreatePasswordRequest.createFrom(from.credentialData)
+ CreatePasswordRequest.createFrom(credentialData)
PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL ->
- CreatePublicKeyCredentialBaseRequest.createFrom(from.credentialData)
- else ->
- CreateCredentialRequest(
- from.type, from.credentialData, from.requireSystemProvider()
- )
+ when (credentialData.getString(BUNDLE_KEY_SUBTYPE)) {
+ CreatePublicKeyCredentialRequest
+ .BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST ->
+ CreatePublicKeyCredentialRequest.createFrom(credentialData)
+ CreatePublicKeyCredentialRequestPrivileged
+ .BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_PRIV ->
+ CreatePublicKeyCredentialRequestPrivileged
+ .createFrom(credentialData)
+ else -> throw FrameworkClassParsingException()
+ }
+ else -> throw FrameworkClassParsingException()
}
} catch (e: FrameworkClassParsingException) {
- CreateCredentialRequest(
- from.type, from.credentialData, from.requireSystemProvider()
+ // Parsing failed but don't crash the process. Instead just output a request with
+ // the raw framework values.
+ CreateCustomCredentialRequest(
+ type,
+ credentialData,
+ candidateQueryData,
+ requireSystemProvider
)
}
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCustomCredentialRequest.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCustomCredentialRequest.kt
new file mode 100644
index 0000000..50da9a1
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCustomCredentialRequest.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 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.credentialmanager.jetpack.developer
+
+import android.os.Bundle
+
+/**
+ * Base custom create request class for registering a credential.
+ *
+ * An application can construct a subtype custom request and call
+ * [CredentialManager.executeCreateCredential] to launch framework UI flows to collect consent and
+ * any other metadata needed from the user to register a new user credential.
+ *
+ * @property type the credential type determined by the credential-type-specific subclass for custom
+ * use cases
+ * @property credentialData the full credential creation request data in the [Bundle] format for
+ * custom use cases
+ * @property candidateQueryData the partial request data in the [Bundle] format that will be sent to
+ * the provider during the initial candidate query stage, which should not contain sensitive user
+ * credential information
+ * @property requireSystemProvider true if must only be fulfilled by a system provider and false
+ * otherwise
+ * @throws IllegalArgumentException If [type] is empty
+ * @throws NullPointerException If [type] or [credentialData] are null
+ */
+open class CreateCustomCredentialRequest(
+ final override val type: String,
+ final override val credentialData: Bundle,
+ final override val candidateQueryData: Bundle,
+ @get:JvmName("requireSystemProvider")
+ final override val requireSystemProvider: Boolean
+) : CreateCredentialRequest(type, credentialData, candidateQueryData, requireSystemProvider) {
+ init {
+ require(type.isNotEmpty()) { "type should not be empty" }
+ }
+}
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePasswordRequest.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePasswordRequest.kt
index f0da9f9..bf0aa8a 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePasswordRequest.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePasswordRequest.kt
@@ -32,9 +32,11 @@
val id: String,
val password: String,
) : CreateCredentialRequest(
- Credential.TYPE_PASSWORD_CREDENTIAL,
- toBundle(id, password),
- false,
+ type = Credential.TYPE_PASSWORD_CREDENTIAL,
+ credentialData = toCredentialDataBundle(id, password),
+ // No credential data should be sent during the query phase.
+ candidateQueryData = Bundle(),
+ requireSystemProvider = false,
) {
init {
@@ -46,7 +48,7 @@
const val BUNDLE_KEY_PASSWORD = "androidx.credentials.BUNDLE_KEY_PASSWORD"
@JvmStatic
- internal fun toBundle(id: String, password: String): Bundle {
+ internal fun toCredentialDataBundle(id: String, password: String): Bundle {
val bundle = Bundle()
bundle.putString(BUNDLE_KEY_ID, id)
bundle.putString(BUNDLE_KEY_PASSWORD, password)
@@ -54,7 +56,14 @@
}
@JvmStatic
- fun createFrom(data: Bundle): CreatePasswordRequest {
+ internal fun toCandidateDataBundle(id: String): Bundle {
+ val bundle = Bundle()
+ bundle.putString(BUNDLE_KEY_ID, id)
+ return bundle
+ }
+
+ @JvmStatic
+ internal fun createFrom(data: Bundle): CreatePasswordRequest {
try {
val id = data.getString(BUNDLE_KEY_ID)
val password = data.getString(BUNDLE_KEY_PASSWORD)
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialBaseRequest.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialBaseRequest.kt
deleted file mode 100644
index 37a4f76..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialBaseRequest.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2022 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.credentialmanager.jetpack.developer
-
-import android.os.Bundle
-
-/**
- * Base request class for registering a public key credential.
- *
- * @property requestJson The request in JSON format
- * @throws NullPointerException If [requestJson] is null. This is handled by the Kotlin runtime
- * @throws IllegalArgumentException If [requestJson] is empty
- *
- * @hide
- */
-abstract class CreatePublicKeyCredentialBaseRequest constructor(
- val requestJson: String,
- type: String,
- data: Bundle,
- requireSystemProvider: Boolean,
-) : CreateCredentialRequest(type, data, requireSystemProvider) {
-
- init {
- require(requestJson.isNotEmpty()) { "request json must not be empty" }
- }
-
- companion object {
- const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
- const val BUNDLE_KEY_SUBTYPE = "androidx.credentials.BUNDLE_KEY_SUBTYPE"
-
- @JvmStatic
- fun createFrom(data: Bundle): CreatePublicKeyCredentialBaseRequest {
- return when (data.getString(BUNDLE_KEY_SUBTYPE)) {
- CreatePublicKeyCredentialRequest
- .BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST ->
- CreatePublicKeyCredentialRequest.createFrom(data)
- CreatePublicKeyCredentialRequestPrivileged
- .BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_PRIVILEGED ->
- CreatePublicKeyCredentialRequestPrivileged.createFrom(data)
- else -> throw FrameworkClassParsingException()
- }
- }
- }
-}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest.kt
index 2eda90b..f3d402a 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest.kt
@@ -17,50 +17,81 @@
package com.android.credentialmanager.jetpack.developer
import android.os.Bundle
+import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.BUNDLE_KEY_SUBTYPE
/**
- * A request to register a passkey from the user's public key credential provider.
- *
- * @property requestJson the request in JSON format
- * @property allowHybrid defines whether hybrid credentials are allowed to fulfill this request,
- * true by default
- * @throws NullPointerException If [requestJson] or [allowHybrid] is null. This is handled by the
- * Kotlin runtime
- * @throws IllegalArgumentException If [requestJson] is empty
- *
- * @hide
- */
+* A request to register a passkey from the user's public key credential provider.
+*
+* @property requestJson the privileged request in JSON format in the standard webauthn web json
+* shown [here](https://w3c.github.io/webauthn/#dictdef-publickeycredentialrequestoptionsjson).
+* @property preferImmediatelyAvailableCredentials true if you prefer the operation to return
+* immediately when there is no available passkey registration offering instead of falling back to
+* discovering remote options, and false (default) otherwise
+* @throws NullPointerException If [requestJson] is null
+* @throws IllegalArgumentException If [requestJson] is empty
+*/
class CreatePublicKeyCredentialRequest @JvmOverloads constructor(
- requestJson: String,
- @get:JvmName("allowHybrid")
- val allowHybrid: Boolean = true
-) : CreatePublicKeyCredentialBaseRequest(
- requestJson,
- PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
- toBundle(requestJson, allowHybrid),
- false,
+ val requestJson: String,
+ @get:JvmName("preferImmediatelyAvailableCredentials")
+ val preferImmediatelyAvailableCredentials: Boolean = false
+) : CreateCredentialRequest(
+ type = PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
+ credentialData = toCredentialDataBundle(requestJson, preferImmediatelyAvailableCredentials),
+ // The whole request data should be passed during the query phase.
+ candidateQueryData = toCredentialDataBundle(requestJson, preferImmediatelyAvailableCredentials),
+ requireSystemProvider = false,
) {
+
+ init {
+ require(requestJson.isNotEmpty()) { "requestJson must not be empty" }
+ }
+
+ /** @hide */
companion object {
- const val BUNDLE_KEY_ALLOW_HYBRID = "androidx.credentials.BUNDLE_KEY_ALLOW_HYBRID"
- const val BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST =
- "androidx.credentials.BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST"
+ const val BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS =
+ "androidx.credentials.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS"
+ internal const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
+ internal const val BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST =
+ "androidx.credentials.BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST"
@JvmStatic
- internal fun toBundle(requestJson: String, allowHybrid: Boolean): Bundle {
+ internal fun toCredentialDataBundle(
+ requestJson: String,
+ preferImmediatelyAvailableCredentials: Boolean
+ ): Bundle {
val bundle = Bundle()
bundle.putString(BUNDLE_KEY_SUBTYPE,
- BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST)
+ BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST)
bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
- bundle.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybrid)
+ bundle.putBoolean(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
+ preferImmediatelyAvailableCredentials)
return bundle
}
@JvmStatic
- fun createFrom(data: Bundle): CreatePublicKeyCredentialRequest {
+ internal fun toCandidateDataBundle(
+ requestJson: String,
+ preferImmediatelyAvailableCredentials: Boolean
+ ): Bundle {
+ val bundle = Bundle()
+ bundle.putString(BUNDLE_KEY_SUBTYPE,
+ BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST)
+ bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
+ bundle.putBoolean(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
+ preferImmediatelyAvailableCredentials)
+ return bundle
+ }
+
+ @Suppress("deprecation") // bundle.get() used for boolean value to prevent default
+ // boolean value from being returned.
+ @JvmStatic
+ internal fun createFrom(data: Bundle): CreatePublicKeyCredentialRequest {
try {
val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
- val allowHybrid = data.get(BUNDLE_KEY_ALLOW_HYBRID)
- return CreatePublicKeyCredentialRequest(requestJson!!, (allowHybrid!!) as Boolean)
+ val preferImmediatelyAvailableCredentials =
+ data.get(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS)
+ return CreatePublicKeyCredentialRequest(requestJson!!,
+ (preferImmediatelyAvailableCredentials!!) as Boolean)
} catch (e: Exception) {
throw FrameworkClassParsingException()
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequestPrivileged.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequestPrivileged.kt
index 36324f8..85ab2d2 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequestPrivileged.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequestPrivileged.kt
@@ -17,45 +17,62 @@
package com.android.credentialmanager.jetpack.developer
import android.os.Bundle
+import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.BUNDLE_KEY_SUBTYPE
/**
* A privileged request to register a passkey from the user’s public key credential provider, where
* the caller can modify the rp. Only callers with privileged permission, e.g. user’s default
- * brower, caBLE, can use this.
+ * brower, caBLE, can use this. These permissions will be introduced in an upcoming release.
+ * TODO("Add specific permission info/annotation")
*
- * @property requestJson the privileged request in JSON format
- * @property allowHybrid defines whether hybrid credentials are allowed to fulfill this request,
- * true by default
- * @property rp the expected true RP ID which will override the one in the [requestJson]
- * @property clientDataHash a hash that is used to verify the [rp] Identity
- * @throws NullPointerException If any of [allowHybrid], [requestJson], [rp], or [clientDataHash] is
- * null. This is handled by the Kotlin runtime
- * @throws IllegalArgumentException If any of [requestJson], [rp], or [clientDataHash] is empty
- *
- * @hide
+ * @property requestJson the privileged request in JSON format in the standard webauthn web json
+ * shown [here](https://w3c.github.io/webauthn/#dictdef-publickeycredentialrequestoptionsjson).
+ * @property preferImmediatelyAvailableCredentials true if you prefer the operation to return
+ * immediately when there is no available passkey registration offering instead of falling back to
+ * discovering remote options, and false (default) otherwise
+ * @property relyingParty the expected true RP ID which will override the one in the [requestJson],
+ * where rp is defined [here](https://w3c.github.io/webauthn/#rp-id)
+ * @property clientDataHash a hash that is used to verify the [relyingParty] Identity
+ * @throws NullPointerException If any of [requestJson], [relyingParty], or [clientDataHash] is
+ * null
+ * @throws IllegalArgumentException If any of [requestJson], [relyingParty], or [clientDataHash] is
+ * empty
*/
class CreatePublicKeyCredentialRequestPrivileged @JvmOverloads constructor(
- requestJson: String,
- val rp: String,
- val clientDataHash: String,
- @get:JvmName("allowHybrid")
- val allowHybrid: Boolean = true
-) : CreatePublicKeyCredentialBaseRequest(
+ val requestJson: String,
+ val relyingParty: String,
+ val clientDataHash: String,
+ @get:JvmName("preferImmediatelyAvailableCredentials")
+ val preferImmediatelyAvailableCredentials: Boolean = false
+) : CreateCredentialRequest(
+ type = PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
+ credentialData = toCredentialDataBundle(
requestJson,
- PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
- toBundle(requestJson, rp, clientDataHash, allowHybrid),
- false,
+ relyingParty,
+ clientDataHash,
+ preferImmediatelyAvailableCredentials
+ ),
+ // The whole request data should be passed during the query phase.
+ candidateQueryData = toCredentialDataBundle(
+ requestJson, relyingParty, clientDataHash, preferImmediatelyAvailableCredentials
+ ),
+ requireSystemProvider = false,
) {
init {
- require(rp.isNotEmpty()) { "rp must not be empty" }
+ require(requestJson.isNotEmpty()) { "requestJson must not be empty" }
+ require(relyingParty.isNotEmpty()) { "rp must not be empty" }
require(clientDataHash.isNotEmpty()) { "clientDataHash must not be empty" }
}
/** A builder for [CreatePublicKeyCredentialRequestPrivileged]. */
- class Builder(var requestJson: String, var rp: String, var clientDataHash: String) {
+ class Builder(
+ private var requestJson: String,
+ private var relyingParty: String,
+ private var clientDataHash: String
+ ) {
- private var allowHybrid: Boolean = true
+ private var preferImmediatelyAvailableCredentials: Boolean = false
/**
* Sets the privileged request in JSON format.
@@ -66,23 +83,30 @@
}
/**
- * Sets whether hybrid credentials are allowed to fulfill this request, true by default.
+ * Sets to true if you prefer the operation to return immediately when there is no available
+ * passkey registration offering instead of falling back to discovering remote options, and
+ * false otherwise.
+ *
+ * The default value is false.
*/
- fun setAllowHybrid(allowHybrid: Boolean): Builder {
- this.allowHybrid = allowHybrid
+ @Suppress("MissingGetterMatchingBuilder")
+ fun setPreferImmediatelyAvailableCredentials(
+ preferImmediatelyAvailableCredentials: Boolean
+ ): Builder {
+ this.preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials
return this
}
/**
* Sets the expected true RP ID which will override the one in the [requestJson].
*/
- fun setRp(rp: String): Builder {
- this.rp = rp
+ fun setRelyingParty(relyingParty: String): Builder {
+ this.relyingParty = relyingParty
return this
}
/**
- * Sets a hash that is used to verify the [rp] Identity.
+ * Sets a hash that is used to verify the [relyingParty] Identity.
*/
fun setClientDataHash(clientDataHash: String): Builder {
this.clientDataHash = clientDataHash
@@ -91,49 +115,65 @@
/** Builds a [CreatePublicKeyCredentialRequestPrivileged]. */
fun build(): CreatePublicKeyCredentialRequestPrivileged {
- return CreatePublicKeyCredentialRequestPrivileged(this.requestJson,
- this.rp, this.clientDataHash, this.allowHybrid)
+ return CreatePublicKeyCredentialRequestPrivileged(
+ this.requestJson,
+ this.relyingParty, this.clientDataHash, this.preferImmediatelyAvailableCredentials
+ )
}
}
+ /** @hide */
companion object {
- const val BUNDLE_KEY_RP = "androidx.credentials.BUNDLE_KEY_RP"
- const val BUNDLE_KEY_CLIENT_DATA_HASH =
- "androidx.credentials.BUNDLE_KEY_CLIENT_DATA_HASH"
- const val BUNDLE_KEY_ALLOW_HYBRID = "androidx.credentials.BUNDLE_KEY_ALLOW_HYBRID"
- const val BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_PRIVILEGED =
- "androidx.credentials.BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_" +
- "PRIVILEGED"
+ internal const val BUNDLE_KEY_RELYING_PARTY =
+ "androidx.credentials.BUNDLE_KEY_RELYING_PARTY"
+ internal const val BUNDLE_KEY_CLIENT_DATA_HASH =
+ "androidx.credentials.BUNDLE_KEY_CLIENT_DATA_HASH"
+ internal const val BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS =
+ "androidx.credentials.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS"
+
+ internal const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
+
+ internal const val BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_PRIV =
+ "androidx.credentials.BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_" +
+ "PRIVILEGED"
@JvmStatic
- internal fun toBundle(
- requestJson: String,
- rp: String,
- clientDataHash: String,
- allowHybrid: Boolean
+ internal fun toCredentialDataBundle(
+ requestJson: String,
+ relyingParty: String,
+ clientDataHash: String,
+ preferImmediatelyAvailableCredentials: Boolean
): Bundle {
val bundle = Bundle()
- bundle.putString(BUNDLE_KEY_SUBTYPE,
- BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_PRIVILEGED)
+ bundle.putString(
+ PublicKeyCredential.BUNDLE_KEY_SUBTYPE,
+ BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_PRIV
+ )
bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
- bundle.putString(BUNDLE_KEY_RP, rp)
+ bundle.putString(BUNDLE_KEY_RELYING_PARTY, relyingParty)
bundle.putString(BUNDLE_KEY_CLIENT_DATA_HASH, clientDataHash)
- bundle.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybrid)
+ bundle.putBoolean(
+ BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
+ preferImmediatelyAvailableCredentials
+ )
return bundle
}
+ @Suppress("deprecation") // bundle.get() used for boolean value to prevent default
+ // boolean value from being returned.
@JvmStatic
- fun createFrom(data: Bundle): CreatePublicKeyCredentialRequestPrivileged {
+ internal fun createFrom(data: Bundle): CreatePublicKeyCredentialRequestPrivileged {
try {
val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
- val rp = data.getString(BUNDLE_KEY_RP)
+ val rp = data.getString(BUNDLE_KEY_RELYING_PARTY)
val clientDataHash = data.getString(BUNDLE_KEY_CLIENT_DATA_HASH)
- val allowHybrid = data.get(BUNDLE_KEY_ALLOW_HYBRID)
+ val preferImmediatelyAvailableCredentials =
+ data.get(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS)
return CreatePublicKeyCredentialRequestPrivileged(
- requestJson!!,
- rp!!,
- clientDataHash!!,
- (allowHybrid!!) as Boolean,
+ requestJson!!,
+ rp!!,
+ clientDataHash!!,
+ (preferImmediatelyAvailableCredentials!!) as Boolean,
)
} catch (e: Exception) {
throw FrameworkClassParsingException()
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialOption.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialOption.kt
index ef48a77..fc7b7de 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialOption.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialOption.kt
@@ -28,30 +28,40 @@
* otherwise
*/
open class GetCredentialOption(
- val type: String,
- val data: Bundle,
- val requireSystemProvider: Boolean,
+ open val type: String,
+ open val requestData: Bundle,
+ open val candidateQueryData: Bundle,
+ open val requireSystemProvider: Boolean,
) {
companion object {
@JvmStatic
- fun createFrom(from: android.credentials.GetCredentialOption): GetCredentialOption {
+ fun createFrom(
+ type: String,
+ requestData: Bundle,
+ candidateQueryData: Bundle,
+ requireSystemProvider: Boolean
+ ): GetCredentialOption {
return try {
- when (from.type) {
+ when (type) {
Credential.TYPE_PASSWORD_CREDENTIAL ->
- GetPasswordOption.createFrom(from.credentialRetrievalData)
+ GetPasswordOption.createFrom(requestData)
PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL ->
- GetPublicKeyCredentialBaseOption.createFrom(from.credentialRetrievalData)
- else ->
- GetCredentialOption(
- from.type, from.credentialRetrievalData, from.requireSystemProvider()
- )
+ when (requestData.getString(PublicKeyCredential.BUNDLE_KEY_SUBTYPE)) {
+ GetPublicKeyCredentialOption
+ .BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION ->
+ GetPublicKeyCredentialOption.createFrom(requestData)
+ GetPublicKeyCredentialOptionPrivileged
+ .BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION_PRIVILEGED ->
+ GetPublicKeyCredentialOptionPrivileged.createFrom(requestData)
+ else -> throw FrameworkClassParsingException()
+ }
+ else -> throw FrameworkClassParsingException()
}
} catch (e: FrameworkClassParsingException) {
- GetCredentialOption(
- from.type,
- from.credentialRetrievalData,
- from.requireSystemProvider()
- )
+ // Parsing failed but don't crash the process. Instead just output a request with
+ // the raw framework values.
+ GetCustomCredentialOption(
+ type, requestData, candidateQueryData, requireSystemProvider)
}
}
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialRequest.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialRequest.kt
index 7f9256e..18d5089 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialRequest.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialRequest.kt
@@ -24,7 +24,7 @@
* @throws IllegalArgumentException If [getCredentialOptions] is empty
*/
class GetCredentialRequest constructor(
- val getCredentialOptions: List<GetCredentialOption>,
+ val getCredentialOptions: List<GetCredentialOption>,
) {
init {
@@ -61,7 +61,14 @@
@JvmStatic
fun createFrom(from: android.credentials.GetCredentialRequest): GetCredentialRequest {
return GetCredentialRequest(
- from.getCredentialOptions.map {GetCredentialOption.createFrom(it)}
+ from.getCredentialOptions.map {
+ GetCredentialOption.createFrom(
+ it.type,
+ it.credentialRetrievalData,
+ it.candidateQueryData,
+ it.requireSystemProvider()
+ )
+ }
)
}
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCustomCredentialOption.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCustomCredentialOption.kt
new file mode 100644
index 0000000..803885c
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCustomCredentialOption.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 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.credentialmanager.jetpack.developer
+
+import android.os.Bundle
+
+/**
+ * Allows extending custom versions of GetCredentialOptions for unique use cases.
+ *
+ * @property type the credential type determined by the credential-type-specific subclass
+ * generated for custom use cases
+ * @property requestData the request data in the [Bundle] format, generated for custom use cases
+ * @property candidateQueryData the partial request data in the [Bundle] format that will be sent to
+ * the provider during the initial candidate query stage, which should not contain sensitive user
+ * information
+ * @property requireSystemProvider true if must only be fulfilled by a system provider and false
+ * otherwise
+ * @throws IllegalArgumentException If [type] is empty
+ * @throws NullPointerException If [requestData] or [type] is null
+ */
+open class GetCustomCredentialOption(
+ final override val type: String,
+ final override val requestData: Bundle,
+ final override val candidateQueryData: Bundle,
+ @get:JvmName("requireSystemProvider")
+ final override val requireSystemProvider: Boolean
+) : GetCredentialOption(
+ type,
+ requestData,
+ candidateQueryData,
+ requireSystemProvider
+) {
+ init {
+ require(type.isNotEmpty()) { "type should not be empty" }
+ }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPasswordOption.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPasswordOption.kt
index 2facad1..2b9cfa3 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPasswordOption.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPasswordOption.kt
@@ -23,6 +23,7 @@
class GetPasswordOption : GetCredentialOption(
Credential.TYPE_PASSWORD_CREDENTIAL,
Bundle(),
+ Bundle(),
false,
) {
companion object {
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialBaseOption.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialBaseOption.kt
deleted file mode 100644
index 9b51b30..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialBaseOption.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2022 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.credentialmanager.jetpack.developer
-
-import android.os.Bundle
-
-/**
- * Base request class for getting a registered public key credential.
- *
- * @property requestJson the request in JSON format
- * @throws NullPointerException If [requestJson] is null - auto handled by the
- * Kotlin runtime
- * @throws IllegalArgumentException If [requestJson] is empty
- *
- * @hide
- */
-abstract class GetPublicKeyCredentialBaseOption constructor(
- val requestJson: String,
- type: String,
- data: Bundle,
- requireSystemProvider: Boolean,
-) : GetCredentialOption(type, data, requireSystemProvider) {
-
- init {
- require(requestJson.isNotEmpty()) { "request json must not be empty" }
- }
-
- companion object {
- const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
- const val BUNDLE_KEY_SUBTYPE = "androidx.credentials.BUNDLE_KEY_SUBTYPE"
-
- @JvmStatic
- fun createFrom(data: Bundle): GetPublicKeyCredentialBaseOption {
- return when (data.getString(BUNDLE_KEY_SUBTYPE)) {
- GetPublicKeyCredentialOption
- .BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION ->
- GetPublicKeyCredentialOption.createFrom(data)
- GetPublicKeyCredentialOptionPrivileged
- .BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION_PRIVILEGED ->
- GetPublicKeyCredentialOptionPrivileged.createFrom(data)
- else -> throw FrameworkClassParsingException()
- }
- }
- }
-}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOption.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOption.kt
index 6f13c17..2f9b249 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOption.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOption.kt
@@ -21,44 +21,62 @@
/**
* A request to get passkeys from the user's public key credential provider.
*
- * @property requestJson the request in JSON format
- * @property allowHybrid defines whether hybrid credentials are allowed to fulfill this request,
- * true by default
- * @throws NullPointerException If [requestJson] or [allowHybrid] is null. It is handled by the
- * Kotlin runtime
+ * @property requestJson the privileged request in JSON format in the standard webauthn web json
+ * shown [here](https://w3c.github.io/webauthn/#dictdef-publickeycredentialrequestoptionsjson).
+ * @property preferImmediatelyAvailableCredentials true if you prefer the operation to return
+ * immediately when there is no available credential instead of falling back to discovering remote
+ * credentials, and false (default) otherwise
+ * @throws NullPointerException If [requestJson] is null
* @throws IllegalArgumentException If [requestJson] is empty
- *
- * @hide
*/
class GetPublicKeyCredentialOption @JvmOverloads constructor(
- requestJson: String,
- @get:JvmName("allowHybrid")
- val allowHybrid: Boolean = true,
-) : GetPublicKeyCredentialBaseOption(
- requestJson,
- PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
- toBundle(requestJson, allowHybrid),
- false
+ val requestJson: String,
+ @get:JvmName("preferImmediatelyAvailableCredentials")
+ val preferImmediatelyAvailableCredentials: Boolean = false,
+) : GetCredentialOption(
+ type = PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
+ requestData = toRequestDataBundle(requestJson, preferImmediatelyAvailableCredentials),
+ candidateQueryData = toRequestDataBundle(requestJson, preferImmediatelyAvailableCredentials),
+ requireSystemProvider = false
) {
+ init {
+ require(requestJson.isNotEmpty()) { "requestJson must not be empty" }
+ }
+
+ /** @hide */
companion object {
- const val BUNDLE_KEY_ALLOW_HYBRID = "androidx.credentials.BUNDLE_KEY_ALLOW_HYBRID"
- const val BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION =
- "androidx.credentials.BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION"
+ internal const val BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS =
+ "androidx.credentials.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS"
+ internal const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
+ internal const val BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION =
+ "androidx.credentials.BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION"
@JvmStatic
- internal fun toBundle(requestJson: String, allowHybrid: Boolean): Bundle {
+ internal fun toRequestDataBundle(
+ requestJson: String,
+ preferImmediatelyAvailableCredentials: Boolean
+ ): Bundle {
val bundle = Bundle()
+ bundle.putString(
+ PublicKeyCredential.BUNDLE_KEY_SUBTYPE,
+ BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION
+ )
bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
- bundle.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybrid)
+ bundle.putBoolean(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
+ preferImmediatelyAvailableCredentials)
return bundle
}
+ @Suppress("deprecation") // bundle.get() used for boolean value to prevent default
+ // boolean value from being returned.
@JvmStatic
- fun createFrom(data: Bundle): GetPublicKeyCredentialOption {
+ internal fun createFrom(data: Bundle): GetPublicKeyCredentialOption {
try {
val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
- val allowHybrid = data.get(BUNDLE_KEY_ALLOW_HYBRID)
- return GetPublicKeyCredentialOption(requestJson!!, (allowHybrid!!) as Boolean)
+ val preferImmediatelyAvailableCredentials =
+ data.get(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS)
+ return GetPublicKeyCredentialOption(requestJson!!,
+ (preferImmediatelyAvailableCredentials!!) as Boolean)
} catch (e: Exception) {
throw FrameworkClassParsingException()
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOptionPrivileged.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOptionPrivileged.kt
index 79c62a1..6f4782a 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOptionPrivileged.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOptionPrivileged.kt
@@ -21,41 +21,59 @@
/**
* A privileged request to get passkeys from the user's public key credential provider. The caller
* can modify the RP. Only callers with privileged permission (e.g. user's public browser or caBLE)
- * can use this.
+ * can use this. These permissions will be introduced in an upcoming release.
+ * TODO("Add specific permission info/annotation")
*
- * @property requestJson the privileged request in JSON format
- * @property allowHybrid defines whether hybrid credentials are allowed to fulfill this request,
- * true by default
- * @property rp the expected true RP ID which will override the one in the [requestJson]
- * @property clientDataHash a hash that is used to verify the [rp] Identity
- * @throws NullPointerException If any of [allowHybrid], [requestJson], [rp], or [clientDataHash]
- * is null. This is handled by the Kotlin runtime
- * @throws IllegalArgumentException If any of [requestJson], [rp], or [clientDataHash] is empty
- *
- * @hide
+ * @property requestJson the privileged request in JSON format in the standard webauthn web json
+ * shown [here](https://w3c.github.io/webauthn/#dictdef-publickeycredentialrequestoptionsjson).
+ * @property preferImmediatelyAvailableCredentials true if you prefer the operation to return
+ * immediately when there is no available credential instead of falling back to discovering remote
+ * credentials, and false (default) otherwise
+ * @property relyingParty the expected true RP ID which will override the one in the [requestJson],
+ * where relyingParty is defined [here](https://w3c.github.io/webauthn/#rp-id) in more detail
+ * @property clientDataHash a hash that is used to verify the [relyingParty] Identity
+ * @throws NullPointerException If any of [requestJson], [relyingParty], or [clientDataHash]
+ * is null
+ * @throws IllegalArgumentException If any of [requestJson], [relyingParty], or [clientDataHash] is
+ * empty
*/
class GetPublicKeyCredentialOptionPrivileged @JvmOverloads constructor(
- requestJson: String,
- val rp: String,
- val clientDataHash: String,
- @get:JvmName("allowHybrid")
- val allowHybrid: Boolean = true
-) : GetPublicKeyCredentialBaseOption(
+ val requestJson: String,
+ val relyingParty: String,
+ val clientDataHash: String,
+ @get:JvmName("preferImmediatelyAvailableCredentials")
+ val preferImmediatelyAvailableCredentials: Boolean = false
+) : GetCredentialOption(
+ type = PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
+ requestData = toBundle(
requestJson,
- PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
- toBundle(requestJson, rp, clientDataHash, allowHybrid),
- false,
+ relyingParty,
+ clientDataHash,
+ preferImmediatelyAvailableCredentials
+ ),
+ candidateQueryData = toBundle(
+ requestJson,
+ relyingParty,
+ clientDataHash,
+ preferImmediatelyAvailableCredentials
+ ),
+ requireSystemProvider = false,
) {
init {
- require(rp.isNotEmpty()) { "rp must not be empty" }
+ require(requestJson.isNotEmpty()) { "requestJson must not be empty" }
+ require(relyingParty.isNotEmpty()) { "rp must not be empty" }
require(clientDataHash.isNotEmpty()) { "clientDataHash must not be empty" }
}
/** A builder for [GetPublicKeyCredentialOptionPrivileged]. */
- class Builder(var requestJson: String, var rp: String, var clientDataHash: String) {
+ class Builder(
+ private var requestJson: String,
+ private var relyingParty: String,
+ private var clientDataHash: String
+ ) {
- private var allowHybrid: Boolean = true
+ private var preferImmediatelyAvailableCredentials: Boolean = false
/**
* Sets the privileged request in JSON format.
@@ -66,23 +84,30 @@
}
/**
- * Sets whether hybrid credentials are allowed to fulfill this request, true by default.
+ * Sets to true if you prefer the operation to return immediately when there is no available
+ * credential instead of falling back to discovering remote credentials, and false
+ * otherwise.
+ *
+ * The default value is false.
*/
- fun setAllowHybrid(allowHybrid: Boolean): Builder {
- this.allowHybrid = allowHybrid
+ @Suppress("MissingGetterMatchingBuilder")
+ fun setPreferImmediatelyAvailableCredentials(
+ preferImmediatelyAvailableCredentials: Boolean
+ ): Builder {
+ this.preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials
return this
}
/**
* Sets the expected true RP ID which will override the one in the [requestJson].
*/
- fun setRp(rp: String): Builder {
- this.rp = rp
+ fun setRelyingParty(relyingParty: String): Builder {
+ this.relyingParty = relyingParty
return this
}
/**
- * Sets a hash that is used to verify the [rp] Identity.
+ * Sets a hash that is used to verify the [relyingParty] Identity.
*/
fun setClientDataHash(clientDataHash: String): Builder {
this.clientDataHash = clientDataHash
@@ -91,47 +116,63 @@
/** Builds a [GetPublicKeyCredentialOptionPrivileged]. */
fun build(): GetPublicKeyCredentialOptionPrivileged {
- return GetPublicKeyCredentialOptionPrivileged(this.requestJson,
- this.rp, this.clientDataHash, this.allowHybrid)
+ return GetPublicKeyCredentialOptionPrivileged(
+ this.requestJson,
+ this.relyingParty, this.clientDataHash, this.preferImmediatelyAvailableCredentials
+ )
}
}
+ /** @hide */
companion object {
- const val BUNDLE_KEY_RP = "androidx.credentials.BUNDLE_KEY_RP"
- const val BUNDLE_KEY_CLIENT_DATA_HASH =
- "androidx.credentials.BUNDLE_KEY_CLIENT_DATA_HASH"
- const val BUNDLE_KEY_ALLOW_HYBRID = "androidx.credentials.BUNDLE_KEY_ALLOW_HYBRID"
- const val BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION_PRIVILEGED =
- "androidx.credentials.BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION" +
- "_PRIVILEGED"
+ internal const val BUNDLE_KEY_RELYING_PARTY =
+ "androidx.credentials.BUNDLE_KEY_RELYING_PARTY"
+ internal const val BUNDLE_KEY_CLIENT_DATA_HASH =
+ "androidx.credentials.BUNDLE_KEY_CLIENT_DATA_HASH"
+ internal const val BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS =
+ "androidx.credentials.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS"
+ internal const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
+ internal const val BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION_PRIVILEGED =
+ "androidx.credentials.BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION" +
+ "_PRIVILEGED"
@JvmStatic
internal fun toBundle(
- requestJson: String,
- rp: String,
- clientDataHash: String,
- allowHybrid: Boolean
+ requestJson: String,
+ relyingParty: String,
+ clientDataHash: String,
+ preferImmediatelyAvailableCredentials: Boolean
): Bundle {
val bundle = Bundle()
+ bundle.putString(
+ PublicKeyCredential.BUNDLE_KEY_SUBTYPE,
+ BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION_PRIVILEGED
+ )
bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
- bundle.putString(BUNDLE_KEY_RP, rp)
+ bundle.putString(BUNDLE_KEY_RELYING_PARTY, relyingParty)
bundle.putString(BUNDLE_KEY_CLIENT_DATA_HASH, clientDataHash)
- bundle.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybrid)
+ bundle.putBoolean(
+ BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
+ preferImmediatelyAvailableCredentials
+ )
return bundle
}
+ @Suppress("deprecation") // bundle.get() used for boolean value to prevent default
+ // boolean value from being returned.
@JvmStatic
- fun createFrom(data: Bundle): GetPublicKeyCredentialOptionPrivileged {
+ internal fun createFrom(data: Bundle): GetPublicKeyCredentialOptionPrivileged {
try {
val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
- val rp = data.getString(BUNDLE_KEY_RP)
+ val rp = data.getString(BUNDLE_KEY_RELYING_PARTY)
val clientDataHash = data.getString(BUNDLE_KEY_CLIENT_DATA_HASH)
- val allowHybrid = data.get(BUNDLE_KEY_ALLOW_HYBRID)
+ val preferImmediatelyAvailableCredentials =
+ data.get(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS)
return GetPublicKeyCredentialOptionPrivileged(
- requestJson!!,
- rp!!,
- clientDataHash!!,
- (allowHybrid!!) as Boolean,
+ requestJson!!,
+ rp!!,
+ clientDataHash!!,
+ (preferImmediatelyAvailableCredentials!!) as Boolean,
)
} catch (e: Exception) {
throw FrameworkClassParsingException()
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/PublicKeyCredential.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/PublicKeyCredential.kt
index b45a63b..6a81167 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/PublicKeyCredential.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/PublicKeyCredential.kt
@@ -45,6 +45,8 @@
/** The type value for public key credential related operations. */
const val TYPE_PUBLIC_KEY_CREDENTIAL: String =
"androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL"
+ /** The Bundle key value for the public key credential subtype (privileged or regular). */
+ internal const val BUNDLE_KEY_SUBTYPE = "androidx.credentials.BUNDLE_KEY_SUBTYPE"
const val BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON =
"androidx.credentials.BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON"
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/AuthenticationAction.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/AuthenticationAction.kt
new file mode 100644
index 0000000..283c7ba
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/AuthenticationAction.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 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.credentialmanager.jetpack.provider
+
+import android.app.PendingIntent
+import android.app.slice.Slice
+import android.util.Log
+import androidx.annotation.VisibleForTesting
+
+/**
+ * UI representation for a credential entry used during the get credential flow.
+ *
+ * TODO: move to jetpack.
+ */
+class AuthenticationAction constructor(
+ val pendingIntent: PendingIntent
+) {
+
+
+ companion object {
+ private const val TAG = "AuthenticationAction"
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ internal const val SLICE_HINT_PENDING_INTENT =
+ "androidx.credentials.provider.authenticationAction.SLICE_HINT_PENDING_INTENT"
+
+ @JvmStatic
+ fun fromSlice(slice: Slice): AuthenticationAction? {
+ slice.items.forEach {
+ if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {
+ return try {
+ AuthenticationAction(it.action)
+ } catch (e: Exception) {
+ Log.i(TAG, "fromSlice failed with: " + e.message)
+ null
+ }
+ }
+ }
+ return null
+ }
+ }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CreateEntry.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CreateEntry.kt
index bed02f8..0ec91d6 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CreateEntry.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CreateEntry.kt
@@ -36,7 +36,8 @@
val pendingIntent: PendingIntent?,
val icon: Icon?,
val lastUsedTimeMillis: Long,
- val credentialCountInformationList: List<CredentialCountInformation>
+ val credentialCountInformationList: List<CredentialCountInformation>,
+ val footerDescription: CharSequence?,
) {
init {
@@ -61,6 +62,7 @@
mutableListOf()
private var icon: Icon? = null
private var lastUsedTimeMillis: Long = 0
+ private var footerDescription: CharSequence? = null
/** Adds a [CredentialCountInformation] denoting a given credential
* type and the count of credentials that the provider has stored for that
@@ -99,6 +101,12 @@
return this
}
+ /** Sets the footer description of this */
+ fun setFooterDescription(footerDescription: CharSequence): Builder {
+ this.footerDescription = footerDescription
+ return this
+ }
+
/**
* Builds an instance of [CreateEntry]
*
@@ -106,7 +114,7 @@
*/
fun build(): CreateEntry {
return CreateEntry(accountName, pendingIntent, icon, lastUsedTimeMillis,
- credentialCountInformationList)
+ credentialCountInformationList, footerDescription)
}
}
@@ -122,6 +130,8 @@
"androidx.credentials.provider.createEntry.SLICE_HINT_LAST_USED_TIME_MILLIS"
internal const val SLICE_HINT_PENDING_INTENT =
"androidx.credentials.provider.createEntry.SLICE_HINT_PENDING_INTENT"
+ internal const val SLICE_HINT_FOOTER_DESCRIPTION =
+ "androidx.credentials.provider.createEntry.SLICE_HINT_FOOTER_DESCRIPTION"
@JvmStatic
fun toSlice(createEntry: CreateEntry): Slice {
@@ -150,6 +160,10 @@
.build(),
/*subType=*/null)
}
+ if (createEntry.footerDescription != null) {
+ sliceBuilder.addText(createEntry.footerDescription, /*subType=*/null,
+ listOf(SLICE_HINT_FOOTER_DESCRIPTION))
+ }
return sliceBuilder.build()
}
@@ -167,6 +181,7 @@
var pendingIntent: PendingIntent? = null
var credentialCountInfo: List<CredentialCountInformation> = listOf()
var lastUsedTimeMillis: Long = 0
+ var footerDescription: CharSequence? = null
slice.items.forEach {
if (it.hasHint(SLICE_HINT_ACCOUNT_NAME)) {
@@ -179,12 +194,14 @@
credentialCountInfo = convertBundleToCredentialCountInfo(it.bundle)
} else if (it.hasHint(SLICE_HINT_LAST_USED_TIME_MILLIS)) {
lastUsedTimeMillis = it.long
+ } else if (it.hasHint(SLICE_HINT_FOOTER_DESCRIPTION)) {
+ footerDescription = it.text
}
}
return try {
CreateEntry(accountName, pendingIntent, icon,
- lastUsedTimeMillis, credentialCountInfo)
+ lastUsedTimeMillis, credentialCountInfo, footerDescription)
} catch (e: Exception) {
Log.i(TAG, "fromSlice failed with: " + e.message)
null
diff --git a/packages/PackageInstaller/res/values/strings.xml b/packages/PackageInstaller/res/values/strings.xml
index b713c14..cb2baa9 100644
--- a/packages/PackageInstaller/res/values/strings.xml
+++ b/packages/PackageInstaller/res/values/strings.xml
@@ -37,6 +37,11 @@
<string name="install_confirm_question">Do you want to install this app?</string>
<!-- Message for updating an existing app [CHAR LIMIT=NONE] -->
<string name="install_confirm_question_update">Do you want to update this app?</string>
+ <!-- TODO(b/244413073) Revise the description after getting UX input and UXR on this. -->
+ <!-- Message for updating an existing app when updating owner changed [CHAR LIMIT=NONE] -->
+ <string name="install_confirm_question_update_owner_changed">Updates to this app are currently managed by <xliff:g id="existing_update_owner">%1$s</xliff:g>.\n\nBy updating, you\'ll get future updates from <xliff:g id="new_update_owner">%2$s</xliff:g> instead.</string>
+ <!-- Message for updating an existing app with update owner reminder [CHAR LIMIT=NONE] -->
+ <string name="install_confirm_question_update_owner_reminder">Updates to this app are currently managed by <xliff:g id="existing_update_owner">%1$s</xliff:g>.\n\nDo you want to install this update from <xliff:g id="new_update_owner">%2$s</xliff:g>.</string>
<!-- [CHAR LIMIT=100] -->
<string name="install_failed">App not installed.</string>
<!-- Reason displayed when installation fails because the package was blocked
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
index 3138158..49c9188 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -33,10 +33,12 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
+import android.content.pm.InstallSourceInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.ApplicationInfoFlags;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
@@ -47,9 +49,11 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
+import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
@@ -88,6 +92,7 @@
private int mOriginatingUid = Process.INVALID_UID;
private String mOriginatingPackage; // The package name corresponding to #mOriginatingUid
private int mActivityResultCode = Activity.RESULT_CANCELED;
+ private int mPendingUserActionReason = -1;
private final boolean mLocalLOGV = false;
PackageManager mPm;
@@ -132,10 +137,27 @@
private boolean mEnableOk = false;
private void startInstallConfirm() {
- View viewToEnable;
+ TextView viewToEnable;
if (mAppInfo != null) {
viewToEnable = requireViewById(R.id.install_confirm_question_update);
+
+ final CharSequence existingUpdateOwnerLabel = getExistingUpdateOwnerLabel();
+ final CharSequence requestedUpdateOwnerLabel = getApplicationLabel(mCallingPackage);
+ if (!TextUtils.isEmpty(existingUpdateOwnerLabel)) {
+ if (mPendingUserActionReason == PackageInstaller.REASON_OWNERSHIP_CHANGED) {
+ viewToEnable.setText(
+ getString(R.string.install_confirm_question_update_owner_changed,
+ existingUpdateOwnerLabel, requestedUpdateOwnerLabel));
+ } else if (mPendingUserActionReason == PackageInstaller.REASON_REMIND_OWNERSHIP
+ || mPendingUserActionReason
+ == PackageInstaller.REASON_CONFIRM_PACKAGE_CHANGE) {
+ viewToEnable.setText(
+ getString(R.string.install_confirm_question_update_owner_reminder,
+ existingUpdateOwnerLabel, requestedUpdateOwnerLabel));
+ }
+ }
+
mOk.setText(R.string.update);
} else {
// This is a new application with no permissions.
@@ -149,6 +171,27 @@
mOk.setFilterTouchesWhenObscured(true);
}
+ private CharSequence getExistingUpdateOwnerLabel() {
+ try {
+ final String packageName = mPkgInfo.packageName;
+ final InstallSourceInfo sourceInfo = mPm.getInstallSourceInfo(packageName);
+ final String existingUpdateOwner = sourceInfo.getUpdateOwnerPackageName();
+ return getApplicationLabel(existingUpdateOwner);
+ } catch (NameNotFoundException e) {
+ return null;
+ }
+ }
+
+ private CharSequence getApplicationLabel(String packageName) {
+ try {
+ final ApplicationInfo appInfo = mPm.getApplicationInfo(packageName,
+ ApplicationInfoFlags.of(0));
+ return mPm.getApplicationLabel(appInfo);
+ } catch (NameNotFoundException e) {
+ return null;
+ }
+ }
+
/**
* Replace any dialog shown by the dialog with the one for the given {@link #createDialog(int)}.
*
@@ -344,6 +387,7 @@
packageSource = Uri.fromFile(new File(resolvedBaseCodePath));
mOriginatingURI = null;
mReferrerURI = null;
+ mPendingUserActionReason = info.getPendingUserActionReason();
} else if (PackageInstaller.ACTION_CONFIRM_PRE_APPROVAL.equals(action)) {
final int sessionId = intent.getIntExtra(PackageInstaller.EXTRA_SESSION_ID,
-1 /* defaultValue */);
@@ -358,11 +402,13 @@
packageSource = info;
mOriginatingURI = null;
mReferrerURI = null;
+ mPendingUserActionReason = info.getPendingUserActionReason();
} else {
mSessionId = -1;
packageSource = intent.getData();
mOriginatingURI = intent.getParcelableExtra(Intent.EXTRA_ORIGINATING_URI);
mReferrerURI = intent.getParcelableExtra(Intent.EXTRA_REFERRER);
+ mPendingUserActionReason = PackageInstaller.REASON_CONFIRM_PACKAGE_CHANGE;
}
// if there's nothing to do, quietly slip into the ether
diff --git a/packages/SettingsLib/IllustrationPreference/Android.bp b/packages/SettingsLib/IllustrationPreference/Android.bp
index 5904589..e80eb66 100644
--- a/packages/SettingsLib/IllustrationPreference/Android.bp
+++ b/packages/SettingsLib/IllustrationPreference/Android.bp
@@ -20,4 +20,9 @@
sdk_version: "system_current",
min_sdk_version: "28",
+
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.permission",
+ ],
}
diff --git a/packages/SettingsLib/Spa/spa/build.gradle b/packages/SettingsLib/Spa/spa/build.gradle
index 73c1099..bf4ad75 100644
--- a/packages/SettingsLib/Spa/spa/build.gradle
+++ b/packages/SettingsLib/Spa/spa/build.gradle
@@ -88,6 +88,7 @@
implementation "com.airbnb.android:lottie-compose:5.2.0"
androidTestImplementation project(":testutils")
+ androidTestImplementation 'androidx.lifecycle:lifecycle-runtime-testing'
androidTestImplementation "com.linkedin.dexmaker:dexmaker-mockito:2.28.1"
}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/LifecycleEffect.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/LifecycleEffect.kt
new file mode 100644
index 0000000..e91fa65
--- /dev/null
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/LifecycleEffect.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 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.settingslib.spa.framework.compose
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.DisposableEffect
+import androidx.compose.ui.platform.LocalLifecycleOwner
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleEventObserver
+
+@Composable
+fun LifecycleEffect(
+ onStart: () -> Unit = {},
+ onStop: () -> Unit = {},
+) {
+ val lifecycleOwner = LocalLifecycleOwner.current
+ DisposableEffect(lifecycleOwner) {
+ val observer = LifecycleEventObserver { _, event ->
+ if (event == Lifecycle.Event.ON_START) {
+ onStart()
+ } else if (event == Lifecycle.Event.ON_STOP) {
+ onStop()
+ }
+ }
+
+ lifecycleOwner.lifecycle.addObserver(observer)
+
+ onDispose {
+ lifecycleOwner.lifecycle.removeObserver(observer)
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/PageLogger.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/PageLogger.kt
index 271443e..73eae07 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/PageLogger.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/PageLogger.kt
@@ -18,55 +18,41 @@
import android.os.Bundle
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember
-import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.core.os.bundleOf
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleEventObserver
import com.android.settingslib.spa.framework.common.LOG_DATA_DISPLAY_NAME
import com.android.settingslib.spa.framework.common.LOG_DATA_SESSION_NAME
import com.android.settingslib.spa.framework.common.LogCategory
import com.android.settingslib.spa.framework.common.LogEvent
+import com.android.settingslib.spa.framework.common.SettingsPage
import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
import com.android.settingslib.spa.framework.common.createSettingsPage
+import com.android.settingslib.spa.framework.compose.LifecycleEffect
import com.android.settingslib.spa.framework.compose.LocalNavController
+import com.android.settingslib.spa.framework.compose.NavControllerWrapper
@Composable
internal fun SettingsPageProvider.PageEvent(arguments: Bundle? = null) {
val page = remember(arguments) { createSettingsPage(arguments) }
- val lifecycleOwner = LocalLifecycleOwner.current
val navController = LocalNavController.current
- DisposableEffect(lifecycleOwner) {
- val observer = LifecycleEventObserver { _, event ->
- val logPageEvent: (event: LogEvent) -> Unit = {
- SpaEnvironmentFactory.instance.logger.event(
- id = page.id,
- event = it,
- category = LogCategory.FRAMEWORK,
- extraData = bundleOf(
- LOG_DATA_DISPLAY_NAME to page.displayName,
- LOG_DATA_SESSION_NAME to navController.sessionSourceName,
- ).apply {
- val normArguments = parameter.normalize(arguments)
- if (normArguments != null) putAll(normArguments)
- }
- )
- }
- if (event == Lifecycle.Event.ON_START) {
- logPageEvent(LogEvent.PAGE_ENTER)
- } else if (event == Lifecycle.Event.ON_STOP) {
- logPageEvent(LogEvent.PAGE_LEAVE)
- }
- }
-
- // Add the observer to the lifecycle
- lifecycleOwner.lifecycle.addObserver(observer)
-
- // When the effect leaves the Composition, remove the observer
- onDispose {
- lifecycleOwner.lifecycle.removeObserver(observer)
- }
- }
+ LifecycleEffect(
+ onStart = { page.logPageEvent(LogEvent.PAGE_ENTER, navController) },
+ onStop = { page.logPageEvent(LogEvent.PAGE_LEAVE, navController) },
+ )
}
+
+private fun SettingsPage.logPageEvent(event: LogEvent, navController: NavControllerWrapper) {
+ SpaEnvironmentFactory.instance.logger.event(
+ id = id,
+ event = event,
+ category = LogCategory.FRAMEWORK,
+ extraData = bundleOf(
+ LOG_DATA_DISPLAY_NAME to displayName,
+ LOG_DATA_SESSION_NAME to navController.sessionSourceName,
+ ).apply {
+ val normArguments = parameter.normalize(arguments)
+ if (normArguments != null) putAll(normArguments)
+ }
+ )
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/Spa/tests/Android.bp b/packages/SettingsLib/Spa/tests/Android.bp
index f9e64ae..b4c67cc 100644
--- a/packages/SettingsLib/Spa/tests/Android.bp
+++ b/packages/SettingsLib/Spa/tests/Android.bp
@@ -31,6 +31,7 @@
"SpaLib",
"SpaLibTestUtils",
"androidx.compose.runtime_runtime",
+ "androidx.lifecycle_lifecycle-runtime-testing",
"androidx.test.ext.junit",
"androidx.test.runner",
"mockito-target-minus-junit4",
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/compose/LifecycleEffectTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/compose/LifecycleEffectTest.kt
new file mode 100644
index 0000000..fe7baff
--- /dev/null
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/compose/LifecycleEffectTest.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 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.settingslib.spa.framework.compose
+
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.ui.platform.LocalLifecycleOwner
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.testing.TestLifecycleOwner
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class LifecycleEffectTest {
+ @get:Rule
+ val composeTestRule = createComposeRule()
+
+ @Test
+ fun onStart_isCalled() {
+ var onStartIsCalled = false
+ composeTestRule.setContent {
+ LifecycleEffect(onStart = { onStartIsCalled = true })
+ }
+
+ assertThat(onStartIsCalled).isTrue()
+ }
+
+ @Test
+ fun onStop_isCalled() {
+ var onStopIsCalled = false
+ val testLifecycleOwner = TestLifecycleOwner()
+
+ composeTestRule.setContent {
+ CompositionLocalProvider(LocalLifecycleOwner provides testLifecycleOwner) {
+ LifecycleEffect(onStop = { onStopIsCalled = true })
+ }
+ LaunchedEffect(Unit) {
+ testLifecycleOwner.currentState = Lifecycle.State.CREATED
+ }
+ }
+
+ assertThat(onStopIsCalled).isTrue()
+ }
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUser.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUser.kt
index b2ea4a0..a2fb101 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUser.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUser.kt
@@ -22,11 +22,9 @@
import android.content.IntentFilter
import android.os.UserHandle
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.platform.LocalLifecycleOwner
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleEventObserver
+import com.android.settingslib.spa.framework.compose.LifecycleEffect
/**
* A [BroadcastReceiver] which registered when on start and unregistered when on stop.
@@ -39,28 +37,22 @@
onReceive: (Intent) -> Unit,
) {
val context = LocalContext.current
- val lifecycleOwner = LocalLifecycleOwner.current
- DisposableEffect(lifecycleOwner) {
- val broadcastReceiver = object : BroadcastReceiver() {
+ val broadcastReceiver = remember {
+ object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
onReceive(intent)
}
}
- val observer = LifecycleEventObserver { _, event ->
- if (event == Lifecycle.Event.ON_START) {
- context.registerReceiverAsUser(
- broadcastReceiver, userHandle, intentFilter, null, null
- )
- onStart()
- } else if (event == Lifecycle.Event.ON_STOP) {
- context.unregisterReceiver(broadcastReceiver)
- }
- }
-
- lifecycleOwner.lifecycle.addObserver(observer)
-
- onDispose {
- lifecycleOwner.lifecycle.removeObserver(observer)
- }
}
+ LifecycleEffect(
+ onStart = {
+ context.registerReceiverAsUser(
+ broadcastReceiver, userHandle, intentFilter, null, null
+ )
+ onStart()
+ },
+ onStop = {
+ context.unregisterReceiver(broadcastReceiver)
+ },
+ )
}
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt
index 6cd6e95..171903f 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt
@@ -17,6 +17,7 @@
package com.android.settingslib.spaprivileged.model.app
import android.app.AppOpsManager.MODE_ALLOWED
+import android.app.AppOpsManager.MODE_ERRORED
import android.app.AppOpsManager.Mode
import android.content.Context
import android.content.pm.ApplicationInfo
@@ -39,7 +40,7 @@
context: Context,
private val app: ApplicationInfo,
private val op: Int,
- private val modeForNotAllowed: Int,
+ private val modeForNotAllowed: Int = MODE_ERRORED,
private val setModeByUid: Boolean = false,
) : IAppOpsController {
private val appOpsManager = context.appOpsManager
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt
index 53af25b..338b16d 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt
@@ -66,7 +66,7 @@
* If true, it uses getAppOpPermissionPackages() to fetch bits to decide whether the permission
* is requested.
*/
- open val permissionHasAppopFlag: Boolean = true
+ open val permissionHasAppOpFlag: Boolean = true
open val modeForNotAllowed: Int = MODE_ERRORED
@@ -105,7 +105,7 @@
}
override fun transform(userIdFlow: Flow<Int>, appListFlow: Flow<List<ApplicationInfo>>) =
- if (permissionHasAppopFlag) {
+ if (permissionHasAppOpFlag) {
userIdFlow
.map { userId -> packageManagers.getAppOpPermissionPackages(userId, permission) }
.combine(appListFlow) { packageNames, appList ->
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt
index 53e52d0..fd2ceb7 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppOpsControllerTest.kt
@@ -19,6 +19,7 @@
import android.app.AppOpsManager
import android.app.AppOpsManager.MODE_ALLOWED
import android.app.AppOpsManager.MODE_ERRORED
+import android.app.AppOpsManager.MODE_IGNORED
import android.content.Context
import android.content.pm.ApplicationInfo
import androidx.test.core.app.ApplicationProvider
@@ -56,7 +57,6 @@
context = context,
app = APP,
op = OP,
- modeForNotAllowed = MODE_ERRORED
)
controller.setAllowed(true)
@@ -71,7 +71,6 @@
context = context,
app = APP,
op = OP,
- modeForNotAllowed = MODE_ERRORED
)
controller.setAllowed(false)
@@ -80,14 +79,28 @@
}
@Test
+ fun setAllowed_setToFalseWithModeForNotAllowed() {
+ val controller =
+ AppOpsController(
+ context = context,
+ app = APP,
+ op = OP,
+ modeForNotAllowed = MODE_IGNORED,
+ )
+
+ controller.setAllowed(false)
+
+ verify(appOpsManager).setMode(OP, APP.uid, APP.packageName, MODE_IGNORED)
+ }
+
+ @Test
fun setAllowed_setToTrueByUid() {
val controller =
AppOpsController(
context = context,
app = APP,
op = OP,
- modeForNotAllowed = MODE_ERRORED,
- setModeByUid = true
+ setModeByUid = true,
)
controller.setAllowed(true)
@@ -102,8 +115,7 @@
context = context,
app = APP,
op = OP,
- modeForNotAllowed = MODE_ERRORED,
- setModeByUid = true
+ setModeByUid = true,
)
controller.setAllowed(false)
@@ -120,7 +132,6 @@
context = context,
app = APP,
op = OP,
- modeForNotAllowed = MODE_ERRORED
)
val mode = controller.getMode()
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt
index da765ba..af59a55 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt
@@ -314,7 +314,6 @@
override val appOp = AppOpsManager.OP_MANAGE_MEDIA
override val permission = PERMISSION
- override val permissionHasAppopFlag = true
override var broaderPermission: String? = null
override var setModeByUid = false
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 90874bb..06c3476 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -123,7 +123,7 @@
Settings.Secure.FINGERPRINT_SIDE_FPS_BP_POWER_WINDOW,
Settings.Secure.FINGERPRINT_SIDE_FPS_ENROLL_TAP_WINDOW,
Settings.Secure.FINGERPRINT_SIDE_FPS_AUTH_DOWNTIME,
- Settings.Secure.SFPS_REQUIRE_SCREEN_ON_TO_AUTH_ENABLED,
+ Settings.Secure.SFPS_PERFORMANT_AUTH_ENABLED,
Settings.Secure.ACTIVE_UNLOCK_ON_WAKE,
Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT,
Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 62f4c41..d72d4d5 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -178,7 +178,7 @@
VALIDATORS.put(Secure.FINGERPRINT_SIDE_FPS_ENROLL_TAP_WINDOW,
NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(Secure.FINGERPRINT_SIDE_FPS_AUTH_DOWNTIME, NON_NEGATIVE_INTEGER_VALIDATOR);
- VALIDATORS.put(Secure.SFPS_REQUIRE_SCREEN_ON_TO_AUTH_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.SFPS_PERFORMANT_AUTH_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.SHOW_MEDIA_WHEN_BYPASSING, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.FACE_UNLOCK_APP_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, BOOLEAN_VALIDATOR);
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index d56300e..d716b32 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -170,6 +170,7 @@
<uses-permission android:name="android.permission.SET_ORIENTATION" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.INSTALL_PACKAGE_UPDATES" />
+ <uses-permission android:name="android.permission.ENFORCE_UPDATE_OWNERSHIP" />
<uses-permission android:name="android.permission.INSTALL_DPC_PACKAGES" />
<uses-permission android:name="com.android.permission.USE_INSTALLER_V2" />
<uses-permission android:name="android.permission.INSTALL_TEST_ONLY_PACKAGE" />
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 4be1d30..ecb88f6 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -415,7 +415,6 @@
<service android:name=".screenshot.ScreenshotCrossProfileService"
android:permission="com.android.systemui.permission.SELF"
- android:process=":screenshot_cross_profile"
android:exported="false" />
<service android:name=".screenrecord.RecordingService"
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
index fe349f2..8f70dcc 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -37,6 +37,8 @@
import android.view.WindowManager
import android.view.animation.Interpolator
import android.view.animation.PathInterpolator
+import androidx.annotation.BinderThread
+import androidx.annotation.UiThread
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.policy.ScreenDecorationsUtils
import kotlin.math.roundToInt
@@ -226,7 +228,7 @@
// If we expect an animation, post a timeout to cancel it in case the remote animation is
// never started.
if (willAnimate) {
- runner.postTimeout()
+ runner.delegate.postTimeout()
// Hide the keyguard using the launch animation instead of the default unlock animation.
if (hideKeyguardWithAnimation) {
@@ -389,14 +391,51 @@
fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean? = null) {}
}
- class Runner(
+ @VisibleForTesting
+ inner class Runner(
+ controller: Controller,
+ callback: Callback,
+ /** The animator to use to animate the window launch. */
+ launchAnimator: LaunchAnimator = DEFAULT_LAUNCH_ANIMATOR,
+ /** Listener for animation lifecycle events. */
+ listener: Listener? = null
+ ) : IRemoteAnimationRunner.Stub() {
+ private val context = controller.launchContainer.context
+ internal val delegate: AnimationDelegate
+
+ init {
+ delegate = AnimationDelegate(controller, callback, launchAnimator, listener)
+ }
+
+ @BinderThread
+ override fun onAnimationStart(
+ transit: Int,
+ apps: Array<out RemoteAnimationTarget>?,
+ wallpapers: Array<out RemoteAnimationTarget>?,
+ nonApps: Array<out RemoteAnimationTarget>?,
+ finishedCallback: IRemoteAnimationFinishedCallback?
+ ) {
+ context.mainExecutor.execute {
+ delegate.onAnimationStart(transit, apps, wallpapers, nonApps, finishedCallback)
+ }
+ }
+
+ @BinderThread
+ override fun onAnimationCancelled(isKeyguardOccluded: Boolean) {
+ context.mainExecutor.execute { delegate.onAnimationCancelled(isKeyguardOccluded) }
+ }
+ }
+
+ class AnimationDelegate
+ @JvmOverloads
+ constructor(
private val controller: Controller,
private val callback: Callback,
/** The animator to use to animate the window launch. */
private val launchAnimator: LaunchAnimator = DEFAULT_LAUNCH_ANIMATOR,
/** Listener for animation lifecycle events. */
private val listener: Listener? = null
- ) : IRemoteAnimationRunner.Stub() {
+ ) : RemoteAnimationDelegate<IRemoteAnimationFinishedCallback> {
private val launchContainer = controller.launchContainer
private val context = launchContainer.context
private val transactionApplierView =
@@ -419,6 +458,7 @@
// posting it.
private var onTimeout = Runnable { onAnimationTimedOut() }
+ @UiThread
internal fun postTimeout() {
launchContainer.postDelayed(onTimeout, LAUNCH_TIMEOUT)
}
@@ -427,19 +467,20 @@
launchContainer.removeCallbacks(onTimeout)
}
+ @UiThread
override fun onAnimationStart(
@WindowManager.TransitionOldType transit: Int,
apps: Array<out RemoteAnimationTarget>?,
wallpapers: Array<out RemoteAnimationTarget>?,
nonApps: Array<out RemoteAnimationTarget>?,
- iCallback: IRemoteAnimationFinishedCallback?
+ callback: IRemoteAnimationFinishedCallback?
) {
removeTimeout()
// The animation was started too late and we already notified the controller that it
// timed out.
if (timedOut) {
- iCallback?.invoke()
+ callback?.invoke()
return
}
@@ -449,7 +490,7 @@
return
}
- context.mainExecutor.execute { startAnimation(apps, nonApps, iCallback) }
+ startAnimation(apps, nonApps, callback)
}
private fun startAnimation(
@@ -687,6 +728,7 @@
controller.onLaunchAnimationCancelled()
}
+ @UiThread
override fun onAnimationCancelled(isKeyguardOccluded: Boolean) {
if (timedOut) {
return
@@ -695,10 +737,9 @@
Log.i(TAG, "Remote animation was cancelled")
cancelled = true
removeTimeout()
- context.mainExecutor.execute {
- animation?.cancel()
- controller.onLaunchAnimationCancelled(newKeyguardOccludedState = isKeyguardOccluded)
- }
+
+ animation?.cancel()
+ controller.onLaunchAnimationCancelled(newKeyguardOccludedState = isKeyguardOccluded)
}
private fun IRemoteAnimationFinishedCallback.invoke() {
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
index 2903288..3d341af 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
@@ -33,7 +33,9 @@
private const val FONT_ITALIC_ANIMATION_STEP = 0.1f
private const val FONT_ITALIC_DEFAULT_VALUE = 0f
-/** Provide interpolation of two fonts by adjusting font variation settings. */
+/**
+ * Provide interpolation of two fonts by adjusting font variation settings.
+ */
class FontInterpolator {
/**
@@ -59,14 +61,11 @@
var index: Int,
val sortedAxes: MutableList<FontVariationAxis>
) {
- constructor(
- font: Font,
- axes: List<FontVariationAxis>
- ) : this(
- font.sourceIdentifier,
- font.ttcIndex,
- axes.toMutableList().apply { sortBy { it.tag } }
- )
+ constructor(font: Font, axes: List<FontVariationAxis>) :
+ this(font.sourceIdentifier,
+ font.ttcIndex,
+ axes.toMutableList().apply { sortBy { it.tag } }
+ )
fun set(font: Font, axes: List<FontVariationAxis>) {
sourceId = font.sourceIdentifier
@@ -87,7 +86,9 @@
private val tmpInterpKey = InterpKey(null, null, 0f)
private val tmpVarFontKey = VarFontKey(0, 0, mutableListOf())
- /** Linear interpolate the font variation settings. */
+ /**
+ * Linear interpolate the font variation settings.
+ */
fun lerp(start: Font, end: Font, progress: Float): Font {
if (progress == 0f) {
return start
@@ -114,34 +115,27 @@
// this doesn't take much time since the variation axes is usually up to 5. If we need to
// support more number of axes, we may want to preprocess the font and store the sorted axes
// and also pre-fill the missing axes value with default value from 'fvar' table.
- val newAxes =
- lerp(startAxes, endAxes) { tag, startValue, endValue ->
- when (tag) {
- // TODO: Good to parse 'fvar' table for retrieving default value.
- TAG_WGHT ->
- adjustWeight(
- MathUtils.lerp(
+ val newAxes = lerp(startAxes, endAxes) { tag, startValue, endValue ->
+ when (tag) {
+ // TODO: Good to parse 'fvar' table for retrieving default value.
+ TAG_WGHT -> adjustWeight(
+ MathUtils.lerp(
startValue ?: FONT_WEIGHT_DEFAULT_VALUE,
endValue ?: FONT_WEIGHT_DEFAULT_VALUE,
- progress
- )
- )
- TAG_ITAL ->
- adjustItalic(
- MathUtils.lerp(
+ progress))
+ TAG_ITAL -> adjustItalic(
+ MathUtils.lerp(
startValue ?: FONT_ITALIC_DEFAULT_VALUE,
endValue ?: FONT_ITALIC_DEFAULT_VALUE,
- progress
- )
- )
- else -> {
- require(startValue != null && endValue != null) {
- "Unable to interpolate due to unknown default axes value : $tag"
- }
- MathUtils.lerp(startValue, endValue, progress)
+ progress))
+ else -> {
+ require(startValue != null && endValue != null) {
+ "Unable to interpolate due to unknown default axes value : $tag"
}
+ MathUtils.lerp(startValue, endValue, progress)
}
}
+ }
// Check if we already make font for this axes. This is typically happens if the animation
// happens backward.
@@ -155,7 +149,9 @@
// This is the first time to make the font for the axes. Build and store it to the cache.
// Font.Builder#build won't throw IOException since creating fonts from existing fonts will
// not do any IO work.
- val newFont = Font.Builder(start).setFontVariationSettings(newAxes.toTypedArray()).build()
+ val newFont = Font.Builder(start)
+ .setFontVariationSettings(newAxes.toTypedArray())
+ .build()
interpCache[InterpKey(start, end, progress)] = newFont
verFontCache[VarFontKey(start, newAxes)] = newFont
return newFont
@@ -177,28 +173,26 @@
val tagA = if (i < start.size) start[i].tag else null
val tagB = if (j < end.size) end[j].tag else null
- val comp =
- when {
- tagA == null -> 1
- tagB == null -> -1
- else -> tagA.compareTo(tagB)
- }
+ val comp = when {
+ tagA == null -> 1
+ tagB == null -> -1
+ else -> tagA.compareTo(tagB)
+ }
- val axis =
- when {
- comp == 0 -> {
- val v = filter(tagA!!, start[i++].styleValue, end[j++].styleValue)
- FontVariationAxis(tagA, v)
- }
- comp < 0 -> {
- val v = filter(tagA!!, start[i++].styleValue, null)
- FontVariationAxis(tagA, v)
- }
- else -> { // comp > 0
- val v = filter(tagB!!, null, end[j++].styleValue)
- FontVariationAxis(tagB, v)
- }
+ val axis = when {
+ comp == 0 -> {
+ val v = filter(tagA!!, start[i++].styleValue, end[j++].styleValue)
+ FontVariationAxis(tagA, v)
}
+ comp < 0 -> {
+ val v = filter(tagA!!, start[i++].styleValue, null)
+ FontVariationAxis(tagA, v)
+ }
+ else -> { // comp > 0
+ val v = filter(tagB!!, null, end[j++].styleValue)
+ FontVariationAxis(tagB, v)
+ }
+ }
result.add(axis)
}
@@ -208,21 +202,21 @@
// For the performance reasons, we animate weight with FONT_WEIGHT_ANIMATION_STEP. This helps
// Cache hit ratio in the Skia glyph cache.
private fun adjustWeight(value: Float) =
- coerceInWithStep(value, FONT_WEIGHT_MIN, FONT_WEIGHT_MAX, FONT_WEIGHT_ANIMATION_STEP)
+ coerceInWithStep(value, FONT_WEIGHT_MIN, FONT_WEIGHT_MAX, FONT_WEIGHT_ANIMATION_STEP)
// For the performance reasons, we animate italic with FONT_ITALIC_ANIMATION_STEP. This helps
// Cache hit ratio in the Skia glyph cache.
private fun adjustItalic(value: Float) =
- coerceInWithStep(value, FONT_ITALIC_MIN, FONT_ITALIC_MAX, FONT_ITALIC_ANIMATION_STEP)
+ coerceInWithStep(value, FONT_ITALIC_MIN, FONT_ITALIC_MAX, FONT_ITALIC_ANIMATION_STEP)
private fun coerceInWithStep(v: Float, min: Float, max: Float, step: Float) =
- (v.coerceIn(min, max) / step).toInt() * step
+ (v.coerceIn(min, max) / step).toInt() * step
companion object {
private val EMPTY_AXES = arrayOf<FontVariationAxis>()
// Returns true if given two font instance can be interpolated.
fun canInterpolate(start: Font, end: Font) =
- start.ttcIndex == end.ttcIndex && start.sourceIdentifier == end.sourceIdentifier
+ start.ttcIndex == end.ttcIndex && start.sourceIdentifier == end.sourceIdentifier
}
}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationDelegate.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationDelegate.kt
new file mode 100644
index 0000000..337408b
--- /dev/null
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationDelegate.kt
@@ -0,0 +1,30 @@
+package com.android.systemui.animation
+
+import android.annotation.UiThread
+import android.view.IRemoteAnimationFinishedCallback
+import android.view.RemoteAnimationTarget
+import android.view.WindowManager
+
+/**
+ * A component capable of running remote animations.
+ *
+ * Expands the IRemoteAnimationRunner API by allowing for different types of more specialized
+ * callbacks.
+ */
+interface RemoteAnimationDelegate<in T : IRemoteAnimationFinishedCallback> {
+ /**
+ * Called on the UI thread when the animation targets are received. Sets up and kicks off the
+ * animation.
+ */
+ @UiThread
+ fun onAnimationStart(
+ @WindowManager.TransitionOldType transit: Int,
+ apps: Array<out RemoteAnimationTarget>?,
+ wallpapers: Array<out RemoteAnimationTarget>?,
+ nonApps: Array<out RemoteAnimationTarget>?,
+ callback: T?
+ )
+
+ /** Called on the UI thread when a signal is received to cancel the animation. */
+ @UiThread fun onAnimationCancelled(isKeyguardOccluded: Boolean)
+}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
index 65d6c83..5f1bb83 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
@@ -36,7 +36,8 @@
* Currently this class can provide text style animation for text weight and text size. For example
* the simple view that draws text with animating text size is like as follows:
*
- * ```
+ * <pre>
+ * <code>
* class SimpleTextAnimation : View {
* @JvmOverloads constructor(...)
*
@@ -52,34 +53,39 @@
* animator.setTextStyle(-1 /* unchanged weight */, sizePx, animate)
* }
* }
- * ```
+ * </code>
+ * </pre>
*/
-class TextAnimator(layout: Layout, private val invalidateCallback: () -> Unit) {
+class TextAnimator(
+ layout: Layout,
+ private val invalidateCallback: () -> Unit
+) {
// Following two members are for mutable for testing purposes.
public var textInterpolator: TextInterpolator = TextInterpolator(layout)
- public var animator: ValueAnimator =
- ValueAnimator.ofFloat(1f).apply {
- duration = DEFAULT_ANIMATION_DURATION
- addUpdateListener {
- textInterpolator.progress = it.animatedValue as Float
- invalidateCallback()
- }
- addListener(
- object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator?) {
- textInterpolator.rebase()
- }
- override fun onAnimationCancel(animation: Animator?) = textInterpolator.rebase()
- }
- )
+ public var animator: ValueAnimator = ValueAnimator.ofFloat(1f).apply {
+ duration = DEFAULT_ANIMATION_DURATION
+ addUpdateListener {
+ textInterpolator.progress = it.animatedValue as Float
+ invalidateCallback()
}
+ addListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator?) {
+ textInterpolator.rebase()
+ }
+ override fun onAnimationCancel(animation: Animator?) = textInterpolator.rebase()
+ })
+ }
sealed class PositionedGlyph {
- /** Mutable X coordinate of the glyph position relative from drawing offset. */
+ /**
+ * Mutable X coordinate of the glyph position relative from drawing offset.
+ */
var x: Float = 0f
- /** Mutable Y coordinate of the glyph position relative from the baseline. */
+ /**
+ * Mutable Y coordinate of the glyph position relative from the baseline.
+ */
var y: Float = 0f
/**
@@ -90,29 +96,40 @@
/**
* Mutable text size of the glyph in pixels.
*/
- /** Mutable text size of the glyph in pixels. */
var textSize: Float = 0f
- /** Mutable color of the glyph. */
+ /**
+ * Mutable color of the glyph.
+ */
var color: Int = 0
- /** Immutable character offset in the text that the current font run start. */
+ /**
+ * Immutable character offset in the text that the current font run start.
+ */
abstract var runStart: Int
protected set
- /** Immutable run length of the font run. */
+ /**
+ * Immutable run length of the font run.
+ */
abstract var runLength: Int
protected set
- /** Immutable glyph index of the font run. */
+ /**
+ * Immutable glyph index of the font run.
+ */
abstract var glyphIndex: Int
protected set
- /** Immutable font instance for this font run. */
+ /**
+ * Immutable font instance for this font run.
+ */
abstract var font: Font
protected set
- /** Immutable glyph ID for this glyph. */
+ /**
+ * Immutable glyph ID for this glyph.
+ */
abstract var glyphId: Int
protected set
}
@@ -130,30 +147,30 @@
/**
* GlyphFilter applied just before drawing to canvas for tweaking positions and text size.
*
- * This callback is called for each glyphs just before drawing the glyphs. This function will be
- * called with the intrinsic position, size, color, glyph ID and font instance. You can mutate
- * the position, size and color for tweaking animations. Do not keep the reference of passed
- * glyph object. The interpolator reuses that object for avoiding object allocations.
+ * This callback is called for each glyphs just before drawing the glyphs. This function will
+ * be called with the intrinsic position, size, color, glyph ID and font instance. You can
+ * mutate the position, size and color for tweaking animations.
+ * Do not keep the reference of passed glyph object. The interpolator reuses that object for
+ * avoiding object allocations.
*
- * Details: The text is drawn with font run units. The font run is a text segment that draws
- * with the same font. The {@code runStart} and {@code runLimit} is a range of the font run in
- * the text that current glyph is in. Once the font run is determined, the system will convert
- * characters into glyph IDs. The {@code glyphId} is the glyph identifier in the font and {@code
- * glyphIndex} is the offset of the converted glyph array. Please note that the {@code
- * glyphIndex} is not a character index, because the character will not be converted to glyph
- * one-by-one. If there are ligatures including emoji sequence, etc, the glyph ID may be
+ * Details:
+ * The text is drawn with font run units. The font run is a text segment that draws with the
+ * same font. The {@code runStart} and {@code runLimit} is a range of the font run in the text
+ * that current glyph is in. Once the font run is determined, the system will convert characters
+ * into glyph IDs. The {@code glyphId} is the glyph identifier in the font and
+ * {@code glyphIndex} is the offset of the converted glyph array. Please note that the
+ * {@code glyphIndex} is not a character index, because the character will not be converted to
+ * glyph one-by-one. If there are ligatures including emoji sequence, etc, the glyph ID may be
* composed from multiple characters.
*
* Here is an example of font runs: "fin. 終わり"
*
- * ```
* Characters : f i n . _ 終 わ り
* Code Points: \u0066 \u0069 \u006E \u002E \u0020 \u7D42 \u308F \u308A
* Font Runs : <-- Roboto-Regular.ttf --><-- NotoSans-CJK.otf -->
* runStart = 0, runLength = 5 runStart = 5, runLength = 3
* Glyph IDs : 194 48 7 8 4367 1039 1002
* Glyph Index: 0 1 2 3 0 1 2
- * ```
*
* In this example, the "fi" is converted into ligature form, thus the single glyph ID is
* assigned for two characters, f and i.
@@ -176,29 +193,28 @@
*/
var glyphFilter: GlyphCallback?
get() = textInterpolator.glyphFilter
- set(value) {
- textInterpolator.glyphFilter = value
- }
+ set(value) { textInterpolator.glyphFilter = value }
fun draw(c: Canvas) = textInterpolator.draw(c)
/**
* Set text style with animation.
*
- * By passing -1 to weight, the view preserve the current weight. By passing -1 to textSize, the
- * view preserve the current text size. Bu passing -1 to duration, the default text animation,
- * 1000ms, is used. By passing false to animate, the text will be updated without animation.
+ * By passing -1 to weight, the view preserve the current weight.
+ * By passing -1 to textSize, the view preserve the current text size.
+ * Bu passing -1 to duration, the default text animation, 1000ms, is used.
+ * By passing false to animate, the text will be updated without animation.
*
* @param weight an optional text weight.
* @param textSize an optional font size.
- * @param colors an optional colors array that must be the same size as numLines passed to the
- * TextInterpolator
+ * @param colors an optional colors array that must be the same size as numLines passed to
+ * the TextInterpolator
* @param animate an optional boolean indicating true for showing style transition as animation,
- * false for immediate style transition. True by default.
+ * false for immediate style transition. True by default.
* @param duration an optional animation duration in milliseconds. This is ignored if animate is
- * false.
+ * false.
* @param interpolator an optional time interpolator. If null is passed, last set interpolator
- * will be used. This is ignored if animate is false.
+ * will be used. This is ignored if animate is false.
*/
fun setTextStyle(
weight: Int = -1,
@@ -221,11 +237,10 @@
if (weight >= 0) {
// Paint#setFontVariationSettings creates Typeface instance from scratch. To reduce the
// memory impact, cache the typeface result.
- textInterpolator.targetPaint.typeface =
- typefaceCache.getOrElse(weight) {
- textInterpolator.targetPaint.fontVariationSettings = "'$TAG_WGHT' $weight"
- textInterpolator.targetPaint.typeface
- }
+ textInterpolator.targetPaint.typeface = typefaceCache.getOrElse(weight) {
+ textInterpolator.targetPaint.fontVariationSettings = "'$TAG_WGHT' $weight"
+ textInterpolator.targetPaint.typeface
+ }
}
if (color != null) {
textInterpolator.targetPaint.color = color
@@ -234,24 +249,22 @@
if (animate) {
animator.startDelay = delay
- animator.duration =
- if (duration == -1L) {
- DEFAULT_ANIMATION_DURATION
- } else {
- duration
- }
+ animator.duration = if (duration == -1L) {
+ DEFAULT_ANIMATION_DURATION
+ } else {
+ duration
+ }
interpolator?.let { animator.interpolator = it }
if (onAnimationEnd != null) {
- val listener =
- object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator?) {
- onAnimationEnd.run()
- animator.removeListener(this)
- }
- override fun onAnimationCancel(animation: Animator?) {
- animator.removeListener(this)
- }
+ val listener = object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator?) {
+ onAnimationEnd.run()
+ animator.removeListener(this)
}
+ override fun onAnimationCancel(animation: Animator?) {
+ animator.removeListener(this)
+ }
+ }
animator.addListener(listener)
}
animator.start()
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
index f9fb42c..0448c81 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
@@ -26,8 +26,12 @@
import com.android.internal.graphics.ColorUtils
import java.lang.Math.max
-/** Provide text style linear interpolation for plain text. */
-class TextInterpolator(layout: Layout) {
+/**
+ * Provide text style linear interpolation for plain text.
+ */
+class TextInterpolator(
+ layout: Layout
+) {
/**
* Returns base paint used for interpolation.
@@ -60,11 +64,12 @@
var baseFont: Font,
var targetFont: Font
) {
- val length: Int
- get() = end - start
+ val length: Int get() = end - start
}
- /** A class represents text layout of a single run. */
+ /**
+ * A class represents text layout of a single run.
+ */
private class Run(
val glyphIds: IntArray,
val baseX: FloatArray, // same length as glyphIds
@@ -74,8 +79,12 @@
val fontRuns: List<FontRun>
)
- /** A class represents text layout of a single line. */
- private class Line(val runs: List<Run>)
+ /**
+ * A class represents text layout of a single line.
+ */
+ private class Line(
+ val runs: List<Run>
+ )
private var lines = listOf<Line>()
private val fontInterpolator = FontInterpolator()
@@ -97,8 +106,8 @@
/**
* The layout used for drawing text.
*
- * Only non-styled text is supported. Even if the given layout is created from Spanned, the span
- * information is not used.
+ * Only non-styled text is supported. Even if the given layout is created from Spanned, the
+ * span information is not used.
*
* The paint objects used for interpolation are not changed by this method call.
*
@@ -121,8 +130,8 @@
/**
* Recalculate internal text layout for interpolation.
*
- * Whenever the target paint is modified, call this method to recalculate internal text layout
- * used for interpolation.
+ * Whenever the target paint is modified, call this method to recalculate internal
+ * text layout used for interpolation.
*/
fun onTargetPaintModified() {
updatePositionsAndFonts(shapeText(layout, targetPaint), updateBase = false)
@@ -131,8 +140,8 @@
/**
* Recalculate internal text layout for interpolation.
*
- * Whenever the base paint is modified, call this method to recalculate internal text layout
- * used for interpolation.
+ * Whenever the base paint is modified, call this method to recalculate internal
+ * text layout used for interpolation.
*/
fun onBasePaintModified() {
updatePositionsAndFonts(shapeText(layout, basePaint), updateBase = true)
@@ -143,11 +152,11 @@
*
* The text interpolator does not calculate all the text position by text shaper due to
* performance reasons. Instead, the text interpolator shape the start and end state and
- * calculate text position of the middle state by linear interpolation. Due to this trick, the
- * text positions of the middle state is likely different from the text shaper result. So, if
- * you want to start animation from the middle state, you will see the glyph jumps due to this
- * trick, i.e. the progress 0.5 of interpolation between weight 400 and 700 is different from
- * text shape result of weight 550.
+ * calculate text position of the middle state by linear interpolation. Due to this trick,
+ * the text positions of the middle state is likely different from the text shaper result.
+ * So, if you want to start animation from the middle state, you will see the glyph jumps due to
+ * this trick, i.e. the progress 0.5 of interpolation between weight 400 and 700 is different
+ * from text shape result of weight 550.
*
* After calling this method, do not call onBasePaintModified() since it reshape the text and
* update the base state. As in above notice, the text shaping result at current progress is
@@ -159,7 +168,8 @@
* animate weight from 200 to 400, then if you want to move back to 200 at the half of the
* animation, it will look like
*
- * ```
+ * <pre>
+ * <code>
* val interp = TextInterpolator(layout)
*
* // Interpolate between weight 200 to 400.
@@ -189,7 +199,9 @@
* // progress is 0.5
* animator.start()
* }
- * ```
+ * </code>
+ * </pre>
+ *
*/
fun rebase() {
if (progress == 0f) {
@@ -251,75 +263,69 @@
}
var maxRunLength = 0
- lines =
- baseLayout.zip(targetLayout) { baseLine, targetLine ->
- val runs =
- baseLine.zip(targetLine) { base, target ->
- require(base.glyphCount() == target.glyphCount()) {
- "Inconsistent glyph count at line ${lines.size}"
+ lines = baseLayout.zip(targetLayout) { baseLine, targetLine ->
+ val runs = baseLine.zip(targetLine) { base, target ->
+
+ require(base.glyphCount() == target.glyphCount()) {
+ "Inconsistent glyph count at line ${lines.size}"
+ }
+
+ val glyphCount = base.glyphCount()
+
+ // Good to recycle the array if the existing array can hold the new layout result.
+ val glyphIds = IntArray(glyphCount) {
+ base.getGlyphId(it).also { baseGlyphId ->
+ require(baseGlyphId == target.getGlyphId(it)) {
+ "Inconsistent glyph ID at $it in line ${lines.size}"
}
+ }
+ }
- val glyphCount = base.glyphCount()
+ val baseX = FloatArray(glyphCount) { base.getGlyphX(it) }
+ val baseY = FloatArray(glyphCount) { base.getGlyphY(it) }
+ val targetX = FloatArray(glyphCount) { target.getGlyphX(it) }
+ val targetY = FloatArray(glyphCount) { target.getGlyphY(it) }
- // Good to recycle the array if the existing array can hold the new layout
- // result.
- val glyphIds =
- IntArray(glyphCount) {
- base.getGlyphId(it).also { baseGlyphId ->
- require(baseGlyphId == target.getGlyphId(it)) {
- "Inconsistent glyph ID at $it in line ${lines.size}"
- }
- }
+ // Calculate font runs
+ val fontRun = mutableListOf<FontRun>()
+ if (glyphCount != 0) {
+ var start = 0
+ var baseFont = base.getFont(start)
+ var targetFont = target.getFont(start)
+ require(FontInterpolator.canInterpolate(baseFont, targetFont)) {
+ "Cannot interpolate font at $start ($baseFont vs $targetFont)"
+ }
+
+ for (i in 1 until glyphCount) {
+ val nextBaseFont = base.getFont(i)
+ val nextTargetFont = target.getFont(i)
+
+ if (baseFont !== nextBaseFont) {
+ require(targetFont !== nextTargetFont) {
+ "Base font has changed at $i but target font has not changed."
}
-
- val baseX = FloatArray(glyphCount) { base.getGlyphX(it) }
- val baseY = FloatArray(glyphCount) { base.getGlyphY(it) }
- val targetX = FloatArray(glyphCount) { target.getGlyphX(it) }
- val targetY = FloatArray(glyphCount) { target.getGlyphY(it) }
-
- // Calculate font runs
- val fontRun = mutableListOf<FontRun>()
- if (glyphCount != 0) {
- var start = 0
- var baseFont = base.getFont(start)
- var targetFont = target.getFont(start)
+ // Font transition point. push run and reset context.
+ fontRun.add(FontRun(start, i, baseFont, targetFont))
+ maxRunLength = max(maxRunLength, i - start)
+ baseFont = nextBaseFont
+ targetFont = nextTargetFont
+ start = i
require(FontInterpolator.canInterpolate(baseFont, targetFont)) {
"Cannot interpolate font at $start ($baseFont vs $targetFont)"
}
-
- for (i in 1 until glyphCount) {
- val nextBaseFont = base.getFont(i)
- val nextTargetFont = target.getFont(i)
-
- if (baseFont !== nextBaseFont) {
- require(targetFont !== nextTargetFont) {
- "Base font has changed at $i but target font has not " +
- "changed."
- }
- // Font transition point. push run and reset context.
- fontRun.add(FontRun(start, i, baseFont, targetFont))
- maxRunLength = max(maxRunLength, i - start)
- baseFont = nextBaseFont
- targetFont = nextTargetFont
- start = i
- require(FontInterpolator.canInterpolate(baseFont, targetFont)) {
- "Cannot interpolate font at $start ($baseFont vs " +
- "$targetFont)"
- }
- } else { // baseFont === nextBaseFont
- require(targetFont === nextTargetFont) {
- "Base font has not changed at $i but target font has " +
- "changed."
- }
- }
+ } else { // baseFont === nextBaseFont
+ require(targetFont === nextTargetFont) {
+ "Base font has not changed at $i but target font has changed."
}
- fontRun.add(FontRun(start, glyphCount, baseFont, targetFont))
- maxRunLength = max(maxRunLength, glyphCount - start)
}
- Run(glyphIds, baseX, baseY, targetX, targetY, fontRun)
}
- Line(runs)
+ fontRun.add(FontRun(start, glyphCount, baseFont, targetFont))
+ maxRunLength = max(maxRunLength, glyphCount - start)
+ }
+ Run(glyphIds, baseX, baseY, targetX, targetY, fontRun)
}
+ Line(runs)
+ }
// Update float array used for drawing.
if (tmpPositionArray.size < maxRunLength * 2) {
@@ -351,9 +357,9 @@
if (glyphFilter == null) {
for (i in run.start until run.end) {
tmpPositionArray[arrayIndex++] =
- MathUtils.lerp(line.baseX[i], line.targetX[i], progress)
+ MathUtils.lerp(line.baseX[i], line.targetX[i], progress)
tmpPositionArray[arrayIndex++] =
- MathUtils.lerp(line.baseY[i], line.targetY[i], progress)
+ MathUtils.lerp(line.baseY[i], line.targetY[i], progress)
}
c.drawGlyphs(line.glyphIds, run.start, tmpPositionArray, 0, run.length, font, paint)
return
@@ -382,14 +388,13 @@
tmpPaintForGlyph.color = tmpGlyph.color
c.drawGlyphs(
- line.glyphIds,
- prevStart,
- tmpPositionArray,
- 0,
- i - prevStart,
- font,
- tmpPaintForGlyph
- )
+ line.glyphIds,
+ prevStart,
+ tmpPositionArray,
+ 0,
+ i - prevStart,
+ font,
+ tmpPaintForGlyph)
prevStart = i
arrayIndex = 0
}
@@ -399,14 +404,13 @@
}
c.drawGlyphs(
- line.glyphIds,
- prevStart,
- tmpPositionArray,
- 0,
- run.end - prevStart,
- font,
- tmpPaintForGlyph
- )
+ line.glyphIds,
+ prevStart,
+ tmpPositionArray,
+ 0,
+ run.end - prevStart,
+ font,
+ tmpPaintForGlyph)
}
private fun updatePositionsAndFonts(
@@ -414,7 +418,9 @@
updateBase: Boolean
) {
// Update target positions with newly calculated text layout.
- check(layoutResult.size == lines.size) { "The new layout result has different line count." }
+ check(layoutResult.size == lines.size) {
+ "The new layout result has different line count."
+ }
lines.zip(layoutResult) { line, runs ->
line.runs.zip(runs) { lineRun, newGlyphs ->
@@ -430,7 +436,7 @@
}
require(newFont === newGlyphs.getFont(i)) {
"The new layout has different font run." +
- " $newFont vs ${newGlyphs.getFont(i)} at $i"
+ " $newFont vs ${newGlyphs.getFont(i)} at $i"
}
}
@@ -438,7 +444,7 @@
// check new font can be interpolatable with base font.
require(FontInterpolator.canInterpolate(newFont, run.baseFont)) {
"New font cannot be interpolated with existing font. $newFont," +
- " ${run.baseFont}"
+ " ${run.baseFont}"
}
if (updateBase) {
@@ -474,7 +480,10 @@
}
// Shape the text and stores the result to out argument.
- private fun shapeText(layout: Layout, paint: TextPaint): List<List<PositionedGlyphs>> {
+ private fun shapeText(
+ layout: Layout,
+ paint: TextPaint
+ ): List<List<PositionedGlyphs>> {
val out = mutableListOf<List<PositionedGlyphs>>()
for (lineNo in 0 until layout.lineCount) { // Shape all lines.
val lineStart = layout.getLineStart(lineNo)
@@ -486,13 +495,10 @@
}
val runs = mutableListOf<PositionedGlyphs>()
- TextShaper.shapeText(
- layout.text,
- lineStart,
- count,
- layout.textDirectionHeuristic,
- paint
- ) { _, _, glyphs, _ -> runs.add(glyphs) }
+ TextShaper.shapeText(layout.text, lineStart, count, layout.textDirectionHeuristic,
+ paint) { _, _, glyphs, _ ->
+ runs.add(glyphs)
+ }
out.add(runs)
}
return out
@@ -500,8 +506,8 @@
}
private fun Layout.getDrawOrigin(lineNo: Int) =
- if (getParagraphDirection(lineNo) == Layout.DIR_LEFT_TO_RIGHT) {
- getLineLeft(lineNo)
- } else {
- getLineRight(lineNo)
- }
+ if (getParagraphDirection(lineNo) == Layout.DIR_LEFT_TO_RIGHT) {
+ getLineLeft(lineNo)
+ } else {
+ getLineRight(lineNo)
+ }
diff --git a/packages/SystemUI/checks/Android.bp b/packages/SystemUI/checks/Android.bp
index 40580d2..d3f66e3 100644
--- a/packages/SystemUI/checks/Android.bp
+++ b/packages/SystemUI/checks/Android.bp
@@ -37,12 +37,6 @@
java_test_host {
name: "SystemUILintCheckerTest",
- // TODO(b/239881504): Since this test was written, Android
- // Lint was updated, and now includes classes that were
- // compiled for java 15. The soong build doesn't support
- // java 15 yet, so we can't compile against "lint". Disable
- // the test until java 15 is supported.
- enabled: false,
srcs: [
"tests/**/*.kt",
"tests/**/*.java",
@@ -59,5 +53,19 @@
],
test_options: {
unit_test: true,
+ tradefed_options: [
+ {
+ // lint bundles in some classes that were built with older versions
+ // of libraries, and no longer load. Since tradefed tries to load
+ // all classes in the jar to look for tests, it crashes loading them.
+ // Exclude these classes from tradefed's search.
+ name: "exclude-paths",
+ value: "org/apache",
+ },
+ {
+ name: "exclude-paths",
+ value: "META-INF",
+ },
+ ],
},
}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
index 462b90a..86bd5f2 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
@@ -54,7 +54,6 @@
defStyleAttr: Int = 0,
defStyleRes: Int = 0
) : TextView(context, attrs, defStyleAttr, defStyleRes) {
- var tag: String = "UnnamedClockView"
var logBuffer: LogBuffer? = null
private val time = Calendar.getInstance()
@@ -132,7 +131,7 @@
override fun onAttachedToWindow() {
super.onAttachedToWindow()
- logBuffer?.log(tag, DEBUG, "onAttachedToWindow")
+ logBuffer?.log(TAG, DEBUG, "onAttachedToWindow")
refreshFormat()
}
@@ -148,7 +147,7 @@
time.timeInMillis = timeOverrideInMillis ?: System.currentTimeMillis()
contentDescription = DateFormat.format(descFormat, time)
val formattedText = DateFormat.format(format, time)
- logBuffer?.log(tag, DEBUG,
+ logBuffer?.log(TAG, DEBUG,
{ str1 = formattedText?.toString() },
{ "refreshTime: new formattedText=$str1" }
)
@@ -157,7 +156,7 @@
// relayout if the text didn't actually change.
if (!TextUtils.equals(text, formattedText)) {
text = formattedText
- logBuffer?.log(tag, DEBUG,
+ logBuffer?.log(TAG, DEBUG,
{ str1 = formattedText?.toString() },
{ "refreshTime: done setting new time text to: $str1" }
)
@@ -167,17 +166,17 @@
// without being notified TextInterpolator being notified.
if (layout != null) {
textAnimator?.updateLayout(layout)
- logBuffer?.log(tag, DEBUG, "refreshTime: done updating textAnimator layout")
+ logBuffer?.log(TAG, DEBUG, "refreshTime: done updating textAnimator layout")
}
requestLayout()
- logBuffer?.log(tag, DEBUG, "refreshTime: after requestLayout")
+ logBuffer?.log(TAG, DEBUG, "refreshTime: after requestLayout")
}
}
fun onTimeZoneChanged(timeZone: TimeZone?) {
time.timeZone = timeZone
refreshFormat()
- logBuffer?.log(tag, DEBUG,
+ logBuffer?.log(TAG, DEBUG,
{ str1 = timeZone?.toString() },
{ "onTimeZoneChanged newTimeZone=$str1" }
)
@@ -194,7 +193,7 @@
} else {
animator.updateLayout(layout)
}
- logBuffer?.log(tag, DEBUG, "onMeasure")
+ logBuffer?.log(TAG, DEBUG, "onMeasure")
}
override fun onDraw(canvas: Canvas) {
@@ -206,12 +205,12 @@
} else {
super.onDraw(canvas)
}
- logBuffer?.log(tag, DEBUG, "onDraw lastDraw")
+ logBuffer?.log(TAG, DEBUG, "onDraw")
}
override fun invalidate() {
super.invalidate()
- logBuffer?.log(tag, DEBUG, "invalidate")
+ logBuffer?.log(TAG, DEBUG, "invalidate")
}
override fun onTextChanged(
@@ -221,7 +220,7 @@
lengthAfter: Int
) {
super.onTextChanged(text, start, lengthBefore, lengthAfter)
- logBuffer?.log(tag, DEBUG,
+ logBuffer?.log(TAG, DEBUG,
{ str1 = text.toString() },
{ "onTextChanged text=$str1" }
)
@@ -238,7 +237,7 @@
}
fun animateColorChange() {
- logBuffer?.log(tag, DEBUG, "animateColorChange")
+ logBuffer?.log(TAG, DEBUG, "animateColorChange")
setTextStyle(
weight = lockScreenWeight,
textSize = -1f,
@@ -260,7 +259,7 @@
}
fun animateAppearOnLockscreen() {
- logBuffer?.log(tag, DEBUG, "animateAppearOnLockscreen")
+ logBuffer?.log(TAG, DEBUG, "animateAppearOnLockscreen")
setTextStyle(
weight = dozingWeight,
textSize = -1f,
@@ -285,7 +284,7 @@
if (isAnimationEnabled && textAnimator == null) {
return
}
- logBuffer?.log(tag, DEBUG, "animateFoldAppear")
+ logBuffer?.log(TAG, DEBUG, "animateFoldAppear")
setTextStyle(
weight = lockScreenWeightInternal,
textSize = -1f,
@@ -312,7 +311,7 @@
// Skip charge animation if dozing animation is already playing.
return
}
- logBuffer?.log(tag, DEBUG, "animateCharge")
+ logBuffer?.log(TAG, DEBUG, "animateCharge")
val startAnimPhase2 = Runnable {
setTextStyle(
weight = if (isDozing()) dozingWeight else lockScreenWeight,
@@ -336,7 +335,7 @@
}
fun animateDoze(isDozing: Boolean, animate: Boolean) {
- logBuffer?.log(tag, DEBUG, "animateDoze")
+ logBuffer?.log(TAG, DEBUG, "animateDoze")
setTextStyle(
weight = if (isDozing) dozingWeight else lockScreenWeight,
textSize = -1f,
@@ -455,7 +454,7 @@
isSingleLineInternal && !use24HourFormat -> Patterns.sClockView12
else -> DOUBLE_LINE_FORMAT_12_HOUR
}
- logBuffer?.log(tag, DEBUG,
+ logBuffer?.log(TAG, DEBUG,
{ str1 = format?.toString() },
{ "refreshFormat format=$str1" }
)
@@ -466,6 +465,7 @@
fun dump(pw: PrintWriter) {
pw.println("$this")
+ pw.println(" alpha=$alpha")
pw.println(" measuredWidth=$measuredWidth")
pw.println(" measuredHeight=$measuredHeight")
pw.println(" singleLineInternal=$isSingleLineInternal")
@@ -626,7 +626,7 @@
}
companion object {
- private val TAG = AnimatableClockView::class.simpleName
+ private val TAG = AnimatableClockView::class.simpleName!!
const val ANIMATION_DURATION_FOLD_TO_AOD: Int = 600
private const val DOUBLE_LINE_FORMAT_12_HOUR = "hh\nmm"
private const val DOUBLE_LINE_FORMAT_24_HOUR = "HH\nmm"
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
index e138ef8..7645dec 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
@@ -88,13 +88,6 @@
events.onTimeTick()
}
- override fun setLogBuffer(logBuffer: LogBuffer) {
- smallClock.view.tag = "smallClockView"
- largeClock.view.tag = "largeClockView"
- smallClock.view.logBuffer = logBuffer
- largeClock.view.logBuffer = logBuffer
- }
-
open inner class DefaultClockFaceController(
override val view: AnimatableClockView,
) : ClockFaceController {
@@ -104,6 +97,12 @@
private var isRegionDark = false
protected var targetRegion: Rect? = null
+ override var logBuffer: LogBuffer?
+ get() = view.logBuffer
+ set(value) {
+ view.logBuffer = value
+ }
+
init {
view.setColors(currentColor, currentColor)
}
diff --git a/packages/SystemUI/ktfmt_includes.txt b/packages/SystemUI/ktfmt_includes.txt
index 4c271ea..2148cb0 100644
--- a/packages/SystemUI/ktfmt_includes.txt
+++ b/packages/SystemUI/ktfmt_includes.txt
@@ -80,8 +80,8 @@
-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.kt
-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpDrawable.kt
--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherView.kt
--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherViewController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyViewController.kt
-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHapticsSimulator.kt
-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayParams.kt
-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
index 66e44b9..a2a0709 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
@@ -71,9 +71,6 @@
/** Optional method for dumping debug information */
fun dump(pw: PrintWriter) {}
-
- /** Optional method for debug logging */
- fun setLogBuffer(logBuffer: LogBuffer) {}
}
/** Interface for a specific clock face version rendered by the clock */
@@ -83,6 +80,9 @@
/** Events specific to this clock face */
val events: ClockFaceEvents
+
+ /** Some clocks may log debug information */
+ var logBuffer: LogBuffer?
}
/** Events that should call when various rendering parameters change */
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogBuffer.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogBuffer.kt
index 6436dcb..e99b214 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogBuffer.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/LogBuffer.kt
@@ -159,8 +159,13 @@
* bug report more actionable, so using the [log] with a messagePrinter to add more detail to
* every log may do more to improve overall logging than adding more logs with this method.
*/
- fun log(tag: String, level: LogLevel, @CompileTimeConstant message: String) =
- log(tag, level, { str1 = message }, { str1!! })
+ @JvmOverloads
+ fun log(
+ tag: String,
+ level: LogLevel,
+ @CompileTimeConstant message: String,
+ exception: Throwable? = null,
+ ) = log(tag, level, { str1 = message }, { str1!! }, exception)
/**
* You should call [log] instead of this method.
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index e598afe..a4ee62c 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -19,6 +19,18 @@
public <init>();
}
+# Needed to ensure callback field references are kept in their respective
+# owning classes when the downstream callback registrars only store weak refs.
+# TODO(b/264686688): Handle these cases with more targeted annotations.
+-keepclassmembers,allowaccessmodification class com.android.systemui.**, com.android.keyguard.** {
+ private com.android.keyguard.KeyguardUpdateMonitorCallback *;
+ private com.android.systemui.privacy.PrivacyItemController$Callback *;
+ private com.android.systemui.settings.UserTracker$Callback *;
+ private com.android.systemui.statusbar.phone.StatusBarWindowCallback *;
+ private com.android.systemui.util.service.Observer$Callback *;
+ private com.android.systemui.util.service.ObservableServiceConnection$Callback *;
+}
+
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
diff --git a/packages/SystemUI/res/drawable/ic_media_explicit_indicator.xml b/packages/SystemUI/res/drawable/ic_media_explicit_indicator.xml
new file mode 100644
index 0000000..08c5aaf
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_media_explicit_indicator.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 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
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="13dp"
+ android:height="13dp"
+ android:viewportWidth="48"
+ android:viewportHeight="48"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M18.3,34H29.65V31H21.3V25.7H29.65V22.7H21.3V17.35H29.65V14.35H18.3ZM9,42Q7.8,42 6.9,41.1Q6,40.2 6,39V9Q6,7.8 6.9,6.9Q7.8,6 9,6H39Q40.2,6 41.1,6.9Q42,7.8 42,9V39Q42,40.2 41.1,41.1Q40.2,42 39,42ZM9,39H39Q39,39 39,39Q39,39 39,39V9Q39,9 39,9Q39,9 39,9H9Q9,9 9,9Q9,9 9,9V39Q9,39 9,39Q9,39 9,39ZM9,9Q9,9 9,9Q9,9 9,9V39Q9,39 9,39Q9,39 9,39Q9,39 9,39Q9,39 9,39V9Q9,9 9,9Q9,9 9,9Z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/overlay_badge_background.xml b/packages/SystemUI/res/drawable/overlay_badge_background.xml
index 857632e..53122c1 100644
--- a/packages/SystemUI/res/drawable/overlay_badge_background.xml
+++ b/packages/SystemUI/res/drawable/overlay_badge_background.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2020 The Android Open Source Project
+ ~ Copyright (C) 2022 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.
@@ -14,8 +14,11 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- android:shape="oval">
- <solid android:color="?androidprv:attr/colorSurface"/>
-</shape>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="48dp"
+ android:height="48dp"
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0">
+ <path
+ android:pathData="M0,0M48,48"/>
+</vector>
diff --git a/packages/SystemUI/res/layout/chipbar.xml b/packages/SystemUI/res/layout/chipbar.xml
index bc97e51..8cf4f4d 100644
--- a/packages/SystemUI/res/layout/chipbar.xml
+++ b/packages/SystemUI/res/layout/chipbar.xml
@@ -23,6 +23,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content">
+ <!-- Extra marginBottom to give room for the drop shadow. -->
<LinearLayout
android:id="@+id/chipbar_inner"
android:orientation="horizontal"
@@ -33,6 +34,8 @@
android:layout_marginTop="20dp"
android:layout_marginStart="@dimen/notification_side_paddings"
android:layout_marginEnd="@dimen/notification_side_paddings"
+ android:translationZ="4dp"
+ android:layout_marginBottom="8dp"
android:clipToPadding="false"
android:gravity="center_vertical"
android:alpha="0.0"
diff --git a/packages/SystemUI/res/layout/clipboard_overlay.xml b/packages/SystemUI/res/layout/clipboard_overlay.xml
index 9134f96..eec3b11 100644
--- a/packages/SystemUI/res/layout/clipboard_overlay.xml
+++ b/packages/SystemUI/res/layout/clipboard_overlay.xml
@@ -32,26 +32,26 @@
android:elevation="4dp"
android:background="@drawable/action_chip_container_background"
android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal"
- app:layout_constraintBottom_toBottomOf="@+id/actions_container"
+ android:layout_marginBottom="@dimen/overlay_action_container_margin_bottom"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/actions_container"
- app:layout_constraintEnd_toEndOf="@+id/actions_container"/>
+ app:layout_constraintEnd_toEndOf="@+id/actions_container"
+ app:layout_constraintBottom_toBottomOf="parent"/>
<HorizontalScrollView
android:id="@+id/actions_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/overlay_action_container_margin_horizontal"
- android:paddingEnd="@dimen/overlay_action_container_padding_right"
+ android:paddingEnd="@dimen/overlay_action_container_padding_end"
android:paddingVertical="@dimen/overlay_action_container_padding_vertical"
android:elevation="4dp"
android:scrollbars="none"
- android:layout_marginBottom="4dp"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintWidth_percent="1.0"
app:layout_constraintWidth_max="wrap"
- app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/preview_border"
- app:layout_constraintEnd_toEndOf="parent">
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toBottomOf="@id/actions_container_background">
<LinearLayout
android:id="@+id/actions"
android:layout_width="wrap_content"
@@ -69,44 +69,30 @@
android:id="@+id/preview_border"
android:layout_width="0dp"
android:layout_height="0dp"
- android:layout_marginStart="@dimen/overlay_offset_x"
- android:layout_marginBottom="12dp"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
+ android:layout_marginStart="@dimen/overlay_preview_container_margin"
+ android:layout_marginTop="@dimen/overlay_border_width_neg"
+ android:layout_marginEnd="@dimen/overlay_border_width_neg"
+ android:layout_marginBottom="@dimen/overlay_preview_container_margin"
android:elevation="7dp"
- app:layout_constraintEnd_toEndOf="@id/clipboard_preview_end"
- app:layout_constraintTop_toTopOf="@id/clipboard_preview_top"
- android:background="@drawable/overlay_border"/>
- <androidx.constraintlayout.widget.Barrier
- android:id="@+id/clipboard_preview_end"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- app:barrierMargin="@dimen/overlay_border_width"
- app:barrierDirection="end"
- app:constraint_referenced_ids="clipboard_preview"/>
- <androidx.constraintlayout.widget.Barrier
- android:id="@+id/clipboard_preview_top"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- app:barrierDirection="top"
- app:barrierMargin="@dimen/overlay_border_width_neg"
- app:constraint_referenced_ids="clipboard_preview"/>
+ android:background="@drawable/overlay_border"
+ app:layout_constraintStart_toStartOf="@id/actions_container_background"
+ app:layout_constraintTop_toTopOf="@id/clipboard_preview"
+ app:layout_constraintEnd_toEndOf="@id/clipboard_preview"
+ app:layout_constraintBottom_toBottomOf="@id/actions_container_background"/>
<FrameLayout
android:id="@+id/clipboard_preview"
+ android:layout_width="@dimen/clipboard_preview_size"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/overlay_border_width"
+ android:layout_marginBottom="@dimen/overlay_border_width"
+ android:layout_gravity="center"
android:elevation="7dp"
android:background="@drawable/overlay_preview_background"
android:clipChildren="true"
android:clipToOutline="true"
android:clipToPadding="true"
- android:layout_width="@dimen/clipboard_preview_size"
- android:layout_margin="@dimen/overlay_border_width"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- app:layout_constraintHorizontal_bias="0"
- app:layout_constraintBottom_toBottomOf="@id/preview_border"
app:layout_constraintStart_toStartOf="@id/preview_border"
- app:layout_constraintEnd_toEndOf="@id/preview_border"
- app:layout_constraintTop_toTopOf="@id/preview_border">
+ app:layout_constraintBottom_toBottomOf="@id/preview_border">
<TextView android:id="@+id/text_preview"
android:textFontWeight="500"
android:padding="8dp"
diff --git a/packages/SystemUI/res/layout/combined_qs_header.xml b/packages/SystemUI/res/layout/combined_qs_header.xml
index a565988..d689828 100644
--- a/packages/SystemUI/res/layout/combined_qs_header.xml
+++ b/packages/SystemUI/res/layout/combined_qs_header.xml
@@ -148,9 +148,4 @@
<include layout="@layout/ongoing_privacy_chip"/>
</FrameLayout>
- <Space
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:id="@+id/space"
- />
</com.android.systemui.util.NoRemeasureMotionLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
index 9add32c..885e5e2 100644
--- a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
@@ -57,6 +57,7 @@
android:layout_width="@dimen/dream_overlay_status_bar_icon_size"
android:layout_height="match_parent"
android:layout_marginStart="@dimen/dream_overlay_status_icon_margin"
+ android:layout_marginTop="@dimen/dream_overlay_status_bar_marginTop"
android:src="@drawable/ic_alarm"
android:tint="@android:color/white"
android:visibility="gone"
@@ -67,6 +68,7 @@
android:layout_width="@dimen/dream_overlay_status_bar_icon_size"
android:layout_height="match_parent"
android:layout_marginStart="@dimen/dream_overlay_status_icon_margin"
+ android:layout_marginTop="@dimen/dream_overlay_status_bar_marginTop"
android:src="@drawable/ic_qs_dnd_on"
android:tint="@android:color/white"
android:visibility="gone"
@@ -77,6 +79,7 @@
android:layout_width="@dimen/dream_overlay_status_bar_icon_size"
android:layout_height="match_parent"
android:layout_marginStart="@dimen/dream_overlay_status_icon_margin"
+ android:layout_marginTop="@dimen/dream_overlay_status_bar_marginTop"
android:src="@drawable/ic_signal_wifi_off"
android:visibility="gone"
android:contentDescription="@string/dream_overlay_status_bar_wifi_off" />
diff --git a/packages/SystemUI/res/layout/media_session_view.xml b/packages/SystemUI/res/layout/media_session_view.xml
index 95aefab..abc8337 100644
--- a/packages/SystemUI/res/layout/media_session_view.xml
+++ b/packages/SystemUI/res/layout/media_session_view.xml
@@ -147,6 +147,14 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
+ <!-- Explicit Indicator -->
+ <com.android.internal.widget.CachingIconView
+ android:id="@+id/media_explicit_indicator"
+ android:layout_width="@dimen/qs_media_explicit_indicator_icon_size"
+ android:layout_height="@dimen/qs_media_explicit_indicator_icon_size"
+ android:src="@drawable/ic_media_explicit_indicator"
+ />
+
<!-- Artist name -->
<TextView
android:id="@+id/header_artist"
diff --git a/packages/SystemUI/res/layout/screenshot_static.xml b/packages/SystemUI/res/layout/screenshot_static.xml
index e4e0bd4..496eb6e 100644
--- a/packages/SystemUI/res/layout/screenshot_static.xml
+++ b/packages/SystemUI/res/layout/screenshot_static.xml
@@ -27,26 +27,26 @@
android:elevation="4dp"
android:background="@drawable/action_chip_container_background"
android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal"
- app:layout_constraintBottom_toBottomOf="@+id/actions_container"
+ android:layout_marginBottom="@dimen/overlay_action_container_margin_bottom"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/actions_container"
- app:layout_constraintEnd_toEndOf="@+id/actions_container"/>
+ app:layout_constraintEnd_toEndOf="@+id/actions_container"
+ app:layout_constraintBottom_toTopOf="@id/screenshot_message_container"/>
<HorizontalScrollView
android:id="@+id/actions_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/overlay_action_container_margin_horizontal"
- android:layout_marginBottom="4dp"
- android:paddingEnd="@dimen/overlay_action_container_padding_right"
+ android:paddingEnd="@dimen/overlay_action_container_padding_end"
android:paddingVertical="@dimen/overlay_action_container_padding_vertical"
android:elevation="4dp"
android:scrollbars="none"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintWidth_percent="1.0"
app:layout_constraintWidth_max="wrap"
- app:layout_constraintBottom_toTopOf="@id/screenshot_message_container"
app:layout_constraintStart_toEndOf="@+id/screenshot_preview_border"
- app:layout_constraintEnd_toEndOf="parent">
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toBottomOf="@id/actions_container_background">
<LinearLayout
android:id="@+id/screenshot_actions"
android:layout_width="wrap_content"
@@ -64,35 +64,24 @@
android:id="@+id/screenshot_preview_border"
android:layout_width="0dp"
android:layout_height="0dp"
- android:layout_marginStart="@dimen/overlay_offset_x"
- android:layout_marginBottom="12dp"
+ android:layout_marginStart="@dimen/overlay_preview_container_margin"
+ android:layout_marginTop="@dimen/overlay_border_width_neg"
+ android:layout_marginEnd="@dimen/overlay_border_width_neg"
+ android:layout_marginBottom="@dimen/overlay_preview_container_margin"
android:elevation="7dp"
android:alpha="0"
android:background="@drawable/overlay_border"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintBottom_toTopOf="@id/screenshot_message_container"
- app:layout_constraintEnd_toEndOf="@id/screenshot_preview_end"
- app:layout_constraintTop_toTopOf="@id/screenshot_preview_top"/>
- <androidx.constraintlayout.widget.Barrier
- android:id="@+id/screenshot_preview_end"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- app:barrierMargin="@dimen/overlay_border_width"
- app:barrierDirection="end"
- app:constraint_referenced_ids="screenshot_preview"/>
- <androidx.constraintlayout.widget.Barrier
- android:id="@+id/screenshot_preview_top"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- app:barrierDirection="top"
- app:barrierMargin="@dimen/overlay_border_width_neg"
- app:constraint_referenced_ids="screenshot_preview"/>
+ app:layout_constraintStart_toStartOf="@id/actions_container_background"
+ app:layout_constraintTop_toTopOf="@id/screenshot_preview"
+ app:layout_constraintEnd_toEndOf="@id/screenshot_preview"
+ app:layout_constraintBottom_toBottomOf="@id/actions_container_background"/>
<ImageView
android:id="@+id/screenshot_preview"
android:visibility="invisible"
android:layout_width="@dimen/overlay_x_scale"
- android:layout_margin="@dimen/overlay_border_width"
android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/overlay_border_width"
+ android:layout_marginBottom="@dimen/overlay_border_width"
android:layout_gravity="center"
android:elevation="7dp"
android:contentDescription="@string/screenshot_edit_description"
@@ -100,20 +89,14 @@
android:background="@drawable/overlay_preview_background"
android:adjustViewBounds="true"
android:clickable="true"
- app:layout_constraintHorizontal_bias="0"
- app:layout_constraintBottom_toBottomOf="@id/screenshot_preview_border"
app:layout_constraintStart_toStartOf="@id/screenshot_preview_border"
- app:layout_constraintEnd_toEndOf="@id/screenshot_preview_border"
- app:layout_constraintTop_toTopOf="@id/screenshot_preview_border"/>
+ app:layout_constraintBottom_toBottomOf="@id/screenshot_preview_border"/>
<ImageView
android:id="@+id/screenshot_badge"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:padding="4dp"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
android:visibility="gone"
- android:background="@drawable/overlay_badge_background"
android:elevation="8dp"
- android:src="@drawable/overlay_cancel"
app:layout_constraintBottom_toBottomOf="@id/screenshot_preview_border"
app:layout_constraintEnd_toEndOf="@id/screenshot_preview_border"/>
<FrameLayout
@@ -150,7 +133,7 @@
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/overlay_action_container_margin_horizontal"
android:layout_marginVertical="4dp"
- android:paddingHorizontal="@dimen/overlay_action_container_padding_right"
+ android:paddingHorizontal="@dimen/overlay_action_container_padding_end"
android:paddingVertical="@dimen/overlay_action_container_padding_vertical"
android:elevation="4dp"
android:background="@drawable/action_chip_container_background"
diff --git a/packages/SystemUI/res/layout/udfps_fpm_other_view.xml b/packages/SystemUI/res/layout/udfps_fpm_empty_view.xml
similarity index 75%
rename from packages/SystemUI/res/layout/udfps_fpm_other_view.xml
rename to packages/SystemUI/res/layout/udfps_fpm_empty_view.xml
index 6ecbb47..de43a5e 100644
--- a/packages/SystemUI/res/layout/udfps_fpm_other_view.xml
+++ b/packages/SystemUI/res/layout/udfps_fpm_empty_view.xml
@@ -14,15 +14,9 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<com.android.systemui.biometrics.UdfpsFpmOtherView
+<com.android.systemui.biometrics.UdfpsFpmEmptyView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/udfps_animation_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
-
- <!-- Fingerprint -->
- <ImageView
- android:id="@+id/udfps_fpm_other_fp_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
-</com.android.systemui.biometrics.UdfpsFpmOtherView>
+</com.android.systemui.biometrics.UdfpsFpmEmptyView>
diff --git a/packages/SystemUI/res/layout/user_switcher_fullscreen.xml b/packages/SystemUI/res/layout/user_switcher_fullscreen.xml
index fa9d739..7eaed43 100644
--- a/packages/SystemUI/res/layout/user_switcher_fullscreen.xml
+++ b/packages/SystemUI/res/layout/user_switcher_fullscreen.xml
@@ -46,7 +46,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:flow_horizontalBias="0.5"
app:flow_verticalAlign="center"
- app:flow_wrapMode="chain"
+ app:flow_wrapMode="chain2"
app:flow_horizontalGap="@dimen/user_switcher_fullscreen_horizontal_gap"
app:flow_verticalGap="44dp"
app:flow_horizontalStyle="packed"/>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 7f45e5e..3c2453e 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -671,6 +671,16 @@
<item>17</item> <!-- WAKE_REASON_BIOMETRIC -->
</integer-array>
+ <!-- Whether to support posture listening for face auth, default is 0(DEVICE_POSTURE_UNKNOWN)
+ means systemui will try listening on all postures.
+ 0 : DEVICE_POSTURE_UNKNOWN
+ 1 : DEVICE_POSTURE_CLOSED
+ 2 : DEVICE_POSTURE_HALF_OPENED
+ 3 : DEVICE_POSTURE_OPENED
+ 4 : DEVICE_POSTURE_FLIPPED
+ -->
+ <integer name="config_face_auth_supported_posture">0</integer>
+
<!-- Whether the communal service should be enabled -->
<bool name="config_communalServiceEnabled">false</bool>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 3b17bce..af6e646 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -334,15 +334,22 @@
<dimen name="overlay_action_chip_spacing">8dp</dimen>
<dimen name="overlay_action_chip_text_size">14sp</dimen>
<dimen name="overlay_offset_x">16dp</dimen>
+ <!-- Used for both start and bottom margin of the preview, relative to the action container -->
+ <dimen name="overlay_preview_container_margin">8dp</dimen>
<dimen name="overlay_action_container_margin_horizontal">8dp</dimen>
+ <dimen name="overlay_action_container_margin_bottom">4dp</dimen>
<dimen name="overlay_bg_protection_height">242dp</dimen>
<dimen name="overlay_action_container_corner_radius">18dp</dimen>
<dimen name="overlay_action_container_padding_vertical">4dp</dimen>
<dimen name="overlay_action_container_padding_right">8dp</dimen>
+ <dimen name="overlay_action_container_padding_end">8dp</dimen>
<dimen name="overlay_dismiss_button_tappable_size">48dp</dimen>
<dimen name="overlay_dismiss_button_margin">8dp</dimen>
+ <!-- must be kept aligned with overlay_border_width_neg, below;
+ overlay_border_width = overlay_border_width_neg * -1 -->
<dimen name="overlay_border_width">4dp</dimen>
- <!-- need a negative margin for some of the constraints. should be overlay_border_width * -1 -->
+ <!-- some constraints use a negative margin. must be aligned with overlay_border_width, above;
+ overlay_border_width_neg = overlay_border_width * -1 -->
<dimen name="overlay_border_width_neg">-4dp</dimen>
<dimen name="clipboard_preview_size">@dimen/overlay_x_scale</dimen>
@@ -1034,8 +1041,6 @@
<dimen name="ongoing_appops_dialog_side_padding">16dp</dimen>
- <!-- Size of the RAT type for CellularTile -->
-
<!-- Size of media cards in the QSPanel carousel -->
<dimen name="qs_media_padding">16dp</dimen>
<dimen name="qs_media_album_radius">14dp</dimen>
@@ -1050,6 +1055,7 @@
<dimen name="qs_media_disabled_seekbar_height">1dp</dimen>
<dimen name="qs_media_enabled_seekbar_height">2dp</dimen>
<dimen name="qs_media_app_icon_size">24dp</dimen>
+ <dimen name="qs_media_explicit_indicator_icon_size">13dp</dimen>
<dimen name="qs_media_session_enabled_seekbar_vertical_padding">15dp</dimen>
<dimen name="qs_media_session_disabled_seekbar_vertical_padding">16dp</dimen>
@@ -1293,6 +1299,12 @@
<!-- OCCLUDED -> LOCKSCREEN transition: Amount to shift lockscreen content on entering -->
<dimen name="occluded_to_lockscreen_transition_lockscreen_translation_y">40dp</dimen>
+ <!-- LOCKSCREEN -> DREAMING transition: Amount to shift lockscreen content on entering -->
+ <dimen name="lockscreen_to_dreaming_transition_lockscreen_translation_y">-40dp</dimen>
+
+ <!-- LOCKSCREEN -> OCCLUDED transition: Amount to shift lockscreen content on entering -->
+ <dimen name="lockscreen_to_occluded_transition_lockscreen_translation_y">-40dp</dimen>
+
<!-- The amount of vertical offset for the keyguard during the full shade transition. -->
<dimen name="lockscreen_shade_keyguard_transition_vertical_offset">0dp</dimen>
@@ -1640,6 +1652,8 @@
<dimen name="dream_overlay_status_bar_ambient_text_shadow_dx">0.5dp</dimen>
<dimen name="dream_overlay_status_bar_ambient_text_shadow_dy">0.5dp</dimen>
<dimen name="dream_overlay_status_bar_ambient_text_shadow_radius">2dp</dimen>
+ <dimen name="dream_overlay_icon_inset_dimen">0dp</dimen>
+ <dimen name="dream_overlay_status_bar_marginTop">22dp</dimen>
<!-- Default device corner radius, used for assist UI -->
<dimen name="config_rounded_mask_size">0px</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 61a6e9d5..e4f339a 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2470,6 +2470,8 @@
<string name="media_transfer_failed">Something went wrong. Try again.</string>
<!-- Text to indicate that a media transfer is currently in-progress, aka loading. [CHAR LIMIT=NONE] -->
<string name="media_transfer_loading">Loading</string>
+ <!-- Default name of the device. [CHAR LIMIT=30] -->
+ <string name="media_ttt_default_device_type">tablet</string>
<!-- Error message indicating that a control timed out while waiting for an update [CHAR_LIMIT=30] -->
<string name="controls_error_timeout">Inactive, check app</string>
@@ -2518,6 +2520,8 @@
<string name="media_output_dialog_volume_percentage"><xliff:g id="percentage" example="10">%1$d</xliff:g>%%</string>
<!-- Title for Speakers and Displays group. [CHAR LIMIT=NONE] -->
<string name="media_output_group_title_speakers_and_displays">Speakers & Displays</string>
+ <!-- Title for Suggested Devices group. [CHAR LIMIT=NONE] -->
+ <string name="media_output_group_title_suggested_device">Suggested Devices</string>
<!-- Media Output Broadcast Dialog -->
<!-- Title for Broadcast First Notify Dialog [CHAR LIMIT=60] -->
@@ -2887,6 +2891,9 @@
<!-- Text for education page content description for unfolded animation. [CHAR_LIMIT=NONE] -->
<string name="rear_display_accessibility_unfolded_animation">Foldable device being flipped around</string>
- <!-- Title for notification of low stylus battery. [CHAR_LIMIT=NONE] -->
- <string name="stylus_battery_low">Stylus battery low</string>
+ <!-- Title for notification of low stylus battery with percentage. "percentage" is
+ the value of the battery capacity remaining [CHAR LIMIT=none]-->
+ <string name="stylus_battery_low_percentage"><xliff:g id="percentage" example="16%">%s</xliff:g> battery remaining</string>
+ <!-- Subtitle for the notification sent when a stylus battery is low. [CHAR LIMIT=none]-->
+ <string name="stylus_battery_low_subtitle">Connect your stylus to a charger</string>
</resources>
diff --git a/packages/SystemUI/res/xml/media_session_collapsed.xml b/packages/SystemUI/res/xml/media_session_collapsed.xml
index 1eb621e..d9c81af 100644
--- a/packages/SystemUI/res/xml/media_session_collapsed.xml
+++ b/packages/SystemUI/res/xml/media_session_collapsed.xml
@@ -66,6 +66,21 @@
app:layout_constraintTop_toBottomOf="@id/icon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintHorizontal_bias="0" />
+
+ <Constraint
+ android:id="@+id/media_explicit_indicator"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/qs_media_info_spacing"
+ android:layout_marginBottom="@dimen/qs_media_padding"
+ android:layout_marginTop="0dp"
+ app:layout_constraintStart_toStartOf="@id/header_title"
+ app:layout_constraintEnd_toStartOf="@id/header_artist"
+ app:layout_constraintTop_toTopOf="@id/header_artist"
+ app:layout_constraintBottom_toTopOf="@id/media_action_barrier_top"
+ app:layout_constraintHorizontal_bias="0"
+ app:layout_constraintHorizontal_chainStyle="packed" />
+
<Constraint
android:id="@+id/header_artist"
android:layout_width="wrap_content"
@@ -75,9 +90,8 @@
app:layout_constraintEnd_toStartOf="@id/action_button_guideline"
app:layout_constrainedWidth="true"
app:layout_constraintTop_toBottomOf="@id/header_title"
- app:layout_constraintStart_toStartOf="@id/header_title"
- app:layout_constraintVertical_bias="0"
- app:layout_constraintHorizontal_bias="0" />
+ app:layout_constraintStart_toEndOf="@id/media_explicit_indicator"
+ app:layout_constraintVertical_bias="0" />
<Constraint
android:id="@+id/actionPlayPause"
diff --git a/packages/SystemUI/res/xml/media_session_expanded.xml b/packages/SystemUI/res/xml/media_session_expanded.xml
index 7de0a5e..0cdc0f9 100644
--- a/packages/SystemUI/res/xml/media_session_expanded.xml
+++ b/packages/SystemUI/res/xml/media_session_expanded.xml
@@ -58,6 +58,21 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@id/header_artist"
app:layout_constraintHorizontal_bias="0" />
+
+ <Constraint
+ android:id="@+id/media_explicit_indicator"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/qs_media_info_spacing"
+ android:layout_marginBottom="@dimen/qs_media_padding"
+ android:layout_marginTop="0dp"
+ app:layout_constraintStart_toStartOf="@id/header_title"
+ app:layout_constraintEnd_toStartOf="@id/header_artist"
+ app:layout_constraintTop_toTopOf="@id/header_artist"
+ app:layout_constraintBottom_toTopOf="@id/media_action_barrier_top"
+ app:layout_constraintHorizontal_bias="0"
+ app:layout_constraintHorizontal_chainStyle="packed"/>
+
<Constraint
android:id="@+id/header_artist"
android:layout_width="wrap_content"
@@ -67,10 +82,9 @@
android:layout_marginTop="0dp"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toStartOf="@id/actionPlayPause"
- app:layout_constraintStart_toStartOf="@id/header_title"
+ app:layout_constraintStart_toEndOf="@id/media_explicit_indicator"
app:layout_constraintBottom_toTopOf="@id/media_action_barrier_top"
- app:layout_constraintVertical_bias="0"
- app:layout_constraintHorizontal_bias="0" />
+ app:layout_constraintVertical_bias="0" />
<Constraint
android:id="@+id/actionPlayPause"
diff --git a/packages/SystemUI/res/xml/qs_header.xml b/packages/SystemUI/res/xml/qs_header.xml
index eca2b2a..d97031f 100644
--- a/packages/SystemUI/res/xml/qs_header.xml
+++ b/packages/SystemUI/res/xml/qs_header.xml
@@ -56,13 +56,9 @@
<Layout
android:layout_width="wrap_content"
android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
- app:layout_constrainedWidth="true"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@id/space"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/carrier_group"
- app:layout_constraintHorizontal_bias="0"
- app:layout_constraintHorizontal_chainStyle="spread_inside"
/>
</Constraint>
@@ -87,39 +83,27 @@
<Constraint
android:id="@+id/statusIcons">
<Layout
- android:layout_width="wrap_content"
+ android:layout_width="0dp"
android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
- app:layout_constraintStart_toEndOf="@id/space"
+ app:layout_constraintWidth_default="wrap"
+ app:layout_constraintStart_toEndOf="@id/date"
app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
app:layout_constraintTop_toTopOf="@id/date"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintHorizontal_bias="1"
+ app:layout_constraintBottom_toBottomOf="@id/date"
/>
</Constraint>
<Constraint
android:id="@+id/batteryRemainingIcon">
<Layout
- android:layout_width="wrap_content"
+ android:layout_width="0dp"
android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
+ app:layout_constraintWidth_default="wrap"
app:layout_constraintHeight_min="@dimen/new_qs_header_non_clickable_element_height"
- app:layout_constraintStart_toEndOf="@id/statusIcons"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/date"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintHorizontal_bias="1"
- app:layout_constraintHorizontal_chainStyle="spread_inside"
+ app:layout_constraintBottom_toBottomOf="@id/date"
/>
</Constraint>
-
- <Constraint
- android:id="@id/space">
- <Layout
- android:layout_width="0dp"
- android:layout_height="0dp"
- app:layout_constraintStart_toEndOf="@id/date"
- app:layout_constraintEnd_toStartOf="@id/statusIcons"
- />
- </Constraint>
</ConstraintSet>
\ No newline at end of file
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextView.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextView.kt
index 25d2721..9b73cc3 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextView.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextView.kt
@@ -48,48 +48,28 @@
val drawableInsetSize: Int
try {
val keyShadowBlur =
- attributes.getDimensionPixelSize(R.styleable.DoubleShadowTextView_keyShadowBlur, 0)
+ attributes.getDimension(R.styleable.DoubleShadowTextView_keyShadowBlur, 0f)
val keyShadowOffsetX =
- attributes.getDimensionPixelSize(
- R.styleable.DoubleShadowTextView_keyShadowOffsetX,
- 0
- )
+ attributes.getDimension(R.styleable.DoubleShadowTextView_keyShadowOffsetX, 0f)
val keyShadowOffsetY =
- attributes.getDimensionPixelSize(
- R.styleable.DoubleShadowTextView_keyShadowOffsetY,
- 0
- )
+ attributes.getDimension(R.styleable.DoubleShadowTextView_keyShadowOffsetY, 0f)
val keyShadowAlpha =
attributes.getFloat(R.styleable.DoubleShadowTextView_keyShadowAlpha, 0f)
mKeyShadowInfo =
- ShadowInfo(
- keyShadowBlur.toFloat(),
- keyShadowOffsetX.toFloat(),
- keyShadowOffsetY.toFloat(),
- keyShadowAlpha
- )
+ ShadowInfo(keyShadowBlur, keyShadowOffsetX, keyShadowOffsetY, keyShadowAlpha)
val ambientShadowBlur =
- attributes.getDimensionPixelSize(
- R.styleable.DoubleShadowTextView_ambientShadowBlur,
- 0
- )
+ attributes.getDimension(R.styleable.DoubleShadowTextView_ambientShadowBlur, 0f)
val ambientShadowOffsetX =
- attributes.getDimensionPixelSize(
- R.styleable.DoubleShadowTextView_ambientShadowOffsetX,
- 0
- )
+ attributes.getDimension(R.styleable.DoubleShadowTextView_ambientShadowOffsetX, 0f)
val ambientShadowOffsetY =
- attributes.getDimensionPixelSize(
- R.styleable.DoubleShadowTextView_ambientShadowOffsetY,
- 0
- )
+ attributes.getDimension(R.styleable.DoubleShadowTextView_ambientShadowOffsetY, 0f)
val ambientShadowAlpha =
attributes.getFloat(R.styleable.DoubleShadowTextView_ambientShadowAlpha, 0f)
mAmbientShadowInfo =
ShadowInfo(
- ambientShadowBlur.toFloat(),
- ambientShadowOffsetX.toFloat(),
- ambientShadowOffsetY.toFloat(),
+ ambientShadowBlur,
+ ambientShadowOffsetX,
+ ambientShadowOffsetY,
ambientShadowAlpha
)
drawableSize =
diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
index 8f38e58..a45ce42 100644
--- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
@@ -38,9 +38,11 @@
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.lifecycle.repeatWhenAttached
-import com.android.systemui.log.dagger.KeyguardClockLog
+import com.android.systemui.log.dagger.KeyguardSmallClockLog
+import com.android.systemui.log.dagger.KeyguardLargeClockLog
import com.android.systemui.plugins.ClockController
import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogLevel.DEBUG
import com.android.systemui.shared.regionsampling.RegionSampler
import com.android.systemui.statusbar.policy.BatteryController
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback
@@ -73,16 +75,18 @@
private val context: Context,
@Main private val mainExecutor: Executor,
@Background private val bgExecutor: Executor,
- @KeyguardClockLog private val logBuffer: LogBuffer?,
+ @KeyguardSmallClockLog private val smallLogBuffer: LogBuffer?,
+ @KeyguardLargeClockLog private val largeLogBuffer: LogBuffer?,
private val featureFlags: FeatureFlags
) {
var clock: ClockController? = null
set(value) {
field = value
if (value != null) {
- if (logBuffer != null) {
- value.setLogBuffer(logBuffer)
- }
+ smallLogBuffer?.log(TAG, DEBUG, {}, { "New Clock" })
+ value.smallClock.logBuffer = smallLogBuffer
+ largeLogBuffer?.log(TAG, DEBUG, {}, { "New Clock" })
+ value.largeClock.logBuffer = largeLogBuffer
value.initialize(resources, dozeAmount, 0f)
updateRegionSamplers(value)
@@ -325,4 +329,8 @@
}
}
}
+
+ companion object {
+ private val TAG = ClockEventController::class.simpleName!!
+ }
}
diff --git a/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt b/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt
index 5bb9367..e0cf7b6 100644
--- a/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt
+++ b/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt
@@ -50,6 +50,7 @@
import com.android.keyguard.InternalFaceAuthReasons.KEYGUARD_VISIBILITY_CHANGED
import com.android.keyguard.InternalFaceAuthReasons.NON_STRONG_BIOMETRIC_ALLOWED_CHANGED
import com.android.keyguard.InternalFaceAuthReasons.OCCLUDING_APP_REQUESTED
+import com.android.keyguard.InternalFaceAuthReasons.POSTURE_CHANGED
import com.android.keyguard.InternalFaceAuthReasons.PRIMARY_BOUNCER_SHOWN
import com.android.keyguard.InternalFaceAuthReasons.PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN
import com.android.keyguard.InternalFaceAuthReasons.RETRY_AFTER_HW_UNAVAILABLE
@@ -126,6 +127,7 @@
const val STRONG_AUTH_ALLOWED_CHANGED = "Face auth stopped because strong auth allowed changed"
const val NON_STRONG_BIOMETRIC_ALLOWED_CHANGED =
"Face auth stopped because non strong biometric allowed changed"
+ const val POSTURE_CHANGED = "Face auth started/stopped due to device posture changed."
}
/**
@@ -173,6 +175,7 @@
return PowerManager.wakeReasonToString(extraInfo)
}
},
+ @UiEvent(doc = POSTURE_CHANGED) FACE_AUTH_UPDATED_POSTURE_CHANGED(1265, POSTURE_CHANGED),
@Deprecated(
"Not a face auth trigger.",
ReplaceWith(
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 62babad..4acbb0a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -7,7 +7,6 @@
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -20,11 +19,15 @@
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.plugins.ClockController;
+import com.android.systemui.plugins.log.LogBuffer;
+import com.android.systemui.plugins.log.LogLevel;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import kotlin.Unit;
+
/**
* Switch to show plugin clock when plugin is connected, otherwise it will show default clock.
*/
@@ -87,6 +90,7 @@
private int mClockSwitchYAmount;
@VisibleForTesting boolean mChildrenAreLaidOut = false;
@VisibleForTesting boolean mAnimateOnLayout = true;
+ private LogBuffer mLogBuffer = null;
public KeyguardClockSwitch(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -113,6 +117,14 @@
onDensityOrFontScaleChanged();
}
+ public void setLogBuffer(LogBuffer logBuffer) {
+ mLogBuffer = logBuffer;
+ }
+
+ public LogBuffer getLogBuffer() {
+ return mLogBuffer;
+ }
+
void setClock(ClockController clock, int statusBarState) {
mClock = clock;
@@ -121,12 +133,16 @@
mLargeClockFrame.removeAllViews();
if (clock == null) {
- Log.e(TAG, "No clock being shown");
+ if (mLogBuffer != null) {
+ mLogBuffer.log(TAG, LogLevel.ERROR, "No clock being shown");
+ }
return;
}
// Attach small and big clock views to hierarchy.
- Log.i(TAG, "Attached new clock views to switch");
+ if (mLogBuffer != null) {
+ mLogBuffer.log(TAG, LogLevel.INFO, "Attached new clock views to switch");
+ }
mSmallClockFrame.addView(clock.getSmallClock().getView());
mLargeClockFrame.addView(clock.getLargeClock().getView());
updateClockTargetRegions();
@@ -152,8 +168,18 @@
}
private void updateClockViews(boolean useLargeClock, boolean animate) {
- Log.i(TAG, "updateClockViews; useLargeClock=" + useLargeClock + "; animate=" + animate
- + "; mChildrenAreLaidOut=" + mChildrenAreLaidOut);
+ if (mLogBuffer != null) {
+ mLogBuffer.log(TAG, LogLevel.DEBUG, (msg) -> {
+ msg.setBool1(useLargeClock);
+ msg.setBool2(animate);
+ msg.setBool3(mChildrenAreLaidOut);
+ return Unit.INSTANCE;
+ }, (msg) -> "updateClockViews"
+ + "; useLargeClock=" + msg.getBool1()
+ + "; animate=" + msg.getBool2()
+ + "; mChildrenAreLaidOut=" + msg.getBool3());
+ }
+
if (mClockInAnim != null) mClockInAnim.cancel();
if (mClockOutAnim != null) mClockOutAnim.cancel();
if (mStatusAreaAnim != null) mStatusAreaAnim.cancel();
@@ -183,6 +209,7 @@
if (!animate) {
out.setAlpha(0f);
+ out.setVisibility(INVISIBLE);
in.setAlpha(1f);
in.setVisibility(VISIBLE);
mStatusArea.setTranslationY(statusAreaYTranslation);
@@ -198,7 +225,10 @@
direction * -mClockSwitchYAmount));
mClockOutAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
- mClockOutAnim = null;
+ if (mClockOutAnim == animation) {
+ out.setVisibility(INVISIBLE);
+ mClockOutAnim = null;
+ }
}
});
@@ -212,7 +242,9 @@
mClockInAnim.setStartDelay(CLOCK_OUT_MILLIS / 2);
mClockInAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
- mClockInAnim = null;
+ if (mClockInAnim == animation) {
+ mClockInAnim = null;
+ }
}
});
@@ -225,7 +257,9 @@
mStatusAreaAnim.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
mStatusAreaAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
- mStatusAreaAnim = null;
+ if (mStatusAreaAnim == animation) {
+ mStatusAreaAnim = null;
+ }
}
});
mStatusAreaAnim.start();
@@ -269,7 +303,9 @@
public void dump(PrintWriter pw, String[] args) {
pw.println("KeyguardClockSwitch:");
pw.println(" mSmallClockFrame: " + mSmallClockFrame);
+ pw.println(" mSmallClockFrame.alpha: " + mSmallClockFrame.getAlpha());
pw.println(" mLargeClockFrame: " + mLargeClockFrame);
+ pw.println(" mLargeClockFrame.alpha: " + mLargeClockFrame.getAlpha());
pw.println(" mStatusArea: " + mStatusArea);
pw.println(" mDisplayedClockSize: " + mDisplayedClockSize);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 6ce84a9..08567a7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -38,8 +38,11 @@
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
+import com.android.systemui.log.dagger.KeyguardClockLog;
import com.android.systemui.plugins.ClockAnimations;
import com.android.systemui.plugins.ClockController;
+import com.android.systemui.plugins.log.LogBuffer;
+import com.android.systemui.plugins.log.LogLevel;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shared.clocks.ClockRegistry;
import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
@@ -62,6 +65,8 @@
*/
public class KeyguardClockSwitchController extends ViewController<KeyguardClockSwitch>
implements Dumpable {
+ private static final String TAG = "KeyguardClockSwitchController";
+
private final StatusBarStateController mStatusBarStateController;
private final ClockRegistry mClockRegistry;
private final KeyguardSliceViewController mKeyguardSliceViewController;
@@ -70,6 +75,7 @@
private final SecureSettings mSecureSettings;
private final DumpManager mDumpManager;
private final ClockEventController mClockEventController;
+ private final LogBuffer mLogBuffer;
private FrameLayout mSmallClockFrame; // top aligned clock
private FrameLayout mLargeClockFrame; // centered clock
@@ -119,7 +125,8 @@
SecureSettings secureSettings,
@Main Executor uiExecutor,
DumpManager dumpManager,
- ClockEventController clockEventController) {
+ ClockEventController clockEventController,
+ @KeyguardClockLog LogBuffer logBuffer) {
super(keyguardClockSwitch);
mStatusBarStateController = statusBarStateController;
mClockRegistry = clockRegistry;
@@ -131,6 +138,8 @@
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
mDumpManager = dumpManager;
mClockEventController = clockEventController;
+ mLogBuffer = logBuffer;
+ mView.setLogBuffer(mLogBuffer);
mClockChangedListener = () -> {
setClock(mClockRegistry.createCurrentClock());
@@ -337,10 +346,6 @@
int clockHeight = clock.getLargeClock().getView().getHeight();
return frameHeight / 2 + clockHeight / 2 + mKeyguardLargeClockTopMargin / -2;
} else {
- // This is only called if we've never shown the large clock as the frame is inflated
- // with 'gone', but then the visibility is never set when it is animated away by
- // KeyguardClockSwitch, instead it is removed from the view hierarchy.
- // TODO(b/261755021): Cleanup Large Frame Visibility
int clockHeight = clock.getSmallClock().getView().getHeight();
return clockHeight + statusBarHeaderHeight + mKeyguardSmallClockTopMargin;
}
@@ -358,15 +363,11 @@
if (mLargeClockFrame.getVisibility() == View.VISIBLE) {
return clock.getLargeClock().getView().getHeight();
} else {
- // Is not called except in certain edge cases, see comment in getClockBottom
- // TODO(b/261755021): Cleanup Large Frame Visibility
return clock.getSmallClock().getView().getHeight();
}
}
boolean isClockTopAligned() {
- // Returns false except certain edge cases, see comment in getClockBottom
- // TODO(b/261755021): Cleanup Large Frame Visibility
return mLargeClockFrame.getVisibility() != View.VISIBLE;
}
@@ -378,6 +379,10 @@
}
private void setClock(ClockController clock) {
+ if (clock != null && mLogBuffer != null) {
+ mLogBuffer.log(TAG, LogLevel.INFO, "New Clock");
+ }
+
mClockEventController.setClock(clock);
mView.setClock(clock, mStatusBarStateController.getState());
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt
index deead19..1a06b5f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt
@@ -39,6 +39,7 @@
var keyguardGoingAway: Boolean = false,
var listeningForFaceAssistant: Boolean = false,
var occludingAppRequestingFaceAuth: Boolean = false,
+ val postureAllowsListening: Boolean = false,
var primaryUser: Boolean = false,
var secureCameraLaunched: Boolean = false,
var supportsDetect: Boolean = false,
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 4e10bff..9d6bb08 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -63,11 +63,13 @@
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_KEYGUARD_VISIBILITY_CHANGED;
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_ON_FACE_AUTHENTICATED;
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_ON_KEYGUARD_INIT;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_POSTURE_CHANGED;
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN;
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_STARTED_WAKING_UP;
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_STRONG_AUTH_CHANGED;
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_USER_SWITCHING;
import static com.android.systemui.DejankUtils.whitelistIpcs;
+import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN;
import android.annotation.AnyThread;
import android.annotation.MainThread;
@@ -154,6 +156,7 @@
import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.telephony.TelephonyListenerManager;
import com.android.systemui.util.Assert;
import com.android.systemui.util.settings.SecureSettings;
@@ -341,6 +344,7 @@
private final TrustManager mTrustManager;
private final UserManager mUserManager;
private final DevicePolicyManager mDevicePolicyManager;
+ private final DevicePostureController mPostureController;
private final BroadcastDispatcher mBroadcastDispatcher;
private final SecureSettings mSecureSettings;
private final InteractionJankMonitor mInteractionJankMonitor;
@@ -358,6 +362,9 @@
private final FaceManager mFaceManager;
private final LockPatternUtils mLockPatternUtils;
private final boolean mWakeOnFingerprintAcquiredStart;
+ @VisibleForTesting
+ @DevicePostureController.DevicePostureInt
+ protected int mConfigFaceAuthSupportedPosture;
private KeyguardBypassController mKeyguardBypassController;
private List<SubscriptionInfo> mSubscriptionInfo;
@@ -368,6 +375,7 @@
private boolean mLogoutEnabled;
private boolean mIsFaceEnrolled;
private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ private int mPostureState = DEVICE_POSTURE_UNKNOWN;
private FingerprintInteractiveToAuthProvider mFingerprintInteractiveToAuthProvider;
/**
@@ -696,8 +704,11 @@
*/
public void setKeyguardGoingAway(boolean goingAway) {
mKeyguardGoingAway = goingAway;
- // This is set specifically to stop face authentication from running.
- updateBiometricListeningState(BIOMETRIC_ACTION_STOP, FACE_AUTH_STOPPED_KEYGUARD_GOING_AWAY);
+ if (mKeyguardGoingAway) {
+ updateFaceListeningState(BIOMETRIC_ACTION_STOP,
+ FACE_AUTH_STOPPED_KEYGUARD_GOING_AWAY);
+ }
+ updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
}
/**
@@ -1776,6 +1787,17 @@
};
@VisibleForTesting
+ final DevicePostureController.Callback mPostureCallback =
+ new DevicePostureController.Callback() {
+ @Override
+ public void onPostureChanged(int posture) {
+ mPostureState = posture;
+ updateFaceListeningState(BIOMETRIC_ACTION_UPDATE,
+ FACE_AUTH_UPDATED_POSTURE_CHANGED);
+ }
+ };
+
+ @VisibleForTesting
CancellationSignal mFingerprintCancelSignal;
@VisibleForTesting
CancellationSignal mFaceCancelSignal;
@@ -1935,9 +1957,9 @@
cb.onFinishedGoingToSleep(arg1);
}
}
- // This is set specifically to stop face authentication from running.
- updateBiometricListeningState(BIOMETRIC_ACTION_STOP,
+ updateFaceListeningState(BIOMETRIC_ACTION_STOP,
FACE_AUTH_STOPPED_FINISHED_GOING_TO_SLEEP);
+ updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
}
private void handleScreenTurnedOff() {
@@ -2041,6 +2063,7 @@
@Nullable FingerprintManager fingerprintManager,
@Nullable BiometricManager biometricManager,
FaceWakeUpTriggersConfig faceWakeUpTriggersConfig,
+ DevicePostureController devicePostureController,
Optional<FingerprintInteractiveToAuthProvider> interactiveToAuthProvider) {
mContext = context;
mSubscriptionManager = subscriptionManager;
@@ -2070,6 +2093,7 @@
mDreamManager = dreamManager;
mTelephonyManager = telephonyManager;
mDevicePolicyManager = devicePolicyManager;
+ mPostureController = devicePostureController;
mPackageManager = packageManager;
mFpm = fingerprintManager;
mFaceManager = faceManager;
@@ -2081,6 +2105,8 @@
R.array.config_face_acquire_device_entry_ignorelist))
.boxed()
.collect(Collectors.toSet());
+ mConfigFaceAuthSupportedPosture = mContext.getResources().getInteger(
+ R.integer.config_face_auth_supported_posture);
mFaceWakeUpTriggersConfig = faceWakeUpTriggersConfig;
mHandler = new Handler(mainLooper) {
@@ -2272,6 +2298,9 @@
FACE_AUTH_TRIGGERED_ENROLLMENTS_CHANGED));
}
});
+ if (mConfigFaceAuthSupportedPosture != DEVICE_POSTURE_UNKNOWN) {
+ mPostureController.addCallback(mPostureCallback);
+ }
updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE, FACE_AUTH_UPDATED_ON_KEYGUARD_INIT);
TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
@@ -2704,7 +2733,7 @@
mFingerprintInteractiveToAuthProvider != null &&
mFingerprintInteractiveToAuthProvider.isEnabled(getCurrentUser());
shouldListenSideFpsState =
- interactiveToAuthEnabled ? isDeviceInteractive() : true;
+ interactiveToAuthEnabled ? isDeviceInteractive() && !mGoingToSleep : true;
}
boolean shouldListen = shouldListenKeyguardState && shouldListenUserState
@@ -2716,7 +2745,7 @@
user,
shouldListen,
biometricEnabledForUser,
- mPrimaryBouncerIsOrWillBeShowing,
+ mPrimaryBouncerIsOrWillBeShowing,
userCanSkipBouncer,
mCredentialAttempted,
mDeviceInteractive,
@@ -2776,6 +2805,9 @@
final boolean biometricEnabledForUser = mBiometricEnabledForUser.get(user);
final boolean shouldListenForFaceAssistant = shouldListenForFaceAssistant();
final boolean isUdfpsFingerDown = mAuthController.isUdfpsFingerDown();
+ final boolean isPostureAllowedForFaceAuth =
+ mConfigFaceAuthSupportedPosture == 0 /* DEVICE_POSTURE_UNKNOWN */ ? true
+ : (mPostureState == mConfigFaceAuthSupportedPosture);
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
@@ -2792,7 +2824,8 @@
&& faceAuthAllowedOrDetectionIsNeeded && mIsPrimaryUser
&& (!mSecureCameraLaunched || mOccludingAppRequestingFace)
&& faceAndFpNotAuthenticated
- && !mGoingToSleep;
+ && !mGoingToSleep
+ && isPostureAllowedForFaceAuth;
// Aggregate relevant fields for debug logging.
logListenerModelData(
@@ -2812,6 +2845,7 @@
mKeyguardGoingAway,
shouldListenForFaceAssistant,
mOccludingAppRequestingFace,
+ isPostureAllowedForFaceAuth,
mIsPrimaryUser,
mSecureCameraLaunched,
supportsDetect,
@@ -2897,7 +2931,7 @@
getKeyguardSessionId(),
faceAuthUiEvent.getExtraInfo()
);
-
+ mLogger.logFaceUnlockPossible(unlockPossible);
if (unlockPossible) {
mFaceCancelSignal = new CancellationSignal();
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
index b106fec..2c7eceb 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
@@ -17,36 +17,46 @@
package com.android.keyguard.logging
import com.android.systemui.log.dagger.KeyguardLog
-import com.android.systemui.plugins.log.ConstantStringsLogger
-import com.android.systemui.plugins.log.ConstantStringsLoggerImpl
import com.android.systemui.plugins.log.LogBuffer
-import com.android.systemui.plugins.log.LogLevel.DEBUG
-import com.android.systemui.plugins.log.LogLevel.ERROR
-import com.android.systemui.plugins.log.LogLevel.INFO
-import com.android.systemui.plugins.log.LogLevel.VERBOSE
+import com.android.systemui.plugins.log.LogLevel
import com.google.errorprone.annotations.CompileTimeConstant
import javax.inject.Inject
-private const val TAG = "KeyguardLog"
+private const val BIO_TAG = "KeyguardLog"
/**
* Generic logger for keyguard that's wrapping [LogBuffer]. This class should be used for adding
* temporary logs or logs for smaller classes when creating whole new [LogBuffer] wrapper might be
* an overkill.
*/
-class KeyguardLogger @Inject constructor(@KeyguardLog val buffer: LogBuffer) :
- ConstantStringsLogger by ConstantStringsLoggerImpl(buffer, TAG) {
+class KeyguardLogger
+@Inject
+constructor(
+ @KeyguardLog val buffer: LogBuffer,
+) {
+ @JvmOverloads
+ fun log(
+ tag: String,
+ level: LogLevel,
+ @CompileTimeConstant msg: String,
+ ex: Throwable? = null,
+ ) = buffer.log(tag, level, msg, ex)
- fun logException(ex: Exception, @CompileTimeConstant logMsg: String) {
- buffer.log(TAG, ERROR, {}, { logMsg }, exception = ex)
- }
-
- fun v(msg: String, arg: Any) {
- buffer.log(TAG, VERBOSE, { str1 = arg.toString() }, { "$msg: $str1" })
- }
-
- fun i(msg: String, arg: Any) {
- buffer.log(TAG, INFO, { str1 = arg.toString() }, { "$msg: $str1" })
+ fun log(
+ tag: String,
+ level: LogLevel,
+ @CompileTimeConstant msg: String,
+ arg: Any,
+ ) {
+ buffer.log(
+ tag,
+ level,
+ {
+ str1 = msg
+ str2 = arg.toString()
+ },
+ { "$str1: $str2" }
+ )
}
@JvmOverloads
@@ -56,8 +66,8 @@
msg: String? = null
) {
buffer.log(
- TAG,
- DEBUG,
+ BIO_TAG,
+ LogLevel.DEBUG,
{
str1 = context
str2 = "$msgId"
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
index 21d3b24..5b42455 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
@@ -132,6 +132,12 @@
logBuffer.log(TAG, DEBUG, { int1 = faceRunningState }, { "faceRunningState: $int1" })
}
+ fun logFaceUnlockPossible(isFaceUnlockPossible: Boolean) {
+ logBuffer.log(TAG, DEBUG,
+ { bool1 = isFaceUnlockPossible },
+ {"isUnlockWithFacePossible: $bool1"})
+ }
+
fun logFingerprintAuthForWrongUser(authUserId: Int) {
logBuffer.log(TAG, DEBUG,
{ int1 = authUserId },
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java b/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
index 0fc9ef9..632fcdc 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
@@ -22,8 +22,6 @@
import android.os.HandlerThread;
import android.util.Log;
-import androidx.annotation.Nullable;
-
import com.android.systemui.dagger.GlobalRootComponent;
import com.android.systemui.dagger.SysUIComponent;
import com.android.systemui.dagger.WMComponent;
@@ -55,7 +53,6 @@
mContext = context;
}
- @Nullable
protected abstract GlobalRootComponent.Builder getGlobalRootComponentBuilder();
/**
@@ -72,11 +69,6 @@
* Starts the initialization process. This stands up the Dagger graph.
*/
public void init(boolean fromTest) throws ExecutionException, InterruptedException {
- GlobalRootComponent.Builder globalBuilder = getGlobalRootComponentBuilder();
- if (globalBuilder == null) {
- return;
- }
-
mRootComponent = getGlobalRootComponentBuilder()
.context(mContext)
.instrumentationTest(fromTest)
@@ -127,7 +119,6 @@
.setBackAnimation(Optional.ofNullable(null))
.setDesktopMode(Optional.ofNullable(null));
}
-
mSysUIComponent = builder.build();
if (initializeComponents) {
mSysUIComponent.init();
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt
index 55c095b..8aa3040 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt
@@ -16,7 +16,6 @@
package com.android.systemui
-import android.app.Application
import android.content.Context
import com.android.systemui.dagger.DaggerReferenceGlobalRootComponent
import com.android.systemui.dagger.GlobalRootComponent
@@ -25,17 +24,7 @@
* {@link SystemUIInitializer} that stands up AOSP SystemUI.
*/
class SystemUIInitializerImpl(context: Context) : SystemUIInitializer(context) {
-
- override fun getGlobalRootComponentBuilder(): GlobalRootComponent.Builder? {
- return when (Application.getProcessName()) {
- SCREENSHOT_CROSS_PROFILE_PROCESS -> null
- else -> DaggerReferenceGlobalRootComponent.builder()
- }
- }
-
- companion object {
- private const val SYSTEMUI_PROCESS = "com.android.systemui"
- private const val SCREENSHOT_CROSS_PROFILE_PROCESS =
- "$SYSTEMUI_PROCESS:screenshot_cross_profile"
+ override fun getGlobalRootComponentBuilder(): GlobalRootComponent.Builder {
+ return DaggerReferenceGlobalRootComponent.builder()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index cfbde15..199e630 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -182,8 +182,8 @@
private int mActivePointerId = -1;
// The timestamp of the most recent touch log.
private long mTouchLogTime;
- // The timestamp of the most recent log of the UNCHANGED interaction.
- private long mLastUnchangedInteractionTime;
+ // The timestamp of the most recent log of a touch InteractionEvent.
+ private long mLastTouchInteractionTime;
// Sensor has a capture (good or bad) for this touch. No need to enable the UDFPS display mode
// anymore for this particular touch event. In other words, do not enable the UDFPS mode until
// the user touches the sensor area again.
@@ -540,12 +540,12 @@
private void logBiometricTouch(InteractionEvent event, NormalizedTouchData data) {
if (event == InteractionEvent.UNCHANGED) {
- long sinceLastLog = mSystemClock.elapsedRealtime() - mLastUnchangedInteractionTime;
+ long sinceLastLog = mSystemClock.elapsedRealtime() - mLastTouchInteractionTime;
if (sinceLastLog < MIN_UNCHANGED_INTERACTION_LOG_INTERVAL) {
return;
}
- mLastUnchangedInteractionTime = mSystemClock.elapsedRealtime();
}
+ mLastTouchInteractionTime = mSystemClock.elapsedRealtime();
final int biometricTouchReportedTouchType = toBiometricTouchReportedTouchType(event);
final InstanceId sessionIdProvider = mSessionTracker.getSessionId(
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
index a3c4985..1b6c8c6 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
@@ -33,6 +33,7 @@
import android.os.Build
import android.os.RemoteException
import android.provider.Settings
+import android.util.FeatureFlagUtils
import android.util.Log
import android.util.RotationUtils
import android.view.LayoutInflater
@@ -232,18 +233,30 @@
return when (filteredRequestReason) {
REASON_ENROLL_FIND_SENSOR,
REASON_ENROLL_ENROLLING -> {
- UdfpsEnrollViewController(
- view.addUdfpsView(R.layout.udfps_enroll_view) {
- updateSensorLocation(sensorBounds)
- },
- enrollHelper ?: throw IllegalStateException("no enrollment helper"),
- statusBarStateController,
- shadeExpansionStateManager,
- dialogManager,
- dumpManager,
- featureFlags,
- overlayParams.scaleFactor
- )
+ if (FeatureFlagUtils.isEnabled(context,
+ FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS)) {
+ // Enroll udfps UI is handled by settings, so use empty view here
+ UdfpsFpmEmptyViewController(
+ view.addUdfpsView(R.layout.udfps_fpm_empty_view),
+ statusBarStateController,
+ shadeExpansionStateManager,
+ dialogManager,
+ dumpManager
+ )
+ } else {
+ UdfpsEnrollViewController(
+ view.addUdfpsView(R.layout.udfps_enroll_view) {
+ updateSensorLocation(sensorBounds)
+ },
+ enrollHelper ?: throw IllegalStateException("no enrollment helper"),
+ statusBarStateController,
+ shadeExpansionStateManager,
+ dialogManager,
+ dumpManager,
+ featureFlags,
+ overlayParams.scaleFactor
+ )
+ }
}
REASON_AUTH_KEYGUARD -> {
UdfpsKeyguardViewController(
@@ -277,8 +290,8 @@
}
REASON_AUTH_OTHER,
REASON_AUTH_SETTINGS -> {
- UdfpsFpmOtherViewController(
- view.addUdfpsView(R.layout.udfps_fpm_other_view),
+ UdfpsFpmEmptyViewController(
+ view.addUdfpsView(R.layout.udfps_fpm_empty_view),
statusBarStateController,
shadeExpansionStateManager,
dialogManager,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt
similarity index 72%
rename from packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherView.kt
rename to packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt
index 4d6da8f..e8f041e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt
@@ -17,24 +17,19 @@
import android.content.Context
import android.util.AttributeSet
-import android.widget.ImageView
-import com.android.systemui.R
/**
- * View corresponding with udfps_fpm_other_view.xml
+ * View corresponding with udfps_fpm_empty_view.xml
+ *
+ * Currently doesn't draw anything.
*/
-class UdfpsFpmOtherView(
+class UdfpsFpmEmptyView(
context: Context,
attrs: AttributeSet?
) : UdfpsAnimationView(context, attrs) {
+ // Drawable isn't ever added to the view, so we don't currently show anything
private val fingerprintDrawable: UdfpsFpDrawable = UdfpsFpDrawable(context)
- private lateinit var fingerprintView: ImageView
-
- override fun onFinishInflate() {
- fingerprintView = findViewById(R.id.udfps_fpm_other_fp_view)!!
- fingerprintView.setImageDrawable(fingerprintDrawable)
- }
override fun getDrawable(): UdfpsDrawable = fingerprintDrawable
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyViewController.kt
similarity index 82%
rename from packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherViewController.kt
rename to packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyViewController.kt
index 7c23278..d122d64 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyViewController.kt
@@ -21,18 +21,17 @@
import com.android.systemui.statusbar.phone.SystemUIDialogManager
/**
- * Class that coordinates non-HBM animations for non keyguard, enrollment or biometric prompt
- * states.
+ * Class that coordinates non-HBM animations for non keyguard, or biometric prompt states.
*
- * Currently only shows the fp drawable.
+ * Currently doesn't draw anything.
*/
-class UdfpsFpmOtherViewController(
- view: UdfpsFpmOtherView,
+class UdfpsFpmEmptyViewController(
+ view: UdfpsFpmEmptyView,
statusBarStateController: StatusBarStateController,
shadeExpansionStateManager: ShadeExpansionStateManager,
systemUIDialogManager: SystemUIDialogManager,
dumpManager: DumpManager
-) : UdfpsAnimationViewController<UdfpsFpmOtherView>(
+) : UdfpsAnimationViewController<UdfpsFpmEmptyView>(
view,
statusBarStateController,
shadeExpansionStateManager,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetector.kt b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetector.kt
index 8572242..682d38a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetector.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetector.kt
@@ -18,6 +18,7 @@
import android.graphics.Point
import android.graphics.Rect
+import androidx.annotation.VisibleForTesting
import com.android.systemui.dagger.SysUISingleton
import kotlin.math.cos
import kotlin.math.pow
@@ -50,7 +51,8 @@
return result <= 1
}
- private fun calculateSensorPoints(sensorBounds: Rect): List<Point> {
+ @VisibleForTesting
+ fun calculateSensorPoints(sensorBounds: Rect): List<Point> {
val sensorX = sensorBounds.centerX()
val sensorY = sensorBounds.centerY()
val cornerOffset: Int = sensorBounds.width() / 4
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessor.kt
index 338bf66..693f64a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessor.kt
@@ -27,6 +27,8 @@
import com.android.systemui.dagger.SysUISingleton
import javax.inject.Inject
+private val SUPPORTED_ROTATIONS = setOf(Surface.ROTATION_90, Surface.ROTATION_270)
+
/**
* TODO(b/259140693): Consider using an object pool of TouchProcessorResult to avoid allocations.
*/
@@ -129,19 +131,27 @@
val nativeY = naturalTouch.y / overlayParams.scaleFactor
val nativeMinor: Float = getTouchMinor(pointerIndex) / overlayParams.scaleFactor
val nativeMajor: Float = getTouchMajor(pointerIndex) / overlayParams.scaleFactor
+ var nativeOrientation: Float = getOrientation(pointerIndex)
+ if (SUPPORTED_ROTATIONS.contains(overlayParams.rotation)) {
+ nativeOrientation = toRadVerticalFromRotated(nativeOrientation.toDouble()).toFloat()
+ }
return NormalizedTouchData(
pointerId = getPointerId(pointerIndex),
x = nativeX,
y = nativeY,
minor = nativeMinor,
major = nativeMajor,
- // TODO(b/259311354): touch orientation should be reported relative to Surface.ROTATION_O.
- orientation = getOrientation(pointerIndex),
+ orientation = nativeOrientation,
time = eventTime,
gestureStart = downTime,
)
}
+private fun toRadVerticalFromRotated(rad: Double): Double {
+ val piBound = ((rad % Math.PI) + Math.PI / 2) % Math.PI
+ return if (piBound < Math.PI / 2.0) piBound else piBound - Math.PI
+}
+
/**
* Returns the [MotionEvent.getRawX] and [MotionEvent.getRawY] of the given pointer as if the device
* is in the [Surface.ROTATION_0] orientation.
@@ -152,7 +162,7 @@
): PointF {
val touchPoint = PointF(getRawX(pointerIndex), getRawY(pointerIndex))
val rot = overlayParams.rotation
- if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
+ if (SUPPORTED_ROTATIONS.contains(rot)) {
RotationUtils.rotatePointF(
touchPoint,
RotationUtils.deltaRotation(rot, Surface.ROTATION_0),
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
index e8e1f2e..e9ac840 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
@@ -176,7 +176,8 @@
private @Classifier.InteractionType int mPriorInteractionType = Classifier.GENERIC;
@Inject
- public BrightLineFalsingManager(FalsingDataProvider falsingDataProvider,
+ public BrightLineFalsingManager(
+ FalsingDataProvider falsingDataProvider,
MetricsLogger metricsLogger,
@Named(BRIGHT_LINE_GESTURE_CLASSIFERS) Set<FalsingClassifier> classifiers,
SingleTapClassifier singleTapClassifier, LongTapClassifier longTapClassifier,
@@ -399,7 +400,9 @@
|| mDataProvider.isJustUnlockedWithFace()
|| mDataProvider.isDocked()
|| mAccessibilityManager.isTouchExplorationEnabled()
- || mDataProvider.isA11yAction();
+ || mDataProvider.isA11yAction()
+ || (mFeatureFlags.isEnabled(Flags.FALSING_OFF_FOR_UNFOLDED)
+ && !mDataProvider.isFolded());
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
index 09ebeea..5f347c1 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
@@ -16,6 +16,7 @@
package com.android.systemui.classifier;
+import android.hardware.devicestate.DeviceStateManager.FoldStateListener;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.MotionEvent.PointerCoords;
@@ -42,6 +43,7 @@
private final int mWidthPixels;
private final int mHeightPixels;
private BatteryController mBatteryController;
+ private final FoldStateListener mFoldStateListener;
private final DockManager mDockManager;
private final float mXdpi;
private final float mYdpi;
@@ -65,12 +67,14 @@
public FalsingDataProvider(
DisplayMetrics displayMetrics,
BatteryController batteryController,
+ FoldStateListener foldStateListener,
DockManager dockManager) {
mXdpi = displayMetrics.xdpi;
mYdpi = displayMetrics.ydpi;
mWidthPixels = displayMetrics.widthPixels;
mHeightPixels = displayMetrics.heightPixels;
mBatteryController = batteryController;
+ mFoldStateListener = foldStateListener;
mDockManager = dockManager;
FalsingClassifier.logInfo("xdpi, ydpi: " + getXdpi() + ", " + getYdpi());
@@ -376,6 +380,10 @@
return mBatteryController.isWirelessCharging() || mDockManager.isDocked();
}
+ public boolean isFolded() {
+ return Boolean.TRUE.equals(mFoldStateListener.getFolded());
+ }
+
/** Implement to be alerted abotu the beginning and ending of falsing tracking. */
public interface SessionListener {
/** Called when the lock screen is shown and falsing-tracking begins. */
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
index f244cb0..96bce4c 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.content.Context;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
@@ -26,6 +27,9 @@
import androidx.constraintlayout.widget.ConstraintLayout;
import com.android.systemui.R;
+import com.android.systemui.shared.shadow.DoubleShadowIconDrawable;
+import com.android.systemui.shared.shadow.DoubleShadowTextHelper.ShadowInfo;
+import com.android.systemui.statusbar.AlphaOptimizedImageView;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -60,8 +64,15 @@
public static final int STATUS_ICON_PRIORITY_MODE_ON = 6;
private final Map<Integer, View> mStatusIcons = new HashMap<>();
+ private Context mContext;
private ViewGroup mSystemStatusViewGroup;
private ViewGroup mExtraSystemStatusViewGroup;
+ private ShadowInfo mKeyShadowInfo;
+ private ShadowInfo mAmbientShadowInfo;
+ private int mDrawableSize;
+ private int mDrawableInsetSize;
+ private static final float KEY_SHADOW_ALPHA = 0.35f;
+ private static final float AMBIENT_SHADOW_ALPHA = 0.4f;
public DreamOverlayStatusBarView(Context context) {
this(context, null);
@@ -73,6 +84,7 @@
public DreamOverlayStatusBarView(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
+ mContext = context;
}
public DreamOverlayStatusBarView(
@@ -80,14 +92,36 @@
super(context, attrs, defStyleAttr, defStyleRes);
}
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
+ mKeyShadowInfo = createShadowInfo(
+ R.dimen.dream_overlay_status_bar_key_text_shadow_radius,
+ R.dimen.dream_overlay_status_bar_key_text_shadow_dx,
+ R.dimen.dream_overlay_status_bar_key_text_shadow_dy,
+ KEY_SHADOW_ALPHA
+ );
+
+ mAmbientShadowInfo = createShadowInfo(
+ R.dimen.dream_overlay_status_bar_ambient_text_shadow_radius,
+ R.dimen.dream_overlay_status_bar_ambient_text_shadow_dx,
+ R.dimen.dream_overlay_status_bar_ambient_text_shadow_dy,
+ AMBIENT_SHADOW_ALPHA
+ );
+
+ mDrawableSize = mContext
+ .getResources()
+ .getDimensionPixelSize(R.dimen.dream_overlay_status_bar_icon_size);
+ mDrawableInsetSize = mContext
+ .getResources()
+ .getDimensionPixelSize(R.dimen.dream_overlay_icon_inset_dimen);
+
mStatusIcons.put(STATUS_ICON_WIFI_UNAVAILABLE,
- fetchStatusIconForResId(R.id.dream_overlay_wifi_status));
+ addDoubleShadow(fetchStatusIconForResId(R.id.dream_overlay_wifi_status)));
mStatusIcons.put(STATUS_ICON_ALARM_SET,
- fetchStatusIconForResId(R.id.dream_overlay_alarm_set));
+ addDoubleShadow(fetchStatusIconForResId(R.id.dream_overlay_alarm_set)));
mStatusIcons.put(STATUS_ICON_CAMERA_DISABLED,
fetchStatusIconForResId(R.id.dream_overlay_camera_off));
mStatusIcons.put(STATUS_ICON_MIC_DISABLED,
@@ -97,7 +131,7 @@
mStatusIcons.put(STATUS_ICON_NOTIFICATIONS,
fetchStatusIconForResId(R.id.dream_overlay_notification_indicator));
mStatusIcons.put(STATUS_ICON_PRIORITY_MODE_ON,
- fetchStatusIconForResId(R.id.dream_overlay_priority_mode));
+ addDoubleShadow(fetchStatusIconForResId(R.id.dream_overlay_priority_mode)));
mSystemStatusViewGroup = findViewById(R.id.dream_overlay_system_status);
mExtraSystemStatusViewGroup = findViewById(R.id.dream_overlay_extra_items);
@@ -137,4 +171,34 @@
}
return false;
}
+
+ private View addDoubleShadow(View icon) {
+ if (icon instanceof AlphaOptimizedImageView) {
+ AlphaOptimizedImageView i = (AlphaOptimizedImageView) icon;
+ Drawable drawableIcon = i.getDrawable();
+ i.setImageDrawable(new DoubleShadowIconDrawable(
+ mKeyShadowInfo,
+ mAmbientShadowInfo,
+ drawableIcon,
+ mDrawableSize,
+ mDrawableInsetSize
+ ));
+ }
+ return icon;
+ }
+
+ private ShadowInfo createShadowInfo(int blurId, int offsetXId, int offsetYId, float alpha) {
+ return new ShadowInfo(
+ fetchDimensionForResId(blurId),
+ fetchDimensionForResId(offsetXId),
+ fetchDimensionForResId(offsetYId),
+ alpha
+ );
+ }
+
+ private Float fetchDimensionForResId(int resId) {
+ return mContext
+ .getResources()
+ .getDimension(resId);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 7ae4d8a..d040f8f 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -114,8 +114,6 @@
// ** Flag retired **
// public static final BooleanFlag KEYGUARD_LAYOUT =
// new BooleanFlag(200, true);
- // TODO(b/254512713): Tracking Bug
- @JvmField val LOCKSCREEN_ANIMATIONS = releasedFlag(201, "lockscreen_animations")
// TODO(b/254512750): Tracking Bug
val NEW_UNLOCK_SWIPE_ANIMATION = releasedFlag(202, "new_unlock_swipe_animation")
@@ -165,7 +163,7 @@
// TODO(b/255618149): Tracking Bug
@JvmField
val CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES =
- unreleasedFlag(216, "customizable_lock_screen_quick_affordances", teamfood = false)
+ unreleasedFlag(216, "customizable_lock_screen_quick_affordances", teamfood = true)
/** Shows chipbar UI whenever the device is unlocked by ActiveUnlock (watch). */
// TODO(b/256513609): Tracking Bug
@@ -209,6 +207,9 @@
val AUTO_PIN_CONFIRMATION =
unreleasedFlag(224, "auto_pin_confirmation", "auto_pin_confirmation")
+ // TODO(b/262859270): Tracking Bug
+ @JvmField val FALSING_OFF_FOR_UNFOLDED = releasedFlag(225, "falsing_off_for_unfolded")
+
// 300 - power menu
// TODO(b/254512600): Tracking Bug
@JvmField val POWER_MENU_LITE = releasedFlag(300, "power_menu_lite")
@@ -260,10 +261,11 @@
// TODO(b/256614751): Tracking Bug
val NEW_STATUS_BAR_MOBILE_ICONS_BACKEND =
- unreleasedFlag(608, "new_status_bar_mobile_icons_backend")
+ unreleasedFlag(608, "new_status_bar_mobile_icons_backend", teamfood = true)
// TODO(b/256613548): Tracking Bug
- val NEW_STATUS_BAR_WIFI_ICON_BACKEND = unreleasedFlag(609, "new_status_bar_wifi_icon_backend")
+ val NEW_STATUS_BAR_WIFI_ICON_BACKEND =
+ unreleasedFlag(609, "new_status_bar_wifi_icon_backend", teamfood = true)
// TODO(b/256623670): Tracking Bug
@JvmField
@@ -302,7 +304,7 @@
// 900 - media
// TODO(b/254512697): Tracking Bug
- val MEDIA_TAP_TO_TRANSFER = unreleasedFlag(900, "media_tap_to_transfer", teamfood = true)
+ val MEDIA_TAP_TO_TRANSFER = releasedFlag(900, "media_tap_to_transfer")
// TODO(b/254512502): Tracking Bug
val MEDIA_SESSION_ACTIONS = unreleasedFlag(901, "media_session_actions")
@@ -332,13 +334,17 @@
val MEDIA_TTT_RECEIVER_SUCCESS_RIPPLE =
unreleasedFlag(910, "media_ttt_receiver_success_ripple", teamfood = true)
+ // TODO(b/263512203): Tracking Bug
+ val MEDIA_EXPLICIT_INDICATOR = unreleasedFlag(911, "media_explicit_indicator", teamfood = true)
+
// 1000 - dock
val SIMULATE_DOCK_THROUGH_CHARGING = releasedFlag(1000, "simulate_dock_through_charging")
// TODO(b/254512758): Tracking Bug
@JvmField val ROUNDED_BOX_RIPPLE = releasedFlag(1002, "rounded_box_ripple")
- val SHOW_LOWLIGHT_ON_DIRECT_BOOT = unreleasedFlag(1003, "show_lowlight_on_direct_boot")
+ // TODO(b/265045965): Tracking Bug
+ val SHOW_LOWLIGHT_ON_DIRECT_BOOT = releasedFlag(1003, "show_lowlight_on_direct_boot")
// 1100 - windowing
@Keep
@@ -436,9 +442,6 @@
unreleasedFlag(1206, "persist.wm.debug.predictive_back_bouncer_anim", teamfood = true)
// 1300 - screenshots
- // TODO(b/254512719): Tracking Bug
- @JvmField val SCREENSHOT_REQUEST_PROCESSOR = releasedFlag(1300, "screenshot_request_processor")
-
// TODO(b/254513155): Tracking Bug
@JvmField
val SCREENSHOT_WORK_PROFILE_POLICY =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 3d4347e..18854e5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -34,12 +34,14 @@
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE;
import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel.LOCKSCREEN_ANIMATION_DURATION_MS;
+import static com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel.DREAMING_ANIMATION_DURATION_MS;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.app.ActivityTaskManager;
import android.app.AlarmManager;
+import android.app.BroadcastOptions;
import android.app.PendingIntent;
import android.app.StatusBarManager;
import android.app.WindowConfiguration;
@@ -122,6 +124,8 @@
import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.keyguard.dagger.KeyguardModule;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -388,6 +392,12 @@
| Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
| Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
+ private static final Bundle USER_PRESENT_INTENT_OPTIONS =
+ BroadcastOptions.makeBasic()
+ .setDeferUntilActive(true)
+ .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
+ .toBundle();
+
/**
* {@link #setKeyguardEnabled} waits on this condition when it re-enables
* the keyguard.
@@ -507,6 +517,8 @@
private CentralSurfaces mCentralSurfaces;
+ private boolean mUnocclusionTransitionFlagEnabled = false;
+
private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
new DeviceConfig.OnPropertiesChangedListener() {
@Override
@@ -959,8 +971,9 @@
public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
- setOccluded(true /* isOccluded */, true /* animate */);
-
+ if (!mUnocclusionTransitionFlagEnabled) {
+ setOccluded(true /* isOccluded */, true /* animate */);
+ }
if (apps == null || apps.length == 0 || apps[0] == null) {
if (DEBUG) {
Log.d(TAG, "No apps provided to the OccludeByDream runner; "
@@ -1002,9 +1015,20 @@
applier.scheduleApply(paramsBuilder.build());
});
mOccludeByDreamAnimator.addListener(new AnimatorListenerAdapter() {
+ private boolean mIsCancelled = false;
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mIsCancelled = true;
+ }
+
@Override
public void onAnimationEnd(Animator animation) {
try {
+ if (!mIsCancelled && mUnocclusionTransitionFlagEnabled) {
+ // We're already on the main thread, don't queue this call
+ handleSetOccluded(true /* isOccluded */,
+ false /* animate */);
+ }
finishedCallback.onAnimationFinished();
mOccludeByDreamAnimator = null;
} catch (RemoteException e) {
@@ -1177,6 +1201,7 @@
ScreenOnCoordinator screenOnCoordinator,
InteractionJankMonitor interactionJankMonitor,
DreamOverlayStateController dreamOverlayStateController,
+ FeatureFlags featureFlags,
Lazy<ShadeController> shadeControllerLazy,
Lazy<NotificationShadeWindowController> notificationShadeWindowControllerLazy,
Lazy<ActivityLaunchAnimator> activityLaunchAnimator,
@@ -1231,9 +1256,9 @@
R.dimen.physical_power_button_center_screen_location_y);
mWindowCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context);
- mDreamOpenAnimationDuration = context.getResources().getInteger(
- com.android.internal.R.integer.config_dreamOpenAnimationDuration);
+ mDreamOpenAnimationDuration = (int) DREAMING_ANIMATION_DURATION_MS;
mDreamCloseAnimationDuration = (int) LOCKSCREEN_ANIMATION_DURATION_MS;
+ mUnocclusionTransitionFlagEnabled = featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION);
}
public void userActivity() {
@@ -1793,7 +1818,6 @@
Trace.beginSection("KeyguardViewMediator#setOccluded");
if (DEBUG) Log.d(TAG, "setOccluded " + isOccluded);
- mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_TRANSITION_FROM_AOD);
mHandler.removeMessages(SET_OCCLUDED);
Message msg = mHandler.obtainMessage(SET_OCCLUDED, isOccluded ? 1 : 0, animate ? 1 : 0);
mHandler.sendMessage(msg);
@@ -1826,6 +1850,8 @@
private void handleSetOccluded(boolean isOccluded, boolean animate) {
Trace.beginSection("KeyguardViewMediator#handleSetOccluded");
Log.d(TAG, "handleSetOccluded(" + isOccluded + ")");
+ mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_TRANSITION_FROM_AOD);
+
synchronized (KeyguardViewMediator.this) {
if (mHiding && isOccluded) {
// We're in the process of going away but WindowManager wants to show a
@@ -1902,13 +1928,23 @@
return;
}
- // if the keyguard is already showing, don't bother. check flags in both files
- // to account for the hiding animation which results in a delay and discrepancy
- // between flags
+ // If the keyguard is already showing, see if we don't need to bother re-showing it. Check
+ // flags in both files to account for the hiding animation which results in a delay and
+ // discrepancy between flags.
if (mShowing && mKeyguardStateController.isShowing()) {
- if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
- resetStateLocked();
- return;
+ if (mPM.isInteractive()) {
+ // It's already showing, and we're not trying to show it while the screen is off.
+ // We can simply reset all of the views.
+ if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
+ resetStateLocked();
+ return;
+ } else {
+ // We are trying to show the keyguard while the screen is off - this results from
+ // race conditions involving locking while unlocking. Don't short-circuit here and
+ // ensure the keyguard is fully re-shown.
+ Log.e(TAG,
+ "doKeyguard: already showing, but re-showing since we're not interactive");
+ }
}
// In split system user mode, we never unlock system user.
@@ -2300,7 +2336,10 @@
Context.USER_SERVICE);
mUiBgExecutor.execute(() -> {
for (int profileId : um.getProfileIdsWithDisabled(currentUser.getIdentifier())) {
- mContext.sendBroadcastAsUser(USER_PRESENT_INTENT, UserHandle.of(profileId));
+ mContext.sendBroadcastAsUser(USER_PRESENT_INTENT,
+ UserHandle.of(profileId),
+ null,
+ USER_PRESENT_INTENT_OPTIONS);
}
mLockPatternUtils.userPresent(currentUserId);
});
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
index 017b65a..ffd8a02 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
@@ -33,6 +33,7 @@
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.util.time.SystemClock;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -63,6 +64,7 @@
private final Context mContext;
private final DisplayMetrics mDisplayMetrics;
+ private final SystemClock mSystemClock;
@Nullable
private final IWallpaperManager mWallpaperManagerService;
@@ -71,6 +73,9 @@
private @PowerManager.WakeReason int mLastWakeReason = PowerManager.WAKE_REASON_UNKNOWN;
+ public static final long UNKNOWN_LAST_WAKE_TIME = -1;
+ private long mLastWakeTime = UNKNOWN_LAST_WAKE_TIME;
+
@Nullable
private Point mLastWakeOriginLocation = null;
@@ -84,10 +89,12 @@
public WakefulnessLifecycle(
Context context,
@Nullable IWallpaperManager wallpaperManagerService,
+ SystemClock systemClock,
DumpManager dumpManager) {
mContext = context;
mDisplayMetrics = context.getResources().getDisplayMetrics();
mWallpaperManagerService = wallpaperManagerService;
+ mSystemClock = systemClock;
dumpManager.registerDumpable(getClass().getSimpleName(), this);
}
@@ -104,6 +111,14 @@
}
/**
+ * Returns the most recent time (in device uptimeMillis) the display woke up.
+ * Returns {@link UNKNOWN_LAST_WAKE_TIME} if there hasn't been a wakeup yet.
+ */
+ public long getLastWakeTime() {
+ return mLastWakeTime;
+ }
+
+ /**
* Returns the most recent reason the device went to sleep up. This is one of
* PowerManager.GO_TO_SLEEP_REASON_*.
*/
@@ -117,6 +132,7 @@
}
setWakefulness(WAKEFULNESS_WAKING);
mLastWakeReason = pmWakeReason;
+ mLastWakeTime = mSystemClock.uptimeMillis();
updateLastWakeOriginLocation();
if (mWallpaperManagerService != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
index 47ef0fa..98d3570 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
@@ -39,6 +39,7 @@
import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.KeyguardViewMediator;
@@ -112,6 +113,7 @@
ScreenOnCoordinator screenOnCoordinator,
InteractionJankMonitor interactionJankMonitor,
DreamOverlayStateController dreamOverlayStateController,
+ FeatureFlags featureFlags,
Lazy<ShadeController> shadeController,
Lazy<NotificationShadeWindowController> notificationShadeWindowController,
Lazy<ActivityLaunchAnimator> activityLaunchAnimator,
@@ -142,6 +144,7 @@
screenOnCoordinator,
interactionJankMonitor,
dreamOverlayStateController,
+ featureFlags,
shadeController,
notificationShadeWindowController,
activityLaunchAnimator,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
index a4fd087..d99af90 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
@@ -40,6 +40,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.phone.BiometricUnlockController.WakeAndUnlockMode
+import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.policy.KeyguardStateController
import javax.inject.Inject
import kotlinx.coroutines.channels.awaitClose
@@ -88,6 +89,9 @@
/** Observable for whether the bouncer is showing. */
val isBouncerShowing: Flow<Boolean>
+ /** Is the always-on display available to be used? */
+ val isAodAvailable: Flow<Boolean>
+
/**
* Observable for whether we are in doze state.
*
@@ -182,6 +186,7 @@
private val keyguardStateController: KeyguardStateController,
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
private val dozeTransitionListener: DozeTransitionListener,
+ private val dozeParameters: DozeParameters,
private val authController: AuthController,
private val dreamOverlayCallbackController: DreamOverlayCallbackController,
) : KeyguardRepository {
@@ -220,6 +225,31 @@
}
.distinctUntilChanged()
+ override val isAodAvailable: Flow<Boolean> =
+ conflatedCallbackFlow {
+ val callback =
+ object : DozeParameters.Callback {
+ override fun onAlwaysOnChange() {
+ trySendWithFailureLogging(
+ dozeParameters.getAlwaysOn(),
+ TAG,
+ "updated isAodAvailable"
+ )
+ }
+ }
+
+ dozeParameters.addCallback(callback)
+ // Adding the callback does not send an initial update.
+ trySendWithFailureLogging(
+ dozeParameters.getAlwaysOn(),
+ TAG,
+ "initial isAodAvailable"
+ )
+
+ awaitClose { dozeParameters.removeCallback(callback) }
+ }
+ .distinctUntilChanged()
+
override val isKeyguardOccluded: Flow<Boolean> =
conflatedCallbackFlow {
val callback =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
index 343c2dc..d14b66a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
@@ -135,11 +135,14 @@
Log.i(TAG, "Duplicate call to start the transition, rejecting: $info")
return null
}
- if (lastStep.transitionState != TransitionState.FINISHED) {
- Log.i(TAG, "Transition still active: $lastStep, canceling")
- }
+ val startingValue =
+ if (lastStep.transitionState != TransitionState.FINISHED) {
+ Log.i(TAG, "Transition still active: $lastStep, canceling")
+ lastStep.value
+ } else {
+ 0f
+ }
- val startingValue = 1f - lastStep.value
lastAnimator?.cancel()
lastAnimator = info.animator
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
index fd2d271..ce61f2f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
@@ -21,9 +21,9 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
-import com.android.systemui.keyguard.shared.model.DozeStateModel.Companion.isDozeOff
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionInfo
+import com.android.systemui.keyguard.shared.model.WakefulnessModel.Companion.isWakingOrStartingToWake
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlin.time.Duration
@@ -48,12 +48,11 @@
private fun listenForDozingToLockscreen() {
scope.launch {
- keyguardInteractor.dozeTransitionModel
+ keyguardInteractor.wakefulnessModel
.sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
- .collect { pair ->
- val (dozeTransitionModel, lastStartedTransition) = pair
+ .collect { (wakefulnessModel, lastStartedTransition) ->
if (
- isDozeOff(dozeTransitionModel.to) &&
+ isWakingOrStartingToWake(wakefulnessModel) &&
lastStartedTransition.to == KeyguardState.DOZING
) {
keyguardTransitionRepository.startTransition(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
index 553fafe..9203a9b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
@@ -26,7 +26,10 @@
import com.android.systemui.keyguard.shared.model.WakefulnessState
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
@SysUISingleton
@@ -40,7 +43,7 @@
) : TransitionInteractor(FromGoneTransitionInteractor::class.simpleName!!) {
override fun start() {
- listenForGoneToAod()
+ listenForGoneToAodOrDozing()
listenForGoneToDreaming()
}
@@ -56,7 +59,7 @@
name,
KeyguardState.GONE,
KeyguardState.DREAMING,
- getAnimator(),
+ getAnimator(TO_DREAMING_DURATION),
)
)
}
@@ -64,12 +67,18 @@
}
}
- private fun listenForGoneToAod() {
+ private fun listenForGoneToAodOrDozing() {
scope.launch {
keyguardInteractor.wakefulnessModel
- .sample(keyguardTransitionInteractor.finishedKeyguardState, ::Pair)
- .collect { pair ->
- val (wakefulnessState, keyguardState) = pair
+ .sample(
+ combine(
+ keyguardTransitionInteractor.finishedKeyguardState,
+ keyguardInteractor.isAodAvailable,
+ ::Pair
+ ),
+ ::toTriple
+ )
+ .collect { (wakefulnessState, keyguardState, isAodAvailable) ->
if (
keyguardState == KeyguardState.GONE &&
wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP
@@ -78,7 +87,11 @@
TransitionInfo(
name,
KeyguardState.GONE,
- KeyguardState.AOD,
+ if (isAodAvailable) {
+ KeyguardState.AOD
+ } else {
+ KeyguardState.DOZING
+ },
getAnimator(),
)
)
@@ -87,14 +100,15 @@
}
}
- private fun getAnimator(): ValueAnimator {
+ private fun getAnimator(duration: Duration = DEFAULT_DURATION): ValueAnimator {
return ValueAnimator().apply {
setInterpolator(Interpolators.LINEAR)
- setDuration(TRANSITION_DURATION_MS)
+ setDuration(duration.inWholeMilliseconds)
}
}
companion object {
- private const val TRANSITION_DURATION_MS = 500L
+ private val DEFAULT_DURATION = 500.milliseconds
+ val TO_DREAMING_DURATION = 933.milliseconds
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
index 326acc9..64028ce 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
@@ -21,15 +21,17 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
-import com.android.systemui.keyguard.shared.model.DozeStateModel
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.StatusBarState.KEYGUARD
import com.android.systemui.keyguard.shared.model.TransitionInfo
import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.WakefulnessState
import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.util.kotlin.sample
import java.util.UUID
import javax.inject.Inject
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.combine
@@ -51,7 +53,8 @@
override fun start() {
listenForLockscreenToGone()
listenForLockscreenToOccluded()
- listenForLockscreenToAod()
+ listenForLockscreenToCamera()
+ listenForLockscreenToAodOrDozing()
listenForLockscreenToBouncer()
listenForLockscreenToDreaming()
listenForLockscreenToBouncerDragging()
@@ -69,7 +72,7 @@
name,
KeyguardState.LOCKSCREEN,
KeyguardState.DREAMING,
- getAnimator(),
+ getAnimator(TO_DREAMING_DURATION),
)
)
}
@@ -184,17 +187,14 @@
),
::toTriple
)
- .collect { triple ->
- val (isOccluded, keyguardState, isDreaming) = triple
- // Occlusion signals come from the framework, and should interrupt any
- // existing transition
- if (isOccluded && !isDreaming) {
+ .collect { (isOccluded, keyguardState, isDreaming) ->
+ if (isOccluded && !isDreaming && keyguardState == KeyguardState.LOCKSCREEN) {
keyguardTransitionRepository.startTransition(
TransitionInfo(
name,
keyguardState,
KeyguardState.OCCLUDED,
- getAnimator(),
+ getAnimator(TO_OCCLUDED_DURATION),
)
)
}
@@ -202,19 +202,59 @@
}
}
- private fun listenForLockscreenToAod() {
+ /** This signal may come in before the occlusion signal, and can provide a custom transition */
+ private fun listenForLockscreenToCamera() {
scope.launch {
- keyguardInteractor
- .dozeTransitionTo(DozeStateModel.DOZE_AOD)
+ keyguardInteractor.onCameraLaunchDetected
.sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
- .collect { pair ->
- val (dozeToAod, lastStartedStep) = pair
- if (lastStartedStep.to == KeyguardState.LOCKSCREEN) {
+ .collect { (_, lastStartedStep) ->
+ // DREAMING/AOD/OFF may trigger on the first power button push, so include this
+ // state in order to cancel and correct the transition
+ if (
+ lastStartedStep.to == KeyguardState.LOCKSCREEN ||
+ lastStartedStep.to == KeyguardState.DREAMING ||
+ lastStartedStep.to == KeyguardState.DOZING ||
+ lastStartedStep.to == KeyguardState.AOD ||
+ lastStartedStep.to == KeyguardState.OFF
+ ) {
keyguardTransitionRepository.startTransition(
TransitionInfo(
name,
KeyguardState.LOCKSCREEN,
- KeyguardState.AOD,
+ KeyguardState.OCCLUDED,
+ getAnimator(TO_OCCLUDED_DURATION),
+ )
+ )
+ }
+ }
+ }
+ }
+
+ private fun listenForLockscreenToAodOrDozing() {
+ scope.launch {
+ keyguardInteractor.wakefulnessModel
+ .sample(
+ combine(
+ keyguardTransitionInteractor.startedKeyguardTransitionStep,
+ keyguardInteractor.isAodAvailable,
+ ::Pair
+ ),
+ ::toTriple
+ )
+ .collect { (wakefulnessState, lastStartedStep, isAodAvailable) ->
+ if (
+ lastStartedStep.to == KeyguardState.LOCKSCREEN &&
+ wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP
+ ) {
+ keyguardTransitionRepository.startTransition(
+ TransitionInfo(
+ name,
+ KeyguardState.LOCKSCREEN,
+ if (isAodAvailable) {
+ KeyguardState.AOD
+ } else {
+ KeyguardState.DOZING
+ },
getAnimator(),
)
)
@@ -223,14 +263,16 @@
}
}
- private fun getAnimator(): ValueAnimator {
+ private fun getAnimator(duration: Duration = DEFAULT_DURATION): ValueAnimator {
return ValueAnimator().apply {
setInterpolator(Interpolators.LINEAR)
- setDuration(TRANSITION_DURATION_MS)
+ setDuration(duration.inWholeMilliseconds)
}
}
companion object {
- private const val TRANSITION_DURATION_MS = 500L
+ private val DEFAULT_DURATION = 500.milliseconds
+ val TO_DREAMING_DURATION = 933.milliseconds
+ val TO_OCCLUDED_DURATION = 450.milliseconds
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
index 8878901..2dc8fee 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
@@ -23,12 +23,14 @@
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionInfo
+import com.android.systemui.keyguard.shared.model.WakefulnessState
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
@SysUISingleton
@@ -44,6 +46,7 @@
override fun start() {
listenForOccludedToLockscreen()
listenForOccludedToDreaming()
+ listenForOccludedToAodOrDozing()
}
private fun listenForOccludedToDreaming() {
@@ -70,8 +73,7 @@
scope.launch {
keyguardInteractor.isKeyguardOccluded
.sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
- .collect { pair ->
- val (isOccluded, lastStartedKeyguardState) = pair
+ .collect { (isOccluded, lastStartedKeyguardState) ->
// Occlusion signals come from the framework, and should interrupt any
// existing transition
if (!isOccluded && lastStartedKeyguardState.to == KeyguardState.OCCLUDED) {
@@ -88,6 +90,39 @@
}
}
+ private fun listenForOccludedToAodOrDozing() {
+ scope.launch {
+ keyguardInteractor.wakefulnessModel
+ .sample(
+ combine(
+ keyguardTransitionInteractor.startedKeyguardTransitionStep,
+ keyguardInteractor.isAodAvailable,
+ ::Pair
+ ),
+ ::toTriple
+ )
+ .collect { (wakefulnessState, lastStartedStep, isAodAvailable) ->
+ if (
+ lastStartedStep.to == KeyguardState.OCCLUDED &&
+ wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP
+ ) {
+ keyguardTransitionRepository.startTransition(
+ TransitionInfo(
+ name,
+ KeyguardState.OCCLUDED,
+ if (isAodAvailable) {
+ KeyguardState.AOD
+ } else {
+ KeyguardState.DOZING
+ },
+ getAnimator(),
+ )
+ )
+ }
+ }
+ }
+ }
+
private fun getAnimator(duration: Duration = DEFAULT_DURATION): ValueAnimator {
return ValueAnimator().apply {
setInterpolator(Interpolators.LINEAR)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index 402c179..490d22e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -17,17 +17,24 @@
package com.android.systemui.keyguard.domain.interactor
+import android.app.StatusBarManager
import android.graphics.Point
+import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
+import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel
import com.android.systemui.keyguard.shared.model.DozeStateModel
import com.android.systemui.keyguard.shared.model.DozeStateModel.Companion.isDozeOff
import com.android.systemui.keyguard.shared.model.DozeTransitionModel
import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.keyguard.shared.model.WakefulnessModel
+import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.statusbar.CommandQueue.Callbacks
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
+import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
@@ -41,6 +48,7 @@
@Inject
constructor(
private val repository: KeyguardRepository,
+ private val commandQueue: CommandQueue,
) {
/**
* The amount of doze the system is in, where `1.0` is fully dozing and `0.0` is not dozing at
@@ -49,6 +57,8 @@
val dozeAmount: Flow<Float> = repository.linearDozeAmount
/** Whether the system is in doze mode. */
val isDozing: Flow<Boolean> = repository.isDozing
+ /** Whether Always-on Display mode is available. */
+ val isAodAvailable: Flow<Boolean> = repository.isAodAvailable
/** Doze transition information. */
val dozeTransitionModel: Flow<DozeTransitionModel> = repository.dozeTransitionModel
/**
@@ -58,6 +68,23 @@
val isDreaming: Flow<Boolean> = repository.isDreaming
/** Whether the system is dreaming with an overlay active */
val isDreamingWithOverlay: Flow<Boolean> = repository.isDreamingWithOverlay
+ /** Event for when the camera gesture is detected */
+ val onCameraLaunchDetected: Flow<CameraLaunchSourceModel> = conflatedCallbackFlow {
+ val callback =
+ object : CommandQueue.Callbacks {
+ override fun onCameraLaunchGestureDetected(source: Int) {
+ trySendWithFailureLogging(
+ cameraLaunchSourceIntToModel(source),
+ TAG,
+ "updated onCameraLaunchGestureDetected"
+ )
+ }
+ }
+
+ commandQueue.addCallback(callback)
+
+ awaitClose { commandQueue.removeCallback(callback) }
+ }
/**
* Dozing and dreaming have overlapping events. If the doze state remains in FINISH, it means
@@ -103,4 +130,21 @@
fun isKeyguardShowing(): Boolean {
return repository.isKeyguardShowing()
}
+
+ private fun cameraLaunchSourceIntToModel(value: Int): CameraLaunchSourceModel {
+ return when (value) {
+ StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE -> CameraLaunchSourceModel.WIGGLE
+ StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP ->
+ CameraLaunchSourceModel.POWER_DOUBLE_TAP
+ StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER ->
+ CameraLaunchSourceModel.LIFT_TRIGGER
+ StatusBarManager.CAMERA_LAUNCH_SOURCE_QUICK_AFFORDANCE ->
+ CameraLaunchSourceModel.QUICK_AFFORDANCE
+ else -> throw IllegalArgumentException("Invalid CameraLaunchSourceModel value: $value")
+ }
+ }
+
+ companion object {
+ private const val TAG = "KeyguardInteractor"
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
index a2661d7..d4e23499 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
@@ -19,11 +19,14 @@
import com.android.keyguard.logging.KeyguardLogger
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.plugins.log.LogLevel.VERBOSE
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
+private val TAG = KeyguardTransitionAuditLogger::class.simpleName!!
+
/** Collect flows of interest for auditing keyguard transitions. */
@SysUISingleton
class KeyguardTransitionAuditLogger
@@ -37,35 +40,47 @@
fun start() {
scope.launch {
- keyguardInteractor.wakefulnessModel.collect { logger.v("WakefulnessModel", it) }
+ keyguardInteractor.wakefulnessModel.collect {
+ logger.log(TAG, VERBOSE, "WakefulnessModel", it)
+ }
}
scope.launch {
- keyguardInteractor.isBouncerShowing.collect { logger.v("Bouncer showing", it) }
+ keyguardInteractor.isBouncerShowing.collect {
+ logger.log(TAG, VERBOSE, "Bouncer showing", it)
+ }
}
- scope.launch { keyguardInteractor.isDozing.collect { logger.v("isDozing", it) } }
+ scope.launch {
+ keyguardInteractor.isDozing.collect { logger.log(TAG, VERBOSE, "isDozing", it) }
+ }
- scope.launch { keyguardInteractor.isDreaming.collect { logger.v("isDreaming", it) } }
+ scope.launch {
+ keyguardInteractor.isDreaming.collect { logger.log(TAG, VERBOSE, "isDreaming", it) }
+ }
scope.launch {
interactor.finishedKeyguardTransitionStep.collect {
- logger.i("Finished transition", it)
+ logger.log(TAG, VERBOSE, "Finished transition", it)
}
}
scope.launch {
interactor.canceledKeyguardTransitionStep.collect {
- logger.i("Canceled transition", it)
+ logger.log(TAG, VERBOSE, "Canceled transition", it)
}
}
scope.launch {
- interactor.startedKeyguardTransitionStep.collect { logger.i("Started transition", it) }
+ interactor.startedKeyguardTransitionStep.collect {
+ logger.log(TAG, VERBOSE, "Started transition", it)
+ }
}
scope.launch {
- keyguardInteractor.dozeTransitionModel.collect { logger.i("Doze transition", it) }
+ keyguardInteractor.dozeTransitionModel.collect {
+ logger.log(TAG, VERBOSE, "Doze transition", it)
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
index 04024be..9cdbcda 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
@@ -42,24 +42,32 @@
constructor(
repository: KeyguardTransitionRepository,
) {
+ /** (any)->AOD transition information */
+ val anyStateToAodTransition: Flow<TransitionStep> =
+ repository.transitions.filter { step -> step.to == KeyguardState.AOD }
+
/** AOD->LOCKSCREEN transition information. */
val aodToLockscreenTransition: Flow<TransitionStep> = repository.transition(AOD, LOCKSCREEN)
- /** LOCKSCREEN->AOD transition information. */
- val lockscreenToAodTransition: Flow<TransitionStep> = repository.transition(LOCKSCREEN, AOD)
-
/** DREAMING->LOCKSCREEN transition information. */
val dreamingToLockscreenTransition: Flow<TransitionStep> =
repository.transition(DREAMING, LOCKSCREEN)
+ /** LOCKSCREEN->AOD transition information. */
+ val lockscreenToAodTransition: Flow<TransitionStep> = repository.transition(LOCKSCREEN, AOD)
+
+ /** LOCKSCREEN->DREAMING transition information. */
+ val lockscreenToDreamingTransition: Flow<TransitionStep> =
+ repository.transition(LOCKSCREEN, DREAMING)
+
+ /** LOCKSCREEN->OCCLUDED transition information. */
+ val lockscreenToOccludedTransition: Flow<TransitionStep> =
+ repository.transition(LOCKSCREEN, OCCLUDED)
+
/** OCCLUDED->LOCKSCREEN transition information. */
val occludedToLockscreenTransition: Flow<TransitionStep> =
repository.transition(OCCLUDED, LOCKSCREEN)
- /** (any)->AOD transition information */
- val anyStateToAodTransition: Flow<TransitionStep> =
- repository.transitions.filter { step -> step.to == KeyguardState.AOD }
-
/**
* AOD<->LOCKSCREEN transition information, mapped to dozeAmount range of AOD (1f) <->
* Lockscreen (0f).
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/CameraLaunchSourceModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/CameraLaunchSourceModel.kt
new file mode 100644
index 0000000..19baf77
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/CameraLaunchSourceModel.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 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.systemui.keyguard.shared.model
+
+/** Camera launch sources */
+enum class CameraLaunchSourceModel {
+ /** Device is wiggled */
+ WIGGLE,
+ /** Power button has been double tapped */
+ POWER_DOUBLE_TAP,
+ /** Device has been lifted */
+ LIFT_TRIGGER,
+ /** Quick affordance button has been pressed */
+ QUICK_AFFORDANCE,
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
index 0e4058b..9d8bf7d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
@@ -45,7 +45,6 @@
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.VibratorHelper
-import com.android.systemui.util.kotlin.pairwise
import kotlin.math.pow
import kotlin.math.sqrt
import kotlin.time.Duration.Companion.milliseconds
@@ -129,18 +128,6 @@
}
launch {
- viewModel.startButton
- .map { it.isActivated }
- .pairwise()
- .collect { (prev, next) ->
- when {
- !prev && next -> vibratorHelper?.vibrate(Vibrations.Activated)
- prev && !next -> vibratorHelper?.vibrate(Vibrations.Deactivated)
- }
- }
- }
-
- launch {
viewModel.endButton.collect { buttonModel ->
updateButton(
view = endButton,
@@ -153,18 +140,6 @@
}
launch {
- viewModel.endButton
- .map { it.isActivated }
- .pairwise()
- .collect { (prev, next) ->
- when {
- !prev && next -> vibratorHelper?.vibrate(Vibrations.Activated)
- prev && !next -> vibratorHelper?.vibrate(Vibrations.Deactivated)
- }
- }
- }
-
- launch {
viewModel.isOverlayContainerVisible.collect { isVisible ->
overlayContainer.visibility =
if (isVisible) {
@@ -383,6 +358,13 @@
.setDuration(longPressDurationMs)
.withEndAction {
view.setOnClickListener {
+ vibratorHelper?.vibrate(
+ if (viewModel.isActivated) {
+ Vibrations.Activated
+ } else {
+ Vibrations.Deactivated
+ }
+ )
viewModel.onClicked(
KeyguardQuickAffordanceViewModel.OnClickedParameters(
configKey = viewModel.configKey,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt
new file mode 100644
index 0000000..d48f87d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModel.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023 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.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor.Companion.TO_DREAMING_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.AnimationParams
+import com.android.systemui.keyguard.shared.model.TransitionState
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
+
+/**
+ * Breaks down LOCKSCREEN->DREAMING transition into discrete steps for corresponding views to
+ * consume.
+ */
+@SysUISingleton
+class LockscreenToDreamingTransitionViewModel
+@Inject
+constructor(
+ private val interactor: KeyguardTransitionInteractor,
+) {
+
+ /** Lockscreen views y-translation */
+ fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
+ return merge(
+ flowForAnimation(LOCKSCREEN_TRANSLATION_Y).map { value ->
+ (EMPHASIZED_ACCELERATE.getInterpolation(value) * translatePx)
+ },
+ // On end, reset the translation to 0
+ interactor.lockscreenToDreamingTransition
+ .filter { step -> step.transitionState == TransitionState.FINISHED }
+ .map { 0f }
+ )
+ }
+
+ /** Lockscreen views alpha */
+ val lockscreenAlpha: Flow<Float> = flowForAnimation(LOCKSCREEN_ALPHA).map { 1f - it }
+
+ private fun flowForAnimation(params: AnimationParams): Flow<Float> {
+ return interactor.transitionStepAnimation(
+ interactor.lockscreenToDreamingTransition,
+ params,
+ totalDuration = TO_DREAMING_DURATION
+ )
+ }
+
+ companion object {
+ @JvmField val DREAMING_ANIMATION_DURATION_MS = TO_DREAMING_DURATION.inWholeMilliseconds
+
+ val LOCKSCREEN_TRANSLATION_Y = AnimationParams(duration = 500.milliseconds)
+ val LOCKSCREEN_ALPHA = AnimationParams(duration = 250.milliseconds)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
new file mode 100644
index 0000000..22d292e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModel.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2023 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.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor.Companion.TO_OCCLUDED_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.AnimationParams
+import com.android.systemui.keyguard.shared.model.TransitionState
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
+
+/**
+ * Breaks down LOCKSCREEN->OCCLUDED transition into discrete steps for corresponding views to
+ * consume.
+ */
+@SysUISingleton
+class LockscreenToOccludedTransitionViewModel
+@Inject
+constructor(
+ private val interactor: KeyguardTransitionInteractor,
+) {
+
+ /** Lockscreen views y-translation */
+ fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
+ return merge(
+ flowForAnimation(LOCKSCREEN_TRANSLATION_Y).map { value ->
+ (EMPHASIZED_ACCELERATE.getInterpolation(value) * translatePx)
+ },
+ // On end, reset the translation to 0
+ interactor.lockscreenToOccludedTransition
+ .filter { step -> step.transitionState == TransitionState.FINISHED }
+ .map { 0f }
+ )
+ }
+
+ /** Lockscreen views alpha */
+ val lockscreenAlpha: Flow<Float> = flowForAnimation(LOCKSCREEN_ALPHA).map { 1f - it }
+
+ private fun flowForAnimation(params: AnimationParams): Flow<Float> {
+ return interactor.transitionStepAnimation(
+ interactor.lockscreenToOccludedTransition,
+ params,
+ totalDuration = TO_OCCLUDED_DURATION
+ )
+ }
+
+ companion object {
+ val LOCKSCREEN_TRANSLATION_Y = AnimationParams(duration = TO_OCCLUDED_DURATION)
+ val LOCKSCREEN_ALPHA = AnimationParams(duration = 250.milliseconds)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardClockLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardClockLog.kt
index 0645236..9f563fe4 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardClockLog.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/KeyguardClockLog.kt
@@ -23,3 +23,15 @@
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
annotation class KeyguardClockLog
+
+/** A [com.android.systemui.plugins.log.LogBuffer] for small keyguard clock logs. */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class KeyguardSmallClockLog
+
+/** A [com.android.systemui.plugins.log.LogBuffer] for large keyguard clock logs. */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class KeyguardLargeClockLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index 711bca0..afbd8ed 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -335,13 +335,33 @@
}
/**
- * Provides a {@link LogBuffer} for keyguard clock logs.
+ * Provides a {@link LogBuffer} for general keyguard clock logs.
*/
@Provides
@SysUISingleton
@KeyguardClockLog
public static LogBuffer provideKeyguardClockLog(LogBufferFactory factory) {
- return factory.create("KeyguardClockLog", 500);
+ return factory.create("KeyguardClockLog", 100);
+ }
+
+ /**
+ * Provides a {@link LogBuffer} for keyguard small clock logs.
+ */
+ @Provides
+ @SysUISingleton
+ @KeyguardSmallClockLog
+ public static LogBuffer provideKeyguardSmallClockLog(LogBufferFactory factory) {
+ return factory.create("KeyguardSmallClockLog", 100);
+ }
+
+ /**
+ * Provides a {@link LogBuffer} for keyguard large clock logs.
+ */
+ @Provides
+ @SysUISingleton
+ @KeyguardLargeClockLog
+ public static LogBuffer provideKeyguardLargeClockLog(LogBufferFactory factory) {
+ return factory.create("KeyguardLargeClockLog", 100);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt
index 7a90a74..7ccc43c 100644
--- a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt
@@ -29,6 +29,18 @@
private val dumpManager: DumpManager,
private val systemClock: SystemClock,
) {
+ private val existingBuffers = mutableMapOf<String, TableLogBuffer>()
+
+ /**
+ * Creates a new [TableLogBuffer]. This method should only be called from static contexts, where
+ * it is guaranteed only to be created one time. See [getOrCreate] for a cache-aware method of
+ * obtaining a buffer.
+ *
+ * @param name a unique table name
+ * @param maxSize the buffer max size. See [adjustMaxSize]
+ *
+ * @return a new [TableLogBuffer] registered with [DumpManager]
+ */
fun create(
name: String,
maxSize: Int,
@@ -37,4 +49,23 @@
dumpManager.registerNormalDumpable(name, tableBuffer)
return tableBuffer
}
+
+ /**
+ * Log buffers are retained indefinitely by [DumpManager], so that they can be represented in
+ * bugreports. Because of this, many of them are created statically in the Dagger graph.
+ *
+ * In the case where you have to create a logbuffer with a name only known at runtime, this
+ * method can be used to lazily create a table log buffer which is then cached for reuse.
+ *
+ * @return a [TableLogBuffer] suitable for reuse
+ */
+ fun getOrCreate(
+ name: String,
+ maxSize: Int,
+ ): TableLogBuffer =
+ existingBuffers.getOrElse(name) {
+ val buffer = create(name, maxSize)
+ existingBuffers[name] = buffer
+ buffer
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaData.kt
index f006442..be18cbe 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaData.kt
@@ -88,7 +88,10 @@
val instanceId: InstanceId,
/** The UID of the app, used for logging */
- val appUid: Int
+ val appUid: Int,
+
+ /** Whether explicit indicator exists */
+ val isExplicit: Boolean = false,
) {
companion object {
/** Media is playing on the local device */
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaViewHolder.kt
index a8f39fa9a..1c8bfd1 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/MediaViewHolder.kt
@@ -24,6 +24,7 @@
import android.widget.SeekBar
import android.widget.TextView
import androidx.constraintlayout.widget.Barrier
+import com.android.internal.widget.CachingIconView
import com.android.systemui.R
import com.android.systemui.media.controls.models.GutsViewHolder
import com.android.systemui.surfaceeffects.ripple.MultiRippleView
@@ -44,6 +45,7 @@
val appIcon = itemView.requireViewById<ImageView>(R.id.icon)
val titleText = itemView.requireViewById<TextView>(R.id.header_title)
val artistText = itemView.requireViewById<TextView>(R.id.header_artist)
+ val explicitIndicator = itemView.requireViewById<CachingIconView>(R.id.media_explicit_indicator)
// Output switcher
val seamless = itemView.requireViewById<ViewGroup>(R.id.media_seamless)
@@ -123,6 +125,7 @@
R.id.app_name,
R.id.header_title,
R.id.header_artist,
+ R.id.media_explicit_indicator,
R.id.media_seamless,
R.id.media_progress_bar,
R.id.actionPlayPause,
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
index 1cc8a13..9f28d46 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
@@ -46,6 +46,7 @@
import android.os.UserHandle
import android.provider.Settings
import android.service.notification.StatusBarNotification
+import android.support.v4.media.MediaMetadataCompat
import android.text.TextUtils
import android.util.Log
import androidx.media.utils.MediaConstants
@@ -661,6 +662,10 @@
val currentEntry = mediaEntries.get(packageName)
val instanceId = currentEntry?.instanceId ?: logger.getNewInstanceId()
val appUid = currentEntry?.appUid ?: Process.INVALID_UID
+ val isExplicit =
+ desc.extras?.getLong(MediaConstants.METADATA_KEY_IS_EXPLICIT) ==
+ MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT &&
+ mediaFlags.isExplicitIndicatorEnabled()
val mediaAction = getResumeMediaAction(resumeAction)
val lastActive = systemClock.elapsedRealtime()
@@ -690,7 +695,8 @@
hasCheckedForResume = true,
lastActive = lastActive,
instanceId = instanceId,
- appUid = appUid
+ appUid = appUid,
+ isExplicit = isExplicit,
)
)
}
@@ -751,6 +757,15 @@
song = HybridGroupManager.resolveTitle(notif)
}
+ // Explicit Indicator
+ var isExplicit = false
+ if (mediaFlags.isExplicitIndicatorEnabled()) {
+ val mediaMetadataCompat = MediaMetadataCompat.fromMediaMetadata(metadata)
+ isExplicit =
+ mediaMetadataCompat?.getLong(MediaConstants.METADATA_KEY_IS_EXPLICIT) ==
+ MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT
+ }
+
// Artist name
var artist: CharSequence? = metadata?.getString(MediaMetadata.METADATA_KEY_ARTIST)
if (artist == null) {
@@ -852,7 +867,8 @@
isClearable = sbn.isClearable(),
lastActive = lastActive,
instanceId = instanceId,
- appUid = appUid
+ appUid = appUid,
+ isExplicit = isExplicit,
)
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
index d5558b2..e7f7647 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
@@ -94,7 +94,7 @@
private var currentCarouselWidth: Int = 0
/** The current height of the carousel */
- private var currentCarouselHeight: Int = 0
+ @VisibleForTesting var currentCarouselHeight: Int = 0
/** Are we currently showing only active players */
private var currentlyShowingOnlyActive: Boolean = false
@@ -128,14 +128,14 @@
/** The measured height of the carousel */
private var carouselMeasureHeight: Int = 0
private var desiredHostState: MediaHostState? = null
- private val mediaCarousel: MediaScrollView
+ @VisibleForTesting var mediaCarousel: MediaScrollView
val mediaCarouselScrollHandler: MediaCarouselScrollHandler
val mediaFrame: ViewGroup
@VisibleForTesting
lateinit var settingsButton: View
private set
private val mediaContent: ViewGroup
- @VisibleForTesting val pageIndicator: PageIndicator
+ @VisibleForTesting var pageIndicator: PageIndicator
private val visualStabilityCallback: OnReorderingAllowedListener
private var needsReordering: Boolean = false
private var keysNeedRemoval = mutableSetOf<String>()
@@ -160,25 +160,20 @@
}
companion object {
- const val ANIMATION_BASE_DURATION = 2200f
- const val DURATION = 167f
- const val DETAILS_DELAY = 1067f
- const val CONTROLS_DELAY = 1400f
- const val PAGINATION_DELAY = 1900f
- const val MEDIATITLES_DELAY = 1000f
- const val MEDIACONTAINERS_DELAY = 967f
val TRANSFORM_BEZIER = PathInterpolator(0.68F, 0F, 0F, 1F)
- val REVERSE_BEZIER = PathInterpolator(0F, 0.68F, 1F, 0F)
- fun calculateAlpha(squishinessFraction: Float, delay: Float, duration: Float): Float {
- val transformStartFraction = delay / ANIMATION_BASE_DURATION
- val transformDurationFraction = duration / ANIMATION_BASE_DURATION
- val squishinessToTime = REVERSE_BEZIER.getInterpolation(squishinessFraction)
- return MathUtils.constrain(
- (squishinessToTime - transformStartFraction) / transformDurationFraction,
- 0F,
- 1F
- )
+ fun calculateAlpha(
+ squishinessFraction: Float,
+ startPosition: Float,
+ endPosition: Float
+ ): Float {
+ val transformFraction =
+ MathUtils.constrain(
+ (squishinessFraction - startPosition) / (endPosition - startPosition),
+ 0F,
+ 1F
+ )
+ return TRANSFORM_BEZIER.getInterpolation(transformFraction)
}
}
@@ -813,7 +808,12 @@
val squishFraction = hostStates[currentEndLocation]?.squishFraction ?: 1.0F
val endAlpha =
(if (endIsVisible) 1.0f else 0.0f) *
- calculateAlpha(squishFraction, PAGINATION_DELAY, DURATION)
+ calculateAlpha(
+ squishFraction,
+ (pageIndicator.translationY + pageIndicator.height) /
+ mediaCarousel.measuredHeight,
+ 1F
+ )
var alpha = 1.0f
if (!endIsVisible || !startIsVisible) {
var progress = currentTransitionProgress
@@ -839,7 +839,8 @@
pageIndicator.translationX = translationX + mediaCarouselScrollHandler.contentTranslation
val layoutParams = pageIndicator.layoutParams as ViewGroup.MarginLayoutParams
pageIndicator.translationY =
- (currentCarouselHeight - pageIndicator.height - layoutParams.bottomMargin).toFloat()
+ (mediaCarousel.measuredHeight - pageIndicator.height - layoutParams.bottomMargin)
+ .toFloat()
}
/** Update the dimension of this carousel. */
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
index ee0147f..9d1ebb6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
@@ -51,7 +51,6 @@
import android.os.Trace;
import android.text.TextUtils;
import android.util.Log;
-import android.util.Pair;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
@@ -69,6 +68,7 @@
import com.android.internal.graphics.ColorUtils;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.InstanceId;
+import com.android.internal.widget.CachingIconView;
import com.android.settingslib.widget.AdaptiveIcon;
import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.R;
@@ -123,6 +123,7 @@
import javax.inject.Inject;
+import kotlin.Triple;
import kotlin.Unit;
/**
@@ -400,10 +401,11 @@
TextView titleText = mMediaViewHolder.getTitleText();
TextView artistText = mMediaViewHolder.getArtistText();
+ CachingIconView explicitIndicator = mMediaViewHolder.getExplicitIndicator();
AnimatorSet enter = loadAnimator(R.anim.media_metadata_enter,
- Interpolators.EMPHASIZED_DECELERATE, titleText, artistText);
+ Interpolators.EMPHASIZED_DECELERATE, titleText, artistText, explicitIndicator);
AnimatorSet exit = loadAnimator(R.anim.media_metadata_exit,
- Interpolators.EMPHASIZED_ACCELERATE, titleText, artistText);
+ Interpolators.EMPHASIZED_ACCELERATE, titleText, artistText, explicitIndicator);
MultiRippleView multiRippleView = vh.getMultiRippleView();
mMultiRippleController = new MultiRippleController(multiRippleView);
@@ -668,11 +670,15 @@
private boolean bindSongMetadata(MediaData data) {
TextView titleText = mMediaViewHolder.getTitleText();
TextView artistText = mMediaViewHolder.getArtistText();
+ ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
+ ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
return mMetadataAnimationHandler.setNext(
- Pair.create(data.getSong(), data.getArtist()),
+ new Triple(data.getSong(), data.getArtist(), data.isExplicit()),
() -> {
titleText.setText(data.getSong());
artistText.setText(data.getArtist());
+ setVisibleAndAlpha(expandedSet, R.id.media_explicit_indicator, data.isExplicit());
+ setVisibleAndAlpha(collapsedSet, R.id.media_explicit_indicator, data.isExplicit());
// refreshState is required here to resize the text views (and prevent ellipsis)
mMediaViewController.refreshState();
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
index f7a9bc7..66f12d6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
@@ -41,6 +41,7 @@
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dreams.DreamOverlayStateController
import com.android.systemui.keyguard.WakefulnessLifecycle
+import com.android.systemui.media.controls.pipeline.MediaDataManager
import com.android.systemui.media.dream.MediaDreamComplication
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.shade.ShadeStateEvents
@@ -93,6 +94,7 @@
private val keyguardStateController: KeyguardStateController,
private val bypassController: KeyguardBypassController,
private val mediaCarouselController: MediaCarouselController,
+ private val mediaManager: MediaDataManager,
private val keyguardViewController: KeyguardViewController,
private val dreamOverlayStateController: DreamOverlayStateController,
configurationController: ConfigurationController,
@@ -224,9 +226,9 @@
private var inSplitShade = false
- /** Is there any active media in the carousel? */
- private var hasActiveMedia: Boolean = false
- get() = mediaHosts.get(LOCATION_QQS)?.visible == true
+ /** Is there any active media or recommendation in the carousel? */
+ private var hasActiveMediaOrRecommendation: Boolean = false
+ get() = mediaManager.hasActiveMediaOrRecommendation()
/** Are we currently waiting on an animation to start? */
private var animationPending: Boolean = false
@@ -582,12 +584,8 @@
val viewHost = createUniqueObjectHost()
mediaObject.hostView = viewHost
mediaObject.addVisibilityChangeListener {
- // If QQS changes visibility, we need to force an update to ensure the transition
- // goes into the correct state
- val stateUpdate = mediaObject.location == LOCATION_QQS
-
// Never animate because of a visibility change, only state changes should do that
- updateDesiredLocation(forceNoAnimation = true, forceStateUpdate = stateUpdate)
+ updateDesiredLocation(forceNoAnimation = true)
}
mediaHosts[mediaObject.location] = mediaObject
if (mediaObject.location == desiredLocation) {
@@ -908,7 +906,7 @@
fun isCurrentlyInGuidedTransformation(): Boolean {
return hasValidStartAndEndLocations() &&
getTransformationProgress() >= 0 &&
- areGuidedTransitionHostsVisible()
+ (areGuidedTransitionHostsVisible() || !hasActiveMediaOrRecommendation)
}
private fun hasValidStartAndEndLocations(): Boolean {
@@ -965,7 +963,7 @@
private fun getQSTransformationProgress(): Float {
val currentHost = getHost(desiredLocation)
val previousHost = getHost(previousLocation)
- if (hasActiveMedia && (currentHost?.location == LOCATION_QS && !inSplitShade)) {
+ if (currentHost?.location == LOCATION_QS && !inSplitShade) {
if (previousHost?.location == LOCATION_QQS) {
if (previousHost.visible || statusbarState != StatusBarState.KEYGUARD) {
return qsExpansion
@@ -1028,7 +1026,8 @@
private fun updateHostAttachment() =
traceSection("MediaHierarchyManager#updateHostAttachment") {
var newLocation = resolveLocationForFading()
- var canUseOverlay = !isCurrentlyFading()
+ // Don't use the overlay when fading or when we don't have active media
+ var canUseOverlay = !isCurrentlyFading() && hasActiveMediaOrRecommendation
if (isCrossFadeAnimatorRunning) {
if (
getHost(newLocation)?.visible == true &&
@@ -1122,7 +1121,6 @@
dreamOverlayActive && dreamMediaComplicationActive -> LOCATION_DREAM_OVERLAY
(qsExpansion > 0.0f || inSplitShade) && !onLockscreen -> LOCATION_QS
qsExpansion > 0.4f && onLockscreen -> LOCATION_QS
- !hasActiveMedia -> LOCATION_QS
onLockscreen && isSplitShadeExpanding() -> LOCATION_QS
onLockscreen && isTransformingToFullShadeAndInQQS() -> LOCATION_QQS
onLockscreen && allowMediaPlayerOnLockScreen -> LOCATION_LOCKSCREEN
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
index 3224213..2ec7be6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
@@ -24,11 +24,6 @@
import com.android.systemui.media.controls.models.GutsViewHolder
import com.android.systemui.media.controls.models.player.MediaViewHolder
import com.android.systemui.media.controls.models.recommendation.RecommendationViewHolder
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.CONTROLS_DELAY
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.DETAILS_DELAY
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.DURATION
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.MEDIACONTAINERS_DELAY
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.MEDIATITLES_DELAY
import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.calculateAlpha
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.animation.MeasurementOutput
@@ -36,6 +31,8 @@
import com.android.systemui.util.animation.TransitionLayoutController
import com.android.systemui.util.animation.TransitionViewState
import com.android.systemui.util.traceSection
+import java.lang.Float.max
+import java.lang.Float.min
import javax.inject.Inject
/**
@@ -80,6 +77,7 @@
setOf(
R.id.header_title,
R.id.header_artist,
+ R.id.media_explicit_indicator,
R.id.actionPlayPause,
)
@@ -304,42 +302,109 @@
val squishedViewState = viewState.copy()
val squishedHeight = (squishedViewState.measureHeight * squishFraction).toInt()
squishedViewState.height = squishedHeight
- controlIds.forEach { id ->
- squishedViewState.widgetStates.get(id)?.let { state ->
- state.alpha = calculateAlpha(squishFraction, CONTROLS_DELAY, DURATION)
- }
- }
-
- detailIds.forEach { id ->
- squishedViewState.widgetStates.get(id)?.let { state ->
- state.alpha = calculateAlpha(squishFraction, DETAILS_DELAY, DURATION)
- }
- }
-
// We are not overriding the squishedViewStates height but only the children to avoid
// them remeasuring the whole view. Instead it just remains as the original size
backgroundIds.forEach { id ->
- squishedViewState.widgetStates.get(id)?.let { state ->
- state.height = squishedHeight
- }
+ squishedViewState.widgetStates.get(id)?.let { state -> state.height = squishedHeight }
}
- RecommendationViewHolder.mediaContainersIds.forEach { id ->
- squishedViewState.widgetStates.get(id)?.let { state ->
- state.alpha = calculateAlpha(squishFraction, MEDIACONTAINERS_DELAY, DURATION)
- }
- }
-
- RecommendationViewHolder.mediaTitlesAndSubtitlesIds.forEach { id ->
- squishedViewState.widgetStates.get(id)?.let { state ->
- state.alpha = calculateAlpha(squishFraction, MEDIATITLES_DELAY, DURATION)
- }
- }
-
+ // media player
+ val controlsTop =
+ calculateWidgetGroupAlphaForSquishiness(
+ controlIds,
+ squishedViewState.measureHeight.toFloat(),
+ squishedViewState,
+ squishFraction
+ )
+ calculateWidgetGroupAlphaForSquishiness(
+ detailIds,
+ controlsTop,
+ squishedViewState,
+ squishFraction
+ )
+ // recommendation card
+ val titlesTop =
+ calculateWidgetGroupAlphaForSquishiness(
+ RecommendationViewHolder.mediaTitlesAndSubtitlesIds,
+ squishedViewState.measureHeight.toFloat(),
+ squishedViewState,
+ squishFraction
+ )
+ calculateWidgetGroupAlphaForSquishiness(
+ RecommendationViewHolder.mediaContainersIds,
+ titlesTop,
+ squishedViewState,
+ squishFraction
+ )
return squishedViewState
}
/**
+ * This function is to make each widget in UMO disappear before being clipped by squished UMO
+ *
+ * The general rule is that widgets in UMO has been divided into several groups, and widgets in
+ * one group have the same alpha during squishing It will change from alpha 0.0 when the visible
+ * bottom of UMO reach the bottom of this group It will change to alpha 1.0 when the visible
+ * bottom of UMO reach the top of the group below e.g.Album title, artist title and play-pause
+ * button will change alpha together.
+ * ```
+ * And their alpha becomes 1.0 when the visible bottom of UMO reach the top of controls,
+ * including progress bar, next button, previous button
+ * ```
+ * widgetGroupIds: a group of widgets have same state during UMO is squished,
+ * ```
+ * e.g. Album title, artist title and play-pause button
+ * ```
+ * groupEndPosition: the height of UMO, when the height reaches this value,
+ * ```
+ * widgets in this group should have 1.0 as alpha
+ * e.g., the group of album title, artist title and play-pause button will become fully
+ * visible when the height of UMO reaches the top of controls group
+ * (progress bar, previous button and next button)
+ * ```
+ * squishedViewState: hold the widgetState of each widget, which will be modified
+ * squishFraction: the squishFraction of UMO
+ */
+ private fun calculateWidgetGroupAlphaForSquishiness(
+ widgetGroupIds: Set<Int>,
+ groupEndPosition: Float,
+ squishedViewState: TransitionViewState,
+ squishFraction: Float
+ ): Float {
+ val nonsquishedHeight = squishedViewState.measureHeight
+ var groupTop = squishedViewState.measureHeight.toFloat()
+ var groupBottom = 0F
+ widgetGroupIds.forEach { id ->
+ squishedViewState.widgetStates.get(id)?.let { state ->
+ groupTop = min(groupTop, state.y)
+ groupBottom = max(groupBottom, state.y + state.height)
+ }
+ }
+ // startPosition means to the height of squished UMO where the widget alpha should start
+ // changing from 0.0
+ // generally, it equals to the bottom of widgets, so that we can meet the requirement that
+ // widget should not go beyond the bounds of background
+ // endPosition means to the height of squished UMO where the widget alpha should finish
+ // changing alpha to 1.0
+ var startPosition = groupBottom
+ val endPosition = groupEndPosition
+ if (startPosition == endPosition) {
+ startPosition = (endPosition - 0.2 * (groupBottom - groupTop)).toFloat()
+ }
+ widgetGroupIds.forEach { id ->
+ squishedViewState.widgetStates.get(id)?.let { state ->
+ state.alpha =
+ calculateAlpha(
+ squishFraction,
+ startPosition / nonsquishedHeight,
+ endPosition / nonsquishedHeight
+ )
+ }
+ }
+ return groupTop // used for the widget group above this group
+ }
+
+ /**
* Obtain a new viewState for a given media state. This usually returns a cached state, but if
* it's not available, it will recreate one by measuring, which may be expensive.
*/
@@ -544,11 +609,13 @@
overrideSize?.let {
// To be safe we're using a maximum here. The override size should always be set
// properly though.
- if (result.measureHeight != it.measuredHeight
- || result.measureWidth != it.measuredWidth) {
+ if (
+ result.measureHeight != it.measuredHeight || result.measureWidth != it.measuredWidth
+ ) {
result.measureHeight = Math.max(it.measuredHeight, result.measureHeight)
result.measureWidth = Math.max(it.measuredWidth, result.measureWidth)
- // The measureHeight and the shown height should both be set to the overridden height
+ // The measureHeight and the shown height should both be set to the overridden
+ // height
result.height = result.measureHeight
result.width = result.measureWidth
// Make sure all background views are also resized such that their size is correct
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
index 8d4931a..5bc35ca 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
@@ -42,4 +42,7 @@
* [android.app.StatusBarManager.registerNearbyMediaDevicesProvider] for more information.
*/
fun areNearbyMediaDevicesEnabled() = featureFlags.isEnabled(Flags.MEDIA_NEARBY_DEVICES)
+
+ /** Check whether we show explicit indicator on UMO */
+ fun isExplicitIndicatorEnabled() = featureFlags.isEnabled(Flags.MEDIA_EXPLICIT_INDICATOR)
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index 316b642..7bc0c0c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -637,44 +637,21 @@
}
// For the first time building list, to make sure the top device is the connected
// device.
+ boolean needToHandleMutingExpectedDevice =
+ hasMutingExpectedDevice() && !isCurrentConnectedDeviceRemote();
+ final MediaDevice connectedMediaDevice =
+ needToHandleMutingExpectedDevice ? null
+ : getCurrentConnectedMediaDevice();
if (mMediaItemList.isEmpty()) {
- boolean needToHandleMutingExpectedDevice =
- hasMutingExpectedDevice() && !isCurrentConnectedDeviceRemote();
- final MediaDevice connectedMediaDevice =
- needToHandleMutingExpectedDevice ? null
- : getCurrentConnectedMediaDevice();
if (connectedMediaDevice == null) {
if (DEBUG) {
Log.d(TAG, "No connected media device or muting expected device exist.");
}
- if (needToHandleMutingExpectedDevice) {
- for (MediaDevice device : devices) {
- if (device.isMutingExpectedDevice()) {
- mMediaItemList.add(0, new MediaItem(device));
- mMediaItemList.add(1, new MediaItem(mContext.getString(
- R.string.media_output_group_title_speakers_and_displays),
- MediaItem.MediaItemType.TYPE_GROUP_DIVIDER));
- } else {
- mMediaItemList.add(new MediaItem(device));
- }
- }
- mMediaItemList.add(new MediaItem());
- } else {
- mMediaItemList.addAll(
- devices.stream().map(MediaItem::new).collect(Collectors.toList()));
- categorizeMediaItems(null);
- }
+ categorizeMediaItems(null, devices, needToHandleMutingExpectedDevice);
return;
}
// selected device exist
- for (MediaDevice device : devices) {
- if (TextUtils.equals(device.getId(), connectedMediaDevice.getId())) {
- mMediaItemList.add(0, new MediaItem(device));
- } else {
- mMediaItemList.add(new MediaItem(device));
- }
- }
- categorizeMediaItems(connectedMediaDevice);
+ categorizeMediaItems(connectedMediaDevice, devices, false);
return;
}
// To keep the same list order
@@ -708,31 +685,46 @@
}
}
- private void categorizeMediaItems(MediaDevice connectedMediaDevice) {
+ private void categorizeMediaItems(MediaDevice connectedMediaDevice, List<MediaDevice> devices,
+ boolean needToHandleMutingExpectedDevice) {
synchronized (mMediaDevicesLock) {
Set<String> selectedDevicesIds = getSelectedMediaDevice().stream().map(
MediaDevice::getId).collect(Collectors.toSet());
if (connectedMediaDevice != null) {
selectedDevicesIds.add(connectedMediaDevice.getId());
}
- int latestSelected = 1;
- for (MediaItem item : mMediaItemList) {
- if (item.getMediaDevice().isPresent()) {
- MediaDevice device = item.getMediaDevice().get();
- if (selectedDevicesIds.contains(device.getId())) {
- latestSelected = mMediaItemList.indexOf(item) + 1;
- } else {
- mMediaItemList.add(latestSelected, new MediaItem(mContext.getString(
- R.string.media_output_group_title_speakers_and_displays),
- MediaItem.MediaItemType.TYPE_GROUP_DIVIDER));
- break;
+ boolean suggestedDeviceAdded = false;
+ boolean displayGroupAdded = false;
+ for (MediaDevice device : devices) {
+ if (needToHandleMutingExpectedDevice && device.isMutingExpectedDevice()) {
+ mMediaItemList.add(0, new MediaItem(device));
+ } else if (!needToHandleMutingExpectedDevice && selectedDevicesIds.contains(
+ device.getId())) {
+ mMediaItemList.add(0, new MediaItem(device));
+ } else {
+ if (device.isSuggestedDevice() && !suggestedDeviceAdded) {
+ attachGroupDivider(mContext.getString(
+ R.string.media_output_group_title_suggested_device));
+ suggestedDeviceAdded = true;
+ } else if (!device.isSuggestedDevice() && !displayGroupAdded) {
+ attachGroupDivider(mContext.getString(
+ R.string.media_output_group_title_speakers_and_displays));
+ displayGroupAdded = true;
}
+ mMediaItemList.add(new MediaItem(device));
}
}
mMediaItemList.add(new MediaItem());
}
}
+ private void attachGroupDivider(String title) {
+ synchronized (mMediaDevicesLock) {
+ mMediaItemList.add(
+ new MediaItem(title, MediaItem.MediaItemType.TYPE_GROUP_DIVIDER));
+ }
+ }
+
private void attachRangeInfo(List<MediaDevice> devices) {
for (MediaDevice mediaDevice : devices) {
if (mNearbyDeviceInfoMap.containsKey(mediaDevice.getId())) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
index 9f44d98..935f38d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
@@ -150,7 +150,12 @@
logger: MediaTttLogger<ChipbarInfo>,
): ChipbarInfo {
val packageName = routeInfo.clientPackageName
- val otherDeviceName = routeInfo.name.toString()
+ val otherDeviceName =
+ if (routeInfo.name.isBlank()) {
+ context.getString(R.string.media_ttt_default_device_type)
+ } else {
+ routeInfo.name.toString()
+ }
return ChipbarInfo(
// Display the app's icon as the start icon
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
index 6dd60d0..8356440 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
@@ -57,7 +57,9 @@
* If the keyguard is locked, notes will open as a full screen experience. A locked device has
* no contextual information which let us use the whole screen space available.
*
- * If no in multi-window or the keyguard is unlocked, notes will open as a floating experience.
+ * If no in multi-window or the keyguard is unlocked, notes will open as a bubble OR it will be
+ * collapsed if the notes bubble is already opened.
+ *
* That will let users open other apps in full screen, and take contextual notes.
*/
fun showNoteTask(isInMultiWindowMode: Boolean = false) {
@@ -75,7 +77,7 @@
context.startActivity(intent)
} else {
// TODO(b/254606432): Should include Intent.EXTRA_FLOATING_WINDOW_MODE parameter.
- bubbles.showAppBubble(intent)
+ bubbles.showOrHideAppBubble(intent)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index da18b57..5ef7126 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -67,6 +67,7 @@
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.util.LifecycleFragment;
+import com.android.systemui.util.Utils;
import java.io.PrintWriter;
import java.util.Arrays;
@@ -682,7 +683,7 @@
} else {
mQsMediaHost.setSquishFraction(mSquishinessFraction);
}
-
+ updateMediaPositions();
}
private void setAlphaAnimationProgress(float progress) {
@@ -757,6 +758,22 @@
- mQSPanelController.getPaddingBottom());
}
+ private void updateMediaPositions() {
+ if (Utils.useQsMediaPlayer(getContext())) {
+ View hostView = mQsMediaHost.getHostView();
+ // Make sure the media appears a bit from the top to make it look nicer
+ if (mLastQSExpansion > 0 && !isKeyguardState() && !mQqsMediaHost.getVisible()
+ && !mQSPanelController.shouldUseHorizontalLayout() && !mInSplitShade) {
+ float interpolation = 1.0f - mLastQSExpansion;
+ interpolation = Interpolators.ACCELERATE.getInterpolation(interpolation);
+ float translationY = -hostView.getHeight() * 1.3f * interpolation;
+ hostView.setTranslationY(translationY);
+ } else {
+ hostView.setTranslationY(0);
+ }
+ }
+ }
+
private boolean headerWillBeAnimating() {
return mStatusBarState == KEYGUARD && mShowCollapsedOnKeyguard && !isKeyguardState();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
index 7cf63f6..1da30ad 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
@@ -36,7 +36,6 @@
void removeCallback(Callback callback);
void removeTile(String tileSpec);
void removeTiles(Collection<String> specs);
- void unmarkTileAsAutoAdded(String tileSpec);
int indexOf(String tileSpec);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index 7bb672c..e85d0a3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -372,18 +372,18 @@
if (mUsingHorizontalLayout) {
// Only height remaining
parameters.getDisappearSize().set(0.0f, 0.4f);
- // Disappearing on the right side on the bottom
- parameters.getGonePivot().set(1.0f, 1.0f);
+ // Disappearing on the right side on the top
+ parameters.getGonePivot().set(1.0f, 0.0f);
// translating a bit horizontal
parameters.getContentTranslationFraction().set(0.25f, 1.0f);
parameters.setDisappearEnd(0.6f);
} else {
// Only width remaining
parameters.getDisappearSize().set(1.0f, 0.0f);
- // Disappearing on the bottom
- parameters.getGonePivot().set(0.0f, 1.0f);
+ // Disappearing on the top
+ parameters.getGonePivot().set(0.0f, 0.0f);
// translating a bit vertical
- parameters.getContentTranslationFraction().set(0.0f, 1.05f);
+ parameters.getContentTranslationFraction().set(0.0f, 1f);
parameters.setDisappearEnd(0.95f);
}
parameters.setFadeStartPosition(0.95f);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index cad296b..100853c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -427,11 +427,6 @@
mMainExecutor.execute(() -> changeTileSpecs(tileSpecs -> tileSpecs.removeAll(specs)));
}
- @Override
- public void unmarkTileAsAutoAdded(String spec) {
- if (mAutoTiles != null) mAutoTiles.unmarkTileAsAutoAdded(spec);
- }
-
/**
* Add a tile to the end
*
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index 79fcc7d..1712490 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -24,6 +24,7 @@
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.Menu;
+import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Toolbar;
@@ -74,8 +75,8 @@
toolbar.setNavigationIcon(
getResources().getDrawable(value.resourceId, mContext.getTheme()));
- toolbar.getMenu().add(Menu.NONE, MENU_RESET, 0,
- mContext.getString(com.android.internal.R.string.reset));
+ toolbar.getMenu().add(Menu.NONE, MENU_RESET, 0, com.android.internal.R.string.reset)
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
toolbar.setTitle(R.string.qs_edit);
mRecyclerView = findViewById(android.R.id.list);
mTransparentView = findViewById(R.id.customizer_transparent_view);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
index d393680..385e720 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
@@ -15,6 +15,9 @@
*/
package com.android.systemui.qs.external;
+import static android.service.quicksettings.TileService.START_ACTIVITY_NEEDS_PENDING_INTENT;
+
+import android.app.compat.CompatChanges;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -41,15 +44,15 @@
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Main;
+import dagger.assisted.Assisted;
+import dagger.assisted.AssistedFactory;
+import dagger.assisted.AssistedInject;
+
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
-import dagger.assisted.Assisted;
-import dagger.assisted.AssistedFactory;
-import dagger.assisted.AssistedInject;
-
/**
* Manages the lifecycle of a TileService.
* <p>
@@ -124,7 +127,9 @@
/** Injectable factory for TileLifecycleManager. */
@AssistedFactory
public interface Factory {
- /** */
+ /**
+ *
+ */
TileLifecycleManager create(Intent intent, UserHandle userHandle);
}
@@ -161,7 +166,7 @@
* Determines whether the associated TileService is a Boolean Tile.
*
* @return true if {@link TileService#META_DATA_TOGGLEABLE_TILE} is set to {@code true} for this
- * tile
+ * tile
* @see TileService#META_DATA_TOGGLEABLE_TILE
*/
public boolean isToggleableTile() {
@@ -207,12 +212,7 @@
if (DEBUG) Log.d(TAG, "Binding service " + mIntent + " " + mUser);
mBindTryCount++;
try {
- mIsBound = mContext.bindServiceAsUser(mIntent, this,
- Context.BIND_AUTO_CREATE
- | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE
- | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS
- | Context.BIND_WAIVE_PRIORITY,
- mUser);
+ mIsBound = bindServices();
if (!mIsBound) {
mContext.unbindService(this);
}
@@ -237,6 +237,24 @@
}
}
+ private boolean bindServices() {
+ String packageName = mIntent.getComponent().getPackageName();
+ if (CompatChanges.isChangeEnabled(START_ACTIVITY_NEEDS_PENDING_INTENT, packageName,
+ mUser)) {
+ return mContext.bindServiceAsUser(mIntent, this,
+ Context.BIND_AUTO_CREATE
+ | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE
+ | Context.BIND_WAIVE_PRIORITY,
+ mUser);
+ }
+ return mContext.bindServiceAsUser(mIntent, this,
+ Context.BIND_AUTO_CREATE
+ | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE
+ | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS
+ | Context.BIND_WAIVE_PRIORITY,
+ mUser);
+ }
+
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (DEBUG) Log.d(TAG, "onServiceConnected " + name);
@@ -418,8 +436,11 @@
mPackageManagerAdapter.getPackageInfoAsUser(packageName, 0, mUser.getIdentifier());
return true;
} catch (PackageManager.NameNotFoundException e) {
- if (DEBUG) Log.d(TAG, "Package not available: " + packageName, e);
- else Log.d(TAG, "Package not available: " + packageName);
+ if (DEBUG) {
+ Log.d(TAG, "Package not available: " + packageName, e);
+ } else {
+ Log.d(TAG, "Package not available: " + packageName);
+ }
}
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt b/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
index 9f376ae..d32ef32 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
@@ -49,109 +49,135 @@
}
fun logTileAdded(tileSpec: String) {
- log(DEBUG, {
- str1 = tileSpec
- }, {
- "[$str1] Tile added"
- })
+ buffer.log(TAG, DEBUG, { str1 = tileSpec }, { "[$str1] Tile added" })
}
fun logTileDestroyed(tileSpec: String, reason: String) {
- log(DEBUG, {
- str1 = tileSpec
- str2 = reason
- }, {
- "[$str1] Tile destroyed. Reason: $str2"
- })
+ buffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = tileSpec
+ str2 = reason
+ },
+ { "[$str1] Tile destroyed. Reason: $str2" }
+ )
}
fun logTileChangeListening(tileSpec: String, listening: Boolean) {
- log(VERBOSE, {
- bool1 = listening
- str1 = tileSpec
- }, {
- "[$str1] Tile listening=$bool1"
- })
+ buffer.log(
+ TAG,
+ VERBOSE,
+ {
+ bool1 = listening
+ str1 = tileSpec
+ },
+ { "[$str1] Tile listening=$bool1" }
+ )
}
fun logAllTilesChangeListening(listening: Boolean, containerName: String, allSpecs: String) {
- log(DEBUG, {
- bool1 = listening
- str1 = containerName
- str2 = allSpecs
- }, {
- "Tiles listening=$bool1 in $str1. $str2"
- })
+ buffer.log(
+ TAG,
+ DEBUG,
+ {
+ bool1 = listening
+ str1 = containerName
+ str2 = allSpecs
+ },
+ { "Tiles listening=$bool1 in $str1. $str2" }
+ )
}
fun logTileClick(tileSpec: String, statusBarState: Int, state: Int, eventId: Int) {
- log(DEBUG, {
- str1 = tileSpec
- int1 = eventId
- str2 = StatusBarState.toString(statusBarState)
- str3 = toStateString(state)
- }, {
- "[$str1][$int1] Tile clicked. StatusBarState=$str2. TileState=$str3"
- })
+ buffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = tileSpec
+ int1 = eventId
+ str2 = StatusBarState.toString(statusBarState)
+ str3 = toStateString(state)
+ },
+ { "[$str1][$int1] Tile clicked. StatusBarState=$str2. TileState=$str3" }
+ )
}
fun logHandleClick(tileSpec: String, eventId: Int) {
- log(DEBUG, {
- str1 = tileSpec
- int1 = eventId
- }, {
- "[$str1][$int1] Tile handling click."
- })
+ buffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = tileSpec
+ int1 = eventId
+ },
+ { "[$str1][$int1] Tile handling click." }
+ )
}
fun logTileSecondaryClick(tileSpec: String, statusBarState: Int, state: Int, eventId: Int) {
- log(DEBUG, {
- str1 = tileSpec
- int1 = eventId
- str2 = StatusBarState.toString(statusBarState)
- str3 = toStateString(state)
- }, {
- "[$str1][$int1] Tile secondary clicked. StatusBarState=$str2. TileState=$str3"
- })
+ buffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = tileSpec
+ int1 = eventId
+ str2 = StatusBarState.toString(statusBarState)
+ str3 = toStateString(state)
+ },
+ { "[$str1][$int1] Tile secondary clicked. StatusBarState=$str2. TileState=$str3" }
+ )
}
fun logHandleSecondaryClick(tileSpec: String, eventId: Int) {
- log(DEBUG, {
- str1 = tileSpec
- int1 = eventId
- }, {
- "[$str1][$int1] Tile handling secondary click."
- })
+ buffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = tileSpec
+ int1 = eventId
+ },
+ { "[$str1][$int1] Tile handling secondary click." }
+ )
}
fun logTileLongClick(tileSpec: String, statusBarState: Int, state: Int, eventId: Int) {
- log(DEBUG, {
- str1 = tileSpec
- int1 = eventId
- str2 = StatusBarState.toString(statusBarState)
- str3 = toStateString(state)
- }, {
- "[$str1][$int1] Tile long clicked. StatusBarState=$str2. TileState=$str3"
- })
+ buffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = tileSpec
+ int1 = eventId
+ str2 = StatusBarState.toString(statusBarState)
+ str3 = toStateString(state)
+ },
+ { "[$str1][$int1] Tile long clicked. StatusBarState=$str2. TileState=$str3" }
+ )
}
fun logHandleLongClick(tileSpec: String, eventId: Int) {
- log(DEBUG, {
- str1 = tileSpec
- int1 = eventId
- }, {
- "[$str1][$int1] Tile handling long click."
- })
+ buffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = tileSpec
+ int1 = eventId
+ },
+ { "[$str1][$int1] Tile handling long click." }
+ )
}
fun logInternetTileUpdate(tileSpec: String, lastType: Int, callback: String) {
- log(VERBOSE, {
- str1 = tileSpec
- int1 = lastType
- str2 = callback
- }, {
- "[$str1] mLastTileState=$int1, Callback=$str2."
- })
+ buffer.log(
+ TAG,
+ VERBOSE,
+ {
+ str1 = tileSpec
+ int1 = lastType
+ str2 = callback
+ },
+ { "[$str1] mLastTileState=$int1, Callback=$str2." }
+ )
}
// TODO(b/250618218): Remove this method once we know the root cause of b/250618218.
@@ -167,58 +193,75 @@
if (tileSpec != "internet") {
return
}
- log(VERBOSE, {
- str1 = tileSpec
- int1 = state
- bool1 = disabledByPolicy
- int2 = color
- }, {
- "[$str1] state=$int1, disabledByPolicy=$bool1, color=$int2."
- })
+ buffer.log(
+ TAG,
+ VERBOSE,
+ {
+ str1 = tileSpec
+ int1 = state
+ bool1 = disabledByPolicy
+ int2 = color
+ },
+ { "[$str1] state=$int1, disabledByPolicy=$bool1, color=$int2." }
+ )
}
fun logTileUpdated(tileSpec: String, state: QSTile.State) {
- log(VERBOSE, {
- str1 = tileSpec
- str2 = state.label?.toString()
- str3 = state.icon?.toString()
- int1 = state.state
- if (state is QSTile.SignalState) {
- bool1 = true
- bool2 = state.activityIn
- bool3 = state.activityOut
+ buffer.log(
+ TAG,
+ VERBOSE,
+ {
+ str1 = tileSpec
+ str2 = state.label?.toString()
+ str3 = state.icon?.toString()
+ int1 = state.state
+ if (state is QSTile.SignalState) {
+ bool1 = true
+ bool2 = state.activityIn
+ bool3 = state.activityOut
+ }
+ },
+ {
+ "[$str1] Tile updated. Label=$str2. State=$int1. Icon=$str3." +
+ if (bool1) " Activity in/out=$bool2/$bool3" else ""
}
- }, {
- "[$str1] Tile updated. Label=$str2. State=$int1. Icon=$str3." +
- if (bool1) " Activity in/out=$bool2/$bool3" else ""
- })
+ )
}
fun logPanelExpanded(expanded: Boolean, containerName: String) {
- log(DEBUG, {
- str1 = containerName
- bool1 = expanded
- }, {
- "$str1 expanded=$bool1"
- })
+ buffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = containerName
+ bool1 = expanded
+ },
+ { "$str1 expanded=$bool1" }
+ )
}
fun logOnViewAttached(orientation: Int, containerName: String) {
- log(DEBUG, {
- str1 = containerName
- int1 = orientation
- }, {
- "onViewAttached: $str1 orientation $int1"
- })
+ buffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = containerName
+ int1 = orientation
+ },
+ { "onViewAttached: $str1 orientation $int1" }
+ )
}
fun logOnViewDetached(orientation: Int, containerName: String) {
- log(DEBUG, {
- str1 = containerName
- int1 = orientation
- }, {
- "onViewDetached: $str1 orientation $int1"
- })
+ buffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = containerName
+ int1 = orientation
+ },
+ { "onViewDetached: $str1 orientation $int1" }
+ )
}
fun logOnConfigurationChanged(
@@ -226,13 +269,16 @@
newOrientation: Int,
containerName: String
) {
- log(DEBUG, {
- str1 = containerName
- int1 = lastOrientation
- int2 = newOrientation
- }, {
- "configuration change: $str1 orientation was $int1, now $int2"
- })
+ buffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = containerName
+ int1 = lastOrientation
+ int2 = newOrientation
+ },
+ { "configuration change: $str1 orientation was $int1, now $int2" }
+ )
}
fun logSwitchTileLayout(
@@ -241,32 +287,41 @@
force: Boolean,
containerName: String
) {
- log(DEBUG, {
- str1 = containerName
- bool1 = after
- bool2 = before
- bool3 = force
- }, {
- "change tile layout: $str1 horizontal=$bool1 (was $bool2), force? $bool3"
- })
+ buffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = containerName
+ bool1 = after
+ bool2 = before
+ bool3 = force
+ },
+ { "change tile layout: $str1 horizontal=$bool1 (was $bool2), force? $bool3" }
+ )
}
fun logTileDistributionInProgress(tilesPerPageCount: Int, totalTilesCount: Int) {
- log(DEBUG, {
- int1 = tilesPerPageCount
- int2 = totalTilesCount
- }, {
- "Distributing tiles: [tilesPerPageCount=$int1] [totalTilesCount=$int2]"
- })
+ buffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = tilesPerPageCount
+ int2 = totalTilesCount
+ },
+ { "Distributing tiles: [tilesPerPageCount=$int1] [totalTilesCount=$int2]" }
+ )
}
fun logTileDistributed(tileName: String, pageIndex: Int) {
- log(DEBUG, {
- str1 = tileName
- int1 = pageIndex
- }, {
- "Adding $str1 to page number $int1"
- })
+ buffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = tileName
+ int1 = pageIndex
+ },
+ { "Adding $str1 to page number $int1" }
+ )
}
private fun toStateString(state: Int): String {
@@ -277,12 +332,4 @@
else -> "wrong state"
}
}
-
- private inline fun log(
- logLevel: LogLevel,
- initializer: LogMessage.() -> Unit,
- noinline printer: LogMessage.() -> String
- ) {
- buffer.log(TAG, logLevel, initializer, printer)
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
index a92c7e3..24a4f60b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -33,7 +33,6 @@
import com.android.systemui.qs.tiles.BluetoothTile;
import com.android.systemui.qs.tiles.CameraToggleTile;
import com.android.systemui.qs.tiles.CastTile;
-import com.android.systemui.qs.tiles.CellularTile;
import com.android.systemui.qs.tiles.ColorCorrectionTile;
import com.android.systemui.qs.tiles.ColorInversionTile;
import com.android.systemui.qs.tiles.DataSaverTile;
@@ -54,7 +53,6 @@
import com.android.systemui.qs.tiles.RotationLockTile;
import com.android.systemui.qs.tiles.ScreenRecordTile;
import com.android.systemui.qs.tiles.UiModeNightTile;
-import com.android.systemui.qs.tiles.WifiTile;
import com.android.systemui.qs.tiles.WorkModeTile;
import com.android.systemui.util.leak.GarbageMonitor;
@@ -68,10 +66,8 @@
private static final String TAG = "QSFactory";
- private final Provider<WifiTile> mWifiTileProvider;
private final Provider<InternetTile> mInternetTileProvider;
private final Provider<BluetoothTile> mBluetoothTileProvider;
- private final Provider<CellularTile> mCellularTileProvider;
private final Provider<DndTile> mDndTileProvider;
private final Provider<ColorCorrectionTile> mColorCorrectionTileProvider;
private final Provider<ColorInversionTile> mColorInversionTileProvider;
@@ -106,10 +102,8 @@
public QSFactoryImpl(
Lazy<QSHost> qsHostLazy,
Provider<CustomTile.Builder> customTileBuilderProvider,
- Provider<WifiTile> wifiTileProvider,
Provider<InternetTile> internetTileProvider,
Provider<BluetoothTile> bluetoothTileProvider,
- Provider<CellularTile> cellularTileProvider,
Provider<DndTile> dndTileProvider,
Provider<ColorInversionTile> colorInversionTileProvider,
Provider<AirplaneModeTile> airplaneModeTileProvider,
@@ -139,10 +133,8 @@
mQsHostLazy = qsHostLazy;
mCustomTileBuilderProvider = customTileBuilderProvider;
- mWifiTileProvider = wifiTileProvider;
mInternetTileProvider = internetTileProvider;
mBluetoothTileProvider = bluetoothTileProvider;
- mCellularTileProvider = cellularTileProvider;
mDndTileProvider = dndTileProvider;
mColorInversionTileProvider = colorInversionTileProvider;
mAirplaneModeTileProvider = airplaneModeTileProvider;
@@ -186,14 +178,10 @@
protected QSTileImpl createTileInternal(String tileSpec) {
// Stock tiles.
switch (tileSpec) {
- case "wifi":
- return mWifiTileProvider.get();
case "internet":
return mInternetTileProvider.get();
case "bt":
return mBluetoothTileProvider.get();
- case "cell":
- return mCellularTileProvider.get();
case "dnd":
return mDndTileProvider.get();
case "inversion":
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
deleted file mode 100644
index 04a25fc..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.qs.tiles;
-
-import static com.android.systemui.Prefs.Key.QS_HAS_TURNED_OFF_MOBILE_DATA;
-
-import android.annotation.NonNull;
-import android.app.AlertDialog;
-import android.app.AlertDialog.Builder;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.service.quicksettings.Tile;
-import android.telephony.SubscriptionManager;
-import android.text.Html;
-import android.text.TextUtils;
-import android.view.View;
-import android.view.WindowManager.LayoutParams;
-import android.widget.Switch;
-
-import androidx.annotation.Nullable;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settingslib.net.DataUsageController;
-import com.android.systemui.Prefs;
-import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.Background;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.qs.QSIconView;
-import com.android.systemui.plugins.qs.QSTile.SignalState;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.QSHost;
-import com.android.systemui.qs.SignalTileView;
-import com.android.systemui.qs.logging.QSLogger;
-import com.android.systemui.qs.tileimpl.QSTileImpl;
-import com.android.systemui.statusbar.connectivity.IconState;
-import com.android.systemui.statusbar.connectivity.MobileDataIndicators;
-import com.android.systemui.statusbar.connectivity.NetworkController;
-import com.android.systemui.statusbar.connectivity.SignalCallback;
-import com.android.systemui.statusbar.phone.SystemUIDialog;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-
-import javax.inject.Inject;
-
-/** Quick settings tile: Cellular **/
-public class CellularTile extends QSTileImpl<SignalState> {
- private static final String ENABLE_SETTINGS_DATA_PLAN = "enable.settings.data.plan";
-
- private final NetworkController mController;
- private final DataUsageController mDataController;
- private final KeyguardStateController mKeyguard;
- private final CellSignalCallback mSignalCallback = new CellSignalCallback();
-
- @Inject
- public CellularTile(
- QSHost host,
- @Background Looper backgroundLooper,
- @Main Handler mainHandler,
- FalsingManager falsingManager,
- MetricsLogger metricsLogger,
- StatusBarStateController statusBarStateController,
- ActivityStarter activityStarter,
- QSLogger qsLogger,
- NetworkController networkController,
- KeyguardStateController keyguardStateController
-
- ) {
- super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
- statusBarStateController, activityStarter, qsLogger);
- mController = networkController;
- mKeyguard = keyguardStateController;
- mDataController = mController.getMobileDataController();
- mController.observe(getLifecycle(), mSignalCallback);
- }
-
- @Override
- public SignalState newTileState() {
- return new SignalState();
- }
-
- @Override
- public QSIconView createTileView(Context context) {
- return new SignalTileView(context);
- }
-
- @Override
- public Intent getLongClickIntent() {
- if (getState().state == Tile.STATE_UNAVAILABLE) {
- return new Intent(Settings.ACTION_WIRELESS_SETTINGS);
- }
- return getCellularSettingIntent();
- }
-
- @Override
- protected void handleClick(@Nullable View view) {
- if (getState().state == Tile.STATE_UNAVAILABLE) {
- return;
- }
- if (mDataController.isMobileDataEnabled()) {
- maybeShowDisableDialog();
- } else {
- mDataController.setMobileDataEnabled(true);
- }
- }
-
- private void maybeShowDisableDialog() {
- if (Prefs.getBoolean(mContext, QS_HAS_TURNED_OFF_MOBILE_DATA, false)) {
- // Directly turn off mobile data if the user has seen the dialog before.
- mDataController.setMobileDataEnabled(false);
- return;
- }
- String carrierName = mController.getMobileDataNetworkName();
- boolean isInService = mController.isMobileDataNetworkInService();
- if (TextUtils.isEmpty(carrierName) || !isInService) {
- carrierName = mContext.getString(R.string.mobile_data_disable_message_default_carrier);
- }
- AlertDialog dialog = new Builder(mContext)
- .setTitle(R.string.mobile_data_disable_title)
- .setMessage(mContext.getString(R.string.mobile_data_disable_message, carrierName))
- .setNegativeButton(android.R.string.cancel, null)
- .setPositiveButton(
- com.android.internal.R.string.alert_windows_notification_turn_off_action,
- (d, w) -> {
- mDataController.setMobileDataEnabled(false);
- Prefs.putBoolean(mContext, QS_HAS_TURNED_OFF_MOBILE_DATA, true);
- })
- .create();
- dialog.getWindow().setType(LayoutParams.TYPE_KEYGUARD_DIALOG);
- SystemUIDialog.setShowForAllUsers(dialog, true);
- SystemUIDialog.registerDismissListener(dialog);
- SystemUIDialog.setWindowOnTop(dialog, mKeyguard.isShowing());
- dialog.show();
- }
-
- @Override
- protected void handleSecondaryClick(@Nullable View view) {
- handleLongClick(view);
- }
-
- @Override
- public CharSequence getTileLabel() {
- return mContext.getString(R.string.quick_settings_cellular_detail_title);
- }
-
- @Override
- protected void handleUpdateState(SignalState state, Object arg) {
- CallbackInfo cb = (CallbackInfo) arg;
- if (cb == null) {
- cb = mSignalCallback.mInfo;
- }
-
- final Resources r = mContext.getResources();
- state.label = r.getString(R.string.mobile_data);
- boolean mobileDataEnabled = mDataController.isMobileDataSupported()
- && mDataController.isMobileDataEnabled();
- state.value = mobileDataEnabled;
- state.activityIn = mobileDataEnabled && cb.activityIn;
- state.activityOut = mobileDataEnabled && cb.activityOut;
- state.expandedAccessibilityClassName = Switch.class.getName();
- if (cb.noSim) {
- state.icon = ResourceIcon.get(R.drawable.ic_qs_no_sim);
- } else {
- state.icon = ResourceIcon.get(R.drawable.ic_swap_vert);
- }
-
- if (cb.noSim) {
- state.state = Tile.STATE_UNAVAILABLE;
- state.secondaryLabel = r.getString(R.string.keyguard_missing_sim_message_short);
- } else if (cb.airplaneModeEnabled) {
- state.state = Tile.STATE_UNAVAILABLE;
- state.secondaryLabel = r.getString(R.string.status_bar_airplane);
- } else if (mobileDataEnabled) {
- state.state = Tile.STATE_ACTIVE;
- state.secondaryLabel = appendMobileDataType(
- // Only show carrier name if there are more than 1 subscription
- cb.multipleSubs ? cb.dataSubscriptionName : "",
- getMobileDataContentName(cb));
- } else {
- state.state = Tile.STATE_INACTIVE;
- state.secondaryLabel = r.getString(R.string.cell_data_off);
- }
-
- state.contentDescription = state.label;
- if (state.state == Tile.STATE_INACTIVE) {
- // This information is appended later by converting the Tile.STATE_INACTIVE state.
- state.stateDescription = "";
- } else {
- state.stateDescription = state.secondaryLabel;
- }
- }
-
- private CharSequence appendMobileDataType(CharSequence current, CharSequence dataType) {
- if (TextUtils.isEmpty(dataType)) {
- return Html.fromHtml(current.toString(), 0);
- }
- if (TextUtils.isEmpty(current)) {
- return Html.fromHtml(dataType.toString(), 0);
- }
- String concat = mContext.getString(R.string.mobile_carrier_text_format, current, dataType);
- return Html.fromHtml(concat, 0);
- }
-
- private CharSequence getMobileDataContentName(CallbackInfo cb) {
- if (cb.roaming && !TextUtils.isEmpty(cb.dataContentDescription)) {
- String roaming = mContext.getString(R.string.data_connection_roaming);
- String dataDescription = cb.dataContentDescription.toString();
- return mContext.getString(R.string.mobile_data_text_format, roaming, dataDescription);
- }
- if (cb.roaming) {
- return mContext.getString(R.string.data_connection_roaming);
- }
- return cb.dataContentDescription;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsEvent.QS_CELLULAR;
- }
-
- @Override
- public boolean isAvailable() {
- return mController.hasMobileDataFeature()
- && mHost.getUserContext().getUserId() == UserHandle.USER_SYSTEM;
- }
-
- private static final class CallbackInfo {
- boolean airplaneModeEnabled;
- @Nullable
- CharSequence dataSubscriptionName;
- @Nullable
- CharSequence dataContentDescription;
- boolean activityIn;
- boolean activityOut;
- boolean noSim;
- boolean roaming;
- boolean multipleSubs;
- }
-
- private final class CellSignalCallback implements SignalCallback {
- private final CallbackInfo mInfo = new CallbackInfo();
-
- @Override
- public void setMobileDataIndicators(@NonNull MobileDataIndicators indicators) {
- if (indicators.qsIcon == null) {
- // Not data sim, don't display.
- return;
- }
- mInfo.dataSubscriptionName = mController.getMobileDataNetworkName();
- mInfo.dataContentDescription = indicators.qsDescription != null
- ? indicators.typeContentDescriptionHtml : null;
- mInfo.activityIn = indicators.activityIn;
- mInfo.activityOut = indicators.activityOut;
- mInfo.roaming = indicators.roaming;
- mInfo.multipleSubs = mController.getNumberSubscriptions() > 1;
- refreshState(mInfo);
- }
-
- @Override
- public void setNoSims(boolean show, boolean simDetected) {
- mInfo.noSim = show;
- refreshState(mInfo);
- }
-
- @Override
- public void setIsAirplaneMode(@NonNull IconState icon) {
- mInfo.airplaneModeEnabled = icon.visible;
- refreshState(mInfo);
- }
- }
-
- static Intent getCellularSettingIntent() {
- Intent intent = new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS);
- int dataSub = SubscriptionManager.getDefaultDataSubscriptionId();
- if (dataSub != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
- intent.putExtra(Settings.EXTRA_SUB_ID,
- SubscriptionManager.getDefaultDataSubscriptionId());
- }
- return intent;
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
deleted file mode 100644
index b2be56cc..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (C) 2014 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.systemui.qs.tiles;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.os.Handler;
-import android.os.Looper;
-import android.provider.Settings;
-import android.service.quicksettings.Tile;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.View;
-import android.widget.Switch;
-
-import androidx.annotation.Nullable;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.Background;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.qs.QSIconView;
-import com.android.systemui.plugins.qs.QSTile;
-import com.android.systemui.plugins.qs.QSTile.SignalState;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.AlphaControlledSignalTileView;
-import com.android.systemui.qs.QSHost;
-import com.android.systemui.qs.logging.QSLogger;
-import com.android.systemui.qs.tileimpl.QSIconViewImpl;
-import com.android.systemui.qs.tileimpl.QSTileImpl;
-import com.android.systemui.statusbar.connectivity.AccessPointController;
-import com.android.systemui.statusbar.connectivity.NetworkController;
-import com.android.systemui.statusbar.connectivity.SignalCallback;
-import com.android.systemui.statusbar.connectivity.WifiIcons;
-import com.android.systemui.statusbar.connectivity.WifiIndicators;
-
-import javax.inject.Inject;
-
-/** Quick settings tile: Wifi **/
-public class WifiTile extends QSTileImpl<SignalState> {
- private static final Intent WIFI_SETTINGS = new Intent(Settings.ACTION_WIFI_SETTINGS);
-
- protected final NetworkController mController;
- private final AccessPointController mWifiController;
- private final QSTile.SignalState mStateBeforeClick = newTileState();
-
- protected final WifiSignalCallback mSignalCallback = new WifiSignalCallback();
- private boolean mExpectDisabled;
-
- @Inject
- public WifiTile(
- QSHost host,
- @Background Looper backgroundLooper,
- @Main Handler mainHandler,
- FalsingManager falsingManager,
- MetricsLogger metricsLogger,
- StatusBarStateController statusBarStateController,
- ActivityStarter activityStarter,
- QSLogger qsLogger,
- NetworkController networkController,
- AccessPointController accessPointController
- ) {
- super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
- statusBarStateController, activityStarter, qsLogger);
- mController = networkController;
- mWifiController = accessPointController;
- mController.observe(getLifecycle(), mSignalCallback);
- mStateBeforeClick.spec = "wifi";
- }
-
- @Override
- public SignalState newTileState() {
- return new SignalState();
- }
-
- @Override
- public QSIconView createTileView(Context context) {
- return new AlphaControlledSignalTileView(context);
- }
-
- @Override
- public Intent getLongClickIntent() {
- return WIFI_SETTINGS;
- }
-
- @Override
- protected void handleClick(@Nullable View view) {
- // Secondary clicks are header clicks, just toggle.
- mState.copyTo(mStateBeforeClick);
- boolean wifiEnabled = mState.value;
- // Immediately enter transient state when turning on wifi.
- refreshState(wifiEnabled ? null : ARG_SHOW_TRANSIENT_ENABLING);
- mController.setWifiEnabled(!wifiEnabled);
- mExpectDisabled = wifiEnabled;
- if (mExpectDisabled) {
- mHandler.postDelayed(() -> {
- if (mExpectDisabled) {
- mExpectDisabled = false;
- refreshState();
- }
- }, QSIconViewImpl.QS_ANIM_LENGTH);
- }
- }
-
- @Override
- protected void handleSecondaryClick(@Nullable View view) {
- if (!mWifiController.canConfigWifi()) {
- mActivityStarter.postStartActivityDismissingKeyguard(
- new Intent(Settings.ACTION_WIFI_SETTINGS), 0);
- return;
- }
- if (!mState.value) {
- mController.setWifiEnabled(true);
- }
- }
-
- @Override
- public CharSequence getTileLabel() {
- return mContext.getString(R.string.quick_settings_wifi_label);
- }
-
- @Override
- protected void handleUpdateState(SignalState state, Object arg) {
- if (DEBUG) Log.d(TAG, "handleUpdateState arg=" + arg);
- final CallbackInfo cb = mSignalCallback.mInfo;
- if (mExpectDisabled) {
- if (cb.enabled) {
- return; // Ignore updates until disabled event occurs.
- } else {
- mExpectDisabled = false;
- }
- }
- boolean transientEnabling = arg == ARG_SHOW_TRANSIENT_ENABLING;
- boolean wifiConnected = cb.enabled && (cb.wifiSignalIconId > 0)
- && (cb.ssid != null || cb.wifiSignalIconId != WifiIcons.QS_WIFI_NO_NETWORK);
- boolean wifiNotConnected = (cb.ssid == null)
- && (cb.wifiSignalIconId == WifiIcons.QS_WIFI_NO_NETWORK);
- if (state.slash == null) {
- state.slash = new SlashState();
- state.slash.rotation = 6;
- }
- state.slash.isSlashed = false;
- boolean isTransient = transientEnabling || cb.isTransient;
- state.secondaryLabel = getSecondaryLabel(isTransient, cb.statusLabel);
- state.state = Tile.STATE_ACTIVE;
- state.dualTarget = true;
- state.value = transientEnabling || cb.enabled;
- state.activityIn = cb.enabled && cb.activityIn;
- state.activityOut = cb.enabled && cb.activityOut;
- final StringBuffer minimalContentDescription = new StringBuffer();
- final StringBuffer minimalStateDescription = new StringBuffer();
- final Resources r = mContext.getResources();
- if (isTransient) {
- state.icon = ResourceIcon.get(
- com.android.internal.R.drawable.ic_signal_wifi_transient_animation);
- state.label = r.getString(R.string.quick_settings_wifi_label);
- } else if (!state.value) {
- state.slash.isSlashed = true;
- state.state = Tile.STATE_INACTIVE;
- state.icon = ResourceIcon.get(WifiIcons.QS_WIFI_DISABLED);
- state.label = r.getString(R.string.quick_settings_wifi_label);
- } else if (wifiConnected) {
- state.icon = ResourceIcon.get(cb.wifiSignalIconId);
- state.label = cb.ssid != null ? removeDoubleQuotes(cb.ssid) : getTileLabel();
- } else if (wifiNotConnected) {
- state.icon = ResourceIcon.get(WifiIcons.QS_WIFI_NO_NETWORK);
- state.label = r.getString(R.string.quick_settings_wifi_label);
- } else {
- state.icon = ResourceIcon.get(WifiIcons.QS_WIFI_NO_NETWORK);
- state.label = r.getString(R.string.quick_settings_wifi_label);
- }
- minimalContentDescription.append(
- mContext.getString(R.string.quick_settings_wifi_label)).append(",");
- if (state.value) {
- if (wifiConnected) {
- minimalStateDescription.append(cb.wifiSignalContentDescription);
- minimalContentDescription.append(removeDoubleQuotes(cb.ssid));
- if (!TextUtils.isEmpty(state.secondaryLabel)) {
- minimalContentDescription.append(",").append(state.secondaryLabel);
- }
- }
- }
- state.stateDescription = minimalStateDescription.toString();
- state.contentDescription = minimalContentDescription.toString();
- state.dualLabelContentDescription = r.getString(
- R.string.accessibility_quick_settings_open_settings, getTileLabel());
- state.expandedAccessibilityClassName = Switch.class.getName();
- }
-
- private CharSequence getSecondaryLabel(boolean isTransient, String statusLabel) {
- return isTransient
- ? mContext.getString(R.string.quick_settings_wifi_secondary_label_transient)
- : statusLabel;
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsEvent.QS_WIFI;
- }
-
- @Override
- public boolean isAvailable() {
- return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI);
- }
-
- @Nullable
- private static String removeDoubleQuotes(String string) {
- if (string == null) return null;
- final int length = string.length();
- if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
- return string.substring(1, length - 1);
- }
- return string;
- }
-
- protected static final class CallbackInfo {
- boolean enabled;
- boolean connected;
- int wifiSignalIconId;
- @Nullable
- String ssid;
- boolean activityIn;
- boolean activityOut;
- @Nullable
- String wifiSignalContentDescription;
- boolean isTransient;
- @Nullable
- public String statusLabel;
-
- @Override
- public String toString() {
- return new StringBuilder("CallbackInfo[")
- .append("enabled=").append(enabled)
- .append(",connected=").append(connected)
- .append(",wifiSignalIconId=").append(wifiSignalIconId)
- .append(",ssid=").append(ssid)
- .append(",activityIn=").append(activityIn)
- .append(",activityOut=").append(activityOut)
- .append(",wifiSignalContentDescription=").append(wifiSignalContentDescription)
- .append(",isTransient=").append(isTransient)
- .append(']').toString();
- }
- }
-
- protected final class WifiSignalCallback implements SignalCallback {
- final CallbackInfo mInfo = new CallbackInfo();
-
- @Override
- public void setWifiIndicators(@NonNull WifiIndicators indicators) {
- if (DEBUG) Log.d(TAG, "onWifiSignalChanged enabled=" + indicators.enabled);
- if (indicators.qsIcon == null) {
- return;
- }
- mInfo.enabled = indicators.enabled;
- mInfo.connected = indicators.qsIcon.visible;
- mInfo.wifiSignalIconId = indicators.qsIcon.icon;
- mInfo.ssid = indicators.description;
- mInfo.activityIn = indicators.activityIn;
- mInfo.activityOut = indicators.activityOut;
- mInfo.wifiSignalContentDescription = indicators.qsIcon.contentDescription;
- mInfo.isTransient = indicators.isTransient;
- mInfo.statusLabel = indicators.statusLabel;
- refreshState();
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index a6c7781..72c6bfe 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -101,7 +101,6 @@
@MainThread
public void onManagedProfileRemoved() {
mHost.removeTile(getTileSpec());
- mHost.unmarkTileAsAutoAdded(getTileSpec());
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 91ebf79..b21a485 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -687,8 +687,8 @@
}
});
if (mFlags.isEnabled(SCREENSHOT_WORK_PROFILE_POLICY)) {
- mScreenshotView.badgeScreenshot(
- mContext.getPackageManager().getUserBadgeForDensity(owner, 0));
+ mScreenshotView.badgeScreenshot(mContext.getPackageManager().getUserBadgedIcon(
+ mContext.getDrawable(R.drawable.overlay_badge_background), owner));
}
mScreenshotView.setScreenshot(mScreenBitmap, screenInsets);
if (DEBUG_WINDOW) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index be40813..7c013a8 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -1097,7 +1097,7 @@
mScreenshotBadge.setVisibility(View.GONE);
mScreenshotBadge.setImageDrawable(null);
mPendingSharedTransition = false;
- mActionsContainerBackground.setVisibility(View.GONE);
+ mActionsContainerBackground.setVisibility(View.INVISIBLE);
mActionsContainer.setVisibility(View.GONE);
mDismissButton.setVisibility(View.GONE);
mScrollingScrim.setVisibility(View.GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index 2176825..35e9f3e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -21,7 +21,6 @@
import static com.android.internal.util.ScreenshotHelper.SCREENSHOT_MSG_PROCESS_COMPLETE;
import static com.android.internal.util.ScreenshotHelper.SCREENSHOT_MSG_URI;
-import static com.android.systemui.flags.Flags.SCREENSHOT_REQUEST_PROCESSOR;
import static com.android.systemui.flags.Flags.SCREENSHOT_WORK_PROFILE_POLICY;
import static com.android.systemui.screenshot.LogConfig.DEBUG_CALLBACK;
import static com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS;
@@ -122,7 +121,6 @@
mContext = context;
mBgExecutor = bgExecutor;
mFeatureFlags = featureFlags;
- mFeatureFlags.addListener(SCREENSHOT_REQUEST_PROCESSOR, FlagEvent::requestNoRestart);
mFeatureFlags.addListener(SCREENSHOT_WORK_PROFILE_POLICY, FlagEvent::requestNoRestart);
mProcessor = processor;
}
@@ -224,14 +222,8 @@
return;
}
- if (mFeatureFlags.isEnabled(SCREENSHOT_REQUEST_PROCESSOR)) {
- Log.d(TAG, "handleMessage: Using request processor");
- mProcessor.processAsync(request,
- (r) -> dispatchToController(r, onSaved, callback));
- return;
- }
-
- dispatchToController(request, onSaved, callback);
+ mProcessor.processAsync(request,
+ (r) -> dispatchToController(r, onSaved, callback));
}
private void dispatchToController(ScreenshotHelper.ScreenshotRequest request,
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
index 200288b..4dbe099 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
@@ -111,7 +111,7 @@
// These get called when a managed profile goes in or out of quiet mode.
addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE)
addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)
-
+ addAction(Intent.ACTION_MANAGED_PROFILE_ADDED)
addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED)
addAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED)
}
@@ -128,6 +128,7 @@
Intent.ACTION_USER_INFO_CHANGED,
Intent.ACTION_MANAGED_PROFILE_AVAILABLE,
Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE,
+ Intent.ACTION_MANAGED_PROFILE_ADDED,
Intent.ACTION_MANAGED_PROFILE_REMOVED,
Intent.ACTION_MANAGED_PROFILE_UNLOCKED -> {
handleProfilesChanged()
diff --git a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
index 7fc0a5f..e406be1 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
@@ -175,9 +175,10 @@
*/
var shadeExpandedFraction = -1f
set(value) {
- if (visible && field != value) {
+ if (field != value) {
header.alpha = ShadeInterpolation.getContentAlpha(value)
field = value
+ updateVisibility()
}
}
@@ -331,6 +332,9 @@
.setDuration(duration)
.alpha(if (show) 0f else 1f)
.setInterpolator(if (show) Interpolators.ALPHA_OUT else Interpolators.ALPHA_IN)
+ .setUpdateListener {
+ updateVisibility()
+ }
.start()
}
@@ -414,7 +418,7 @@
private fun updateVisibility() {
val visibility = if (!largeScreenActive && !combinedHeaders || qsDisabled) {
View.GONE
- } else if (qsVisible) {
+ } else if (qsVisible && header.alpha > 0f) {
View.VISIBLE
} else {
View.INVISIBLE
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index d711d15..93e8151 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -145,6 +145,8 @@
import com.android.systemui.keyguard.shared.model.TransitionStep;
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel;
import com.android.systemui.media.controls.pipeline.MediaDataManager;
import com.android.systemui.media.controls.ui.KeyguardMediaController;
@@ -689,12 +691,16 @@
private boolean mExpandLatencyTracking;
private DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel;
private OccludedToLockscreenTransitionViewModel mOccludedToLockscreenTransitionViewModel;
+ private LockscreenToDreamingTransitionViewModel mLockscreenToDreamingTransitionViewModel;
+ private LockscreenToOccludedTransitionViewModel mLockscreenToOccludedTransitionViewModel;
private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
private CoroutineDispatcher mMainDispatcher;
- private boolean mIsToLockscreenTransitionRunning = false;
+ private boolean mIsOcclusionTransitionRunning = false;
private int mDreamingToLockscreenTransitionTranslationY;
private int mOccludedToLockscreenTransitionTranslationY;
+ private int mLockscreenToDreamingTransitionTranslationY;
+ private int mLockscreenToOccludedTransitionTranslationY;
private boolean mUnocclusionTransitionFlagEnabled = false;
private final Runnable mFlingCollapseRunnable = () -> fling(0, false /* expand */,
@@ -713,13 +719,25 @@
private final Consumer<TransitionStep> mDreamingToLockscreenTransition =
(TransitionStep step) -> {
- mIsToLockscreenTransitionRunning =
+ mIsOcclusionTransitionRunning =
step.getTransitionState() == TransitionState.RUNNING;
};
private final Consumer<TransitionStep> mOccludedToLockscreenTransition =
(TransitionStep step) -> {
- mIsToLockscreenTransitionRunning =
+ mIsOcclusionTransitionRunning =
+ step.getTransitionState() == TransitionState.RUNNING;
+ };
+
+ private final Consumer<TransitionStep> mLockscreenToDreamingTransition =
+ (TransitionStep step) -> {
+ mIsOcclusionTransitionRunning =
+ step.getTransitionState() == TransitionState.RUNNING;
+ };
+
+ private final Consumer<TransitionStep> mLockscreenToOccludedTransition =
+ (TransitionStep step) -> {
+ mIsOcclusionTransitionRunning =
step.getTransitionState() == TransitionState.RUNNING;
};
@@ -794,6 +812,8 @@
AlternateBouncerInteractor alternateBouncerInteractor,
DreamingToLockscreenTransitionViewModel dreamingToLockscreenTransitionViewModel,
OccludedToLockscreenTransitionViewModel occludedToLockscreenTransitionViewModel,
+ LockscreenToDreamingTransitionViewModel lockscreenToDreamingTransitionViewModel,
+ LockscreenToOccludedTransitionViewModel lockscreenToOccludedTransitionViewModel,
@Main CoroutineDispatcher mainDispatcher,
KeyguardTransitionInteractor keyguardTransitionInteractor,
DumpManager dumpManager) {
@@ -813,6 +833,8 @@
mGutsManager = gutsManager;
mDreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel;
mOccludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel;
+ mLockscreenToDreamingTransitionViewModel = lockscreenToDreamingTransitionViewModel;
+ mLockscreenToOccludedTransitionViewModel = lockscreenToOccludedTransitionViewModel;
mKeyguardTransitionInteractor = keyguardTransitionInteractor;
mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
@@ -1121,22 +1143,44 @@
collectFlow(mView, mKeyguardTransitionInteractor.getDreamingToLockscreenTransition(),
mDreamingToLockscreenTransition, mMainDispatcher);
collectFlow(mView, mDreamingToLockscreenTransitionViewModel.getLockscreenAlpha(),
- toLockscreenTransitionAlpha(mNotificationStackScrollLayoutController),
+ setTransitionAlpha(mNotificationStackScrollLayoutController),
mMainDispatcher);
collectFlow(mView, mDreamingToLockscreenTransitionViewModel.lockscreenTranslationY(
mDreamingToLockscreenTransitionTranslationY),
- toLockscreenTransitionY(mNotificationStackScrollLayoutController),
+ setTransitionY(mNotificationStackScrollLayoutController),
mMainDispatcher);
// Occluded->Lockscreen
collectFlow(mView, mKeyguardTransitionInteractor.getOccludedToLockscreenTransition(),
mOccludedToLockscreenTransition, mMainDispatcher);
collectFlow(mView, mOccludedToLockscreenTransitionViewModel.getLockscreenAlpha(),
- toLockscreenTransitionAlpha(mNotificationStackScrollLayoutController),
+ setTransitionAlpha(mNotificationStackScrollLayoutController),
mMainDispatcher);
collectFlow(mView, mOccludedToLockscreenTransitionViewModel.lockscreenTranslationY(
mOccludedToLockscreenTransitionTranslationY),
- toLockscreenTransitionY(mNotificationStackScrollLayoutController),
+ setTransitionY(mNotificationStackScrollLayoutController),
+ mMainDispatcher);
+
+ // Lockscreen->Dreaming
+ collectFlow(mView, mKeyguardTransitionInteractor.getLockscreenToDreamingTransition(),
+ mLockscreenToDreamingTransition, mMainDispatcher);
+ collectFlow(mView, mLockscreenToDreamingTransitionViewModel.getLockscreenAlpha(),
+ setTransitionAlpha(mNotificationStackScrollLayoutController),
+ mMainDispatcher);
+ collectFlow(mView, mLockscreenToDreamingTransitionViewModel.lockscreenTranslationY(
+ mLockscreenToDreamingTransitionTranslationY),
+ setTransitionY(mNotificationStackScrollLayoutController),
+ mMainDispatcher);
+
+ // Lockscreen->Occluded
+ collectFlow(mView, mKeyguardTransitionInteractor.getLockscreenToOccludedTransition(),
+ mLockscreenToOccludedTransition, mMainDispatcher);
+ collectFlow(mView, mLockscreenToOccludedTransitionViewModel.getLockscreenAlpha(),
+ setTransitionAlpha(mNotificationStackScrollLayoutController),
+ mMainDispatcher);
+ collectFlow(mView, mLockscreenToOccludedTransitionViewModel.lockscreenTranslationY(
+ mLockscreenToOccludedTransitionTranslationY),
+ setTransitionY(mNotificationStackScrollLayoutController),
mMainDispatcher);
}
}
@@ -1177,6 +1221,10 @@
R.dimen.dreaming_to_lockscreen_transition_lockscreen_translation_y);
mOccludedToLockscreenTransitionTranslationY = mResources.getDimensionPixelSize(
R.dimen.occluded_to_lockscreen_transition_lockscreen_translation_y);
+ mLockscreenToDreamingTransitionTranslationY = mResources.getDimensionPixelSize(
+ R.dimen.lockscreen_to_dreaming_transition_lockscreen_translation_y);
+ mLockscreenToOccludedTransitionTranslationY = mResources.getDimensionPixelSize(
+ R.dimen.lockscreen_to_occluded_transition_lockscreen_translation_y);
}
private void updateViewControllers(KeyguardStatusView keyguardStatusView,
@@ -1840,7 +1888,7 @@
}
private void updateClock() {
- if (mIsToLockscreenTransitionRunning) {
+ if (mIsOcclusionTransitionRunning) {
return;
}
float alpha = mClockPositionResult.clockAlpha * mKeyguardOnlyContentAlpha;
@@ -2292,7 +2340,7 @@
// When false, down but not synthesized motion event.
mLastEventSynthesizedDown = mExpectingSynthesizedDown;
mLastDownEvents.insert(
- mSystemClock.currentTimeMillis(),
+ event.getEventTime(),
mDownX,
mDownY,
mQsTouchAboveFalsingThreshold,
@@ -2731,7 +2779,7 @@
} else if (statusBarState == KEYGUARD
|| statusBarState == StatusBarState.SHADE_LOCKED) {
mKeyguardBottomArea.setVisibility(View.VISIBLE);
- if (!mIsToLockscreenTransitionRunning) {
+ if (!mIsOcclusionTransitionRunning) {
mKeyguardBottomArea.setAlpha(1f);
}
} else {
@@ -3600,7 +3648,7 @@
}
private void updateNotificationTranslucency() {
- if (mIsToLockscreenTransitionRunning) {
+ if (mIsOcclusionTransitionRunning) {
return;
}
float alpha = 1f;
@@ -3658,7 +3706,7 @@
}
private void updateKeyguardBottomAreaAlpha() {
- if (mIsToLockscreenTransitionRunning) {
+ if (mIsOcclusionTransitionRunning) {
return;
}
// There are two possible panel expansion behaviors:
@@ -5890,7 +5938,7 @@
mCurrentPanelState = state;
}
- private Consumer<Float> toLockscreenTransitionAlpha(
+ private Consumer<Float> setTransitionAlpha(
NotificationStackScrollLayoutController stackScroller) {
return (Float alpha) -> {
mKeyguardStatusViewController.setAlpha(alpha);
@@ -5908,7 +5956,7 @@
};
}
- private Consumer<Float> toLockscreenTransitionY(
+ private Consumer<Float> setTransitionY(
NotificationStackScrollLayoutController stackScroller) {
return (Float translationY) -> {
mKeyguardStatusViewController.setTranslationY(translationY, /* excludeMedia= */false);
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index 64b6e61..7ed6e3e 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -16,6 +16,8 @@
package com.android.systemui.shade;
+import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
+
import android.app.StatusBarManager;
import android.media.AudioManager;
import android.media.session.MediaSessionLegacyHelper;
@@ -40,6 +42,9 @@
import com.android.systemui.flags.Flags;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
+import com.android.systemui.keyguard.shared.model.TransitionState;
+import com.android.systemui.keyguard.shared.model.TransitionStep;
import com.android.systemui.keyguard.ui.binder.KeyguardBouncerViewBinder;
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel;
import com.android.systemui.statusbar.DragDownHelper;
@@ -58,6 +63,7 @@
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
import java.io.PrintWriter;
+import java.util.function.Consumer;
import javax.inject.Inject;
@@ -98,6 +104,13 @@
private final ShadeExpansionStateManager mShadeExpansionStateManager;
private boolean mIsTrackingBarGesture = false;
+ private boolean mIsOcclusionTransitionRunning = false;
+
+ private final Consumer<TransitionStep> mLockscreenToDreamingTransition =
+ (TransitionStep step) -> {
+ mIsOcclusionTransitionRunning =
+ step.getTransitionState() == TransitionState.RUNNING;
+ };
@Inject
public NotificationShadeWindowViewController(
@@ -122,7 +135,8 @@
FeatureFlags featureFlags,
KeyguardBouncerViewModel keyguardBouncerViewModel,
KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory,
- AlternateBouncerInteractor alternateBouncerInteractor
+ AlternateBouncerInteractor alternateBouncerInteractor,
+ KeyguardTransitionInteractor keyguardTransitionInteractor
) {
mLockscreenShadeTransitionController = transitionController;
mFalsingCollector = falsingCollector;
@@ -152,6 +166,11 @@
keyguardBouncerViewModel,
keyguardBouncerComponentFactory);
}
+
+ if (featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION)) {
+ collectFlow(mView, keyguardTransitionInteractor.getLockscreenToDreamingTransition(),
+ mLockscreenToDreamingTransition);
+ }
}
/**
@@ -219,6 +238,10 @@
return true;
}
+ if (mIsOcclusionTransitionRunning) {
+ return false;
+ }
+
mFalsingCollector.onTouchEvent(ev);
mPulsingWakeupGestureHandler.onTouchEvent(ev);
mStatusBarKeyguardViewManager.onTouch(ev);
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
index 5fedbeb..11617be 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
@@ -36,16 +36,9 @@
buffer.log(TAG, LogLevel.DEBUG, msg)
}
- private inline fun log(
- logLevel: LogLevel,
- initializer: LogMessage.() -> Unit,
- noinline printer: LogMessage.() -> String
- ) {
- buffer.log(TAG, logLevel, initializer, printer)
- }
-
fun onQsInterceptMoveQsTrackingEnabled(h: Float) {
- log(
+ buffer.log(
+ TAG,
LogLevel.VERBOSE,
{ double1 = h.toDouble() },
{ "onQsIntercept: move action, QS tracking enabled. h = $double1" }
@@ -62,7 +55,8 @@
keyguardShowing: Boolean,
qsExpansionEnabled: Boolean
) {
- log(
+ buffer.log(
+ TAG,
LogLevel.VERBOSE,
{
int1 = initialTouchY.toInt()
@@ -82,7 +76,8 @@
}
fun logMotionEvent(event: MotionEvent, message: String) {
- log(
+ buffer.log(
+ TAG,
LogLevel.VERBOSE,
{
str1 = message
@@ -99,7 +94,8 @@
}
fun logMotionEventStatusBarState(event: MotionEvent, statusBarState: Int, message: String) {
- log(
+ buffer.log(
+ TAG,
LogLevel.VERBOSE,
{
str1 = message
@@ -128,25 +124,33 @@
tracking: Boolean,
dragDownPxAmount: Float,
) {
- log(LogLevel.VERBOSE, {
- str1 = message
- double1 = fraction.toDouble()
- bool1 = expanded
- bool2 = tracking
- long1 = dragDownPxAmount.toLong()
- }, {
- "$str1 fraction=$double1,expanded=$bool1," +
+ buffer.log(
+ TAG,
+ LogLevel.VERBOSE,
+ {
+ str1 = message
+ double1 = fraction.toDouble()
+ bool1 = expanded
+ bool2 = tracking
+ long1 = dragDownPxAmount.toLong()
+ },
+ {
+ "$str1 fraction=$double1,expanded=$bool1," +
"tracking=$bool2," + "dragDownPxAmount=$dragDownPxAmount"
- })
+ }
+ )
}
fun logHasVibrated(hasVibratedOnOpen: Boolean, fraction: Float) {
- log(LogLevel.VERBOSE, {
- bool1 = hasVibratedOnOpen
- double1 = fraction.toDouble()
- }, {
- "hasVibratedOnOpen=$bool1, expansionFraction=$double1"
- })
+ buffer.log(
+ TAG,
+ LogLevel.VERBOSE,
+ {
+ bool1 = hasVibratedOnOpen
+ double1 = fraction.toDouble()
+ },
+ { "hasVibratedOnOpen=$bool1, expansionFraction=$double1" }
+ )
}
fun logQsExpansionChanged(
@@ -159,42 +163,56 @@
qsAnimatorExpand: Boolean,
animatingQs: Boolean
) {
- log(LogLevel.VERBOSE, {
- str1 = message
- bool1 = qsExpanded
- int1 = qsMinExpansionHeight
- int2 = qsMaxExpansionHeight
- bool2 = stackScrollerOverscrolling
- bool3 = dozing
- bool4 = qsAnimatorExpand
- // 0 = false, 1 = true
- long1 = animatingQs.compareTo(false).toLong()
- }, {
- "$str1 qsExpanded=$bool1,qsMinExpansionHeight=$int1,qsMaxExpansionHeight=$int2," +
+ buffer.log(
+ TAG,
+ LogLevel.VERBOSE,
+ {
+ str1 = message
+ bool1 = qsExpanded
+ int1 = qsMinExpansionHeight
+ int2 = qsMaxExpansionHeight
+ bool2 = stackScrollerOverscrolling
+ bool3 = dozing
+ bool4 = qsAnimatorExpand
+ // 0 = false, 1 = true
+ long1 = animatingQs.compareTo(false).toLong()
+ },
+ {
+ "$str1 qsExpanded=$bool1,qsMinExpansionHeight=$int1,qsMaxExpansionHeight=$int2," +
"stackScrollerOverscrolling=$bool2,dozing=$bool3,qsAnimatorExpand=$bool4," +
"animatingQs=$long1"
- })
+ }
+ )
}
fun logSingleTapUp(isDozing: Boolean, singleTapEnabled: Boolean, isNotDocked: Boolean) {
- log(LogLevel.DEBUG, {
- bool1 = isDozing
- bool2 = singleTapEnabled
- bool3 = isNotDocked
- }, {
- "PulsingGestureListener#onSingleTapUp all of this must true for single " +
- "tap to be detected: isDozing: $bool1, singleTapEnabled: $bool2, isNotDocked: $bool3"
+ buffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ bool1 = isDozing
+ bool2 = singleTapEnabled
+ bool3 = isNotDocked
+ },
+ {
+ "PulsingGestureListener#onSingleTapUp all of this must true for single " +
+ "tap to be detected: isDozing: $bool1, singleTapEnabled: $bool2, isNotDocked: $bool3"
})
}
fun logSingleTapUpFalsingState(proximityIsNotNear: Boolean, isNotFalseTap: Boolean) {
- log(LogLevel.DEBUG, {
- bool1 = proximityIsNotNear
- bool2 = isNotFalseTap
- }, {
- "PulsingGestureListener#onSingleTapUp all of this must true for single " +
+ buffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ bool1 = proximityIsNotNear
+ bool2 = isNotFalseTap
+ },
+ {
+ "PulsingGestureListener#onSingleTapUp all of this must true for single " +
"tap to be detected: proximityIsNotNear: $bool1, isNotFalseTap: $bool2"
- })
+ }
+ )
}
fun logNotInterceptingTouchInstantExpanding(
@@ -202,13 +220,18 @@
notificationsDragEnabled: Boolean,
touchDisabled: Boolean
) {
- log(LogLevel.VERBOSE, {
- bool1 = instantExpanding
- bool2 = notificationsDragEnabled
- bool3 = touchDisabled
- }, {
- "NPVC not intercepting touch, instantExpanding: $bool1, " +
+ buffer.log(
+ TAG,
+ LogLevel.VERBOSE,
+ {
+ bool1 = instantExpanding
+ bool2 = notificationsDragEnabled
+ bool3 = touchDisabled
+ },
+ {
+ "NPVC not intercepting touch, instantExpanding: $bool1, " +
"!notificationsDragEnabled: $bool2, touchDisabled: $bool3"
- })
+ }
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLogger.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLogger.kt
index c6a6e87..9851625 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLogger.kt
@@ -32,11 +32,21 @@
ConstantStringsLogger by ConstantStringsLoggerImpl(buffer, TAG) {
fun logApplyingWindowLayoutParams(lp: WindowManager.LayoutParams) {
- log(DEBUG, { str1 = lp.toString() }, { "Applying new window layout params: $str1" })
+ buffer.log(
+ TAG,
+ DEBUG,
+ { str1 = lp.toString() },
+ { "Applying new window layout params: $str1" }
+ )
}
fun logNewState(state: Any) {
- log(DEBUG, { str1 = state.toString() }, { "Applying new state: $str1" })
+ buffer.log(
+ TAG,
+ DEBUG,
+ { str1 = state.toString() },
+ { "Applying new state: $str1" }
+ )
}
private inline fun log(
@@ -48,11 +58,16 @@
}
fun logApplyVisibility(visible: Boolean) {
- log(DEBUG, { bool1 = visible }, { "Updating visibility, should be visible : $bool1" })
+ buffer.log(
+ TAG,
+ DEBUG,
+ { bool1 = visible },
+ { "Updating visibility, should be visible : $bool1" })
}
fun logShadeVisibleAndFocusable(visible: Boolean) {
- log(
+ buffer.log(
+ TAG,
DEBUG,
{ bool1 = visible },
{ "Updating shade, should be visible and focusable: $bool1" }
@@ -60,6 +75,11 @@
}
fun logShadeFocusable(focusable: Boolean) {
- log(DEBUG, { bool1 = focusable }, { "Updating shade, should be focusable : $bool1" })
+ buffer.log(
+ TAG,
+ DEBUG,
+ { bool1 = focusable },
+ { "Updating shade, should be focusable : $bool1" }
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 96a6169..0f52133 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -41,6 +41,7 @@
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_USER_LOCKED;
import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_ON;
import static com.android.systemui.plugins.FalsingManager.LOW_PENALTY;
+import static com.android.systemui.plugins.log.LogLevel.ERROR;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
@@ -1044,7 +1045,7 @@
mChargingTimeRemaining = mPowerPluggedIn
? mBatteryInfo.computeChargeTimeRemaining() : -1;
} catch (RemoteException e) {
- mKeyguardLogger.logException(e, "Error calling IBatteryStats");
+ mKeyguardLogger.log(TAG, ERROR, "Error calling IBatteryStats", e);
mChargingTimeRemaining = -1;
}
updateDeviceEntryIndication(!wasPluggedIn && mPowerPluggedInWired);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 8f9365c..99081e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -65,8 +65,6 @@
import com.android.systemui.util.DumpUtilsKt;
import com.android.systemui.util.ListenerSet;
-import dagger.Lazy;
-
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -74,6 +72,8 @@
import java.util.Optional;
import java.util.function.Consumer;
+import dagger.Lazy;
+
/**
* Class for handling remote input state over a set of notifications. This class handles things
* like keeping notifications temporarily that were cancelled as a response to a remote input
@@ -465,8 +465,7 @@
riv.getController().setRemoteInput(input);
riv.getController().setRemoteInputs(inputs);
riv.getController().setEditedSuggestionInfo(editedSuggestionInfo);
- ViewGroup parent = view.getParent() != null ? (ViewGroup) view.getParent() : null;
- riv.focusAnimated(parent);
+ riv.focusAnimated();
if (userMessageContent != null) {
riv.setEditTextContent(userMessageContent);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java
index 76025ab7..0446165 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java
@@ -53,7 +53,9 @@
return true;
}
if (otherState instanceof ImageTransformState) {
- return mIcon != null && mIcon.sameAs(((ImageTransformState) otherState).getIcon());
+ final Icon otherIcon = ((ImageTransformState) otherState).mIcon;
+ return mIcon == otherIcon || (mIcon != null && otherIcon != null && mIcon.sameAs(
+ otherIcon));
}
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
index c496102..b084a76 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
@@ -109,7 +109,7 @@
return true;
}
if (ev.getAction() == MotionEvent.ACTION_UP) {
- mView.setLastActionUpTime(SystemClock.uptimeMillis());
+ mView.setLastActionUpTime(ev.getEventTime());
}
// With a11y, just do nothing.
if (mAccessibilityManager.isTouchExplorationEnabled()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index 8d48d73..9b93d7b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -1431,6 +1431,22 @@
@Override
public void applyRoundnessAndInvalidate() {
boolean last = true;
+ if (mUseRoundnessSourceTypes) {
+ if (mNotificationHeaderWrapper != null) {
+ mNotificationHeaderWrapper.requestTopRoundness(
+ /* value = */ getTopRoundness(),
+ /* sourceType = */ FROM_PARENT,
+ /* animate = */ false
+ );
+ }
+ if (mNotificationHeaderWrapperLowPriority != null) {
+ mNotificationHeaderWrapperLowPriority.requestTopRoundness(
+ /* value = */ getTopRoundness(),
+ /* sourceType = */ FROM_PARENT,
+ /* animate = */ false
+ );
+ }
+ }
for (int i = mAttachedChildren.size() - 1; i >= 0; i--) {
ExpandableNotificationRow child = mAttachedChildren.get(i);
if (child.getVisibility() == View.GONE) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index ca1e397..356ddfa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -1811,9 +1811,7 @@
@Override
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- mBottomInset = insets.getSystemWindowInsetBottom()
- + insets.getInsets(WindowInsets.Type.ime()).bottom;
-
+ mBottomInset = insets.getInsets(WindowInsets.Type.ime()).bottom;
mWaterfallTopInset = 0;
final DisplayCutout cutout = insets.getDisplayCutout();
if (cutout != null) {
@@ -2262,7 +2260,11 @@
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
private int getImeInset() {
- return Math.max(0, mBottomInset - (getRootView().getHeight() - getHeight()));
+ // The NotificationStackScrollLayout does not extend all the way to the bottom of the
+ // display. Therefore, subtract that space from the mBottomInset, in order to only include
+ // the portion of the bottom inset that actually overlaps the NotificationStackScrollLayout.
+ return Math.max(0, mBottomInset
+ - (getRootView().getHeight() - getHeight() - getLocationOnScreen()[1]));
}
/**
@@ -2970,12 +2972,19 @@
childInGroup = (ExpandableNotificationRow) requestedView;
requestedView = requestedRow = childInGroup.getNotificationParent();
}
- int position = 0;
+ final float scrimTopPadding = mAmbientState.isOnKeyguard() ? 0 : mMinimumPaddings;
+ int position = (int) scrimTopPadding;
+ int visibleIndex = -1;
+ ExpandableView lastVisibleChild = null;
for (int i = 0; i < getChildCount(); i++) {
ExpandableView child = getChildAtIndex(i);
boolean notGone = child.getVisibility() != View.GONE;
+ if (notGone) visibleIndex++;
if (notGone && !child.hasNoContentHeight()) {
- if (position != 0) {
+ if (position != scrimTopPadding) {
+ if (lastVisibleChild != null) {
+ position += calculateGapHeight(lastVisibleChild, child, visibleIndex);
+ }
position += mPaddingBetweenElements;
}
}
@@ -2987,6 +2996,7 @@
}
if (notGone) {
position += getIntrinsicHeight(child);
+ lastVisibleChild = child;
}
}
return 0;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index 9070ead..149ec54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -154,9 +154,7 @@
if (!mAutoTracker.isAdded(SAVER)) {
mDataSaverController.addCallback(mDataSaverListener);
}
- if (!mAutoTracker.isAdded(WORK)) {
- mManagedProfileController.addCallback(mProfileCallback);
- }
+ mManagedProfileController.addCallback(mProfileCallback);
if (!mAutoTracker.isAdded(NIGHT)
&& ColorDisplayManager.isNightDisplayAvailable(mContext)) {
mNightDisplayListener.setCallback(mNightDisplayCallback);
@@ -275,18 +273,18 @@
return mCurrentUser.getIdentifier();
}
- public void unmarkTileAsAutoAdded(String tabSpec) {
- mAutoTracker.setTileRemoved(tabSpec);
- }
-
private final ManagedProfileController.Callback mProfileCallback =
new ManagedProfileController.Callback() {
@Override
public void onManagedProfileChanged() {
- if (mAutoTracker.isAdded(WORK)) return;
if (mManagedProfileController.hasActiveProfile()) {
+ if (mAutoTracker.isAdded(WORK)) return;
mHost.addTile(WORK);
mAutoTracker.setTileAdded(WORK);
+ } else {
+ if (!mAutoTracker.isAdded(WORK)) return;
+ mHost.removeTile(WORK);
+ mAutoTracker.setTileRemoved(WORK);
}
}
@@ -429,7 +427,7 @@
initSafetyTile();
} else if (!isSafetyCenterEnabled && mAutoTracker.isAdded(mSafetySpec)) {
mHost.removeTile(mSafetySpec);
- mHost.unmarkTileAsAutoAdded(mSafetySpec);
+ mAutoTracker.setTileRemoved(mSafetySpec);
}
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index 9a8c5d7..9f38361 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -18,6 +18,8 @@
import static android.app.StatusBarManager.SESSION_KEYGUARD;
+import static com.android.systemui.keyguard.WakefulnessLifecycle.UNKNOWN_LAST_WAKE_TIME;
+
import android.annotation.IntDef;
import android.content.res.Resources;
import android.hardware.biometrics.BiometricFaceConstants;
@@ -27,7 +29,6 @@
import android.metrics.LogMaker;
import android.os.Handler;
import android.os.PowerManager;
-import android.os.SystemClock;
import android.os.Trace;
import androidx.annotation.Nullable;
@@ -59,6 +60,7 @@
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.time.SystemClock;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -75,6 +77,7 @@
*/
@SysUISingleton
public class BiometricUnlockController extends KeyguardUpdateMonitorCallback implements Dumpable {
+ private static final long RECENT_POWER_BUTTON_PRESS_THRESHOLD_MS = 400L;
private static final long BIOMETRIC_WAKELOCK_TIMEOUT_MS = 15 * 1000;
private static final String BIOMETRIC_WAKE_LOCK_NAME = "wake-and-unlock:wakelock";
private static final UiEventLogger UI_EVENT_LOGGER = new UiEventLoggerImpl();
@@ -165,9 +168,11 @@
private final MetricsLogger mMetricsLogger;
private final AuthController mAuthController;
private final StatusBarStateController mStatusBarStateController;
+ private final WakefulnessLifecycle mWakefulnessLifecycle;
private final LatencyTracker mLatencyTracker;
private final VibratorHelper mVibratorHelper;
private final BiometricUnlockLogger mLogger;
+ private final SystemClock mSystemClock;
private long mLastFpFailureUptimeMillis;
private int mNumConsecutiveFpFailures;
@@ -272,13 +277,16 @@
SessionTracker sessionTracker,
LatencyTracker latencyTracker,
ScreenOffAnimationController screenOffAnimationController,
- VibratorHelper vibrator) {
+ VibratorHelper vibrator,
+ SystemClock systemClock
+ ) {
mPowerManager = powerManager;
mUpdateMonitor = keyguardUpdateMonitor;
mUpdateMonitor.registerCallback(this);
mMediaManager = notificationMediaManager;
mLatencyTracker = latencyTracker;
- wakefulnessLifecycle.addObserver(mWakefulnessObserver);
+ mWakefulnessLifecycle = wakefulnessLifecycle;
+ mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
screenLifecycle.addObserver(mScreenObserver);
mNotificationShadeWindowController = notificationShadeWindowController;
@@ -297,6 +305,7 @@
mScreenOffAnimationController = screenOffAnimationController;
mVibratorHelper = vibrator;
mLogger = biometricUnlockLogger;
+ mSystemClock = systemClock;
dumpManager.registerDumpable(getClass().getName(), this);
}
@@ -420,8 +429,11 @@
Runnable wakeUp = ()-> {
if (!wasDeviceInteractive || mUpdateMonitor.isDreaming()) {
mLogger.i("bio wakelock: Authenticated, waking up...");
- mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_BIOMETRIC,
- "android.policy:BIOMETRIC");
+ mPowerManager.wakeUp(
+ mSystemClock.uptimeMillis(),
+ PowerManager.WAKE_REASON_BIOMETRIC,
+ "android.policy:BIOMETRIC"
+ );
}
Trace.beginSection("release wake-and-unlock");
releaseBiometricWakeLock();
@@ -652,7 +664,7 @@
startWakeAndUnlock(MODE_ONLY_WAKE);
} else if (biometricSourceType == BiometricSourceType.FINGERPRINT
&& mUpdateMonitor.isUdfpsSupported()) {
- long currUptimeMillis = SystemClock.uptimeMillis();
+ long currUptimeMillis = mSystemClock.uptimeMillis();
if (currUptimeMillis - mLastFpFailureUptimeMillis < mConsecutiveFpFailureThreshold) {
mNumConsecutiveFpFailures += 1;
} else {
@@ -700,12 +712,26 @@
cleanup();
}
- //these haptics are for device-entry only
+ // these haptics are for device-entry only
private void vibrateSuccess(BiometricSourceType type) {
+ if (mAuthController.isSfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser())
+ && lastWakeupFromPowerButtonWithinHapticThreshold()) {
+ mLogger.d("Skip auth success haptic. Power button was recently pressed.");
+ return;
+ }
mVibratorHelper.vibrateAuthSuccess(
getClass().getSimpleName() + ", type =" + type + "device-entry::success");
}
+ private boolean lastWakeupFromPowerButtonWithinHapticThreshold() {
+ final boolean lastWakeupFromPowerButton = mWakefulnessLifecycle.getLastWakeReason()
+ == PowerManager.WAKE_REASON_POWER_BUTTON;
+ return lastWakeupFromPowerButton
+ && mWakefulnessLifecycle.getLastWakeTime() != UNKNOWN_LAST_WAKE_TIME
+ && mSystemClock.uptimeMillis() - mWakefulnessLifecycle.getLastWakeTime()
+ < RECENT_POWER_BUTTON_PRESS_THRESHOLD_MS;
+ }
+
private void vibrateError(BiometricSourceType type) {
mVibratorHelper.vibrateAuthError(
getClass().getSimpleName() + ", type =" + type + "device-entry::error");
@@ -798,7 +824,7 @@
if (mUpdateMonitor.isUdfpsSupported()) {
pw.print(" mNumConsecutiveFpFailures="); pw.println(mNumConsecutiveFpFailures);
pw.print(" time since last failure=");
- pw.println(SystemClock.uptimeMillis() - mLastFpFailureUptimeMillis);
+ pw.println(mSystemClock.uptimeMillis() - mLastFpFailureUptimeMillis);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 22ebcab..4b56594 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -4247,8 +4247,7 @@
@Override
public void onDozeAmountChanged(float linear, float eased) {
- if (mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS)
- && !mFeatureFlags.isEnabled(Flags.LIGHT_REVEAL_MIGRATION)
+ if (!mFeatureFlags.isEnabled(Flags.LIGHT_REVEAL_MIGRATION)
&& !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) {
mLightRevealScrim.setRevealAmount(1f - linear);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index de7b152..0446cef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -44,10 +44,9 @@
import com.android.systemui.doze.AlwaysOnDisplayPolicy;
import com.android.systemui.doze.DozeScreenState;
import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.tuner.TunerService;
@@ -82,7 +81,6 @@
private final AlwaysOnDisplayPolicy mAlwaysOnPolicy;
private final Resources mResources;
private final BatteryController mBatteryController;
- private final FeatureFlags mFeatureFlags;
private final ScreenOffAnimationController mScreenOffAnimationController;
private final FoldAodAnimationController mFoldAodAnimationController;
private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
@@ -125,7 +123,6 @@
BatteryController batteryController,
TunerService tunerService,
DumpManager dumpManager,
- FeatureFlags featureFlags,
ScreenOffAnimationController screenOffAnimationController,
Optional<SysUIUnfoldComponent> sysUiUnfoldComponent,
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
@@ -141,7 +138,6 @@
mControlScreenOffAnimation = !getDisplayNeedsBlanking();
mPowerManager = powerManager;
mPowerManager.setDozeAfterScreenOff(!mControlScreenOffAnimation);
- mFeatureFlags = featureFlags;
mScreenOffAnimationController = screenOffAnimationController;
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
@@ -162,6 +158,13 @@
SettingsObserver quickPickupSettingsObserver = new SettingsObserver(context, handler);
quickPickupSettingsObserver.observe();
+
+ batteryController.addCallback(new BatteryStateChangeCallback() {
+ @Override
+ public void onPowerSaveChanged(boolean isPowerSave) {
+ dispatchAlwaysOnEvent();
+ }
+ });
}
private void updateQuickPickupEnabled() {
@@ -300,13 +303,10 @@
/**
* Whether we're capable of controlling the screen off animation if we want to. This isn't
- * possible if AOD isn't even enabled or if the flag is disabled, or if the display needs
- * blanking.
+ * possible if AOD isn't even enabled or if the display needs blanking.
*/
public boolean canControlUnlockedScreenOff() {
- return getAlwaysOn()
- && mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS)
- && !getDisplayNeedsBlanking();
+ return getAlwaysOn() && !getDisplayNeedsBlanking();
}
/**
@@ -424,9 +424,7 @@
updateControlScreenOff();
}
- for (Callback callback : mCallbacks) {
- callback.onAlwaysOnChange();
- }
+ dispatchAlwaysOnEvent();
mScreenOffAnimationController.onAlwaysOnChanged(getAlwaysOn());
}
@@ -463,6 +461,12 @@
pw.print("isQuickPickupEnabled(): "); pw.println(isQuickPickupEnabled());
}
+ private void dispatchAlwaysOnEvent() {
+ for (Callback callback : mCallbacks) {
+ callback.onAlwaysOnChange();
+ }
+ }
+
private boolean getPostureSpecificBool(
int[] postureMapping,
boolean defaultSensorBool,
@@ -477,7 +481,8 @@
return bool;
}
- interface Callback {
+ /** Callbacks for doze parameter related information */
+ public interface Callback {
/**
* Invoked when the value of getAlwaysOn may have changed.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
index 3483574..4ad3199 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
@@ -45,6 +45,7 @@
import com.android.systemui.animation.Interpolators;
import com.android.systemui.battery.BatteryMeterViewController;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.plugins.log.LogLevel;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.statusbar.CommandQueue;
@@ -76,6 +77,7 @@
/** View Controller for {@link com.android.systemui.statusbar.phone.KeyguardStatusBarView}. */
public class KeyguardStatusBarViewController extends ViewController<KeyguardStatusBarView> {
+ private static final String TAG = "KeyguardStatusBarViewController";
private static final AnimationProperties KEYGUARD_HUN_PROPERTIES =
new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
@@ -422,7 +424,7 @@
/** Animate the keyguard status bar in. */
public void animateKeyguardStatusBarIn() {
- mLogger.d("animating status bar in");
+ mLogger.log(TAG, LogLevel.DEBUG, "animating status bar in");
if (mDisableStateTracker.isDisabled()) {
// If our view is disabled, don't allow us to animate in.
return;
@@ -438,7 +440,7 @@
/** Animate the keyguard status bar out. */
public void animateKeyguardStatusBarOut(long startDelay, long duration) {
- mLogger.d("animating status bar out");
+ mLogger.log(TAG, LogLevel.DEBUG, "animating status bar out");
ValueAnimator anim = ValueAnimator.ofFloat(mView.getAlpha(), 0f);
anim.addUpdateListener(mAnimatorUpdateListener);
anim.setStartDelay(startDelay);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt
index 08599c2..fbe374c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.phone
+import android.view.InsetsFlags
+import android.view.ViewDebug
import android.view.WindowInsets.Type.InsetsType
import android.view.WindowInsetsController.Appearance
import android.view.WindowInsetsController.Behavior
@@ -148,4 +150,20 @@
) {
val letterboxesArray = letterboxes.toTypedArray()
val appearanceRegionsArray = appearanceRegions.toTypedArray()
+ override fun toString(): String {
+ val appearanceToString =
+ ViewDebug.flagsToString(InsetsFlags::class.java, "appearance", appearance)
+ return """SystemBarAttributesParams(
+ displayId=$displayId,
+ appearance=$appearanceToString,
+ appearanceRegions=$appearanceRegions,
+ navbarColorManagedByIme=$navbarColorManagedByIme,
+ behavior=$behavior,
+ requestedVisibleTypes=$requestedVisibleTypes,
+ packageName='$packageName',
+ letterboxes=$letterboxes,
+ letterboxesArray=${letterboxesArray.contentToString()},
+ appearanceRegionsArray=${appearanceRegionsArray.contentToString()}
+ )""".trimMargin()
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt
index 0e164e7..8ac1237 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt
@@ -149,7 +149,7 @@
}
private fun createDemoMobileConnectionRepo(subId: Int): DemoMobileConnectionRepository {
- val tableLogBuffer = logFactory.create("DemoMobileConnectionLog [$subId]", 100)
+ val tableLogBuffer = logFactory.getOrCreate("DemoMobileConnectionLog [$subId]", 100)
return DemoMobileConnectionRepository(
subId,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
index 0fa0fea..4e42f9b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
@@ -308,7 +308,7 @@
networkNameSeparator: String,
globalMobileDataSettingChangedEvent: Flow<Unit>,
): MobileConnectionRepository {
- val mobileLogger = logFactory.create(tableBufferLogName(subId), 100)
+ val mobileLogger = logFactory.getOrCreate(tableBufferLogName(subId), 100)
return MobileConnectionRepositoryImpl(
context,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index c9ed0cb..f8c17e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -109,6 +109,8 @@
private static final long FOCUS_ANIMATION_FADE_IN_DELAY = 33;
private static final long FOCUS_ANIMATION_FADE_IN_DURATION = 83;
private static final float FOCUS_ANIMATION_MIN_SCALE = 0.5f;
+ private static final long DEFOCUS_ANIMATION_FADE_OUT_DELAY = 120;
+ private static final long DEFOCUS_ANIMATION_CROSSFADE_DELAY = 180;
public final Object mToken = new Object();
@@ -421,7 +423,7 @@
}
@VisibleForTesting
- void onDefocus(boolean animate, boolean logClose) {
+ void onDefocus(boolean animate, boolean logClose, @Nullable Runnable doAfterDefocus) {
mController.removeRemoteInput(mEntry, mToken);
mEntry.remoteInputText = mEditText.getText();
@@ -431,18 +433,20 @@
ViewGroup parent = (ViewGroup) getParent();
if (animate && parent != null && mIsFocusAnimationFlagActive) {
-
ViewGroup grandParent = (ViewGroup) parent.getParent();
ViewGroupOverlay overlay = parent.getOverlay();
+ View actionsContainer = getActionsContainerLayout();
+ int actionsContainerHeight =
+ actionsContainer != null ? actionsContainer.getHeight() : 0;
// After adding this RemoteInputView to the overlay of the parent (and thus removing
// it from the parent itself), the parent will shrink in height. This causes the
// overlay to be moved. To correct the position of the overlay we need to offset it.
- int overlayOffsetY = getMaxSiblingHeight() - getHeight();
+ int overlayOffsetY = actionsContainerHeight - getHeight();
overlay.add(this);
if (grandParent != null) grandParent.setClipChildren(false);
- Animator animator = getDefocusAnimator(overlayOffsetY);
+ Animator animator = getDefocusAnimator(actionsContainer, overlayOffsetY);
View self = this;
animator.addListener(new AnimatorListenerAdapter() {
@Override
@@ -454,8 +458,12 @@
if (mWrapper != null) {
mWrapper.setRemoteInputVisible(false);
}
+ if (doAfterDefocus != null) {
+ doAfterDefocus.run();
+ }
}
});
+ if (actionsContainer != null) actionsContainer.setAlpha(0f);
animator.start();
} else if (animate && mRevealParams != null && mRevealParams.radius > 0) {
@@ -474,6 +482,7 @@
reveal.start();
} else {
setVisibility(GONE);
+ if (doAfterDefocus != null) doAfterDefocus.run();
if (mWrapper != null) {
mWrapper.setRemoteInputVisible(false);
}
@@ -596,10 +605,8 @@
/**
* Focuses the RemoteInputView and animates its appearance
- *
- * @param crossFadeView view that will be crossfaded during the appearance animation
*/
- public void focusAnimated(View crossFadeView) {
+ public void focusAnimated() {
if (!mIsFocusAnimationFlagActive && getVisibility() != VISIBLE
&& mRevealParams != null) {
android.animation.Animator animator = mRevealParams.createCircularRevealAnimator(this);
@@ -609,7 +616,7 @@
} else if (mIsFocusAnimationFlagActive && getVisibility() != VISIBLE) {
mIsAnimatingAppearance = true;
setAlpha(0f);
- Animator focusAnimator = getFocusAnimator(crossFadeView);
+ Animator focusAnimator = getFocusAnimator(getActionsContainerLayout());
focusAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation, boolean isReverse) {
@@ -661,6 +668,23 @@
}
private void reset() {
+ if (mIsFocusAnimationFlagActive) {
+ mProgressBar.setVisibility(INVISIBLE);
+ mResetting = true;
+ mSending = false;
+ onDefocus(true /* animate */, false /* logClose */, () -> {
+ mEntry.remoteInputTextWhenReset = SpannedString.valueOf(mEditText.getText());
+ mEditText.getText().clear();
+ mEditText.setEnabled(isAggregatedVisible());
+ mSendButton.setVisibility(VISIBLE);
+ mController.removeSpinning(mEntry.getKey(), mToken);
+ updateSendButton();
+ setAttachment(null);
+ mResetting = false;
+ });
+ return;
+ }
+
mResetting = true;
mSending = false;
mEntry.remoteInputTextWhenReset = SpannedString.valueOf(mEditText.getText());
@@ -671,7 +695,7 @@
mProgressBar.setVisibility(INVISIBLE);
mController.removeSpinning(mEntry.getKey(), mToken);
updateSendButton();
- onDefocus(false /* animate */, false /* logClose */);
+ onDefocus(false /* animate */, false /* logClose */, null /* doAfterDefocus */);
setAttachment(null);
mResetting = false;
@@ -825,23 +849,22 @@
}
/**
- * @return max sibling height (0 in case of no siblings)
+ * @return action button container view (i.e. ViewGroup containing Reply button etc.)
*/
- public int getMaxSiblingHeight() {
+ public View getActionsContainerLayout() {
ViewGroup parentView = (ViewGroup) getParent();
- int maxHeight = 0;
- if (parentView == null) return 0;
- for (int i = 0; i < parentView.getChildCount(); i++) {
- View siblingView = parentView.getChildAt(i);
- if (siblingView != this) maxHeight = Math.max(maxHeight, siblingView.getHeight());
- }
- return maxHeight;
+ if (parentView == null) return null;
+ return parentView.findViewById(com.android.internal.R.id.actions_container_layout);
}
/**
* Creates an animator for the focus animation.
+ *
+ * @param fadeOutView View that will be faded out during the focus animation.
*/
- private Animator getFocusAnimator(View crossFadeView) {
+ private Animator getFocusAnimator(@Nullable View fadeOutView) {
+ final AnimatorSet animatorSet = new AnimatorSet();
+
final Animator alphaAnimator = ObjectAnimator.ofFloat(this, View.ALPHA, 0f, 1f);
alphaAnimator.setStartDelay(FOCUS_ANIMATION_FADE_IN_DELAY);
alphaAnimator.setDuration(FOCUS_ANIMATION_FADE_IN_DURATION);
@@ -854,30 +877,36 @@
scaleAnimator.setDuration(FOCUS_ANIMATION_TOTAL_DURATION);
scaleAnimator.setInterpolator(InterpolatorsAndroidX.FAST_OUT_SLOW_IN);
- final Animator crossFadeViewAlphaAnimator =
- ObjectAnimator.ofFloat(crossFadeView, View.ALPHA, 1f, 0f);
- crossFadeViewAlphaAnimator.setDuration(FOCUS_ANIMATION_CROSSFADE_DURATION);
- crossFadeViewAlphaAnimator.setInterpolator(InterpolatorsAndroidX.LINEAR);
- alphaAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation, boolean isReverse) {
- crossFadeView.setAlpha(1f);
- }
- });
-
- final AnimatorSet animatorSet = new AnimatorSet();
- animatorSet.playTogether(alphaAnimator, scaleAnimator, crossFadeViewAlphaAnimator);
+ if (fadeOutView == null) {
+ animatorSet.playTogether(alphaAnimator, scaleAnimator);
+ } else {
+ final Animator fadeOutViewAlphaAnimator =
+ ObjectAnimator.ofFloat(fadeOutView, View.ALPHA, 1f, 0f);
+ fadeOutViewAlphaAnimator.setDuration(FOCUS_ANIMATION_CROSSFADE_DURATION);
+ fadeOutViewAlphaAnimator.setInterpolator(InterpolatorsAndroidX.LINEAR);
+ animatorSet.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation, boolean isReverse) {
+ fadeOutView.setAlpha(1f);
+ }
+ });
+ animatorSet.playTogether(alphaAnimator, scaleAnimator, fadeOutViewAlphaAnimator);
+ }
return animatorSet;
}
/**
* Creates an animator for the defocus animation.
*
- * @param offsetY The RemoteInputView will be offset by offsetY during the animation
+ * @param fadeInView View that will be faded in during the defocus animation.
+ * @param offsetY The RemoteInputView will be offset by offsetY during the animation
*/
- private Animator getDefocusAnimator(int offsetY) {
+ private Animator getDefocusAnimator(@Nullable View fadeInView, int offsetY) {
+ final AnimatorSet animatorSet = new AnimatorSet();
+
final Animator alphaAnimator = ObjectAnimator.ofFloat(this, View.ALPHA, 1f, 0f);
- alphaAnimator.setDuration(FOCUS_ANIMATION_CROSSFADE_DURATION);
+ alphaAnimator.setDuration(FOCUS_ANIMATION_FADE_IN_DURATION);
+ alphaAnimator.setStartDelay(DEFOCUS_ANIMATION_FADE_OUT_DELAY);
alphaAnimator.setInterpolator(InterpolatorsAndroidX.LINEAR);
ValueAnimator scaleAnimator = ValueAnimator.ofFloat(1f, FOCUS_ANIMATION_MIN_SCALE);
@@ -893,8 +922,17 @@
}
});
- final AnimatorSet animatorSet = new AnimatorSet();
- animatorSet.playTogether(alphaAnimator, scaleAnimator);
+ if (fadeInView == null) {
+ animatorSet.playTogether(alphaAnimator, scaleAnimator);
+ } else {
+ fadeInView.forceHasOverlappingRendering(false);
+ Animator fadeInViewAlphaAnimator =
+ ObjectAnimator.ofFloat(fadeInView, View.ALPHA, 0f, 1f);
+ fadeInViewAlphaAnimator.setDuration(FOCUS_ANIMATION_FADE_IN_DURATION);
+ fadeInViewAlphaAnimator.setInterpolator(InterpolatorsAndroidX.LINEAR);
+ fadeInViewAlphaAnimator.setStartDelay(DEFOCUS_ANIMATION_CROSSFADE_DELAY);
+ animatorSet.playTogether(alphaAnimator, scaleAnimator, fadeInViewAlphaAnimator);
+ }
return animatorSet;
}
@@ -1011,7 +1049,8 @@
if (isFocusable() && isEnabled()) {
setInnerFocusable(false);
if (mRemoteInputView != null) {
- mRemoteInputView.onDefocus(animate, true /* logClose */);
+ mRemoteInputView
+ .onDefocus(animate, true /* logClose */, null /* doAfterDefocus */);
}
mShowImeOnInputConnection = false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusFirstUsageListener.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusFirstUsageListener.kt
deleted file mode 100644
index 154c6e2..0000000
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusFirstUsageListener.kt
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2022 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.systemui.stylus
-
-import android.content.Context
-import android.hardware.BatteryState
-import android.hardware.input.InputManager
-import android.os.Handler
-import android.util.Log
-import android.view.InputDevice
-import androidx.annotation.VisibleForTesting
-import com.android.systemui.CoreStartable
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
-import java.util.concurrent.Executor
-import javax.inject.Inject
-
-/**
- * A listener that detects when a stylus has first been used, by detecting 1) the presence of an
- * internal SOURCE_STYLUS with a battery, or 2) any added SOURCE_STYLUS device with a bluetooth
- * address.
- */
-@SysUISingleton
-class StylusFirstUsageListener
-@Inject
-constructor(
- private val context: Context,
- private val inputManager: InputManager,
- private val stylusManager: StylusManager,
- private val featureFlags: FeatureFlags,
- @Background private val executor: Executor,
- @Background private val handler: Handler,
-) : CoreStartable, StylusManager.StylusCallback, InputManager.InputDeviceBatteryListener {
-
- // Set must be only accessed from the background handler, which is the same handler that
- // runs the StylusManager callbacks.
- private val internalStylusDeviceIds: MutableSet<Int> = mutableSetOf()
- @VisibleForTesting var hasStarted = false
-
- override fun start() {
- if (true) return // TODO(b/261826950): remove on main
- if (hasStarted) return
- if (!featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)) return
- if (inputManager.isStylusEverUsed(context)) return
- if (!hostDeviceSupportsStylusInput()) return
-
- hasStarted = true
- inputManager.inputDeviceIds.forEach(this::onStylusAdded)
- stylusManager.registerCallback(this)
- stylusManager.startListener()
- }
-
- override fun onStylusAdded(deviceId: Int) {
- if (!hasStarted) return
-
- val device = inputManager.getInputDevice(deviceId) ?: return
- if (device.isExternal || !device.supportsSource(InputDevice.SOURCE_STYLUS)) return
-
- try {
- inputManager.addInputDeviceBatteryListener(deviceId, executor, this)
- internalStylusDeviceIds += deviceId
- } catch (e: SecurityException) {
- Log.e(TAG, "$e: Failed to register battery listener for $deviceId ${device.name}.")
- }
- }
-
- override fun onStylusRemoved(deviceId: Int) {
- if (!hasStarted) return
-
- if (!internalStylusDeviceIds.contains(deviceId)) return
- try {
- inputManager.removeInputDeviceBatteryListener(deviceId, this)
- internalStylusDeviceIds.remove(deviceId)
- } catch (e: SecurityException) {
- Log.e(TAG, "$e: Failed to remove registered battery listener for $deviceId.")
- }
- }
-
- override fun onStylusBluetoothConnected(deviceId: Int, btAddress: String) {
- if (!hasStarted) return
-
- onRemoteDeviceFound()
- }
-
- override fun onBatteryStateChanged(
- deviceId: Int,
- eventTimeMillis: Long,
- batteryState: BatteryState
- ) {
- if (!hasStarted) return
-
- if (batteryState.isPresent) {
- onRemoteDeviceFound()
- }
- }
-
- private fun onRemoteDeviceFound() {
- inputManager.setStylusEverUsed(context, true)
- cleanupListeners()
- }
-
- private fun cleanupListeners() {
- stylusManager.unregisterCallback(this)
- handler.post {
- internalStylusDeviceIds.forEach {
- inputManager.removeInputDeviceBatteryListener(it, this)
- }
- }
- }
-
- private fun hostDeviceSupportsStylusInput(): Boolean {
- return inputManager.inputDeviceIds
- .asSequence()
- .mapNotNull { inputManager.getInputDevice(it) }
- .any { it.supportsSource(InputDevice.SOURCE_STYLUS) && !it.isExternal }
- }
-
- companion object {
- private val TAG = StylusFirstUsageListener::class.simpleName.orEmpty()
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
index 302d6a9..235495cf 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
@@ -18,6 +18,8 @@
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
+import android.content.Context
+import android.hardware.BatteryState
import android.hardware.input.InputManager
import android.os.Handler
import android.util.ArrayMap
@@ -25,6 +27,8 @@
import android.view.InputDevice
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.Executor
import javax.inject.Inject
@@ -37,25 +41,37 @@
class StylusManager
@Inject
constructor(
+ private val context: Context,
private val inputManager: InputManager,
private val bluetoothAdapter: BluetoothAdapter?,
@Background private val handler: Handler,
@Background private val executor: Executor,
-) : InputManager.InputDeviceListener, BluetoothAdapter.OnMetadataChangedListener {
+ private val featureFlags: FeatureFlags,
+) :
+ InputManager.InputDeviceListener,
+ InputManager.InputDeviceBatteryListener,
+ BluetoothAdapter.OnMetadataChangedListener {
private val stylusCallbacks: CopyOnWriteArrayList<StylusCallback> = CopyOnWriteArrayList()
private val stylusBatteryCallbacks: CopyOnWriteArrayList<StylusBatteryCallback> =
CopyOnWriteArrayList()
// This map should only be accessed on the handler
private val inputDeviceAddressMap: MutableMap<Int, String?> = ArrayMap()
+ // This variable should only be accessed on the handler
+ private var hasStarted: Boolean = false
/**
* Starts listening to InputManager InputDevice events. Will also load the InputManager snapshot
* at time of starting.
*/
fun startListener() {
- addExistingStylusToMap()
- inputManager.registerInputDeviceListener(this, handler)
+ handler.post {
+ if (hasStarted) return@post
+ hasStarted = true
+ addExistingStylusToMap()
+
+ inputManager.registerInputDeviceListener(this, handler)
+ }
}
/** Registers a StylusCallback to listen to stylus events. */
@@ -77,21 +93,30 @@
}
override fun onInputDeviceAdded(deviceId: Int) {
+ if (!hasStarted) return
+
val device: InputDevice = inputManager.getInputDevice(deviceId) ?: return
if (!device.supportsSource(InputDevice.SOURCE_STYLUS)) return
+ if (!device.isExternal) {
+ registerBatteryListener(deviceId)
+ }
+
// TODO(b/257936830): get address once input api available
val btAddress: String? = null
inputDeviceAddressMap[deviceId] = btAddress
executeStylusCallbacks { cb -> cb.onStylusAdded(deviceId) }
if (btAddress != null) {
+ onStylusUsed()
onStylusBluetoothConnected(btAddress)
executeStylusCallbacks { cb -> cb.onStylusBluetoothConnected(deviceId, btAddress) }
}
}
override fun onInputDeviceChanged(deviceId: Int) {
+ if (!hasStarted) return
+
val device: InputDevice = inputManager.getInputDevice(deviceId) ?: return
if (!device.supportsSource(InputDevice.SOURCE_STYLUS)) return
@@ -112,7 +137,10 @@
}
override fun onInputDeviceRemoved(deviceId: Int) {
+ if (!hasStarted) return
+
if (!inputDeviceAddressMap.contains(deviceId)) return
+ unregisterBatteryListener(deviceId)
val btAddress: String? = inputDeviceAddressMap[deviceId]
inputDeviceAddressMap.remove(deviceId)
@@ -124,13 +152,14 @@
}
override fun onMetadataChanged(device: BluetoothDevice, key: Int, value: ByteArray?) {
- handler.post executeMetadataChanged@{
- if (key != BluetoothDevice.METADATA_MAIN_CHARGING || value == null)
- return@executeMetadataChanged
+ handler.post {
+ if (!hasStarted) return@post
+
+ if (key != BluetoothDevice.METADATA_MAIN_CHARGING || value == null) return@post
val inputDeviceId: Int =
inputDeviceAddressMap.filterValues { it == device.address }.keys.firstOrNull()
- ?: return@executeMetadataChanged
+ ?: return@post
val isCharging = String(value) == "true"
@@ -140,6 +169,24 @@
}
}
+ override fun onBatteryStateChanged(
+ deviceId: Int,
+ eventTimeMillis: Long,
+ batteryState: BatteryState
+ ) {
+ handler.post {
+ if (!hasStarted) return@post
+
+ if (batteryState.isPresent) {
+ onStylusUsed()
+ }
+
+ executeStylusBatteryCallbacks { cb ->
+ cb.onStylusUsiBatteryStateChanged(deviceId, eventTimeMillis, batteryState)
+ }
+ }
+ }
+
private fun onStylusBluetoothConnected(btAddress: String) {
val device: BluetoothDevice = bluetoothAdapter?.getRemoteDevice(btAddress) ?: return
try {
@@ -158,6 +205,21 @@
}
}
+ /**
+ * An InputDevice that supports [InputDevice.SOURCE_STYLUS] may still be present even when a
+ * physical stylus device has never been used. This method is run when 1) a USI stylus battery
+ * event happens, or 2) a bluetooth stylus is connected, as they are both indicators that a
+ * physical stylus device has actually been used.
+ */
+ private fun onStylusUsed() {
+ if (true) return // TODO(b/261826950): remove on main
+ if (!featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)) return
+ if (inputManager.isStylusEverUsed(context)) return
+
+ inputManager.setStylusEverUsed(context, true)
+ executeStylusCallbacks { cb -> cb.onStylusFirstUsed() }
+ }
+
private fun executeStylusCallbacks(run: (cb: StylusCallback) -> Unit) {
stylusCallbacks.forEach(run)
}
@@ -166,31 +228,69 @@
stylusBatteryCallbacks.forEach(run)
}
+ private fun registerBatteryListener(deviceId: Int) {
+ try {
+ inputManager.addInputDeviceBatteryListener(deviceId, executor, this)
+ } catch (e: SecurityException) {
+ Log.e(TAG, "$e: Failed to register battery listener for $deviceId.")
+ }
+ }
+
+ private fun unregisterBatteryListener(deviceId: Int) {
+ // If deviceId wasn't registered, the result is a no-op, so an "is registered"
+ // check is not needed.
+ try {
+ inputManager.removeInputDeviceBatteryListener(deviceId, this)
+ } catch (e: SecurityException) {
+ Log.e(TAG, "$e: Failed to remove registered battery listener for $deviceId.")
+ }
+ }
+
private fun addExistingStylusToMap() {
for (deviceId: Int in inputManager.inputDeviceIds) {
val device: InputDevice = inputManager.getInputDevice(deviceId) ?: continue
if (device.supportsSource(InputDevice.SOURCE_STYLUS)) {
// TODO(b/257936830): get address once input api available
inputDeviceAddressMap[deviceId] = null
+
+ if (!device.isExternal) { // TODO(b/263556967): add supportsUsi check once available
+ // For most devices, an active (non-bluetooth) stylus is represented by an
+ // internal InputDevice. This InputDevice will be present in InputManager
+ // before CoreStartables run, and will not be removed.
+ // In many cases, it reports the battery level of the stylus.
+ registerBatteryListener(deviceId)
+ }
}
}
}
- /** Callback interface to receive events from the StylusManager. */
+ /**
+ * Callback interface to receive events from the StylusManager. All callbacks are run on the
+ * same background handler.
+ */
interface StylusCallback {
fun onStylusAdded(deviceId: Int) {}
fun onStylusRemoved(deviceId: Int) {}
fun onStylusBluetoothConnected(deviceId: Int, btAddress: String) {}
fun onStylusBluetoothDisconnected(deviceId: Int, btAddress: String) {}
+ fun onStylusFirstUsed() {}
}
- /** Callback interface to receive stylus battery events from the StylusManager. */
+ /**
+ * Callback interface to receive stylus battery events from the StylusManager. All callbacks are
+ * runs on the same background handler.
+ */
interface StylusBatteryCallback {
fun onStylusBluetoothChargingStateChanged(
inputDeviceId: Int,
btDevice: BluetoothDevice,
isCharging: Boolean
) {}
+ fun onStylusUsiBatteryStateChanged(
+ deviceId: Int,
+ eventTimeMillis: Long,
+ batteryState: BatteryState,
+ ) {}
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerStartable.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerStartable.kt
index 11233dd..14a9161 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerStartable.kt
@@ -18,14 +18,11 @@
import android.hardware.BatteryState
import android.hardware.input.InputManager
-import android.util.Log
import android.view.InputDevice
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
-import java.util.concurrent.Executor
import javax.inject.Inject
/**
@@ -40,16 +37,7 @@
private val inputManager: InputManager,
private val stylusUsiPowerUi: StylusUsiPowerUI,
private val featureFlags: FeatureFlags,
- @Background private val executor: Executor,
-) : CoreStartable, StylusManager.StylusCallback, InputManager.InputDeviceBatteryListener {
-
- override fun onStylusAdded(deviceId: Int) {
- val device = inputManager.getInputDevice(deviceId) ?: return
-
- if (!device.isExternal) {
- registerBatteryListener(deviceId)
- }
- }
+) : CoreStartable, StylusManager.StylusCallback, StylusManager.StylusBatteryCallback {
override fun onStylusBluetoothConnected(deviceId: Int, btAddress: String) {
stylusUsiPowerUi.refresh()
@@ -59,15 +47,7 @@
stylusUsiPowerUi.refresh()
}
- override fun onStylusRemoved(deviceId: Int) {
- val device = inputManager.getInputDevice(deviceId) ?: return
-
- if (!device.isExternal) {
- unregisterBatteryListener(deviceId)
- }
- }
-
- override fun onBatteryStateChanged(
+ override fun onStylusUsiBatteryStateChanged(
deviceId: Int,
eventTimeMillis: Long,
batteryState: BatteryState
@@ -77,39 +57,19 @@
}
}
- private fun registerBatteryListener(deviceId: Int) {
- try {
- inputManager.addInputDeviceBatteryListener(deviceId, executor, this)
- } catch (e: SecurityException) {
- Log.e(TAG, "$e: Failed to register battery listener for $deviceId.")
- }
- }
-
- private fun unregisterBatteryListener(deviceId: Int) {
- try {
- inputManager.removeInputDeviceBatteryListener(deviceId, this)
- } catch (e: SecurityException) {
- Log.e(TAG, "$e: Failed to unregister battery listener for $deviceId.")
- }
- }
-
override fun start() {
if (!featureFlags.isEnabled(Flags.ENABLE_USI_BATTERY_NOTIFICATIONS)) return
- addBatteryListenerForInternalStyluses()
+ if (!hostDeviceSupportsStylusInput()) return
stylusManager.registerCallback(this)
stylusManager.startListener()
}
- private fun addBatteryListenerForInternalStyluses() {
- // For most devices, an active stylus is represented by an internal InputDevice.
- // This InputDevice will be present in InputManager before CoreStartables run,
- // and will not be removed. In many cases, it reports the battery level of the stylus.
- inputManager.inputDeviceIds
+ private fun hostDeviceSupportsStylusInput(): Boolean {
+ return inputManager.inputDeviceIds
.asSequence()
.mapNotNull { inputManager.getInputDevice(it) }
- .filter { it.supportsSource(InputDevice.SOURCE_STYLUS) }
- .forEach { onStylusAdded(it.id) }
+ .any { it.supportsSource(InputDevice.SOURCE_STYLUS) && !it.isExternal }
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
index 70a5b36..e821657 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
@@ -123,13 +123,13 @@
.setSmallIcon(R.drawable.ic_power_low)
.setDeleteIntent(getPendingBroadcast(ACTION_DISMISSED_LOW_BATTERY))
.setContentIntent(getPendingBroadcast(ACTION_CLICKED_LOW_BATTERY))
- .setContentTitle(context.getString(R.string.stylus_battery_low))
- .setContentText(
+ .setContentTitle(
context.getString(
- R.string.battery_low_percent_format,
+ R.string.stylus_battery_low_percentage,
NumberFormat.getPercentInstance().format(batteryCapacity)
)
)
+ .setContentText(context.getString(R.string.stylus_battery_low_subtitle))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setLocalOnly(true)
.setAutoCancel(true)
@@ -177,7 +177,7 @@
// https://source.chromium.org/chromium/chromium/src/+/main:ash/system/power/peripheral_battery_notifier.cc;l=41
private const val LOW_BATTERY_THRESHOLD = 0.16f
- private val USI_NOTIFICATION_ID = R.string.stylus_battery_low
+ private val USI_NOTIFICATION_ID = R.string.stylus_battery_low_percentage
private const val ACTION_DISMISSED_LOW_BATTERY = "StylusUsiPowerUI.dismiss"
private const val ACTION_CLICKED_LOW_BATTERY = "StylusUsiPowerUI.click"
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
index 59ad24a..2709da3 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
@@ -17,6 +17,9 @@
package com.android.systemui.unfold
import android.content.Context
+import android.hardware.devicestate.DeviceStateManager
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.LifecycleScreenStatusProvider
import com.android.systemui.unfold.config.UnfoldTransitionConfig
import com.android.systemui.unfold.system.SystemUnfoldSharedModule
@@ -32,6 +35,7 @@
import dagger.Module
import dagger.Provides
import java.util.Optional
+import java.util.concurrent.Executor
import javax.inject.Named
import javax.inject.Singleton
@@ -40,6 +44,20 @@
@Provides @UnfoldTransitionATracePrefix fun tracingTagPrefix() = "systemui"
+ /** A globally available FoldStateListener that allows one to query the fold state. */
+ @Provides
+ @Singleton
+ fun providesFoldStateListener(
+ deviceStateManager: DeviceStateManager,
+ @Application context: Context,
+ @Main executor: Executor
+ ): DeviceStateManager.FoldStateListener {
+ val listener = DeviceStateManager.FoldStateListener(context)
+ deviceStateManager.registerCallback(executor, listener)
+
+ return listener
+ }
+
@Provides
@Singleton
fun providesFoldStateLoggingProvider(
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 7d23399..0f9ae39 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -1522,6 +1522,7 @@
.setDuration(mDialogHideAnimationDurationMs)
.setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator())
.withEndAction(() -> mHandler.postDelayed(() -> {
+ mController.notifyVisible(false);
mDialog.dismiss();
tryToRemoveCaptionsTooltip();
mIsAnimatingDismiss = false;
@@ -1535,7 +1536,6 @@
animator.setListener(getJankListener(getDialogView(), TYPE_DISMISS,
mDialogHideAnimationDurationMs)).start();
checkODICaptionsTooltip(true);
- mController.notifyVisible(false);
synchronized (mSafetyWarningLock) {
if (mSafetyWarning != null) {
if (D.BUG) Log.d(TAG, "SafetyWarning dismissed");
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
index e8f8e25..c76b127 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
@@ -15,6 +15,7 @@
*/
package com.android.keyguard
+import com.android.systemui.statusbar.CommandQueue
import android.content.BroadcastReceiver
import android.testing.AndroidTestingRunner
import android.view.View
@@ -81,8 +82,10 @@
@Mock private lateinit var largeClockEvents: ClockFaceEvents
@Mock private lateinit var parentView: View
@Mock private lateinit var transitionRepository: KeyguardTransitionRepository
+ @Mock private lateinit var commandQueue: CommandQueue
private lateinit var repository: FakeKeyguardRepository
- @Mock private lateinit var logBuffer: LogBuffer
+ @Mock private lateinit var smallLogBuffer: LogBuffer
+ @Mock private lateinit var largeLogBuffer: LogBuffer
private lateinit var underTest: ClockEventController
@Before
@@ -99,7 +102,7 @@
repository = FakeKeyguardRepository()
underTest = ClockEventController(
- KeyguardInteractor(repository = repository),
+ KeyguardInteractor(repository = repository, commandQueue = commandQueue),
KeyguardTransitionInteractor(repository = transitionRepository),
broadcastDispatcher,
batteryController,
@@ -109,7 +112,8 @@
context,
mainExecutor,
bgExecutor,
- logBuffer,
+ smallLogBuffer,
+ largeLogBuffer,
featureFlags
)
underTest.clock = clock
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
index c8e7538..9a9acf3 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
@@ -48,6 +48,7 @@
import com.android.systemui.plugins.ClockController;
import com.android.systemui.plugins.ClockEvents;
import com.android.systemui.plugins.ClockFaceController;
+import com.android.systemui.plugins.log.LogBuffer;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shared.clocks.AnimatableClockView;
import com.android.systemui.shared.clocks.ClockRegistry;
@@ -115,6 +116,8 @@
private FrameLayout mLargeClockFrame;
@Mock
private SecureSettings mSecureSettings;
+ @Mock
+ private LogBuffer mLogBuffer;
private final View mFakeSmartspaceView = new View(mContext);
@@ -156,7 +159,8 @@
mSecureSettings,
mExecutor,
mDumpManager,
- mClockEventController
+ mClockEventController,
+ mLogBuffer
);
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index 254f953..8dc1e8f 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -16,6 +16,7 @@
package com.android.keyguard;
+import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import static com.android.keyguard.KeyguardClockSwitch.LARGE;
@@ -189,6 +190,7 @@
assertThat(mLargeClockFrame.getAlpha()).isEqualTo(1);
assertThat(mLargeClockFrame.getVisibility()).isEqualTo(VISIBLE);
assertThat(mSmallClockFrame.getAlpha()).isEqualTo(0);
+ assertThat(mSmallClockFrame.getVisibility()).isEqualTo(INVISIBLE);
}
@Test
@@ -198,6 +200,7 @@
assertThat(mLargeClockFrame.getAlpha()).isEqualTo(1);
assertThat(mLargeClockFrame.getVisibility()).isEqualTo(VISIBLE);
assertThat(mSmallClockFrame.getAlpha()).isEqualTo(0);
+ assertThat(mSmallClockFrame.getVisibility()).isEqualTo(INVISIBLE);
}
@Test
@@ -212,6 +215,7 @@
// only big clock is removed at switch
assertThat(mLargeClockFrame.getParent()).isNull();
assertThat(mLargeClockFrame.getAlpha()).isEqualTo(0);
+ assertThat(mLargeClockFrame.getVisibility()).isEqualTo(INVISIBLE);
}
@Test
@@ -223,6 +227,7 @@
// only big clock is removed at switch
assertThat(mLargeClockFrame.getParent()).isNull();
assertThat(mLargeClockFrame.getAlpha()).isEqualTo(0);
+ assertThat(mLargeClockFrame.getVisibility()).isEqualTo(INVISIBLE);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index ac22de9..87dd6a4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -33,6 +33,9 @@
import static com.android.keyguard.KeyguardUpdateMonitor.DEFAULT_CANCEL_SIGNAL_TIMEOUT;
import static com.android.keyguard.KeyguardUpdateMonitor.HAL_POWER_PRESS_TIMEOUT;
import static com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser;
+import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_CLOSED;
+import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_OPENED;
+import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN;
import static com.google.common.truth.Truth.assertThat;
@@ -93,6 +96,7 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
+import android.provider.Settings;
import android.service.dreams.IDreamManager;
import android.service.trust.TrustAgentService;
import android.telephony.ServiceState;
@@ -125,6 +129,7 @@
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.telephony.TelephonyListenerManager;
import com.android.systemui.util.settings.GlobalSettings;
import com.android.systemui.util.settings.SecureSettings;
@@ -194,6 +199,8 @@
@Mock
private DevicePolicyManager mDevicePolicyManager;
@Mock
+ private DevicePostureController mDevicePostureController;
+ @Mock
private IDreamManager mDreamManager;
@Mock
private KeyguardBypassController mKeyguardBypassController;
@@ -300,6 +307,7 @@
.thenReturn(new ServiceState());
when(mLockPatternUtils.getLockSettings()).thenReturn(mLockSettings);
when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(false);
+ when(mDevicePostureController.getDevicePosture()).thenReturn(DEVICE_POSTURE_UNKNOWN);
mMockitoSession = ExtendedMockito.mockitoSession()
.spyStatic(SubscriptionManager.class)
@@ -311,6 +319,9 @@
when(mUserTracker.getUserId()).thenReturn(mCurrentUserId);
ExtendedMockito.doReturn(mActivityService).when(ActivityManager::getService);
+ mContext.getOrCreateTestableResources().addOverride(
+ com.android.systemui.R.integer.config_face_auth_supported_posture,
+ DEVICE_POSTURE_UNKNOWN);
mFaceWakeUpTriggersConfig = new FaceWakeUpTriggersConfig(
mContext.getResources(),
mGlobalSettings,
@@ -1254,7 +1265,7 @@
}
@Test
- public void testStartsListeningForSfps_whenKeyguardIsVisible_ifRequireScreenOnToAuthEnabled()
+ public void startsListeningForSfps_whenKeyguardIsVisible_ifRequireInteractiveToAuthEnabled()
throws RemoteException {
// SFPS supported and enrolled
final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
@@ -1262,12 +1273,9 @@
when(mAuthController.getSfpsProps()).thenReturn(props);
when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
- // WHEN require screen on to auth is disabled, and keyguard is not awake
+ // WHEN require interactive to auth is disabled, and keyguard is not awake
when(mInteractiveToAuthProvider.isEnabled(anyInt())).thenReturn(false);
- mContext.getOrCreateTestableResources().addOverride(
- com.android.internal.R.bool.config_requireScreenOnToAuthEnabled, true);
-
// Preconditions for sfps auth to run
keyguardNotGoingAway();
currentUserIsPrimary();
@@ -1282,8 +1290,8 @@
// THEN we should listen for sfps when screen off, because require screen on is disabled
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isTrue();
- // WHEN require screen on to auth is enabled, and keyguard is not awake
- when(mInteractiveToAuthProvider.isEnabled(anyInt())).thenReturn(false);
+ // WHEN require interactive to auth is enabled, and keyguard is not awake
+ when(mInteractiveToAuthProvider.isEnabled(anyInt())).thenReturn(true);
// THEN we shouldn't listen for sfps when screen off, because require screen on is enabled
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isFalse();
@@ -1297,6 +1305,62 @@
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isTrue();
}
+ @Test
+ public void notListeningForSfps_whenGoingToSleep_ifRequireInteractiveToAuthEnabled()
+ throws RemoteException {
+ // GIVEN SFPS supported and enrolled
+ final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
+ props.add(newFingerprintSensorPropertiesInternal(TYPE_POWER_BUTTON));
+ when(mAuthController.getSfpsProps()).thenReturn(props);
+ when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
+
+ // GIVEN Preconditions for sfps auth to run
+ keyguardNotGoingAway();
+ currentUserIsPrimary();
+ currentUserDoesNotHaveTrust();
+ biometricsNotDisabledThroughDevicePolicyManager();
+ biometricsEnabledForCurrentUser();
+ userNotCurrentlySwitching();
+ statusBarShadeIsLocked();
+
+ // WHEN require interactive to auth is enabled & keyguard is going to sleep
+ when(mInteractiveToAuthProvider.isEnabled(anyInt())).thenReturn(true);
+ deviceGoingToSleep();
+
+ mTestableLooper.processAllMessages();
+
+ // THEN we should NOT listen for sfps because device is going to sleep
+ assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isFalse();
+ }
+
+ @Test
+ public void listeningForSfps_whenGoingToSleep_ifRequireInteractiveToAuthDisabled()
+ throws RemoteException {
+ // GIVEN SFPS supported and enrolled
+ final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
+ props.add(newFingerprintSensorPropertiesInternal(TYPE_POWER_BUTTON));
+ when(mAuthController.getSfpsProps()).thenReturn(props);
+ when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
+
+ // GIVEN Preconditions for sfps auth to run
+ keyguardNotGoingAway();
+ currentUserIsPrimary();
+ currentUserDoesNotHaveTrust();
+ biometricsNotDisabledThroughDevicePolicyManager();
+ biometricsEnabledForCurrentUser();
+ userNotCurrentlySwitching();
+ statusBarShadeIsLocked();
+
+ // WHEN require interactive to auth is disabled & keyguard is going to sleep
+ when(mInteractiveToAuthProvider.isEnabled(anyInt())).thenReturn(false);
+ deviceGoingToSleep();
+
+ mTestableLooper.processAllMessages();
+
+ // THEN we should listen for sfps because screen on to auth is disabled
+ assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isTrue();
+ }
+
private FingerprintSensorPropertiesInternal newFingerprintSensorPropertiesInternal(
@FingerprintSensorProperties.SensorType int sensorType) {
return new FingerprintSensorPropertiesInternal(
@@ -2188,6 +2252,54 @@
eq(true));
}
+ @Test
+ public void testShouldListenForFace_withAuthSupportPostureConfig_returnsTrue()
+ throws RemoteException {
+ mKeyguardUpdateMonitor.mConfigFaceAuthSupportedPosture = DEVICE_POSTURE_CLOSED;
+ keyguardNotGoingAway();
+ bouncerFullyVisibleAndNotGoingToSleep();
+ currentUserIsPrimary();
+ currentUserDoesNotHaveTrust();
+ biometricsNotDisabledThroughDevicePolicyManager();
+ biometricsEnabledForCurrentUser();
+ userNotCurrentlySwitching();
+ supportsFaceDetection();
+
+ deviceInPostureStateOpened();
+ mTestableLooper.processAllMessages();
+ // Should not listen for face when posture state in DEVICE_POSTURE_OPENED
+ assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isFalse();
+
+ deviceInPostureStateClosed();
+ mTestableLooper.processAllMessages();
+ // Should listen for face when posture state in DEVICE_POSTURE_CLOSED
+ assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isTrue();
+ }
+
+ @Test
+ public void testShouldListenForFace_withoutAuthSupportPostureConfig_returnsTrue()
+ throws RemoteException {
+ mKeyguardUpdateMonitor.mConfigFaceAuthSupportedPosture = DEVICE_POSTURE_UNKNOWN;
+ keyguardNotGoingAway();
+ bouncerFullyVisibleAndNotGoingToSleep();
+ currentUserIsPrimary();
+ currentUserDoesNotHaveTrust();
+ biometricsNotDisabledThroughDevicePolicyManager();
+ biometricsEnabledForCurrentUser();
+ userNotCurrentlySwitching();
+ supportsFaceDetection();
+
+ deviceInPostureStateClosed();
+ mTestableLooper.processAllMessages();
+ // Whether device in any posture state, always listen for face
+ assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isTrue();
+
+ deviceInPostureStateOpened();
+ mTestableLooper.processAllMessages();
+ // Whether device in any posture state, always listen for face
+ assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isTrue();
+ }
+
private void userDeviceLockDown() {
when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
when(mStrongAuthTracker.getStrongAuthForUser(mCurrentUserId))
@@ -2267,6 +2379,14 @@
.onAuthenticationAcquired(FINGERPRINT_ACQUIRED_START);
}
+ private void deviceInPostureStateOpened() {
+ mKeyguardUpdateMonitor.mPostureCallback.onPostureChanged(DEVICE_POSTURE_OPENED);
+ }
+
+ private void deviceInPostureStateClosed() {
+ mKeyguardUpdateMonitor.mPostureCallback.onPostureChanged(DEVICE_POSTURE_CLOSED);
+ }
+
private void successfulFingerprintAuth() {
mKeyguardUpdateMonitor.mFingerprintAuthenticationCallback
.onAuthenticationSucceeded(
@@ -2408,7 +2528,8 @@
mPowerManager, mTrustManager, mSubscriptionManager, mUserManager,
mDreamManager, mDevicePolicyManager, mSensorPrivacyManager, mTelephonyManager,
mPackageManager, mFaceManager, mFingerprintManager, mBiometricManager,
- mFaceWakeUpTriggersConfig, Optional.of(mInteractiveToAuthProvider));
+ mFaceWakeUpTriggersConfig, mDevicePostureController,
+ Optional.of(mInteractiveToAuthProvider));
setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
index e4c41a7..05bd1e4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
@@ -49,6 +49,7 @@
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -91,6 +92,7 @@
protected @Mock AuthRippleController mAuthRippleController;
protected @Mock FeatureFlags mFeatureFlags;
protected @Mock KeyguardTransitionRepository mTransitionRepository;
+ protected @Mock CommandQueue mCommandQueue;
protected FakeExecutor mDelayableExecutor = new FakeExecutor(new FakeSystemClock());
protected LockIconViewController mUnderTest;
@@ -157,7 +159,7 @@
mAuthRippleController,
mResources,
new KeyguardTransitionInteractor(mTransitionRepository),
- new KeyguardInteractor(new FakeKeyguardRepository()),
+ new KeyguardInteractor(new FakeKeyguardRepository(), mCommandQueue),
mFeatureFlags
);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
index c6fa983..7c9d22f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
@@ -124,8 +124,8 @@
.thenReturn(mock(UdfpsBpView::class.java))
whenever(inflater.inflate(R.layout.udfps_keyguard_view, null))
.thenReturn(mock(UdfpsKeyguardView::class.java))
- whenever(inflater.inflate(R.layout.udfps_fpm_other_view, null))
- .thenReturn(mock(UdfpsFpmOtherView::class.java))
+ whenever(inflater.inflate(R.layout.udfps_fpm_empty_view, null))
+ .thenReturn(mock(UdfpsFpmEmptyView::class.java))
whenever(udfpsEnrollView.context).thenReturn(context)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index 83a6db0..d7b7a7d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -190,7 +190,7 @@
@Mock
private UdfpsBpView mBpView;
@Mock
- private UdfpsFpmOtherView mFpmOtherView;
+ private UdfpsFpmEmptyView mFpmEmptyView;
@Mock
private UdfpsKeyguardView mKeyguardView;
private final UdfpsAnimationViewController mUdfpsKeyguardViewController =
@@ -240,8 +240,8 @@
.thenReturn(mKeyguardView); // for showOverlay REASON_AUTH_FPM_KEYGUARD
when(mLayoutInflater.inflate(R.layout.udfps_bp_view, null))
.thenReturn(mBpView);
- when(mLayoutInflater.inflate(R.layout.udfps_fpm_other_view, null))
- .thenReturn(mFpmOtherView);
+ when(mLayoutInflater.inflate(R.layout.udfps_fpm_empty_view, null))
+ .thenReturn(mFpmEmptyView);
when(mEnrollView.getContext()).thenReturn(mContext);
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
when(mSessionTracker.getSessionId(anyInt())).thenReturn(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetectorTest.kt
new file mode 100644
index 0000000..af46d9b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetectorTest.kt
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2023 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.systemui.biometrics.udfps
+
+import android.graphics.Point
+import android.graphics.Rect
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import org.junit.runners.Parameterized.Parameters
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.`when` as whenEver
+
+@SmallTest
+@RunWith(Parameterized::class)
+class EllipseOverlapDetectorTest(val testCase: TestCase) : SysuiTestCase() {
+ val underTest = spy(EllipseOverlapDetector(neededPoints = 1))
+
+ @Before
+ fun setUp() {
+ // Use one single center point for testing, required or total number of points may change
+ whenEver(underTest.calculateSensorPoints(SENSOR))
+ .thenReturn(listOf(Point(SENSOR.centerX(), SENSOR.centerY())))
+ }
+
+ @Test
+ fun isGoodOverlap() {
+ val touchData =
+ TOUCH_DATA.copy(
+ x = testCase.x.toFloat(),
+ y = testCase.y.toFloat(),
+ minor = testCase.minor,
+ major = testCase.major
+ )
+ val actual = underTest.isGoodOverlap(touchData, SENSOR)
+
+ assertThat(actual).isEqualTo(testCase.expected)
+ }
+
+ data class TestCase(
+ val x: Int,
+ val y: Int,
+ val minor: Float,
+ val major: Float,
+ val expected: Boolean
+ )
+
+ companion object {
+ @Parameters(name = "{0}")
+ @JvmStatic
+ fun data(): List<TestCase> =
+ listOf(
+ genTestCases(
+ innerXs = listOf(SENSOR.left, SENSOR.right, SENSOR.centerX()),
+ innerYs = listOf(SENSOR.top, SENSOR.bottom, SENSOR.centerY()),
+ outerXs = listOf(SENSOR.left - 1, SENSOR.right + 1),
+ outerYs = listOf(SENSOR.top - 1, SENSOR.bottom + 1),
+ minor = 300f,
+ major = 300f,
+ expected = true
+ ),
+ genTestCases(
+ innerXs = listOf(SENSOR.left, SENSOR.right),
+ innerYs = listOf(SENSOR.top, SENSOR.bottom),
+ outerXs = listOf(SENSOR.left - 1, SENSOR.right + 1),
+ outerYs = listOf(SENSOR.top - 1, SENSOR.bottom + 1),
+ minor = 100f,
+ major = 100f,
+ expected = false
+ )
+ )
+ .flatten()
+ }
+}
+
+/* Placeholder touch parameters. */
+private const val POINTER_ID = 42
+private const val NATIVE_MINOR = 2.71828f
+private const val NATIVE_MAJOR = 3.14f
+private const val ORIENTATION = 0f // used for perfect circles
+private const val TIME = 12345699L
+private const val GESTURE_START = 12345600L
+
+/* Template [NormalizedTouchData]. */
+private val TOUCH_DATA =
+ NormalizedTouchData(
+ POINTER_ID,
+ x = 0f,
+ y = 0f,
+ NATIVE_MINOR,
+ NATIVE_MAJOR,
+ ORIENTATION,
+ TIME,
+ GESTURE_START
+ )
+
+private val SENSOR = Rect(100 /* left */, 200 /* top */, 300 /* right */, 400 /* bottom */)
+
+private fun genTestCases(
+ innerXs: List<Int>,
+ innerYs: List<Int>,
+ outerXs: List<Int>,
+ outerYs: List<Int>,
+ minor: Float,
+ major: Float,
+ expected: Boolean
+): List<EllipseOverlapDetectorTest.TestCase> {
+ return (innerXs + outerXs).flatMap { x ->
+ (innerYs + outerYs).map { y ->
+ EllipseOverlapDetectorTest.TestCase(x, y, minor, major, expected)
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
index 95c53b4..56043e30 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
@@ -221,6 +221,14 @@
private const val ROTATION_0_NATIVE_DISPLAY_WIDTH = 400
private const val ROTATION_0_NATIVE_DISPLAY_HEIGHT = 600
+/* Placeholder touch parameters. */
+private const val POINTER_ID = 42
+private const val NATIVE_MINOR = 2.71828f
+private const val NATIVE_MAJOR = 3.14f
+private const val ORIENTATION = 1.2345f
+private const val TIME = 12345699L
+private const val GESTURE_START = 12345600L
+
/*
* ROTATION_0 map:
* _ _ _ _
@@ -244,6 +252,7 @@
private val ROTATION_0_INPUTS =
OrientationBasedInputs(
rotation = Surface.ROTATION_0,
+ nativeOrientation = ORIENTATION,
nativeXWithinSensor = ROTATION_0_NATIVE_SENSOR_BOUNDS.exactCenterX(),
nativeYWithinSensor = ROTATION_0_NATIVE_SENSOR_BOUNDS.exactCenterY(),
nativeXOutsideSensor = 250f,
@@ -271,6 +280,7 @@
private val ROTATION_90_INPUTS =
OrientationBasedInputs(
rotation = Surface.ROTATION_90,
+ nativeOrientation = (ORIENTATION - Math.PI.toFloat() / 2),
nativeXWithinSensor = ROTATION_90_NATIVE_SENSOR_BOUNDS.exactCenterX(),
nativeYWithinSensor = ROTATION_90_NATIVE_SENSOR_BOUNDS.exactCenterY(),
nativeXOutsideSensor = 150f,
@@ -304,20 +314,13 @@
private val ROTATION_270_INPUTS =
OrientationBasedInputs(
rotation = Surface.ROTATION_270,
+ nativeOrientation = (ORIENTATION + Math.PI.toFloat() / 2),
nativeXWithinSensor = ROTATION_270_NATIVE_SENSOR_BOUNDS.exactCenterX(),
nativeYWithinSensor = ROTATION_270_NATIVE_SENSOR_BOUNDS.exactCenterY(),
nativeXOutsideSensor = 450f,
nativeYOutsideSensor = 250f,
)
-/* Placeholder touch parameters. */
-private const val POINTER_ID = 42
-private const val NATIVE_MINOR = 2.71828f
-private const val NATIVE_MAJOR = 3.14f
-private const val ORIENTATION = 1.23f
-private const val TIME = 12345699L
-private const val GESTURE_START = 12345600L
-
/* Template [MotionEvent]. */
private val MOTION_EVENT =
obtainMotionEvent(
@@ -352,6 +355,7 @@
*/
private data class OrientationBasedInputs(
@Rotation val rotation: Int,
+ val nativeOrientation: Float,
val nativeXWithinSensor: Float,
val nativeYWithinSensor: Float,
val nativeXOutsideSensor: Float,
@@ -404,6 +408,7 @@
y = nativeY * scaleFactor,
minor = NATIVE_MINOR * scaleFactor,
major = NATIVE_MAJOR * scaleFactor,
+ orientation = orientation.nativeOrientation
)
val expectedTouchData =
NORMALIZED_TOUCH_DATA.copy(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
index 0fadc13..e4df754 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
@@ -106,6 +106,7 @@
mClassifiers.add(mClassifierB);
when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList);
when(mKeyguardStateController.isShowing()).thenReturn(true);
+ when(mFalsingDataProvider.isFolded()).thenReturn(true);
mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider,
mMetricsLogger, mClassifiers, mSingleTapClassfier, mLongTapClassifier,
mDoubleTapClassifier, mHistoryTracker, mKeyguardStateController,
@@ -121,6 +122,7 @@
mGestureFinalizedListener = gestureCompleteListenerCaptor.getValue();
mFakeFeatureFlags.set(Flags.FALSING_FOR_LONG_TAPS, true);
mFakeFeatureFlags.set(Flags.MEDIA_FALSING_PENALTY, true);
+ mFakeFeatureFlags.set(Flags.FALSING_OFF_FOR_UNFOLDED, true);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
index 4281ee0..ae38eb6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
@@ -89,25 +89,27 @@
mClassifiers.add(mClassifierA);
when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList);
when(mKeyguardStateController.isShowing()).thenReturn(true);
+ when(mFalsingDataProvider.isFolded()).thenReturn(true);
mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider,
mMetricsLogger, mClassifiers, mSingleTapClassifier, mLongTapClassifier,
mDoubleTapClassifier, mHistoryTracker, mKeyguardStateController,
mAccessibilityManager, false, mFakeFeatureFlags);
mFakeFeatureFlags.set(Flags.FALSING_FOR_LONG_TAPS, true);
+ mFakeFeatureFlags.set(Flags.FALSING_OFF_FOR_UNFOLDED, true);
}
@Test
public void testA11yDisablesGesture() {
- assertThat(mBrightLineFalsingManager.isFalseTap(1)).isTrue();
+ assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue();
when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
- assertThat(mBrightLineFalsingManager.isFalseTap(1)).isFalse();
+ assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse();
}
@Test
public void testA11yDisablesTap() {
- assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue();
+ assertThat(mBrightLineFalsingManager.isFalseTap(1)).isTrue();
when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
- assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse();
+ assertThat(mBrightLineFalsingManager.isFalseTap(1)).isFalse();
}
@@ -179,4 +181,11 @@
when(mFalsingDataProvider.isA11yAction()).thenReturn(true);
assertThat(mBrightLineFalsingManager.isFalseTap(1)).isFalse();
}
+
+ @Test
+ public void testSkipUnfolded() {
+ assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue();
+ when(mFalsingDataProvider.isFolded()).thenReturn(false);
+ assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse();
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java
index 5fa7214..94cf384 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java
@@ -16,6 +16,7 @@
package com.android.systemui.classifier;
+import android.hardware.devicestate.DeviceStateManager.FoldStateListener;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
@@ -38,6 +39,7 @@
private float mOffsetY = 0;
@Mock
private BatteryController mBatteryController;
+ private FoldStateListener mFoldStateListener = new FoldStateListener(mContext);
private final DockManagerFake mDockManager = new DockManagerFake();
public void setup() {
@@ -47,7 +49,8 @@
displayMetrics.ydpi = 100;
displayMetrics.widthPixels = 1000;
displayMetrics.heightPixels = 1000;
- mDataProvider = new FalsingDataProvider(displayMetrics, mBatteryController, mDockManager);
+ mDataProvider = new FalsingDataProvider(
+ displayMetrics, mBatteryController, mFoldStateListener, mDockManager);
}
@After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
index d315c2d..c451a1e7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
@@ -24,6 +24,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.hardware.devicestate.DeviceStateManager.FoldStateListener;
import android.testing.AndroidTestingRunner;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
@@ -50,6 +51,8 @@
private FalsingDataProvider mDataProvider;
@Mock
private BatteryController mBatteryController;
+ @Mock
+ private FoldStateListener mFoldStateListener;
private final DockManagerFake mDockManager = new DockManagerFake();
@Before
@@ -61,7 +64,8 @@
displayMetrics.ydpi = 100;
displayMetrics.widthPixels = 1000;
displayMetrics.heightPixels = 1000;
- mDataProvider = new FalsingDataProvider(displayMetrics, mBatteryController, mDockManager);
+ mDataProvider = new FalsingDataProvider(
+ displayMetrics, mBatteryController, mFoldStateListener, mDockManager);
}
@After
@@ -316,4 +320,16 @@
mDataProvider.onA11yAction();
assertThat(mDataProvider.isA11yAction()).isTrue();
}
+
+ @Test
+ public void test_FoldedState_Folded() {
+ when(mFoldStateListener.getFolded()).thenReturn(true);
+ assertThat(mDataProvider.isFolded()).isTrue();
+ }
+
+ @Test
+ public void test_FoldedState_Unfolded() {
+ when(mFoldStateListener.getFolded()).thenReturn(false);
+ assertThat(mDataProvider.isFolded()).isFalse();
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
index 4659766..0a03b2c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
@@ -51,6 +51,7 @@
import com.android.systemui.settings.UserTracker
import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
+import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.FakeSharedPreferences
import com.android.systemui.util.mockito.any
@@ -86,9 +87,9 @@
@Mock private lateinit var backgroundHandler: Handler
@Mock private lateinit var previewSurfacePackage: SurfaceControlViewHost.SurfacePackage
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
+ @Mock private lateinit var commandQueue: CommandQueue
private lateinit var underTest: CustomizationProvider
-
private lateinit var testScope: TestScope
@Before
@@ -160,6 +161,7 @@
keyguardInteractor =
KeyguardInteractor(
repository = FakeKeyguardRepository(),
+ commandQueue = commandQueue,
),
registry = mock(),
lockPatternUtils = lockPatternUtils,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 9b0d8db..7c20e3c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -29,6 +29,7 @@
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -66,6 +67,7 @@
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shade.NotificationShadeWindowControllerImpl;
@@ -134,6 +136,7 @@
private @Mock SysuiColorExtractor mColorExtractor;
private @Mock AuthController mAuthController;
private @Mock ShadeExpansionStateManager mShadeExpansionStateManager;
+ private @Mock FeatureFlags mFeatureFlags;
private @Mock ShadeWindowLogger mShadeWindowLogger;
private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake();
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
@@ -483,6 +486,38 @@
assertTrue(mViewMediator.isShowingAndNotOccluded());
}
+ @Test
+ @TestableLooper.RunWithLooper(setAsMainLooper = true)
+ public void testDoKeyguardWhileInteractive_resets() {
+ mViewMediator.setShowingLocked(true);
+ when(mKeyguardStateController.isShowing()).thenReturn(true);
+ TestableLooper.get(this).processAllMessages();
+
+ when(mPowerManager.isInteractive()).thenReturn(true);
+
+ mViewMediator.onSystemReady();
+ TestableLooper.get(this).processAllMessages();
+
+ assertTrue(mViewMediator.isShowingAndNotOccluded());
+ verify(mStatusBarKeyguardViewManager).reset(anyBoolean());
+ }
+
+ @Test
+ @TestableLooper.RunWithLooper(setAsMainLooper = true)
+ public void testDoKeyguardWhileNotInteractive_showsInsteadOfResetting() {
+ mViewMediator.setShowingLocked(true);
+ when(mKeyguardStateController.isShowing()).thenReturn(true);
+ TestableLooper.get(this).processAllMessages();
+
+ when(mPowerManager.isInteractive()).thenReturn(false);
+
+ mViewMediator.onSystemReady();
+ TestableLooper.get(this).processAllMessages();
+
+ assertTrue(mViewMediator.isShowingAndNotOccluded());
+ verify(mStatusBarKeyguardViewManager, never()).reset(anyBoolean());
+ }
+
private void createAndStartViewMediator() {
mViewMediator = new KeyguardViewMediator(
mContext,
@@ -510,6 +545,7 @@
mScreenOnCoordinator,
mInteractionJankMonitor,
mDreamOverlayStateController,
+ mFeatureFlags,
() -> mShadeController,
() -> mNotificationShadeWindowController,
() -> mActivityLaunchAnimator,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WakefulnessLifecycleTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WakefulnessLifecycleTest.java
index f32d76b..39a453d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WakefulnessLifecycleTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WakefulnessLifecycleTest.java
@@ -30,6 +30,7 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
import org.junit.Test;
@@ -51,7 +52,12 @@
public void setUp() throws Exception {
mWallpaperManager = mock(IWallpaperManager.class);
mWakefulness =
- new WakefulnessLifecycle(mContext, mWallpaperManager, mock(DumpManager.class));
+ new WakefulnessLifecycle(
+ mContext,
+ mWallpaperManager,
+ new FakeSystemClock(),
+ mock(DumpManager.class)
+ );
mWakefulnessObserver = mock(WakefulnessLifecycle.Observer.class);
mWakefulness.addObserver(mWakefulnessObserver);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
index be712f6..f997d18 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
@@ -24,6 +24,7 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.AuthController
import com.android.systemui.common.shared.model.Position
+import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.doze.DozeHost
import com.android.systemui.doze.DozeMachine
import com.android.systemui.doze.DozeTransitionCallback
@@ -38,14 +39,17 @@
import com.android.systemui.keyguard.shared.model.WakefulnessState
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.phone.BiometricUnlockController
+import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.mockito.withArgCaptor
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
@@ -68,6 +72,7 @@
@Mock private lateinit var authController: AuthController
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
@Mock private lateinit var dreamOverlayCallbackController: DreamOverlayCallbackController
+ @Mock private lateinit var dozeParameters: DozeParameters
private lateinit var underTest: KeyguardRepositoryImpl
@@ -84,6 +89,7 @@
keyguardStateController,
keyguardUpdateMonitor,
dozeTransitionListener,
+ dozeParameters,
authController,
dreamOverlayCallbackController,
)
@@ -170,6 +176,26 @@
}
@Test
+ fun isAodAvailable() = runTest {
+ val flow = underTest.isAodAvailable
+ var isAodAvailable = collectLastValue(flow)
+ runCurrent()
+
+ val callback =
+ withArgCaptor<DozeParameters.Callback> { verify(dozeParameters).addCallback(capture()) }
+
+ whenever(dozeParameters.getAlwaysOn()).thenReturn(false)
+ callback.onAlwaysOnChange()
+ assertThat(isAodAvailable()).isEqualTo(false)
+
+ whenever(dozeParameters.getAlwaysOn()).thenReturn(true)
+ callback.onAlwaysOnChange()
+ assertThat(isAodAvailable()).isEqualTo(true)
+
+ flow.onCompletion { verify(dozeParameters).removeCallback(callback) }
+ }
+
+ @Test
fun isKeyguardOccluded() =
runTest(UnconfinedTestDispatcher()) {
whenever(keyguardStateController.isOccluded).thenReturn(false)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
index 5d2f0eb..f8f2a56 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
@@ -104,7 +104,7 @@
val firstTransitionSteps = listWithStep(step = BigDecimal(.1), stop = BigDecimal(.1))
assertSteps(steps.subList(0, 4), firstTransitionSteps, AOD, LOCKSCREEN)
- val secondTransitionSteps = listWithStep(step = BigDecimal(.1), start = BigDecimal(.9))
+ val secondTransitionSteps = listWithStep(step = BigDecimal(.1), start = BigDecimal(.1))
assertSteps(steps.subList(4, steps.size), secondTransitionSteps, LOCKSCREEN, AOD)
job.cancel()
@@ -201,7 +201,10 @@
)
)
fractions.forEachIndexed { index, fraction ->
- assertThat(steps[index + 1])
+ val step = steps[index + 1]
+ val truncatedValue =
+ BigDecimal(step.value.toDouble()).setScale(2, RoundingMode.HALF_UP).toFloat()
+ assertThat(step.copy(value = truncatedValue))
.isEqualTo(
TransitionStep(
from,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
new file mode 100644
index 0000000..68d13d3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2023 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.systemui.keyguard.domain.interactor
+
+import android.app.StatusBarManager
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
+import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel
+import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.statusbar.CommandQueue.Callbacks
+import com.android.systemui.util.mockito.argumentCaptor
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.onCompletion
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(JUnit4::class)
+class KeyguardInteractorTest : SysuiTestCase() {
+ @Mock private lateinit var commandQueue: CommandQueue
+
+ private lateinit var underTest: KeyguardInteractor
+ private lateinit var repository: FakeKeyguardRepository
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ repository = FakeKeyguardRepository()
+ underTest = KeyguardInteractor(repository, commandQueue)
+ }
+
+ @Test
+ fun onCameraLaunchDetected() = runTest {
+ val flow = underTest.onCameraLaunchDetected
+ var cameraLaunchSource = collectLastValue(flow)
+ runCurrent()
+
+ val captor = argumentCaptor<CommandQueue.Callbacks>()
+ verify(commandQueue).addCallback(captor.capture())
+
+ captor.value.onCameraLaunchGestureDetected(StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE)
+ assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.WIGGLE)
+
+ captor.value.onCameraLaunchGestureDetected(
+ StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP
+ )
+ assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.POWER_DOUBLE_TAP)
+
+ captor.value.onCameraLaunchGestureDetected(
+ StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER
+ )
+ assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.LIFT_TRIGGER)
+
+ captor.value.onCameraLaunchGestureDetected(
+ StatusBarManager.CAMERA_LAUNCH_SOURCE_QUICK_AFFORDANCE
+ )
+ assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.QUICK_AFFORDANCE)
+
+ flow.onCompletion { verify(commandQueue).removeCallback(captor.value) }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
index 14b7c31..43287b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
@@ -44,6 +44,7 @@
import com.android.systemui.settings.FakeUserTracker
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
+import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.FakeSharedPreferences
import com.android.systemui.util.mockito.any
@@ -216,6 +217,7 @@
@Mock private lateinit var animationController: ActivityLaunchAnimator.Controller
@Mock private lateinit var expandable: Expandable
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
+ @Mock private lateinit var commandQueue: CommandQueue
private lateinit var underTest: KeyguardQuickAffordanceInteractor
@@ -286,7 +288,11 @@
)
underTest =
KeyguardQuickAffordanceInteractor(
- keyguardInteractor = KeyguardInteractor(repository = FakeKeyguardRepository()),
+ keyguardInteractor =
+ KeyguardInteractor(
+ repository = FakeKeyguardRepository(),
+ commandQueue = commandQueue
+ ),
registry =
FakeKeyguardQuickAffordanceRegistry(
mapOf(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
index 972919a..b75a15d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
@@ -46,6 +46,7 @@
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
+import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.FakeSharedPreferences
import com.android.systemui.util.mockito.mock
@@ -75,6 +76,7 @@
@Mock private lateinit var userTracker: UserTracker
@Mock private lateinit var activityStarter: ActivityStarter
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
+ @Mock private lateinit var commandQueue: CommandQueue
private lateinit var underTest: KeyguardQuickAffordanceInteractor
@@ -152,7 +154,8 @@
underTest =
KeyguardQuickAffordanceInteractor(
- keyguardInteractor = KeyguardInteractor(repository = repository),
+ keyguardInteractor =
+ KeyguardInteractor(repository = repository, commandQueue = commandQueue),
registry =
FakeKeyguardQuickAffordanceRegistry(
mapOf(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index d2b7838..b3cee22 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -33,6 +33,7 @@
import com.android.systemui.keyguard.util.KeyguardTransitionRunner
import com.android.systemui.shade.data.repository.FakeShadeRepository
import com.android.systemui.shade.data.repository.ShadeRepository
+import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.util.mockito.withArgCaptor
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.cancelChildren
@@ -66,9 +67,14 @@
// Used to verify transition requests for test output
@Mock private lateinit var mockTransitionRepository: KeyguardTransitionRepository
+ @Mock private lateinit var commandQueue: CommandQueue
private lateinit var fromLockscreenTransitionInteractor: FromLockscreenTransitionInteractor
private lateinit var fromDreamingTransitionInteractor: FromDreamingTransitionInteractor
+ private lateinit var fromDozingTransitionInteractor: FromDozingTransitionInteractor
+ private lateinit var fromOccludedTransitionInteractor: FromOccludedTransitionInteractor
+ private lateinit var fromGoneTransitionInteractor: FromGoneTransitionInteractor
+ private lateinit var fromAodTransitionInteractor: FromAodTransitionInteractor
@Before
fun setUp() {
@@ -85,7 +91,7 @@
fromLockscreenTransitionInteractor =
FromLockscreenTransitionInteractor(
scope = testScope,
- keyguardInteractor = KeyguardInteractor(keyguardRepository),
+ keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
shadeRepository = shadeRepository,
keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
@@ -95,11 +101,47 @@
fromDreamingTransitionInteractor =
FromDreamingTransitionInteractor(
scope = testScope,
- keyguardInteractor = KeyguardInteractor(keyguardRepository),
+ keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
)
fromDreamingTransitionInteractor.start()
+
+ fromAodTransitionInteractor =
+ FromAodTransitionInteractor(
+ scope = testScope,
+ keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
+ keyguardTransitionRepository = mockTransitionRepository,
+ keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
+ )
+ fromAodTransitionInteractor.start()
+
+ fromGoneTransitionInteractor =
+ FromGoneTransitionInteractor(
+ scope = testScope,
+ keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
+ keyguardTransitionRepository = mockTransitionRepository,
+ keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
+ )
+ fromGoneTransitionInteractor.start()
+
+ fromDozingTransitionInteractor =
+ FromDozingTransitionInteractor(
+ scope = testScope,
+ keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
+ keyguardTransitionRepository = mockTransitionRepository,
+ keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
+ )
+ fromDozingTransitionInteractor.start()
+
+ fromOccludedTransitionInteractor =
+ FromOccludedTransitionInteractor(
+ scope = testScope,
+ keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
+ keyguardTransitionRepository = mockTransitionRepository,
+ keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
+ )
+ fromOccludedTransitionInteractor.start()
}
@Test
@@ -190,6 +232,289 @@
coroutineContext.cancelChildren()
}
+ @Test
+ fun `OCCLUDED to DOZING`() =
+ testScope.runTest {
+ // GIVEN a device with AOD not available
+ keyguardRepository.setAodAvailable(false)
+ runCurrent()
+
+ // GIVEN a prior transition has run to OCCLUDED
+ runner.startTransition(
+ testScope,
+ TransitionInfo(
+ ownerName = "",
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.OCCLUDED,
+ animator =
+ ValueAnimator().apply {
+ duration = 10
+ interpolator = Interpolators.LINEAR
+ },
+ )
+ )
+ runCurrent()
+ reset(mockTransitionRepository)
+
+ // WHEN the device begins to sleep
+ keyguardRepository.setWakefulnessModel(startingToSleep())
+ runCurrent()
+
+ val info =
+ withArgCaptor<TransitionInfo> {
+ verify(mockTransitionRepository).startTransition(capture())
+ }
+ // THEN a transition to DOZING should occur
+ assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor")
+ assertThat(info.from).isEqualTo(KeyguardState.OCCLUDED)
+ assertThat(info.to).isEqualTo(KeyguardState.DOZING)
+ assertThat(info.animator).isNotNull()
+
+ coroutineContext.cancelChildren()
+ }
+
+ @Test
+ fun `OCCLUDED to AOD`() =
+ testScope.runTest {
+ // GIVEN a device with AOD available
+ keyguardRepository.setAodAvailable(true)
+ runCurrent()
+
+ // GIVEN a prior transition has run to OCCLUDED
+ runner.startTransition(
+ testScope,
+ TransitionInfo(
+ ownerName = "",
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.OCCLUDED,
+ animator =
+ ValueAnimator().apply {
+ duration = 10
+ interpolator = Interpolators.LINEAR
+ },
+ )
+ )
+ runCurrent()
+ reset(mockTransitionRepository)
+
+ // WHEN the device begins to sleep
+ keyguardRepository.setWakefulnessModel(startingToSleep())
+ runCurrent()
+
+ val info =
+ withArgCaptor<TransitionInfo> {
+ verify(mockTransitionRepository).startTransition(capture())
+ }
+ // THEN a transition to DOZING should occur
+ assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor")
+ assertThat(info.from).isEqualTo(KeyguardState.OCCLUDED)
+ assertThat(info.to).isEqualTo(KeyguardState.AOD)
+ assertThat(info.animator).isNotNull()
+
+ coroutineContext.cancelChildren()
+ }
+
+ @Test
+ fun `LOCKSCREEN to DOZING`() =
+ testScope.runTest {
+ // GIVEN a device with AOD not available
+ keyguardRepository.setAodAvailable(false)
+ runCurrent()
+
+ // GIVEN a prior transition has run to LOCKSCREEN
+ runner.startTransition(
+ testScope,
+ TransitionInfo(
+ ownerName = "",
+ from = KeyguardState.GONE,
+ to = KeyguardState.LOCKSCREEN,
+ animator =
+ ValueAnimator().apply {
+ duration = 10
+ interpolator = Interpolators.LINEAR
+ },
+ )
+ )
+ runCurrent()
+ reset(mockTransitionRepository)
+
+ // WHEN the device begins to sleep
+ keyguardRepository.setWakefulnessModel(startingToSleep())
+ runCurrent()
+
+ val info =
+ withArgCaptor<TransitionInfo> {
+ verify(mockTransitionRepository).startTransition(capture())
+ }
+ // THEN a transition to DOZING should occur
+ assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor")
+ assertThat(info.from).isEqualTo(KeyguardState.LOCKSCREEN)
+ assertThat(info.to).isEqualTo(KeyguardState.DOZING)
+ assertThat(info.animator).isNotNull()
+
+ coroutineContext.cancelChildren()
+ }
+
+ @Test
+ fun `LOCKSCREEN to AOD`() =
+ testScope.runTest {
+ // GIVEN a device with AOD available
+ keyguardRepository.setAodAvailable(true)
+ runCurrent()
+
+ // GIVEN a prior transition has run to LOCKSCREEN
+ runner.startTransition(
+ testScope,
+ TransitionInfo(
+ ownerName = "",
+ from = KeyguardState.GONE,
+ to = KeyguardState.LOCKSCREEN,
+ animator =
+ ValueAnimator().apply {
+ duration = 10
+ interpolator = Interpolators.LINEAR
+ },
+ )
+ )
+ runCurrent()
+ reset(mockTransitionRepository)
+
+ // WHEN the device begins to sleep
+ keyguardRepository.setWakefulnessModel(startingToSleep())
+ runCurrent()
+
+ val info =
+ withArgCaptor<TransitionInfo> {
+ verify(mockTransitionRepository).startTransition(capture())
+ }
+ // THEN a transition to DOZING should occur
+ assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor")
+ assertThat(info.from).isEqualTo(KeyguardState.LOCKSCREEN)
+ assertThat(info.to).isEqualTo(KeyguardState.AOD)
+ assertThat(info.animator).isNotNull()
+
+ coroutineContext.cancelChildren()
+ }
+
+ @Test
+ fun `DOZING to LOCKSCREEN`() =
+ testScope.runTest {
+ // GIVEN a prior transition has run to DOZING
+ runner.startTransition(
+ testScope,
+ TransitionInfo(
+ ownerName = "",
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.DOZING,
+ animator =
+ ValueAnimator().apply {
+ duration = 10
+ interpolator = Interpolators.LINEAR
+ },
+ )
+ )
+ runCurrent()
+ reset(mockTransitionRepository)
+
+ // WHEN the device begins to wake
+ keyguardRepository.setWakefulnessModel(startingToWake())
+ runCurrent()
+
+ val info =
+ withArgCaptor<TransitionInfo> {
+ verify(mockTransitionRepository).startTransition(capture())
+ }
+ // THEN a transition to DOZING should occur
+ assertThat(info.ownerName).isEqualTo("FromDozingTransitionInteractor")
+ assertThat(info.from).isEqualTo(KeyguardState.DOZING)
+ assertThat(info.to).isEqualTo(KeyguardState.LOCKSCREEN)
+ assertThat(info.animator).isNotNull()
+
+ coroutineContext.cancelChildren()
+ }
+
+ @Test
+ fun `GONE to DOZING`() =
+ testScope.runTest {
+ // GIVEN a device with AOD not available
+ keyguardRepository.setAodAvailable(false)
+ runCurrent()
+
+ // GIVEN a prior transition has run to GONE
+ runner.startTransition(
+ testScope,
+ TransitionInfo(
+ ownerName = "",
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GONE,
+ animator =
+ ValueAnimator().apply {
+ duration = 10
+ interpolator = Interpolators.LINEAR
+ },
+ )
+ )
+ runCurrent()
+ reset(mockTransitionRepository)
+
+ // WHEN the device begins to sleep
+ keyguardRepository.setWakefulnessModel(startingToSleep())
+ runCurrent()
+
+ val info =
+ withArgCaptor<TransitionInfo> {
+ verify(mockTransitionRepository).startTransition(capture())
+ }
+ // THEN a transition to DOZING should occur
+ assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor")
+ assertThat(info.from).isEqualTo(KeyguardState.GONE)
+ assertThat(info.to).isEqualTo(KeyguardState.DOZING)
+ assertThat(info.animator).isNotNull()
+
+ coroutineContext.cancelChildren()
+ }
+
+ @Test
+ fun `GONE to AOD`() =
+ testScope.runTest {
+ // GIVEN a device with AOD available
+ keyguardRepository.setAodAvailable(true)
+ runCurrent()
+
+ // GIVEN a prior transition has run to GONE
+ runner.startTransition(
+ testScope,
+ TransitionInfo(
+ ownerName = "",
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GONE,
+ animator =
+ ValueAnimator().apply {
+ duration = 10
+ interpolator = Interpolators.LINEAR
+ },
+ )
+ )
+ runCurrent()
+ reset(mockTransitionRepository)
+
+ // WHEN the device begins to sleep
+ keyguardRepository.setWakefulnessModel(startingToSleep())
+ runCurrent()
+
+ val info =
+ withArgCaptor<TransitionInfo> {
+ verify(mockTransitionRepository).startTransition(capture())
+ }
+ // THEN a transition to DOZING should occur
+ assertThat(info.ownerName).isEqualTo("FromGoneTransitionInteractor")
+ assertThat(info.from).isEqualTo(KeyguardState.GONE)
+ assertThat(info.to).isEqualTo(KeyguardState.AOD)
+ assertThat(info.animator).isNotNull()
+
+ coroutineContext.cancelChildren()
+ }
+
private fun startingToWake() =
WakefulnessModel(
WakefulnessState.STARTING_TO_WAKE,
@@ -197,4 +522,12 @@
WakeSleepReason.OTHER,
WakeSleepReason.OTHER
)
+
+ private fun startingToSleep() =
+ WakefulnessModel(
+ WakefulnessState.STARTING_TO_SLEEP,
+ true,
+ WakeSleepReason.OTHER,
+ WakeSleepReason.OTHER
+ )
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
index a2c2f71..022afdd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
@@ -47,6 +47,7 @@
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
+import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.FakeSharedPreferences
import com.android.systemui.util.mockito.any
@@ -84,6 +85,7 @@
@Mock private lateinit var userTracker: UserTracker
@Mock private lateinit var activityStarter: ActivityStarter
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
+ @Mock private lateinit var commandQueue: CommandQueue
private lateinit var underTest: KeyguardBottomAreaViewModel
@@ -124,7 +126,8 @@
)
repository = FakeKeyguardRepository()
- val keyguardInteractor = KeyguardInteractor(repository = repository)
+ val keyguardInteractor =
+ KeyguardInteractor(repository = repository, commandQueue = commandQueue)
whenever(userTracker.userHandle).thenReturn(mock())
whenever(lockPatternUtils.getStrongAuthForUser(anyInt()))
.thenReturn(LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
new file mode 100644
index 0000000..7390591
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2023 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.systemui.keyguard.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE
+import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor.Companion.TO_DREAMING_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.AnimationParams
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel.Companion.LOCKSCREEN_ALPHA
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel.Companion.LOCKSCREEN_TRANSLATION_Y
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@SmallTest
+@RunWith(JUnit4::class)
+class LockscreenToDreamingTransitionViewModelTest : SysuiTestCase() {
+ private lateinit var underTest: LockscreenToDreamingTransitionViewModel
+ private lateinit var repository: FakeKeyguardTransitionRepository
+
+ @Before
+ fun setUp() {
+ repository = FakeKeyguardTransitionRepository()
+ val interactor = KeyguardTransitionInteractor(repository)
+ underTest = LockscreenToDreamingTransitionViewModel(interactor)
+ }
+
+ @Test
+ fun lockscreenFadeOut() =
+ runTest(UnconfinedTestDispatcher()) {
+ val values = mutableListOf<Float>()
+
+ val job = underTest.lockscreenAlpha.onEach { values.add(it) }.launchIn(this)
+
+ // Should start running here...
+ repository.sendTransitionStep(step(0f))
+ repository.sendTransitionStep(step(0.1f))
+ repository.sendTransitionStep(step(0.2f))
+ // ...up to here
+ repository.sendTransitionStep(step(0.3f))
+ repository.sendTransitionStep(step(1f))
+
+ // Only three values should be present, since the dream overlay runs for a small
+ // fraction
+ // of the overall animation time
+ assertThat(values.size).isEqualTo(3)
+ assertThat(values[0]).isEqualTo(1f - animValue(0f, LOCKSCREEN_ALPHA))
+ assertThat(values[1]).isEqualTo(1f - animValue(0.1f, LOCKSCREEN_ALPHA))
+ assertThat(values[2]).isEqualTo(1f - animValue(0.2f, LOCKSCREEN_ALPHA))
+
+ job.cancel()
+ }
+
+ @Test
+ fun lockscreenTranslationY() =
+ runTest(UnconfinedTestDispatcher()) {
+ val values = mutableListOf<Float>()
+
+ val pixels = 100
+ val job =
+ underTest.lockscreenTranslationY(pixels).onEach { values.add(it) }.launchIn(this)
+
+ // Should start running here...
+ repository.sendTransitionStep(step(0f))
+ repository.sendTransitionStep(step(0.3f))
+ repository.sendTransitionStep(step(0.5f))
+ // ...up to here
+ repository.sendTransitionStep(step(1f))
+
+ assertThat(values.size).isEqualTo(3)
+ assertThat(values[0])
+ .isEqualTo(
+ EMPHASIZED_ACCELERATE.getInterpolation(
+ animValue(0f, LOCKSCREEN_TRANSLATION_Y)
+ ) * pixels
+ )
+ assertThat(values[1])
+ .isEqualTo(
+ EMPHASIZED_ACCELERATE.getInterpolation(
+ animValue(0.3f, LOCKSCREEN_TRANSLATION_Y)
+ ) * pixels
+ )
+ assertThat(values[2])
+ .isEqualTo(
+ EMPHASIZED_ACCELERATE.getInterpolation(
+ animValue(0.5f, LOCKSCREEN_TRANSLATION_Y)
+ ) * pixels
+ )
+ job.cancel()
+ }
+
+ private fun animValue(stepValue: Float, params: AnimationParams): Float {
+ val totalDuration = TO_DREAMING_DURATION
+ val startValue = (params.startTime / totalDuration).toFloat()
+
+ val multiplier = (totalDuration / params.duration).toFloat()
+ return (stepValue - startValue) * multiplier
+ }
+
+ private fun step(value: Float): TransitionStep {
+ return TransitionStep(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.DREAMING,
+ value = value,
+ transitionState = TransitionState.RUNNING,
+ ownerName = "LockscreenToDreamingTransitionViewModelTest"
+ )
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
new file mode 100644
index 0000000..759345f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2023 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.systemui.keyguard.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE
+import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor.Companion.TO_OCCLUDED_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.AnimationParams
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel.Companion.LOCKSCREEN_ALPHA
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel.Companion.LOCKSCREEN_TRANSLATION_Y
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@SmallTest
+@RunWith(JUnit4::class)
+class LockscreenToOccludedTransitionViewModelTest : SysuiTestCase() {
+ private lateinit var underTest: LockscreenToOccludedTransitionViewModel
+ private lateinit var repository: FakeKeyguardTransitionRepository
+
+ @Before
+ fun setUp() {
+ repository = FakeKeyguardTransitionRepository()
+ val interactor = KeyguardTransitionInteractor(repository)
+ underTest = LockscreenToOccludedTransitionViewModel(interactor)
+ }
+
+ @Test
+ fun lockscreenFadeOut() =
+ runTest(UnconfinedTestDispatcher()) {
+ val values = mutableListOf<Float>()
+
+ val job = underTest.lockscreenAlpha.onEach { values.add(it) }.launchIn(this)
+
+ // Should start running here...
+ repository.sendTransitionStep(step(0f))
+ repository.sendTransitionStep(step(0.1f))
+ repository.sendTransitionStep(step(0.4f))
+ // ...up to here
+ repository.sendTransitionStep(step(0.7f))
+ repository.sendTransitionStep(step(1f))
+
+ // Only 3 values should be present, since the dream overlay runs for a small fraction
+ // of the overall animation time
+ assertThat(values.size).isEqualTo(3)
+ assertThat(values[0]).isEqualTo(1f - animValue(0f, LOCKSCREEN_ALPHA))
+ assertThat(values[1]).isEqualTo(1f - animValue(0.1f, LOCKSCREEN_ALPHA))
+ assertThat(values[2]).isEqualTo(1f - animValue(0.4f, LOCKSCREEN_ALPHA))
+
+ job.cancel()
+ }
+
+ @Test
+ fun lockscreenTranslationY() =
+ runTest(UnconfinedTestDispatcher()) {
+ val values = mutableListOf<Float>()
+
+ val pixels = 100
+ val job =
+ underTest.lockscreenTranslationY(pixels).onEach { values.add(it) }.launchIn(this)
+
+ // Should start running here...
+ repository.sendTransitionStep(step(0f))
+ repository.sendTransitionStep(step(0.3f))
+ repository.sendTransitionStep(step(0.5f))
+ repository.sendTransitionStep(step(1f))
+ // ...up to here
+
+ assertThat(values.size).isEqualTo(4)
+ assertThat(values[0])
+ .isEqualTo(
+ EMPHASIZED_ACCELERATE.getInterpolation(
+ animValue(0f, LOCKSCREEN_TRANSLATION_Y)
+ ) * pixels
+ )
+ assertThat(values[1])
+ .isEqualTo(
+ EMPHASIZED_ACCELERATE.getInterpolation(
+ animValue(0.3f, LOCKSCREEN_TRANSLATION_Y)
+ ) * pixels
+ )
+ assertThat(values[2])
+ .isEqualTo(
+ EMPHASIZED_ACCELERATE.getInterpolation(
+ animValue(0.5f, LOCKSCREEN_TRANSLATION_Y)
+ ) * pixels
+ )
+ assertThat(values[3])
+ .isEqualTo(
+ EMPHASIZED_ACCELERATE.getInterpolation(
+ animValue(1f, LOCKSCREEN_TRANSLATION_Y)
+ ) * pixels
+ )
+ job.cancel()
+ }
+
+ private fun animValue(stepValue: Float, params: AnimationParams): Float {
+ val totalDuration = TO_OCCLUDED_DURATION
+ val startValue = (params.startTime / totalDuration).toFloat()
+
+ val multiplier = (totalDuration / params.duration).toFloat()
+ return (stepValue - startValue) * multiplier
+ }
+
+ private fun step(value: Float): TransitionStep {
+ return TransitionStep(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.OCCLUDED,
+ value = value,
+ transitionState = TransitionState.RUNNING,
+ ownerName = "LockscreenToOccludedTransitionViewModelTest"
+ )
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt
new file mode 100644
index 0000000..411b1bd
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 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.systemui.log.table
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+
+@SmallTest
+class TableLogBufferFactoryTest : SysuiTestCase() {
+ private val dumpManager: DumpManager = mock()
+ private val systemClock = FakeSystemClock()
+ private val underTest = TableLogBufferFactory(dumpManager, systemClock)
+
+ @Test
+ fun `create - always creates new instance`() {
+ val b1 = underTest.create(NAME_1, SIZE)
+ val b1_copy = underTest.create(NAME_1, SIZE)
+ val b2 = underTest.create(NAME_2, SIZE)
+ val b2_copy = underTest.create(NAME_2, SIZE)
+
+ assertThat(b1).isNotSameInstanceAs(b1_copy)
+ assertThat(b1).isNotSameInstanceAs(b2)
+ assertThat(b2).isNotSameInstanceAs(b2_copy)
+ }
+
+ @Test
+ fun `getOrCreate - reuses instance`() {
+ val b1 = underTest.getOrCreate(NAME_1, SIZE)
+ val b1_copy = underTest.getOrCreate(NAME_1, SIZE)
+ val b2 = underTest.getOrCreate(NAME_2, SIZE)
+ val b2_copy = underTest.getOrCreate(NAME_2, SIZE)
+
+ assertThat(b1).isSameInstanceAs(b1_copy)
+ assertThat(b2).isSameInstanceAs(b2_copy)
+ assertThat(b1).isNotSameInstanceAs(b2)
+ assertThat(b1_copy).isNotSameInstanceAs(b2_copy)
+ }
+
+ companion object {
+ const val NAME_1 = "name 1"
+ const val NAME_2 = "name 2"
+
+ const val SIZE = 8
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataCombineLatestTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataCombineLatestTest.java
index 4d2d0f0..c0639f3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataCombineLatestTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataCombineLatestTest.java
@@ -79,7 +79,7 @@
USER_ID, true, APP, null, ARTIST, TITLE, null,
new ArrayList<>(), new ArrayList<>(), null, PACKAGE, null, null, null, true, null,
MediaData.PLAYBACK_LOCAL, false, KEY, false, false, false, 0L,
- InstanceId.fakeInstanceId(-1), -1);
+ InstanceId.fakeInstanceId(-1), -1, false);
mDeviceData = new MediaDeviceData(true, null, DEVICE_NAME, null, false);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
index 52b694f..c24c8c7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
@@ -228,6 +228,7 @@
whenever(mediaSmartspaceTarget.iconGrid).thenReturn(validRecommendationList)
whenever(mediaSmartspaceTarget.creationTimeMillis).thenReturn(1234L)
whenever(mediaFlags.areMediaSessionActionsEnabled(any(), any())).thenReturn(false)
+ whenever(mediaFlags.isExplicitIndicatorEnabled()).thenReturn(true)
whenever(logger.getNewInstanceId()).thenReturn(instanceIdSequence.newInstanceId())
}
@@ -300,6 +301,60 @@
}
@Test
+ fun testLoadMetadata_withExplicitIndicator() {
+ val metadata =
+ MediaMetadata.Builder().run {
+ putString(MediaMetadata.METADATA_KEY_ARTIST, SESSION_ARTIST)
+ putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_TITLE)
+ putLong(
+ MediaConstants.METADATA_KEY_IS_EXPLICIT,
+ MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT
+ )
+ build()
+ }
+ whenever(mediaControllerFactory.create(anyObject())).thenReturn(controller)
+ whenever(controller.metadata).thenReturn(metadata)
+
+ mediaDataManager.addListener(listener)
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+
+ assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+ assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
+ verify(listener)
+ .onMediaDataLoaded(
+ eq(KEY),
+ eq(null),
+ capture(mediaDataCaptor),
+ eq(true),
+ eq(0),
+ eq(false)
+ )
+ assertThat(mediaDataCaptor.value!!.isExplicit).isTrue()
+ }
+
+ @Test
+ fun testOnMetaDataLoaded_withoutExplicitIndicator() {
+ whenever(mediaControllerFactory.create(anyObject())).thenReturn(controller)
+ whenever(controller.metadata).thenReturn(metadataBuilder.build())
+
+ mediaDataManager.addListener(listener)
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+
+ assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+ assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
+ verify(listener)
+ .onMediaDataLoaded(
+ eq(KEY),
+ eq(null),
+ capture(mediaDataCaptor),
+ eq(true),
+ eq(0),
+ eq(false)
+ )
+ assertThat(mediaDataCaptor.value!!.isExplicit).isFalse()
+ }
+
+ @Test
fun testOnMetaDataLoaded_callsListener() {
addNotificationAndLoad()
verify(logger)
@@ -603,6 +658,53 @@
}
@Test
+ fun testAddResumptionControls_withExplicitIndicator() {
+ val bundle = Bundle()
+ // WHEN resumption controls are added with explicit indicator
+ bundle.putLong(
+ MediaConstants.METADATA_KEY_IS_EXPLICIT,
+ MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT
+ )
+ val desc =
+ MediaDescription.Builder().run {
+ setTitle(SESSION_TITLE)
+ setExtras(bundle)
+ build()
+ }
+ val currentTime = clock.elapsedRealtime()
+ mediaDataManager.addResumptionControls(
+ USER_ID,
+ desc,
+ Runnable {},
+ session.sessionToken,
+ APP_NAME,
+ pendingIntent,
+ PACKAGE_NAME
+ )
+ assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+ assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
+ // THEN the media data indicates that it is for resumption
+ verify(listener)
+ .onMediaDataLoaded(
+ eq(PACKAGE_NAME),
+ eq(null),
+ capture(mediaDataCaptor),
+ eq(true),
+ eq(0),
+ eq(false)
+ )
+ val data = mediaDataCaptor.value
+ assertThat(data.resumption).isTrue()
+ assertThat(data.song).isEqualTo(SESSION_TITLE)
+ assertThat(data.app).isEqualTo(APP_NAME)
+ assertThat(data.actions).hasSize(1)
+ assertThat(data.semanticActions!!.playOrPause).isNotNull()
+ assertThat(data.lastActive).isAtLeast(currentTime)
+ assertThat(data.isExplicit).isTrue()
+ verify(logger).logResumeMediaAdded(anyInt(), eq(PACKAGE_NAME), eq(data.instanceId))
+ }
+
+ @Test
fun testResumptionDisabled_dismissesResumeControls() {
// WHEN there are resume controls and resumption is switched off
val desc =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
index 039dd4d..e4e95e5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
@@ -20,6 +20,7 @@
import android.content.res.Configuration
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import android.util.MathUtils.abs
import androidx.test.filters.SmallTest
import com.android.internal.logging.InstanceId
import com.android.systemui.SysuiTestCase
@@ -31,14 +32,11 @@
import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaData
import com.android.systemui.media.controls.pipeline.EMPTY_SMARTSPACE_MEDIA_DATA
import com.android.systemui.media.controls.pipeline.MediaDataManager
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.ANIMATION_BASE_DURATION
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.DURATION
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.PAGINATION_DELAY
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.TRANSFORM_BEZIER
import com.android.systemui.media.controls.ui.MediaHierarchyManager.Companion.LOCATION_QS
import com.android.systemui.media.controls.util.MediaUiEventLogger
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.qs.PageIndicator
import com.android.systemui.statusbar.notification.collection.provider.OnReorderingAllowedListener
import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider
import com.android.systemui.statusbar.policy.ConfigurationController
@@ -56,6 +54,7 @@
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
+import org.mockito.Mockito.floatThat
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
@@ -86,6 +85,8 @@
@Mock lateinit var debugLogger: MediaCarouselControllerLogger
@Mock lateinit var mediaViewController: MediaViewController
@Mock lateinit var smartspaceMediaData: SmartspaceMediaData
+ @Mock lateinit var mediaCarousel: MediaScrollView
+ @Mock lateinit var pageIndicator: PageIndicator
@Captor lateinit var listener: ArgumentCaptor<MediaDataManager.Listener>
@Captor
lateinit var configListener: ArgumentCaptor<ConfigurationController.ConfigurationListener>
@@ -647,25 +648,22 @@
@Test
fun testSetCurrentState_UpdatePageIndicatorAlphaWhenSquish() {
val delta = 0.0001F
- val paginationSquishMiddle =
- TRANSFORM_BEZIER.getInterpolation(
- (PAGINATION_DELAY + DURATION / 2) / ANIMATION_BASE_DURATION
- )
- val paginationSquishEnd =
- TRANSFORM_BEZIER.getInterpolation(
- (PAGINATION_DELAY + DURATION) / ANIMATION_BASE_DURATION
- )
+ mediaCarouselController.mediaCarousel = mediaCarousel
+ mediaCarouselController.pageIndicator = pageIndicator
+ whenever(mediaCarousel.measuredHeight).thenReturn(100)
+ whenever(pageIndicator.translationY).thenReturn(80F)
+ whenever(pageIndicator.height).thenReturn(10)
whenever(mediaHostStatesManager.mediaHostStates)
.thenReturn(mutableMapOf(LOCATION_QS to mediaHostState))
whenever(mediaHostState.visible).thenReturn(true)
mediaCarouselController.currentEndLocation = LOCATION_QS
- whenever(mediaHostState.squishFraction).thenReturn(paginationSquishMiddle)
+ whenever(mediaHostState.squishFraction).thenReturn(0.938F)
mediaCarouselController.updatePageIndicatorAlpha()
- assertEquals(mediaCarouselController.pageIndicator.alpha, 0.5F, delta)
+ verify(pageIndicator).alpha = floatThat { abs(it - 0.5F) < delta }
- whenever(mediaHostState.squishFraction).thenReturn(paginationSquishEnd)
+ whenever(mediaHostState.squishFraction).thenReturn(1.0F)
mediaCarouselController.updatePageIndicatorAlpha()
- assertEquals(mediaCarouselController.pageIndicator.alpha, 1.0F, delta)
+ verify(pageIndicator).alpha = floatThat { abs(it - 1.0F) < delta }
}
@Ignore("b/253229241")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
index b65f5cb..cfb19fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
@@ -54,6 +54,7 @@
import androidx.lifecycle.LiveData
import androidx.test.filters.SmallTest
import com.android.internal.logging.InstanceId
+import com.android.internal.widget.CachingIconView
import com.android.systemui.ActivityIntentHelper
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
@@ -154,6 +155,7 @@
@Mock private lateinit var albumView: ImageView
private lateinit var titleText: TextView
private lateinit var artistText: TextView
+ private lateinit var explicitIndicator: CachingIconView
private lateinit var seamless: ViewGroup
private lateinit var seamlessButton: View
@Mock private lateinit var seamlessBackground: RippleDrawable
@@ -216,6 +218,7 @@
this.set(Flags.UMO_SURFACE_RIPPLE, false)
this.set(Flags.UMO_TURBULENCE_NOISE, false)
this.set(Flags.MEDIA_FALSING_PENALTY, true)
+ this.set(Flags.MEDIA_EXPLICIT_INDICATOR, true)
}
@JvmField @Rule val mockito = MockitoJUnit.rule()
@@ -350,6 +353,7 @@
appIcon = ImageView(context)
titleText = TextView(context)
artistText = TextView(context)
+ explicitIndicator = CachingIconView(context).also { it.id = R.id.media_explicit_indicator }
seamless = FrameLayout(context)
seamless.foreground = seamlessBackground
seamlessButton = View(context)
@@ -396,6 +400,7 @@
whenever(albumView.foreground).thenReturn(mock(Drawable::class.java))
whenever(viewHolder.titleText).thenReturn(titleText)
whenever(viewHolder.artistText).thenReturn(artistText)
+ whenever(viewHolder.explicitIndicator).thenReturn(explicitIndicator)
whenever(seamlessBackground.getDrawable(0)).thenReturn(mock(GradientDrawable::class.java))
whenever(viewHolder.seamless).thenReturn(seamless)
whenever(viewHolder.seamlessButton).thenReturn(seamlessButton)
@@ -1019,6 +1024,7 @@
@Test
fun bindText() {
+ useRealConstraintSets()
player.attachPlayer(viewHolder)
player.bindPlayer(mediaData, PACKAGE)
@@ -1036,6 +1042,8 @@
handler.onAnimationEnd(mockAnimator)
assertThat(titleText.getText()).isEqualTo(TITLE)
assertThat(artistText.getText()).isEqualTo(ARTIST)
+ assertThat(expandedSet.getVisibility(explicitIndicator.id)).isEqualTo(ConstraintSet.GONE)
+ assertThat(collapsedSet.getVisibility(explicitIndicator.id)).isEqualTo(ConstraintSet.GONE)
// Rebinding should not trigger animation
player.bindPlayer(mediaData, PACKAGE)
@@ -1043,6 +1051,36 @@
}
@Test
+ fun bindTextWithExplicitIndicator() {
+ useRealConstraintSets()
+ val mediaDataWitExp = mediaData.copy(isExplicit = true)
+ player.attachPlayer(viewHolder)
+ player.bindPlayer(mediaDataWitExp, PACKAGE)
+
+ // Capture animation handler
+ val captor = argumentCaptor<Animator.AnimatorListener>()
+ verify(mockAnimator, times(2)).addListener(captor.capture())
+ val handler = captor.value
+
+ // Validate text views unchanged but animation started
+ assertThat(titleText.getText()).isEqualTo("")
+ assertThat(artistText.getText()).isEqualTo("")
+ verify(mockAnimator, times(1)).start()
+
+ // Binding only after animator runs
+ handler.onAnimationEnd(mockAnimator)
+ assertThat(titleText.getText()).isEqualTo(TITLE)
+ assertThat(artistText.getText()).isEqualTo(ARTIST)
+ assertThat(expandedSet.getVisibility(explicitIndicator.id)).isEqualTo(ConstraintSet.VISIBLE)
+ assertThat(collapsedSet.getVisibility(explicitIndicator.id))
+ .isEqualTo(ConstraintSet.VISIBLE)
+
+ // Rebinding should not trigger animation
+ player.bindPlayer(mediaData, PACKAGE)
+ verify(mockAnimator, times(3)).start()
+ }
+
+ @Test
fun bindTextInterrupted() {
val data0 = mediaData.copy(artist = "ARTIST_0")
val data1 = mediaData.copy(artist = "ARTIST_1")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt
index 920801f..a579518 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt
@@ -29,6 +29,7 @@
import com.android.systemui.controls.controller.ControlsControllerImplTest.Companion.eq
import com.android.systemui.dreams.DreamOverlayStateController
import com.android.systemui.keyguard.WakefulnessLifecycle
+import com.android.systemui.media.controls.pipeline.MediaDataManager
import com.android.systemui.media.dream.MediaDreamComplication
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.shade.ShadeExpansionStateManager
@@ -76,6 +77,7 @@
@Mock private lateinit var mediaCarouselScrollHandler: MediaCarouselScrollHandler
@Mock private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
@Mock private lateinit var keyguardViewController: KeyguardViewController
+ @Mock private lateinit var mediaDataManager: MediaDataManager
@Mock private lateinit var uniqueObjectHostView: UniqueObjectHostView
@Mock private lateinit var dreamOverlayStateController: DreamOverlayStateController
@Captor
@@ -110,6 +112,7 @@
keyguardStateController,
bypassController,
mediaCarouselController,
+ mediaDataManager,
keyguardViewController,
dreamOverlayStateController,
configurationController,
@@ -125,6 +128,7 @@
setupHost(qsHost, MediaHierarchyManager.LOCATION_QS, QS_TOP)
setupHost(qqsHost, MediaHierarchyManager.LOCATION_QQS, QQS_TOP)
whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE)
+ whenever(mediaDataManager.hasActiveMedia()).thenReturn(true)
whenever(mediaCarouselController.mediaCarouselScrollHandler)
.thenReturn(mediaCarouselScrollHandler)
val observer = wakefullnessObserver.value
@@ -357,17 +361,31 @@
}
@Test
- fun isCurrentlyInGuidedTransformation_hostNotVisible_returnsTrue() {
+ fun isCurrentlyInGuidedTransformation_hostNotVisible_returnsFalse_with_active() {
goToLockscreen()
enterGuidedTransformation()
whenever(lockHost.visible).thenReturn(false)
whenever(qsHost.visible).thenReturn(true)
whenever(qqsHost.visible).thenReturn(true)
+ whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(true)
assertThat(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).isFalse()
}
@Test
+ fun isCurrentlyInGuidedTransformation_hostNotVisible_returnsTrue_without_active() {
+ // To keep the appearing behavior, we need to be in a guided transition
+ goToLockscreen()
+ enterGuidedTransformation()
+ whenever(lockHost.visible).thenReturn(false)
+ whenever(qsHost.visible).thenReturn(true)
+ whenever(qqsHost.visible).thenReturn(true)
+ whenever(mediaDataManager.hasActiveMediaOrRecommendation()).thenReturn(false)
+
+ assertThat(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).isTrue()
+ }
+
+ @Test
fun testDream() {
goToDream()
setMediaDreamComplicationEnabled(true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt
index 35b0eb6..4ed6d7c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt
@@ -22,13 +22,6 @@
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.ANIMATION_BASE_DURATION
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.CONTROLS_DELAY
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.DETAILS_DELAY
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.DURATION
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.MEDIACONTAINERS_DELAY
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.MEDIATITLES_DELAY
-import com.android.systemui.media.controls.ui.MediaCarouselController.Companion.TRANSFORM_BEZIER
import com.android.systemui.util.animation.MeasurementInput
import com.android.systemui.util.animation.TransitionLayout
import com.android.systemui.util.animation.TransitionViewState
@@ -60,9 +53,10 @@
@Mock private lateinit var controlWidgetState: WidgetState
@Mock private lateinit var bgWidgetState: WidgetState
@Mock private lateinit var mediaTitleWidgetState: WidgetState
+ @Mock private lateinit var mediaSubTitleWidgetState: WidgetState
@Mock private lateinit var mediaContainerWidgetState: WidgetState
- val delta = 0.0001F
+ val delta = 0.1F
private lateinit var mediaViewController: MediaViewController
@@ -76,10 +70,11 @@
@Test
fun testObtainViewState_applySquishFraction_toPlayerTransitionViewState_height() {
mediaViewController.attach(player, MediaViewController.TYPE.PLAYER)
- player.measureState = TransitionViewState().apply {
- this.height = 100
- this.measureHeight = 100
- }
+ player.measureState =
+ TransitionViewState().apply {
+ this.height = 100
+ this.measureHeight = 100
+ }
mediaHostStateHolder.expansion = 1f
val widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY)
val heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY)
@@ -128,29 +123,21 @@
R.id.header_artist to detailWidgetState
)
)
-
- val detailSquishMiddle =
- TRANSFORM_BEZIER.getInterpolation(
- (DETAILS_DELAY + DURATION / 2) / ANIMATION_BASE_DURATION
- )
- mediaViewController.squishViewState(mockViewState, detailSquishMiddle)
+ whenever(mockCopiedState.measureHeight).thenReturn(200)
+ // detail widgets occupy [90, 100]
+ whenever(detailWidgetState.y).thenReturn(90F)
+ whenever(detailWidgetState.height).thenReturn(10)
+ // control widgets occupy [150, 170]
+ whenever(controlWidgetState.y).thenReturn(150F)
+ whenever(controlWidgetState.height).thenReturn(20)
+ // in current beizer, when the progress reach 0.38, the result will be 0.5
+ mediaViewController.squishViewState(mockViewState, 119F / 200F)
verify(detailWidgetState).alpha = floatThat { kotlin.math.abs(it - 0.5F) < delta }
-
- val detailSquishEnd =
- TRANSFORM_BEZIER.getInterpolation((DETAILS_DELAY + DURATION) / ANIMATION_BASE_DURATION)
- mediaViewController.squishViewState(mockViewState, detailSquishEnd)
+ mediaViewController.squishViewState(mockViewState, 150F / 200F)
verify(detailWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
-
- val controlSquishMiddle =
- TRANSFORM_BEZIER.getInterpolation(
- (CONTROLS_DELAY + DURATION / 2) / ANIMATION_BASE_DURATION
- )
- mediaViewController.squishViewState(mockViewState, controlSquishMiddle)
+ mediaViewController.squishViewState(mockViewState, 181.4F / 200F)
verify(controlWidgetState).alpha = floatThat { kotlin.math.abs(it - 0.5F) < delta }
-
- val controlSquishEnd =
- TRANSFORM_BEZIER.getInterpolation((CONTROLS_DELAY + DURATION) / ANIMATION_BASE_DURATION)
- mediaViewController.squishViewState(mockViewState, controlSquishEnd)
+ mediaViewController.squishViewState(mockViewState, 200F / 200F)
verify(controlWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
}
@@ -161,36 +148,33 @@
.thenReturn(
mutableMapOf(
R.id.media_title1 to mediaTitleWidgetState,
+ R.id.media_subtitle1 to mediaSubTitleWidgetState,
R.id.media_cover1_container to mediaContainerWidgetState
)
)
+ whenever(mockCopiedState.measureHeight).thenReturn(360)
+ // media container widgets occupy [20, 300]
+ whenever(mediaContainerWidgetState.y).thenReturn(20F)
+ whenever(mediaContainerWidgetState.height).thenReturn(280)
+ // media title widgets occupy [320, 330]
+ whenever(mediaTitleWidgetState.y).thenReturn(320F)
+ whenever(mediaTitleWidgetState.height).thenReturn(10)
+ // media subtitle widgets occupy [340, 350]
+ whenever(mediaSubTitleWidgetState.y).thenReturn(340F)
+ whenever(mediaSubTitleWidgetState.height).thenReturn(10)
- val containerSquishMiddle =
- TRANSFORM_BEZIER.getInterpolation(
- (MEDIACONTAINERS_DELAY + DURATION / 2) / ANIMATION_BASE_DURATION
- )
- mediaViewController.squishViewState(mockViewState, containerSquishMiddle)
+ // in current beizer, when the progress reach 0.38, the result will be 0.5
+ mediaViewController.squishViewState(mockViewState, 307.6F / 360F)
verify(mediaContainerWidgetState).alpha = floatThat { kotlin.math.abs(it - 0.5F) < delta }
-
- val containerSquishEnd =
- TRANSFORM_BEZIER.getInterpolation(
- (MEDIACONTAINERS_DELAY + DURATION) / ANIMATION_BASE_DURATION
- )
- mediaViewController.squishViewState(mockViewState, containerSquishEnd)
+ mediaViewController.squishViewState(mockViewState, 320F / 360F)
verify(mediaContainerWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
-
- val titleSquishMiddle =
- TRANSFORM_BEZIER.getInterpolation(
- (MEDIATITLES_DELAY + DURATION / 2) / ANIMATION_BASE_DURATION
- )
- mediaViewController.squishViewState(mockViewState, titleSquishMiddle)
+ // media title and media subtitle are in same widget group, should be calculate together and
+ // have same alpha
+ mediaViewController.squishViewState(mockViewState, 353.8F / 360F)
verify(mediaTitleWidgetState).alpha = floatThat { kotlin.math.abs(it - 0.5F) < delta }
-
- val titleSquishEnd =
- TRANSFORM_BEZIER.getInterpolation(
- (MEDIATITLES_DELAY + DURATION) / ANIMATION_BASE_DURATION
- )
- mediaViewController.squishViewState(mockViewState, titleSquishEnd)
+ verify(mediaSubTitleWidgetState).alpha = floatThat { kotlin.math.abs(it - 0.5F) < delta }
+ mediaViewController.squishViewState(mockViewState, 360F / 360F)
verify(mediaTitleWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
+ verify(mediaSubTitleWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
index b16a39f..f5432e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
@@ -102,8 +102,6 @@
private MediaOutputController.Callback mCb = mock(MediaOutputController.Callback.class);
private MediaDevice mMediaDevice1 = mock(MediaDevice.class);
private MediaDevice mMediaDevice2 = mock(MediaDevice.class);
- private MediaItem mMediaItem1 = mock(MediaItem.class);
- private MediaItem mMediaItem2 = mock(MediaItem.class);
private NearbyDevice mNearbyDevice1 = mock(NearbyDevice.class);
private NearbyDevice mNearbyDevice2 = mock(NearbyDevice.class);
private MediaMetadata mMediaMetadata = mock(MediaMetadata.class);
@@ -127,7 +125,6 @@
private LocalMediaManager mLocalMediaManager;
private List<MediaController> mMediaControllers = new ArrayList<>();
private List<MediaDevice> mMediaDevices = new ArrayList<>();
- private List<MediaItem> mMediaItemList = new ArrayList<>();
private List<NearbyDevice> mNearbyDevices = new ArrayList<>();
private MediaDescription mMediaDescription;
private List<RoutingSessionInfo> mRoutingSessionInfos = new ArrayList<>();
@@ -149,7 +146,9 @@
Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
mKeyguardManager, mFlags);
when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(false);
+ when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ROUTES_PROCESSING)).thenReturn(false);
mLocalMediaManager = spy(mMediaOutputController.mLocalMediaManager);
+ when(mLocalMediaManager.isPreferenceRouteListingExist()).thenReturn(false);
mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
MediaDescription.Builder builder = new MediaDescription.Builder();
builder.setTitle(TEST_SONG);
@@ -160,16 +159,12 @@
when(mMediaDevice2.getId()).thenReturn(TEST_DEVICE_2_ID);
mMediaDevices.add(mMediaDevice1);
mMediaDevices.add(mMediaDevice2);
- when(mMediaItem1.getMediaDevice()).thenReturn(Optional.of(mMediaDevice1));
- when(mMediaItem2.getMediaDevice()).thenReturn(Optional.of(mMediaDevice2));
- mMediaItemList.add(mMediaItem1);
- mMediaItemList.add(mMediaItem2);
when(mNearbyDevice1.getMediaRoute2Id()).thenReturn(TEST_DEVICE_1_ID);
- when(mNearbyDevice1.getRangeZone()).thenReturn(NearbyDevice.RANGE_CLOSE);
+ when(mNearbyDevice1.getRangeZone()).thenReturn(NearbyDevice.RANGE_FAR);
when(mNearbyDevice2.getMediaRoute2Id()).thenReturn(TEST_DEVICE_2_ID);
- when(mNearbyDevice2.getRangeZone()).thenReturn(NearbyDevice.RANGE_FAR);
+ when(mNearbyDevice2.getRangeZone()).thenReturn(NearbyDevice.RANGE_CLOSE);
mNearbyDevices.add(mNearbyDevice1);
mNearbyDevices.add(mNearbyDevice2);
}
@@ -274,8 +269,20 @@
mMediaOutputController.onDevicesUpdated(mNearbyDevices);
mMediaOutputController.onDeviceListUpdate(mMediaDevices);
- verify(mMediaDevice1).setRangeZone(NearbyDevice.RANGE_CLOSE);
- verify(mMediaDevice2).setRangeZone(NearbyDevice.RANGE_FAR);
+ verify(mMediaDevice1).setRangeZone(NearbyDevice.RANGE_FAR);
+ verify(mMediaDevice2).setRangeZone(NearbyDevice.RANGE_CLOSE);
+ }
+
+ @Test
+ public void onDeviceListUpdate_withNearbyDevices_rankByRangeInformation()
+ throws RemoteException {
+ mMediaOutputController.start(mCb);
+ reset(mCb);
+
+ mMediaOutputController.onDevicesUpdated(mNearbyDevices);
+ mMediaOutputController.onDeviceListUpdate(mMediaDevices);
+
+ assertThat(mMediaDevices.get(0).getId()).isEqualTo(TEST_DEVICE_1_ID);
}
@Test
@@ -292,6 +299,22 @@
}
@Test
+ public void routeProcessSupport_onDeviceListUpdate_preferenceExist_NotUpdatesRangeInformation()
+ throws RemoteException {
+ when(mLocalMediaManager.isPreferenceRouteListingExist()).thenReturn(true);
+ when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ROUTES_PROCESSING)).thenReturn(true);
+ when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
+ mMediaOutputController.start(mCb);
+ reset(mCb);
+
+ mMediaOutputController.onDevicesUpdated(mNearbyDevices);
+ mMediaOutputController.onDeviceListUpdate(mMediaDevices);
+
+ verify(mMediaDevice1, never()).setRangeZone(anyInt());
+ verify(mMediaDevice2, never()).setRangeZone(anyInt());
+ }
+
+ @Test
public void advanced_onDeviceListUpdate_verifyDeviceListCallback() {
when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
mMediaOutputController.start(mCb);
@@ -307,6 +330,35 @@
assertThat(devices.containsAll(mMediaDevices)).isTrue();
assertThat(devices.size()).isEqualTo(mMediaDevices.size());
+ assertThat(mMediaOutputController.getMediaItemList().size()).isEqualTo(
+ mMediaDevices.size() + 2);
+ verify(mCb).onDeviceListChanged();
+ }
+
+ @Test
+ public void advanced_categorizeMediaItems_withSuggestedDevice_verifyDeviceListSize() {
+ when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
+ when(mMediaDevice1.isSuggestedDevice()).thenReturn(true);
+ when(mMediaDevice2.isSuggestedDevice()).thenReturn(false);
+
+ mMediaOutputController.start(mCb);
+ reset(mCb);
+ mMediaOutputController.getMediaItemList().clear();
+ mMediaOutputController.onDeviceListUpdate(mMediaDevices);
+ final List<MediaDevice> devices = new ArrayList<>();
+ int dividerSize = 0;
+ for (MediaItem item : mMediaOutputController.getMediaItemList()) {
+ if (item.getMediaDevice().isPresent()) {
+ devices.add(item.getMediaDevice().get());
+ }
+ if (item.getMediaItemType() == MediaItem.MediaItemType.TYPE_GROUP_DIVIDER) {
+ dividerSize++;
+ }
+ }
+
+ assertThat(devices.containsAll(mMediaDevices)).isTrue();
+ assertThat(devices.size()).isEqualTo(mMediaDevices.size());
+ assertThat(dividerSize).isEqualTo(2);
verify(mCb).onDeviceListChanged();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
index 4cc12c7..f5b3959 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
@@ -206,6 +206,21 @@
}
@Test
+ fun commandQueueCallback_almostCloseToStartCast_deviceNameBlank_showsDefaultDeviceName() {
+ commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+ StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
+ routeInfoWithBlankDeviceName,
+ null,
+ )
+
+ val chipbarView = getChipbarView()
+ assertThat(chipbarView.getChipText())
+ .contains(context.getString(R.string.media_ttt_default_device_type))
+ assertThat(chipbarView.getChipText())
+ .isNotEqualTo(ChipStateSender.ALMOST_CLOSE_TO_START_CAST.getExpectedStateText())
+ }
+
+ @Test
fun commandQueueCallback_almostCloseToEndCast_triggersCorrectChip() {
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
@@ -248,6 +263,21 @@
}
@Test
+ fun commandQueueCallback_transferToReceiverTriggered_deviceNameBlank_showsDefaultDeviceName() {
+ commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+ StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED,
+ routeInfoWithBlankDeviceName,
+ null,
+ )
+
+ val chipbarView = getChipbarView()
+ assertThat(chipbarView.getChipText())
+ .contains(context.getString(R.string.media_ttt_default_device_type))
+ assertThat(chipbarView.getChipText())
+ .isNotEqualTo(ChipStateSender.TRANSFER_TO_RECEIVER_TRIGGERED.getExpectedStateText())
+ }
+
+ @Test
fun commandQueueCallback_transferToThisDeviceTriggered_triggersCorrectChip() {
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
@@ -934,6 +964,7 @@
private const val APP_NAME = "Fake app name"
private const val OTHER_DEVICE_NAME = "My Tablet"
+private const val BLANK_DEVICE_NAME = " "
private const val PACKAGE_NAME = "com.android.systemui"
private const val TIMEOUT = 10000
@@ -942,3 +973,9 @@
.addFeature("feature")
.setClientPackageName(PACKAGE_NAME)
.build()
+
+private val routeInfoWithBlankDeviceName =
+ MediaRoute2Info.Builder("id", BLANK_DEVICE_NAME)
+ .addFeature("feature")
+ .setClientPackageName(PACKAGE_NAME)
+ .build()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
index 4a9c750..fc90c1a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
@@ -93,7 +93,7 @@
createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
verify(context).startActivity(notesIntent)
- verify(bubbles, never()).showAppBubble(notesIntent)
+ verify(bubbles, never()).showOrHideAppBubble(notesIntent)
}
@Test
@@ -102,7 +102,7 @@
createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
- verify(bubbles).showAppBubble(notesIntent)
+ verify(bubbles).showOrHideAppBubble(notesIntent)
verify(context, never()).startActivity(notesIntent)
}
@@ -113,7 +113,7 @@
createNoteTaskController().showNoteTask(isInMultiWindowMode = true)
verify(context).startActivity(notesIntent)
- verify(bubbles, never()).showAppBubble(notesIntent)
+ verify(bubbles, never()).showOrHideAppBubble(notesIntent)
}
@Test
@@ -123,7 +123,7 @@
createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
verify(context, never()).startActivity(notesIntent)
- verify(bubbles, never()).showAppBubble(notesIntent)
+ verify(bubbles, never()).showOrHideAppBubble(notesIntent)
}
@Test
@@ -133,7 +133,7 @@
createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
verify(context, never()).startActivity(notesIntent)
- verify(bubbles, never()).showAppBubble(notesIntent)
+ verify(bubbles, never()).showOrHideAppBubble(notesIntent)
}
@Test
@@ -143,7 +143,7 @@
createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
verify(context, never()).startActivity(notesIntent)
- verify(bubbles, never()).showAppBubble(notesIntent)
+ verify(bubbles, never()).showOrHideAppBubble(notesIntent)
}
@Test
@@ -153,7 +153,7 @@
createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
verify(context, never()).startActivity(notesIntent)
- verify(bubbles, never()).showAppBubble(notesIntent)
+ verify(bubbles, never()).showOrHideAppBubble(notesIntent)
}
@Test
@@ -161,7 +161,7 @@
createNoteTaskController(isEnabled = false).showNoteTask()
verify(context, never()).startActivity(notesIntent)
- verify(bubbles, never()).showAppBubble(notesIntent)
+ verify(bubbles, never()).showOrHideAppBubble(notesIntent)
}
@Test
@@ -171,7 +171,7 @@
createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
verify(context, never()).startActivity(notesIntent)
- verify(bubbles, never()).showAppBubble(notesIntent)
+ verify(bubbles, never()).showOrHideAppBubble(notesIntent)
}
// endregion
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java
index 04b50d8..2e6b0cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java
@@ -15,11 +15,17 @@
*/
package com.android.systemui.qs.external;
+import static android.service.quicksettings.TileService.START_ACTIVITY_NEEDS_PENDING_INTENT;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
@@ -29,6 +35,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.compat.CompatChanges;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -59,6 +66,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.MockitoSession;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -77,11 +85,16 @@
private Handler mHandler;
private TileLifecycleManager mStateManager;
private TestContextWrapper mWrappedContext;
+ private MockitoSession mMockitoSession;
@Before
public void setUp() throws Exception {
setPackageEnabled(true);
mTileServiceComponentName = new ComponentName(mContext, "FakeTileService.class");
+ mMockitoSession = mockitoSession()
+ .initMocks(this)
+ .mockStatic(CompatChanges.class)
+ .startMocking();
// Stub.asInterface will just return itself.
when(mMockTileService.queryLocalInterface(anyString())).thenReturn(mMockTileService);
@@ -106,7 +119,13 @@
@After
public void tearDown() throws Exception {
- mThread.quit();
+ if (mMockitoSession != null) {
+ mMockitoSession.finishMocking();
+ }
+ if (mThread != null) {
+ mThread.quit();
+ }
+
mStateManager.handleDestroy();
}
@@ -290,6 +309,50 @@
verify(falseContext).unbindService(captor.getValue());
}
+ @Test
+ public void testVersionUDoesNotBindsAllowBackgroundActivity() {
+ mockChangeEnabled(START_ACTIVITY_NEEDS_PENDING_INTENT, true);
+ Context falseContext = mock(Context.class);
+ TileLifecycleManager manager = new TileLifecycleManager(mHandler, falseContext,
+ mock(IQSService.class),
+ mMockPackageManagerAdapter,
+ mMockBroadcastDispatcher,
+ mTileServiceIntent,
+ mUser);
+
+ manager.setBindService(true);
+ int flags = Context.BIND_AUTO_CREATE
+ | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE
+ | Context.BIND_WAIVE_PRIORITY;
+
+ verify(falseContext).bindServiceAsUser(any(), any(), eq(flags), any());
+ }
+
+ @Test
+ public void testVersionLessThanUBindsAllowBackgroundActivity() {
+ mockChangeEnabled(START_ACTIVITY_NEEDS_PENDING_INTENT, false);
+ Context falseContext = mock(Context.class);
+ TileLifecycleManager manager = new TileLifecycleManager(mHandler, falseContext,
+ mock(IQSService.class),
+ mMockPackageManagerAdapter,
+ mMockBroadcastDispatcher,
+ mTileServiceIntent,
+ mUser);
+
+ manager.setBindService(true);
+ int flags = Context.BIND_AUTO_CREATE
+ | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE
+ | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS
+ | Context.BIND_WAIVE_PRIORITY;
+
+ verify(falseContext).bindServiceAsUser(any(), any(), eq(flags), any());
+ }
+
+ private void mockChangeEnabled(long changeId, boolean enabled) {
+ doReturn(enabled).when(() -> CompatChanges.isChangeEnabled(eq(changeId), anyString(),
+ any(UserHandle.class)));
+ }
+
private static class TestContextWrapper extends ContextWrapper {
private IntentFilter mLastIntentFilter;
private int mLastFlag;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt
index ca3182a..3281fa9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt
@@ -28,7 +28,6 @@
import com.android.systemui.qs.tiles.BluetoothTile
import com.android.systemui.qs.tiles.CameraToggleTile
import com.android.systemui.qs.tiles.CastTile
-import com.android.systemui.qs.tiles.CellularTile
import com.android.systemui.qs.tiles.ColorCorrectionTile
import com.android.systemui.qs.tiles.ColorInversionTile
import com.android.systemui.qs.tiles.DataSaverTile
@@ -49,7 +48,6 @@
import com.android.systemui.qs.tiles.RotationLockTile
import com.android.systemui.qs.tiles.ScreenRecordTile
import com.android.systemui.qs.tiles.UiModeNightTile
-import com.android.systemui.qs.tiles.WifiTile
import com.android.systemui.qs.tiles.WorkModeTile
import com.android.systemui.util.leak.GarbageMonitor
import com.google.common.truth.Truth.assertThat
@@ -63,10 +61,8 @@
import org.mockito.Mockito.`when` as whenever
private val specMap = mapOf(
- "wifi" to WifiTile::class.java,
"internet" to InternetTile::class.java,
"bt" to BluetoothTile::class.java,
- "cell" to CellularTile::class.java,
"dnd" to DndTile::class.java,
"inversion" to ColorInversionTile::class.java,
"airplane" to AirplaneModeTile::class.java,
@@ -102,10 +98,8 @@
@Mock(answer = Answers.RETURNS_SELF) private lateinit var customTileBuilder: CustomTile.Builder
@Mock private lateinit var customTile: CustomTile
- @Mock private lateinit var wifiTile: WifiTile
@Mock private lateinit var internetTile: InternetTile
@Mock private lateinit var bluetoothTile: BluetoothTile
- @Mock private lateinit var cellularTile: CellularTile
@Mock private lateinit var dndTile: DndTile
@Mock private lateinit var colorInversionTile: ColorInversionTile
@Mock private lateinit var airplaneTile: AirplaneModeTile
@@ -146,10 +140,8 @@
factory = QSFactoryImpl(
{ qsHost },
{ customTileBuilder },
- { wifiTile },
{ internetTile },
{ bluetoothTile },
- { cellularTile },
{ dndTile },
{ colorInversionTile },
{ airplaneTile },
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt
index fa1fedb..99c79b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt
@@ -39,7 +39,6 @@
import com.android.internal.util.ScreenshotHelper.ScreenshotRequest
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FakeFeatureFlags
-import com.android.systemui.flags.Flags.SCREENSHOT_REQUEST_PROCESSOR
import com.android.systemui.flags.Flags.SCREENSHOT_WORK_PROFILE_POLICY
import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_REQUESTED_KEY_CHORD
import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_REQUESTED_OVERVIEW
@@ -101,7 +100,6 @@
}.`when`(requestProcessor).processAsync(/* request= */ any(), /* callback= */ any())
// Flipped in selected test cases
- flags.set(SCREENSHOT_REQUEST_PROCESSOR, false)
flags.set(SCREENSHOT_WORK_PROFILE_POLICY, false)
service.attach(
@@ -149,31 +147,6 @@
}
@Test
- fun takeScreenshot_requestProcessorEnabled() {
- flags.set(SCREENSHOT_REQUEST_PROCESSOR, true)
-
- val request = ScreenshotRequest(
- TAKE_SCREENSHOT_FULLSCREEN,
- SCREENSHOT_KEY_CHORD,
- topComponent)
-
- service.handleRequest(request, { /* onSaved */ }, callback)
-
- verify(controller, times(1)).takeScreenshotFullscreen(
- eq(topComponent),
- /* onSavedListener = */ any(),
- /* requestCallback = */ any())
-
- assertEquals("Expected one UiEvent", eventLogger.numLogs(), 1)
- val logEvent = eventLogger.get(0)
-
- assertEquals("Expected SCREENSHOT_REQUESTED UiEvent",
- logEvent.eventId, SCREENSHOT_REQUESTED_KEY_CHORD.id)
- assertEquals("Expected supplied package name",
- topComponent.packageName, eventLogger.get(0).packageName)
- }
-
- @Test
fun takeScreenshotProvidedImage() {
val bounds = Rect(50, 50, 150, 150)
val bitmap = makeHardwareBitmap(100, 100)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplReceiveTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplReceiveTest.kt
new file mode 100644
index 0000000..3710281
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplReceiveTest.kt
@@ -0,0 +1,100 @@
+package com.android.systemui.settings
+
+import android.content.Context
+import android.content.Intent
+import android.content.pm.UserInfo
+import android.os.Handler
+import android.os.UserHandle
+import android.os.UserManager
+import androidx.concurrent.futures.DirectExecutor
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.capture
+import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.Executor
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(Parameterized::class)
+class UserTrackerImplReceiveTest : SysuiTestCase() {
+
+ companion object {
+
+ @JvmStatic
+ @Parameterized.Parameters
+ fun data(): Iterable<String> =
+ listOf(
+ Intent.ACTION_USER_INFO_CHANGED,
+ Intent.ACTION_MANAGED_PROFILE_AVAILABLE,
+ Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE,
+ Intent.ACTION_MANAGED_PROFILE_ADDED,
+ Intent.ACTION_MANAGED_PROFILE_REMOVED,
+ Intent.ACTION_MANAGED_PROFILE_UNLOCKED
+ )
+ }
+
+ private val executor: Executor = DirectExecutor.INSTANCE
+
+ @Mock private lateinit var context: Context
+ @Mock private lateinit var userManager: UserManager
+ @Mock(stubOnly = true) private lateinit var dumpManager: DumpManager
+ @Mock(stubOnly = true) private lateinit var handler: Handler
+
+ @Parameterized.Parameter lateinit var intentAction: String
+ @Mock private lateinit var callback: UserTracker.Callback
+ @Captor private lateinit var captor: ArgumentCaptor<List<UserInfo>>
+
+ private lateinit var tracker: UserTrackerImpl
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ `when`(context.user).thenReturn(UserHandle.SYSTEM)
+ `when`(context.createContextAsUser(ArgumentMatchers.any(), anyInt())).thenReturn(context)
+
+ tracker = UserTrackerImpl(context, userManager, dumpManager, handler)
+ }
+
+ @Test
+ fun `calls callback and updates profiles when an intent received`() {
+ tracker.initialize(0)
+ tracker.addCallback(callback, executor)
+ val profileID = tracker.userId + 10
+
+ `when`(userManager.getProfiles(anyInt())).thenAnswer { invocation ->
+ val id = invocation.getArgument<Int>(0)
+ val info = UserInfo(id, "", UserInfo.FLAG_FULL)
+ val infoProfile =
+ UserInfo(
+ id + 10,
+ "",
+ "",
+ UserInfo.FLAG_MANAGED_PROFILE,
+ UserManager.USER_TYPE_PROFILE_MANAGED
+ )
+ infoProfile.profileGroupId = id
+ listOf(info, infoProfile)
+ }
+
+ tracker.onReceive(context, Intent(intentAction))
+
+ verify(callback, times(0)).onUserChanged(anyInt(), any())
+ verify(callback, times(1)).onProfilesChanged(capture(captor))
+ assertThat(captor.value.map { it.id }).containsExactly(0, profileID)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
index 52462c7..e65bbb1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
@@ -124,6 +124,16 @@
verify(context).registerReceiverForAllUsers(
eq(tracker), capture(captor), isNull(), eq(handler))
+ with(captor.value) {
+ assertThat(countActions()).isEqualTo(7)
+ assertThat(hasAction(Intent.ACTION_USER_SWITCHED)).isTrue()
+ assertThat(hasAction(Intent.ACTION_USER_INFO_CHANGED)).isTrue()
+ assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE)).isTrue()
+ assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)).isTrue()
+ assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_ADDED)).isTrue()
+ assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_REMOVED)).isTrue()
+ assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED)).isTrue()
+ }
}
@Test
@@ -280,37 +290,6 @@
}
@Test
- fun testCallbackCalledOnProfileChanged() {
- tracker.initialize(0)
- val callback = TestCallback()
- tracker.addCallback(callback, executor)
- val profileID = tracker.userId + 10
-
- `when`(userManager.getProfiles(anyInt())).thenAnswer { invocation ->
- val id = invocation.getArgument<Int>(0)
- val info = UserInfo(id, "", UserInfo.FLAG_FULL)
- val infoProfile = UserInfo(
- id + 10,
- "",
- "",
- UserInfo.FLAG_MANAGED_PROFILE,
- UserManager.USER_TYPE_PROFILE_MANAGED
- )
- infoProfile.profileGroupId = id
- listOf(info, infoProfile)
- }
-
- val intent = Intent(Intent.ACTION_MANAGED_PROFILE_AVAILABLE)
- .putExtra(Intent.EXTRA_USER, UserHandle.of(profileID))
-
- tracker.onReceive(context, intent)
-
- assertThat(callback.calledOnUserChanged).isEqualTo(0)
- assertThat(callback.calledOnProfilesChanged).isEqualTo(1)
- assertThat(callback.lastUserProfiles.map { it.id }).containsExactly(0, profileID)
- }
-
- @Test
fun testCallbackCalledOnUserInfoChanged() {
tracker.initialize(0)
val callback = TestCallback()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
index 88651c1..f802a5e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
@@ -17,6 +17,7 @@
package com.android.systemui.shade
import android.testing.AndroidTestingRunner
+import android.view.ViewGroup
import androidx.constraintlayout.widget.ConstraintSet
import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
import androidx.constraintlayout.widget.ConstraintSet.START
@@ -92,12 +93,12 @@
assertThat(getConstraint(R.id.clock).layout.horizontalBias).isEqualTo(0f)
assertThat(getConstraint(R.id.date).layout.startToStart).isEqualTo(PARENT_ID)
- assertThat(getConstraint(R.id.date).layout.horizontalBias).isEqualTo(0f)
+ assertThat(getConstraint(R.id.date).layout.horizontalBias).isEqualTo(0.5f)
assertThat(getConstraint(R.id.batteryRemainingIcon).layout.endToEnd)
.isEqualTo(PARENT_ID)
assertThat(getConstraint(R.id.batteryRemainingIcon).layout.horizontalBias)
- .isEqualTo(1f)
+ .isEqualTo(0.5f)
assertThat(getConstraint(R.id.privacy_container).layout.endToEnd)
.isEqualTo(R.id.end_guide)
@@ -331,10 +332,8 @@
val views = mapOf(
R.id.clock to "clock",
R.id.date to "date",
- R.id.statusIcons to "icons",
R.id.privacy_container to "privacy",
R.id.carrier_group to "carriers",
- R.id.batteryRemainingIcon to "battery",
)
views.forEach { (id, name) ->
assertWithMessage("$name has 0 height in qqs")
@@ -352,11 +351,8 @@
fun testCheckViewsDontChangeSizeBetweenAnimationConstraints() {
val views = mapOf(
R.id.clock to "clock",
- R.id.date to "date",
- R.id.statusIcons to "icons",
R.id.privacy_container to "privacy",
R.id.carrier_group to "carriers",
- R.id.batteryRemainingIcon to "battery",
)
views.forEach { (id, name) ->
expect.withMessage("$name changes height")
@@ -369,8 +365,8 @@
}
private fun Int.fromConstraint() = when (this) {
- -1 -> "MATCH_PARENT"
- -2 -> "WRAP_CONTENT"
+ ViewGroup.LayoutParams.MATCH_PARENT -> "MATCH_PARENT"
+ ViewGroup.LayoutParams.WRAP_CONTENT -> "WRAP_CONTENT"
else -> toString()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
index 1d30ad9..f580f5e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
@@ -182,6 +182,7 @@
null
}
whenever(view.visibility).thenAnswer { _ -> viewVisibility }
+ whenever(view.alpha).thenReturn(1f)
whenever(iconManagerFactory.create(any(), any())).thenReturn(iconManager)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
index b4c8f98..b568122 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
@@ -1,5 +1,6 @@
package com.android.systemui.shade
+import android.animation.ValueAnimator
import android.app.StatusBarManager
import android.content.Context
import android.testing.AndroidTestingRunner
@@ -30,6 +31,7 @@
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
@@ -37,6 +39,7 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Answers
+import org.mockito.ArgumentMatchers.anyFloat
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mockito.mock
@@ -75,6 +78,7 @@
@JvmField @Rule val mockitoRule = MockitoJUnit.rule()
var viewVisibility = View.GONE
+ var viewAlpha = 1f
private lateinit var mLargeScreenShadeHeaderController: LargeScreenShadeHeaderController
private lateinit var carrierIconSlots: List<String>
@@ -101,6 +105,13 @@
null
}
whenever(view.visibility).thenAnswer { _ -> viewVisibility }
+
+ whenever(view.setAlpha(anyFloat())).then {
+ viewAlpha = it.arguments[0] as Float
+ null
+ }
+ whenever(view.alpha).thenAnswer { _ -> viewAlpha }
+
whenever(variableDateViewControllerFactory.create(any()))
.thenReturn(variableDateViewController)
whenever(iconManagerFactory.create(any(), any())).thenReturn(iconManager)
@@ -155,6 +166,16 @@
}
@Test
+ fun alphaChangesUpdateVisibility() {
+ makeShadeVisible()
+ mLargeScreenShadeHeaderController.shadeExpandedFraction = 0f
+ assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
+
+ mLargeScreenShadeHeaderController.shadeExpandedFraction = 1f
+ assertThat(viewVisibility).isEqualTo(View.VISIBLE)
+ }
+
+ @Test
fun singleCarrier_enablesCarrierIconsInStatusIcons() {
whenever(qsCarrierGroupController.isSingleCarrier).thenReturn(true)
@@ -239,6 +260,39 @@
}
@Test
+ fun testShadeExpanded_true_alpha_zero_invisible() {
+ view.alpha = 0f
+ mLargeScreenShadeHeaderController.largeScreenActive = true
+ mLargeScreenShadeHeaderController.qsVisible = true
+
+ assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
+ }
+
+ @Test
+ fun animatorCallsUpdateVisibilityOnUpdate() {
+ val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
+ whenever(view.animate()).thenReturn(animator)
+
+ mLargeScreenShadeHeaderController.startCustomizingAnimation(show = false, 0L)
+
+ val updateCaptor = argumentCaptor<ValueAnimator.AnimatorUpdateListener>()
+ verify(animator).setUpdateListener(capture(updateCaptor))
+
+ mLargeScreenShadeHeaderController.largeScreenActive = true
+ mLargeScreenShadeHeaderController.qsVisible = true
+
+ view.alpha = 1f
+ updateCaptor.value.onAnimationUpdate(mock())
+
+ assertThat(viewVisibility).isEqualTo(View.VISIBLE)
+
+ view.alpha = 0f
+ updateCaptor.value.onAnimationUpdate(mock())
+
+ assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
+ }
+
+ @Test
fun demoMode_attachDemoMode() {
val cb = argumentCaptor<DemoMode>()
verify(demoModeController).addCallback(capture(cb))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 53ab19c..a1e9a27 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -108,6 +108,8 @@
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel;
import com.android.systemui.media.controls.pipeline.MediaDataManager;
import com.android.systemui.media.controls.ui.KeyguardMediaController;
@@ -295,6 +297,9 @@
@Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
@Mock private DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel;
@Mock private OccludedToLockscreenTransitionViewModel mOccludedToLockscreenTransitionViewModel;
+ @Mock private LockscreenToDreamingTransitionViewModel mLockscreenToDreamingTransitionViewModel;
+ @Mock private LockscreenToOccludedTransitionViewModel mLockscreenToOccludedTransitionViewModel;
+
@Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
@Mock private CoroutineDispatcher mMainDispatcher;
@Mock private MotionEvent mDownMotionEvent;
@@ -516,6 +521,8 @@
mAlternateBouncerInteractor,
mDreamingToLockscreenTransitionViewModel,
mOccludedToLockscreenTransitionViewModel,
+ mLockscreenToDreamingTransitionViewModel,
+ mLockscreenToOccludedTransitionViewModel,
mMainDispatcher,
mKeyguardTransitionInteractor,
mDumpManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
index 3137aa5..4c76825 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -31,6 +31,7 @@
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.keyguard.KeyguardUnlockAnimationController
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel
import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
import com.android.systemui.statusbar.LockscreenShadeTransitionController
@@ -104,6 +105,7 @@
@Mock lateinit var keyguardBouncerContainer: ViewGroup
@Mock lateinit var keyguardBouncerComponent: KeyguardBouncerComponent
@Mock lateinit var keyguardHostViewController: KeyguardHostViewController
+ @Mock lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
private lateinit var interactionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
private lateinit var interactionEventHandler: InteractionEventHandler
@@ -136,7 +138,8 @@
featureFlags,
keyguardBouncerViewModel,
keyguardBouncerComponentFactory,
- alternateBouncerInteractor
+ alternateBouncerInteractor,
+ keyguardTransitionInteractor,
)
underTest.setupExpandedStatusBar()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java
index 544b00e..d435624 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java
@@ -41,6 +41,7 @@
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
@@ -95,6 +96,7 @@
@Mock private KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory;
@Mock private NotificationInsetsController mNotificationInsetsController;
@Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
+ @Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
@Captor private ArgumentCaptor<NotificationShadeWindowView.InteractionEventHandler>
mInteractionEventHandlerCaptor;
@@ -135,7 +137,8 @@
mFeatureFlags,
mKeyguardBouncerViewModel,
mKeyguardBouncerComponentFactory,
- mAlternateBouncerInteractor
+ mAlternateBouncerInteractor,
+ mKeyguardTransitionInteractor
);
mController.setupExpandedStatusBar();
mController.setDragDownHelper(mDragDownHelper);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
index ca99e24..e41929f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
@@ -29,6 +29,7 @@
import com.android.systemui.statusbar.notification.SourceType;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
+import com.android.systemui.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper;
import org.junit.Assert;
import org.junit.Before;
@@ -216,4 +217,29 @@
Assert.assertEquals(1f, mChildrenContainer.getBottomRoundness(), 0.001f);
Assert.assertEquals(1f, notificationRow.getBottomRoundness(), 0.001f);
}
+
+ @Test
+ public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_header() {
+ mChildrenContainer.useRoundnessSourceTypes(true);
+
+ NotificationHeaderViewWrapper header = mChildrenContainer.getNotificationHeaderWrapper();
+ Assert.assertEquals(0f, header.getTopRoundness(), 0.001f);
+
+ mChildrenContainer.requestTopRoundness(1f, SourceType.from(""), false);
+
+ Assert.assertEquals(1f, header.getTopRoundness(), 0.001f);
+ }
+
+ @Test
+ public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_headerLowPriority() {
+ mChildrenContainer.useRoundnessSourceTypes(true);
+ mChildrenContainer.setIsLowPriority(true);
+
+ NotificationHeaderViewWrapper header = mChildrenContainer.getNotificationHeaderWrapper();
+ Assert.assertEquals(0f, header.getTopRoundness(), 0.001f);
+
+ mChildrenContainer.requestTopRoundness(1f, SourceType.from(""), false);
+
+ Assert.assertEquals(1f, header.getTopRoundness(), 0.001f);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index 4ccbc6d..091bb54 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -24,6 +24,7 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNotNull;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doReturn;
@@ -74,6 +75,7 @@
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import org.mockito.stubbing.Answer;
import java.util.Collections;
import java.util.List;
@@ -115,8 +117,10 @@
@Spy private PackageManager mPackageManager;
private final boolean mIsReduceBrightColorsAvailable = true;
- private AutoTileManager mAutoTileManager;
+ private AutoTileManager mAutoTileManager; // under test
+
private SecureSettings mSecureSettings;
+ private ManagedProfileController.Callback mManagedProfileCallback;
@Before
public void setUp() throws Exception {
@@ -303,7 +307,7 @@
InOrder inOrderManagedProfile = inOrder(mManagedProfileController);
inOrderManagedProfile.verify(mManagedProfileController).removeCallback(any());
- inOrderManagedProfile.verify(mManagedProfileController, never()).addCallback(any());
+ inOrderManagedProfile.verify(mManagedProfileController).addCallback(any());
if (ColorDisplayManager.isNightDisplayAvailable(mContext)) {
InOrder inOrderNightDisplay = inOrder(mNightDisplayListener);
@@ -504,6 +508,40 @@
}
@Test
+ public void managedProfileAdded_tileAdded() {
+ when(mAutoAddTracker.isAdded(eq("work"))).thenReturn(false);
+ mAutoTileManager = createAutoTileManager(mContext);
+ Mockito.doAnswer((Answer<Object>) invocation -> {
+ mManagedProfileCallback = invocation.getArgument(0);
+ return null;
+ }).when(mManagedProfileController).addCallback(any());
+ mAutoTileManager.init();
+ when(mManagedProfileController.hasActiveProfile()).thenReturn(true);
+
+ mManagedProfileCallback.onManagedProfileChanged();
+
+ verify(mQsTileHost, times(1)).addTile(eq("work"));
+ verify(mAutoAddTracker, times(1)).setTileAdded(eq("work"));
+ }
+
+ @Test
+ public void managedProfileRemoved_tileRemoved() {
+ when(mAutoAddTracker.isAdded(eq("work"))).thenReturn(true);
+ mAutoTileManager = createAutoTileManager(mContext);
+ Mockito.doAnswer((Answer<Object>) invocation -> {
+ mManagedProfileCallback = invocation.getArgument(0);
+ return null;
+ }).when(mManagedProfileController).addCallback(any());
+ mAutoTileManager.init();
+ when(mManagedProfileController.hasActiveProfile()).thenReturn(false);
+
+ mManagedProfileCallback.onManagedProfileChanged();
+
+ verify(mQsTileHost, times(1)).removeTile(eq("work"));
+ verify(mAutoAddTracker, times(1)).setTileRemoved(eq("work"));
+ }
+
+ @Test
public void testEmptyArray_doesNotCrash() {
mContext.getOrCreateTestableResources().addOverride(
R.array.config_quickSettingsAutoAdd, new String[0]);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
index 9695000..ec294b1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.phone;
+import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -54,6 +56,7 @@
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
import org.junit.Test;
@@ -115,6 +118,7 @@
private VibratorHelper mVibratorHelper;
@Mock
private BiometricUnlockLogger mLogger;
+ private final FakeSystemClock mSystemClock = new FakeSystemClock();
private BiometricUnlockController mBiometricUnlockController;
@Before
@@ -137,7 +141,9 @@
mMetricsLogger, mDumpManager, mPowerManager, mLogger,
mNotificationMediaManager, mWakefulnessLifecycle, mScreenLifecycle,
mAuthController, mStatusBarStateController,
- mSessionTracker, mLatencyTracker, mScreenOffAnimationController, mVibratorHelper);
+ mSessionTracker, mLatencyTracker, mScreenOffAnimationController, mVibratorHelper,
+ mSystemClock
+ );
mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
mBiometricUnlockController.addBiometricModeListener(mBiometricModeListener);
when(mUpdateMonitor.getStrongAuthTracker()).thenReturn(mStrongAuthTracker);
@@ -200,7 +206,7 @@
verify(mKeyguardViewMediator).onWakeAndUnlocking();
assertThat(mBiometricUnlockController.getMode())
- .isEqualTo(BiometricUnlockController.MODE_WAKE_AND_UNLOCK);
+ .isEqualTo(MODE_WAKE_AND_UNLOCK);
}
@Test
@@ -437,4 +443,83 @@
// THEN wakeup the device
verify(mPowerManager).wakeUp(anyLong(), anyInt(), anyString());
}
+
+ @Test
+ public void onSideFingerprintSuccess_recentPowerButtonPress_noHaptic() {
+ // GIVEN side fingerprint enrolled, last wake reason was power button
+ when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
+ when(mWakefulnessLifecycle.getLastWakeReason())
+ .thenReturn(PowerManager.WAKE_REASON_POWER_BUTTON);
+
+ // GIVEN last wake time just occurred
+ when(mWakefulnessLifecycle.getLastWakeTime()).thenReturn(mSystemClock.uptimeMillis());
+
+ // WHEN biometric fingerprint succeeds
+ givenFingerprintModeUnlockCollapsing();
+ mBiometricUnlockController.startWakeAndUnlock(BiometricSourceType.FINGERPRINT,
+ true);
+
+ // THEN DO NOT vibrate the device
+ verify(mVibratorHelper, never()).vibrateAuthSuccess(anyString());
+ }
+
+ @Test
+ public void onSideFingerprintSuccess_oldPowerButtonPress_playHaptic() {
+ // GIVEN side fingerprint enrolled, last wake reason was power button
+ when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
+ when(mWakefulnessLifecycle.getLastWakeReason())
+ .thenReturn(PowerManager.WAKE_REASON_POWER_BUTTON);
+
+ // GIVEN last wake time was 500ms ago
+ when(mWakefulnessLifecycle.getLastWakeTime()).thenReturn(mSystemClock.uptimeMillis());
+ mSystemClock.advanceTime(500);
+
+ // WHEN biometric fingerprint succeeds
+ givenFingerprintModeUnlockCollapsing();
+ mBiometricUnlockController.startWakeAndUnlock(BiometricSourceType.FINGERPRINT,
+ true);
+
+ // THEN vibrate the device
+ verify(mVibratorHelper).vibrateAuthSuccess(anyString());
+ }
+
+ @Test
+ public void onSideFingerprintSuccess_recentGestureWakeUp_playHaptic() {
+ // GIVEN side fingerprint enrolled, wakeup just happened
+ when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
+ when(mWakefulnessLifecycle.getLastWakeTime()).thenReturn(mSystemClock.uptimeMillis());
+
+ // GIVEN last wake reason was from a gesture
+ when(mWakefulnessLifecycle.getLastWakeReason())
+ .thenReturn(PowerManager.WAKE_REASON_GESTURE);
+
+ // WHEN biometric fingerprint succeeds
+ givenFingerprintModeUnlockCollapsing();
+ mBiometricUnlockController.startWakeAndUnlock(BiometricSourceType.FINGERPRINT,
+ true);
+
+ // THEN vibrate the device
+ verify(mVibratorHelper).vibrateAuthSuccess(anyString());
+ }
+
+ @Test
+ public void onSideFingerprintFail_alwaysPlaysHaptic() {
+ // GIVEN side fingerprint enrolled, last wake reason was recent power button
+ when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
+ when(mWakefulnessLifecycle.getLastWakeReason())
+ .thenReturn(PowerManager.WAKE_REASON_POWER_BUTTON);
+ when(mWakefulnessLifecycle.getLastWakeTime()).thenReturn(mSystemClock.uptimeMillis());
+
+ // WHEN biometric fingerprint fails
+ mBiometricUnlockController.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT);
+
+ // THEN always vibrate the device
+ verify(mVibratorHelper).vibrateAuthError(anyString());
+ }
+
+ private void givenFingerprintModeUnlockCollapsing() {
+ when(mUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
+ when(mUpdateMonitor.isDeviceInteractive()).thenReturn(true);
+ when(mKeyguardStateController.isShowing()).thenReturn(true);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 3a1f9b7..c8157cc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -178,8 +178,6 @@
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.startingsurface.StartingSurface;
-import dagger.Lazy;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -192,6 +190,8 @@
import java.io.PrintWriter;
import java.util.Optional;
+import dagger.Lazy;
+
@SmallTest
@RunWith(AndroidTestingRunner.class)
@RunWithLooper(setAsMainLooper = true)
@@ -380,7 +380,8 @@
}).when(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(any());
mWakefulnessLifecycle =
- new WakefulnessLifecycle(mContext, mIWallpaperManager, mDumpManager);
+ new WakefulnessLifecycle(mContext, mIWallpaperManager, mFakeSystemClock,
+ mDumpManager);
mWakefulnessLifecycle.dispatchStartedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
mWakefulnessLifecycle.dispatchFinishedWakingUp();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
index 077b41a..c843850 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
@@ -23,6 +23,10 @@
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.res.Resources;
@@ -39,10 +43,9 @@
import com.android.systemui.doze.AlwaysOnDisplayPolicy;
import com.android.systemui.doze.DozeScreenState;
import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.unfold.FoldAodAnimationController;
@@ -52,6 +55,8 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -69,7 +74,6 @@
@Mock private PowerManager mPowerManager;
@Mock private TunerService mTunerService;
@Mock private BatteryController mBatteryController;
- @Mock private FeatureFlags mFeatureFlags;
@Mock private DumpManager mDumpManager;
@Mock private ScreenOffAnimationController mScreenOffAnimationController;
@Mock private FoldAodAnimationController mFoldAodAnimationController;
@@ -78,6 +82,7 @@
@Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock private StatusBarStateController mStatusBarStateController;
@Mock private ConfigurationController mConfigurationController;
+ @Captor private ArgumentCaptor<BatteryStateChangeCallback> mBatteryStateChangeCallback;
/**
* The current value of PowerManager's dozeAfterScreenOff property.
@@ -113,7 +118,6 @@
mBatteryController,
mTunerService,
mDumpManager,
- mFeatureFlags,
mScreenOffAnimationController,
Optional.of(mSysUIUnfoldComponent),
mUnlockedScreenOffAnimationController,
@@ -122,7 +126,8 @@
mStatusBarStateController
);
- when(mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS)).thenReturn(true);
+ verify(mBatteryController).addCallback(mBatteryStateChangeCallback.capture());
+
setAodEnabledForTest(true);
setShouldControlUnlockedScreenOffForTest(true);
setDisplayNeedsBlankingForTest(false);
@@ -173,6 +178,29 @@
assertThat(mDozeParameters.getAlwaysOn()).isFalse();
}
+ @Test
+ public void testGetAlwaysOn_whenBatterySaverCallback() {
+ DozeParameters.Callback callback = mock(DozeParameters.Callback.class);
+ mDozeParameters.addCallback(callback);
+
+ when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true);
+ when(mBatteryController.isAodPowerSave()).thenReturn(true);
+
+ // Both lines should trigger an event
+ mDozeParameters.onTuningChanged(Settings.Secure.DOZE_ALWAYS_ON, "1");
+ mBatteryStateChangeCallback.getValue().onPowerSaveChanged(true);
+
+ verify(callback, times(2)).onAlwaysOnChange();
+ assertThat(mDozeParameters.getAlwaysOn()).isFalse();
+
+ reset(callback);
+ when(mBatteryController.isAodPowerSave()).thenReturn(false);
+ mBatteryStateChangeCallback.getValue().onPowerSaveChanged(true);
+
+ verify(callback).onAlwaysOnChange();
+ assertThat(mDozeParameters.getAlwaysOn()).isTrue();
+ }
+
/**
* PowerManager.setDozeAfterScreenOff(true) means we are not controlling screen off, and calling
* it with false means we are. Confusing, but sure - make sure that we call PowerManager with
@@ -196,17 +224,6 @@
}
@Test
- public void testControlUnlockedScreenOffAnimationDisabled_dozeAfterScreenOff() {
- when(mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS)).thenReturn(false);
-
- assertFalse(mDozeParameters.shouldControlUnlockedScreenOff());
-
- // Trigger the setter for the current value.
- mDozeParameters.setControlScreenOffAnimation(mDozeParameters.shouldControlScreenOff());
- assertFalse(mDozeParameters.shouldControlScreenOff());
- }
-
- @Test
public void propagatesAnimateScreenOff_noAlwaysOn() {
setAodEnabledForTest(false);
setDisplayNeedsBlankingForTest(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
index 0da15e2..0958970 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
@@ -37,6 +37,7 @@
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.log.table.TableLogBufferFactory
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
+import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
@@ -46,6 +47,7 @@
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.settings.FakeSettings
+import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -94,7 +96,7 @@
}
}
- whenever(logBufferFactory.create(anyString(), anyInt())).thenAnswer { _ ->
+ whenever(logBufferFactory.getOrCreate(anyString(), anyInt())).thenAnswer { _ ->
mock<TableLogBuffer>()
}
@@ -292,13 +294,13 @@
// Get repos to trigger creation
underTest.getRepoForSubId(SUB_1_ID)
verify(logBufferFactory)
- .create(
+ .getOrCreate(
eq(MobileConnectionRepositoryImpl.tableBufferLogName(SUB_1_ID)),
anyInt(),
)
underTest.getRepoForSubId(SUB_2_ID)
verify(logBufferFactory)
- .create(
+ .getOrCreate(
eq(MobileConnectionRepositoryImpl.tableBufferLogName(SUB_2_ID)),
anyInt(),
)
@@ -307,6 +309,46 @@
}
@Test
+ fun `connection repository factory - reuses log buffers for same connection`() =
+ runBlocking(IMMEDIATE) {
+ val realLoggerFactory = TableLogBufferFactory(mock(), FakeSystemClock())
+
+ connectionFactory =
+ MobileConnectionRepositoryImpl.Factory(
+ fakeBroadcastDispatcher,
+ context = context,
+ telephonyManager = telephonyManager,
+ bgDispatcher = IMMEDIATE,
+ globalSettings = globalSettings,
+ logger = logger,
+ mobileMappingsProxy = mobileMappings,
+ scope = scope,
+ logFactory = realLoggerFactory,
+ )
+
+ // Create two connections for the same subId. Similar to if the connection appeared
+ // and disappeared from the connectionFactory's perspective
+ val connection1 =
+ connectionFactory.build(
+ 1,
+ NetworkNameModel.Default("default_name"),
+ "-",
+ underTest.globalMobileDataSettingChangedEvent,
+ )
+
+ val connection1_repeat =
+ connectionFactory.build(
+ 1,
+ NetworkNameModel.Default("default_name"),
+ "-",
+ underTest.globalMobileDataSettingChangedEvent,
+ )
+
+ assertThat(connection1.tableLogBuffer)
+ .isSameInstanceAs(connection1_repeat.tableLogBuffer)
+ }
+
+ @Test
fun mobileConnectivity_default() {
assertThat(underTest.defaultMobileNetworkConnectivity.value)
.isEqualTo(MobileConnectivityModel(isConnected = false, isValidated = false))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
index 4b32ee2..0cca7b2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
@@ -390,19 +390,27 @@
bindController(view, row.getEntry());
view.setVisibility(View.GONE);
- View crossFadeView = new View(mContext);
+ View fadeOutView = new View(mContext);
+ fadeOutView.setId(com.android.internal.R.id.actions_container_layout);
+
+ FrameLayout parent = new FrameLayout(mContext);
+ parent.addView(view);
+ parent.addView(fadeOutView);
// Start focus animation
- view.focusAnimated(crossFadeView);
-
+ view.focusAnimated();
assertTrue(view.isAnimatingAppearance());
- // fast forward to end of animation
- mAnimatorTestRule.advanceTimeBy(ANIMATION_DURATION_STANDARD);
+ // fast forward to 1 ms before end of animation and verify fadeOutView has alpha set to 0f
+ mAnimatorTestRule.advanceTimeBy(ANIMATION_DURATION_STANDARD - 1);
+ assertEquals(0f, fadeOutView.getAlpha());
- // assert that crossFadeView's alpha is reset to 1f after the animation (hidden behind
+ // fast forward to end of animation
+ mAnimatorTestRule.advanceTimeBy(1);
+
+ // assert that fadeOutView's alpha is reset to 1f after the animation (hidden behind
// RemoteInputView)
- assertEquals(1f, crossFadeView.getAlpha());
+ assertEquals(1f, fadeOutView.getAlpha());
assertFalse(view.isAnimatingAppearance());
assertEquals(View.VISIBLE, view.getVisibility());
assertEquals(1f, view.getAlpha());
@@ -415,20 +423,27 @@
mDependency,
TestableLooper.get(this));
ExpandableNotificationRow row = helper.createRow();
- FrameLayout remoteInputViewParent = new FrameLayout(mContext);
RemoteInputView view = RemoteInputView.inflate(mContext, null, row.getEntry(), mController);
- remoteInputViewParent.addView(view);
bindController(view, row.getEntry());
+ View fadeInView = new View(mContext);
+ fadeInView.setId(com.android.internal.R.id.actions_container_layout);
+
+ FrameLayout parent = new FrameLayout(mContext);
+ parent.addView(view);
+ parent.addView(fadeInView);
+
// Start defocus animation
- view.onDefocus(true, false);
+ view.onDefocus(true /* animate */, false /* logClose */, null /* doAfterDefocus */);
assertEquals(View.VISIBLE, view.getVisibility());
+ assertEquals(0f, fadeInView.getAlpha());
// fast forward to end of animation
mAnimatorTestRule.advanceTimeBy(ANIMATION_DURATION_STANDARD);
// assert that RemoteInputView is no longer visible
assertEquals(View.GONE, view.getVisibility());
+ assertEquals(1f, fadeInView.getAlpha());
}
// NOTE: because we're refactoring the RemoteInputView and moving logic into the
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusFirstUsageListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusFirstUsageListenerTest.kt
deleted file mode 100644
index 8dd088f..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusFirstUsageListenerTest.kt
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Copyright (C) 2022 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.systemui.stylus
-
-import android.content.Context
-import android.hardware.BatteryState
-import android.hardware.input.InputManager
-import android.os.Handler
-import android.testing.AndroidTestingRunner
-import android.view.InputDevice
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
-import com.android.systemui.util.concurrency.FakeExecutor
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.whenever
-import com.android.systemui.util.time.FakeSystemClock
-import org.junit.Before
-import org.junit.Ignore
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito.never
-import org.mockito.Mockito.times
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyNoMoreInteractions
-import org.mockito.Mockito.verifyZeroInteractions
-import org.mockito.MockitoAnnotations
-
-@RunWith(AndroidTestingRunner::class)
-@SmallTest
-@Ignore("TODO(b/20579491): unignore on main")
-class StylusFirstUsageListenerTest : SysuiTestCase() {
- @Mock lateinit var context: Context
- @Mock lateinit var inputManager: InputManager
- @Mock lateinit var stylusManager: StylusManager
- @Mock lateinit var featureFlags: FeatureFlags
- @Mock lateinit var internalStylusDevice: InputDevice
- @Mock lateinit var otherDevice: InputDevice
- @Mock lateinit var externalStylusDevice: InputDevice
- @Mock lateinit var batteryState: BatteryState
- @Mock lateinit var handler: Handler
-
- private lateinit var stylusListener: StylusFirstUsageListener
-
- @Before
- fun setUp() {
- MockitoAnnotations.initMocks(this)
- whenever(featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)).thenReturn(true)
- whenever(inputManager.isStylusEverUsed(context)).thenReturn(false)
-
- stylusListener =
- StylusFirstUsageListener(
- context,
- inputManager,
- stylusManager,
- featureFlags,
- EXECUTOR,
- handler
- )
- stylusListener.hasStarted = false
-
- whenever(handler.post(any())).thenAnswer {
- (it.arguments[0] as Runnable).run()
- true
- }
-
- whenever(otherDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(false)
- whenever(internalStylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
- whenever(internalStylusDevice.isExternal).thenReturn(false)
- whenever(externalStylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
- whenever(externalStylusDevice.isExternal).thenReturn(true)
-
- whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf())
- whenever(inputManager.getInputDevice(OTHER_DEVICE_ID)).thenReturn(otherDevice)
- whenever(inputManager.getInputDevice(INTERNAL_STYLUS_DEVICE_ID))
- .thenReturn(internalStylusDevice)
- whenever(inputManager.getInputDevice(EXTERNAL_STYLUS_DEVICE_ID))
- .thenReturn(externalStylusDevice)
- }
-
- @Test
- fun start_flagDisabled_doesNotRegister() {
- whenever(featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)).thenReturn(false)
-
- stylusListener.start()
-
- verify(stylusManager, never()).registerCallback(any())
- verify(inputManager, never()).setStylusEverUsed(context, true)
- }
-
- @Test
- fun start_toggleHasStarted() {
- stylusListener.start()
-
- assert(stylusListener.hasStarted)
- }
-
- @Test
- fun start_hasStarted_doesNotRegister() {
- stylusListener.hasStarted = true
-
- stylusListener.start()
-
- verify(stylusManager, never()).registerCallback(any())
- }
-
- @Test
- fun start_hostDeviceDoesNotSupportStylus_doesNotRegister() {
- whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(OTHER_DEVICE_ID))
-
- stylusListener.start()
-
- verify(stylusManager, never()).registerCallback(any())
- verify(inputManager, never()).setStylusEverUsed(context, true)
- }
-
- @Test
- fun start_stylusEverUsed_doesNotRegister() {
- whenever(inputManager.inputDeviceIds)
- .thenReturn(intArrayOf(OTHER_DEVICE_ID, INTERNAL_STYLUS_DEVICE_ID))
- whenever(inputManager.isStylusEverUsed(context)).thenReturn(true)
-
- stylusListener.start()
-
- verify(stylusManager, never()).registerCallback(any())
- verify(inputManager, never()).setStylusEverUsed(context, true)
- }
-
- @Test
- fun start_hostDeviceSupportsStylus_registersListener() {
- whenever(inputManager.inputDeviceIds)
- .thenReturn(intArrayOf(OTHER_DEVICE_ID, INTERNAL_STYLUS_DEVICE_ID))
-
- stylusListener.start()
-
- verify(stylusManager).registerCallback(any())
- verify(inputManager, never()).setStylusEverUsed(context, true)
- }
-
- @Test
- fun onStylusAdded_hasNotStarted_doesNotRegisterListener() {
- stylusListener.hasStarted = false
-
- stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-
- verifyZeroInteractions(inputManager)
- }
-
- @Test
- fun onStylusAdded_internalStylus_registersListener() {
- stylusListener.hasStarted = true
-
- stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-
- verify(inputManager, times(1))
- .addInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, EXECUTOR, stylusListener)
- }
-
- @Test
- fun onStylusAdded_externalStylus_doesNotRegisterListener() {
- stylusListener.hasStarted = true
-
- stylusListener.onStylusAdded(EXTERNAL_STYLUS_DEVICE_ID)
-
- verify(inputManager, never()).addInputDeviceBatteryListener(any(), any(), any())
- }
-
- @Test
- fun onStylusAdded_otherDevice_doesNotRegisterListener() {
- stylusListener.onStylusAdded(OTHER_DEVICE_ID)
-
- verify(inputManager, never()).addInputDeviceBatteryListener(any(), any(), any())
- }
-
- @Test
- fun onStylusRemoved_registeredDevice_unregistersListener() {
- stylusListener.hasStarted = true
- stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-
- stylusListener.onStylusRemoved(INTERNAL_STYLUS_DEVICE_ID)
-
- verify(inputManager, times(1))
- .removeInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, stylusListener)
- }
-
- @Test
- fun onStylusRemoved_hasNotStarted_doesNotUnregisterListener() {
- stylusListener.hasStarted = false
- stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-
- stylusListener.onStylusRemoved(INTERNAL_STYLUS_DEVICE_ID)
-
- verifyZeroInteractions(inputManager)
- }
-
- @Test
- fun onStylusRemoved_unregisteredDevice_doesNotUnregisterListener() {
- stylusListener.hasStarted = true
-
- stylusListener.onStylusRemoved(INTERNAL_STYLUS_DEVICE_ID)
-
- verifyNoMoreInteractions(inputManager)
- }
-
- @Test
- fun onStylusBluetoothConnected_updateStylusFlagAndUnregisters() {
- stylusListener.hasStarted = true
- stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-
- stylusListener.onStylusBluetoothConnected(EXTERNAL_STYLUS_DEVICE_ID, "ANY")
-
- verify(inputManager).setStylusEverUsed(context, true)
- verify(inputManager, times(1))
- .removeInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, stylusListener)
- verify(stylusManager).unregisterCallback(stylusListener)
- }
-
- @Test
- fun onStylusBluetoothConnected_hasNotStarted_doesNoting() {
- stylusListener.hasStarted = false
- stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
-
- stylusListener.onStylusBluetoothConnected(EXTERNAL_STYLUS_DEVICE_ID, "ANY")
-
- verifyZeroInteractions(inputManager)
- verifyZeroInteractions(stylusManager)
- }
-
- @Test
- fun onBatteryStateChanged_batteryPresent_updateStylusFlagAndUnregisters() {
- stylusListener.hasStarted = true
- stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
- whenever(batteryState.isPresent).thenReturn(true)
-
- stylusListener.onBatteryStateChanged(0, 1, batteryState)
-
- verify(inputManager).setStylusEverUsed(context, true)
- verify(inputManager, times(1))
- .removeInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, stylusListener)
- verify(stylusManager).unregisterCallback(stylusListener)
- }
-
- @Test
- fun onBatteryStateChanged_batteryNotPresent_doesNotUpdateFlagOrUnregister() {
- stylusListener.hasStarted = true
- stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
- whenever(batteryState.isPresent).thenReturn(false)
-
- stylusListener.onBatteryStateChanged(0, 1, batteryState)
-
- verifyZeroInteractions(stylusManager)
- verify(inputManager, never())
- .removeInputDeviceBatteryListener(INTERNAL_STYLUS_DEVICE_ID, stylusListener)
- }
-
- @Test
- fun onBatteryStateChanged_hasNotStarted_doesNothing() {
- stylusListener.hasStarted = false
- stylusListener.onStylusAdded(INTERNAL_STYLUS_DEVICE_ID)
- whenever(batteryState.isPresent).thenReturn(false)
-
- stylusListener.onBatteryStateChanged(0, 1, batteryState)
-
- verifyZeroInteractions(inputManager)
- verifyZeroInteractions(stylusManager)
- }
-
- companion object {
- private const val OTHER_DEVICE_ID = 0
- private const val INTERNAL_STYLUS_DEVICE_ID = 1
- private const val EXTERNAL_STYLUS_DEVICE_ID = 2
- private val EXECUTOR = FakeExecutor(FakeSystemClock())
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt
index 984de5b..6d6e40a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt
@@ -17,12 +17,15 @@
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
+import android.hardware.BatteryState
import android.hardware.input.InputManager
import android.os.Handler
import android.testing.AndroidTestingRunner
import android.view.InputDevice
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.whenever
import java.util.concurrent.Executor
@@ -31,30 +34,27 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
+import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.inOrder
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
@SmallTest
-@Ignore("b/257936830 until bt APIs")
class StylusManagerTest : SysuiTestCase() {
@Mock lateinit var inputManager: InputManager
-
@Mock lateinit var stylusDevice: InputDevice
-
@Mock lateinit var btStylusDevice: InputDevice
-
@Mock lateinit var otherDevice: InputDevice
-
+ @Mock lateinit var batteryState: BatteryState
@Mock lateinit var bluetoothAdapter: BluetoothAdapter
-
@Mock lateinit var bluetoothDevice: BluetoothDevice
-
@Mock lateinit var handler: Handler
+ @Mock lateinit var featureFlags: FeatureFlags
@Mock lateinit var stylusCallback: StylusManager.StylusCallback
@@ -75,11 +75,8 @@
true
}
- stylusManager = StylusManager(inputManager, bluetoothAdapter, handler, EXECUTOR)
-
- stylusManager.registerCallback(stylusCallback)
-
- stylusManager.registerBatteryCallback(stylusBatteryCallback)
+ stylusManager =
+ StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
whenever(otherDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(false)
whenever(stylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
@@ -92,19 +89,47 @@
whenever(inputManager.getInputDevice(STYLUS_DEVICE_ID)).thenReturn(stylusDevice)
whenever(inputManager.getInputDevice(BT_STYLUS_DEVICE_ID)).thenReturn(btStylusDevice)
whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(STYLUS_DEVICE_ID))
+ whenever(inputManager.isStylusEverUsed(mContext)).thenReturn(false)
whenever(bluetoothAdapter.getRemoteDevice(STYLUS_BT_ADDRESS)).thenReturn(bluetoothDevice)
whenever(bluetoothDevice.address).thenReturn(STYLUS_BT_ADDRESS)
+
+ whenever(featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)).thenReturn(true)
+
+ stylusManager.startListener()
+ stylusManager.registerCallback(stylusCallback)
+ stylusManager.registerBatteryCallback(stylusBatteryCallback)
+ clearInvocations(inputManager)
}
@Test
- fun startListener_registersInputDeviceListener() {
+ fun startListener_hasNotStarted_registersInputDeviceListener() {
+ stylusManager =
+ StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
+
stylusManager.startListener()
verify(inputManager, times(1)).registerInputDeviceListener(any(), any())
}
@Test
+ fun startListener_hasStarted_doesNothing() {
+ stylusManager.startListener()
+
+ verifyZeroInteractions(inputManager)
+ }
+
+ @Test
+ fun onInputDeviceAdded_hasNotStarted_doesNothing() {
+ stylusManager =
+ StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
+
+ stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
+
+ verifyZeroInteractions(stylusCallback)
+ }
+
+ @Test
fun onInputDeviceAdded_multipleRegisteredCallbacks_callsAll() {
stylusManager.registerCallback(otherStylusCallback)
@@ -117,6 +142,26 @@
}
@Test
+ fun onInputDeviceAdded_internalStylus_registersBatteryListener() {
+ whenever(stylusDevice.isExternal).thenReturn(false)
+
+ stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
+
+ verify(inputManager, times(1))
+ .addInputDeviceBatteryListener(STYLUS_DEVICE_ID, EXECUTOR, stylusManager)
+ }
+
+ @Test
+ fun onInputDeviceAdded_externalStylus_doesNotRegisterbatteryListener() {
+ whenever(stylusDevice.isExternal).thenReturn(true)
+
+ stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
+
+ verify(inputManager, never())
+ .addInputDeviceBatteryListener(STYLUS_DEVICE_ID, EXECUTOR, stylusManager)
+ }
+
+ @Test
fun onInputDeviceAdded_stylus_callsCallbacksOnStylusAdded() {
stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
@@ -125,6 +170,23 @@
}
@Test
+ @Ignore("b/257936830 until bt APIs")
+ fun onInputDeviceAdded_btStylus_firstUsed_callsCallbacksOnStylusFirstUsed() {
+ stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
+
+ verify(stylusCallback, times(1)).onStylusFirstUsed()
+ }
+
+ @Test
+ @Ignore("b/257936830 until bt APIs")
+ fun onInputDeviceAdded_btStylus_firstUsed_setsFlag() {
+ stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
+
+ verify(inputManager, times(1)).setStylusEverUsed(mContext, true)
+ }
+
+ @Test
+ @Ignore("b/257936830 until bt APIs")
fun onInputDeviceAdded_btStylus_callsCallbacksWithAddress() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
@@ -143,6 +205,17 @@
}
@Test
+ fun onInputDeviceChanged_hasNotStarted_doesNothing() {
+ stylusManager =
+ StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
+
+ stylusManager.onInputDeviceChanged(STYLUS_DEVICE_ID)
+
+ verifyZeroInteractions(stylusCallback)
+ }
+
+ @Test
+ @Ignore("b/257936830 until bt APIs")
fun onInputDeviceChanged_multipleRegisteredCallbacks_callsAll() {
stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
// whenever(stylusDevice.bluetoothAddress).thenReturn(STYLUS_BT_ADDRESS)
@@ -157,6 +230,7 @@
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onInputDeviceChanged_stylusNewBtConnection_callsCallbacks() {
stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
// whenever(stylusDevice.bluetoothAddress).thenReturn(STYLUS_BT_ADDRESS)
@@ -168,6 +242,7 @@
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onInputDeviceChanged_stylusLostBtConnection_callsCallbacks() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
// whenever(btStylusDevice.bluetoothAddress).thenReturn(null)
@@ -179,6 +254,7 @@
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onInputDeviceChanged_btConnection_stylusAlreadyBtConnected_onlyCallsListenersOnce() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
@@ -189,6 +265,7 @@
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onInputDeviceChanged_noBtConnection_stylusNeverBtConnected_doesNotCallCallbacks() {
stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
@@ -198,6 +275,17 @@
}
@Test
+ fun onInputDeviceRemoved_hasNotStarted_doesNothing() {
+ stylusManager =
+ StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
+ stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
+
+ stylusManager.onInputDeviceRemoved(STYLUS_DEVICE_ID)
+
+ verifyZeroInteractions(stylusCallback)
+ }
+
+ @Test
fun onInputDeviceRemoved_multipleRegisteredCallbacks_callsAll() {
stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
stylusManager.registerCallback(otherStylusCallback)
@@ -219,6 +307,17 @@
}
@Test
+ fun onInputDeviceRemoved_unregistersBatteryListener() {
+ stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
+
+ stylusManager.onInputDeviceRemoved(STYLUS_DEVICE_ID)
+
+ verify(inputManager, times(1))
+ .removeInputDeviceBatteryListener(STYLUS_DEVICE_ID, stylusManager)
+ }
+
+ @Test
+ @Ignore("b/257936830 until bt APIs")
fun onInputDeviceRemoved_btStylus_callsCallbacks() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
@@ -232,6 +331,7 @@
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onStylusBluetoothConnected_registersMetadataListener() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
@@ -239,6 +339,7 @@
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onStylusBluetoothConnected_noBluetoothDevice_doesNotRegisterMetadataListener() {
whenever(bluetoothAdapter.getRemoteDevice(STYLUS_BT_ADDRESS)).thenReturn(null)
@@ -248,6 +349,7 @@
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onStylusBluetoothDisconnected_unregistersMetadataListener() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
@@ -257,6 +359,7 @@
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onMetadataChanged_multipleRegisteredBatteryCallbacks_executesAll() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
stylusManager.registerBatteryCallback(otherStylusBatteryCallback)
@@ -274,6 +377,7 @@
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onMetadataChanged_chargingStateTrue_executesBatteryCallbacks() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
@@ -288,6 +392,7 @@
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onMetadataChanged_chargingStateFalse_executesBatteryCallbacks() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
@@ -302,6 +407,7 @@
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onMetadataChanged_chargingStateNoDevice_doesNotExecuteBatteryCallbacks() {
stylusManager.onMetadataChanged(
bluetoothDevice,
@@ -313,6 +419,7 @@
}
@Test
+ @Ignore("b/257936830 until bt APIs")
fun onMetadataChanged_notChargingState_doesNotExecuteBatteryCallbacks() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
@@ -326,6 +433,63 @@
.onStylusBluetoothChargingStateChanged(any(), any(), any())
}
+ @Test
+ @Ignore("TODO(b/261826950): remove on main")
+ fun onBatteryStateChanged_batteryPresent_stylusNeverUsed_updateEverUsedFlag() {
+ whenever(batteryState.isPresent).thenReturn(true)
+
+ stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+ verify(inputManager).setStylusEverUsed(mContext, true)
+ }
+
+ @Test
+ @Ignore("TODO(b/261826950): remove on main")
+ fun onBatteryStateChanged_batteryPresent_stylusNeverUsed_executesStylusFirstUsed() {
+ whenever(batteryState.isPresent).thenReturn(true)
+
+ stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+ verify(stylusCallback, times(1)).onStylusFirstUsed()
+ }
+
+ @Test
+ @Ignore("TODO(b/261826950): remove on main")
+ fun onBatteryStateChanged_batteryPresent_stylusUsed_doesNotUpdateEverUsedFlag() {
+ whenever(inputManager.isStylusEverUsed(mContext)).thenReturn(true)
+ whenever(batteryState.isPresent).thenReturn(true)
+
+ stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+ verify(inputManager, never()).setStylusEverUsed(mContext, true)
+ }
+
+ @Test
+ @Ignore("TODO(b/261826950): remove on main")
+ fun onBatteryStateChanged_batteryNotPresent_doesNotUpdateEverUsedFlag() {
+ whenever(batteryState.isPresent).thenReturn(false)
+
+ stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+ verify(inputManager, never())
+ .removeInputDeviceBatteryListener(STYLUS_DEVICE_ID, stylusManager)
+ }
+
+ @Test
+ fun onBatteryStateChanged_hasNotStarted_doesNothing() {
+ stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+ verifyZeroInteractions(inputManager)
+ }
+
+ @Test
+ fun onBatteryStateChanged_executesBatteryCallbacks() {
+ stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+ verify(stylusBatteryCallback, times(1))
+ .onStylusUsiBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+ }
+
companion object {
private val EXECUTOR = Executor { r -> r.run() }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt
index ff382a3..117e00d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt
@@ -25,17 +25,15 @@
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.util.mockito.whenever
-import java.util.concurrent.Executor
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
-import org.mockito.Mockito.inOrder
import org.mockito.Mockito.mock
-import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
@@ -60,7 +58,6 @@
inputManager,
stylusUsiPowerUi,
featureFlags,
- DIRECT_EXECUTOR,
)
whenever(featureFlags.isEnabled(Flags.ENABLE_USI_BATTERY_NOTIFICATIONS)).thenReturn(true)
@@ -79,40 +76,12 @@
}
@Test
- fun start_addsBatteryListenerForInternalStylus() {
+ fun start_hostDeviceDoesNotSupportStylus_doesNotRegister() {
+ whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(EXTERNAL_DEVICE_ID))
+
startable.start()
- verify(inputManager, times(1))
- .addInputDeviceBatteryListener(STYLUS_DEVICE_ID, DIRECT_EXECUTOR, startable)
- }
-
- @Test
- fun onStylusAdded_internalStylus_addsBatteryListener() {
- startable.onStylusAdded(STYLUS_DEVICE_ID)
-
- verify(inputManager, times(1))
- .addInputDeviceBatteryListener(STYLUS_DEVICE_ID, DIRECT_EXECUTOR, startable)
- }
-
- @Test
- fun onStylusAdded_externalStylus_doesNotAddBatteryListener() {
- startable.onStylusAdded(EXTERNAL_DEVICE_ID)
-
- verify(inputManager, never())
- .addInputDeviceBatteryListener(EXTERNAL_DEVICE_ID, DIRECT_EXECUTOR, startable)
- }
-
- @Test
- fun onStylusRemoved_registeredStylus_removesBatteryListener() {
- startable.onStylusAdded(STYLUS_DEVICE_ID)
- startable.onStylusRemoved(STYLUS_DEVICE_ID)
-
- inOrder(inputManager).let {
- it.verify(inputManager, times(1))
- .addInputDeviceBatteryListener(STYLUS_DEVICE_ID, DIRECT_EXECUTOR, startable)
- it.verify(inputManager, times(1))
- .removeInputDeviceBatteryListener(STYLUS_DEVICE_ID, startable)
- }
+ verifyZeroInteractions(stylusManager)
}
@Test
@@ -130,28 +99,26 @@
}
@Test
- fun onBatteryStateChanged_batteryPresent_refreshesNotification() {
+ fun onStylusUsiBatteryStateChanged_batteryPresent_refreshesNotification() {
val batteryState = mock(BatteryState::class.java)
whenever(batteryState.isPresent).thenReturn(true)
- startable.onBatteryStateChanged(STYLUS_DEVICE_ID, 123, batteryState)
+ startable.onStylusUsiBatteryStateChanged(STYLUS_DEVICE_ID, 123, batteryState)
verify(stylusUsiPowerUi, times(1)).updateBatteryState(batteryState)
}
@Test
- fun onBatteryStateChanged_batteryNotPresent_noop() {
+ fun onStylusUsiBatteryStateChanged_batteryNotPresent_noop() {
val batteryState = mock(BatteryState::class.java)
whenever(batteryState.isPresent).thenReturn(false)
- startable.onBatteryStateChanged(STYLUS_DEVICE_ID, 123, batteryState)
+ startable.onStylusUsiBatteryStateChanged(STYLUS_DEVICE_ID, 123, batteryState)
verifyNoMoreInteractions(stylusUsiPowerUi)
}
companion object {
- private val DIRECT_EXECUTOR = Executor { r -> r.run() }
-
private const val EXTERNAL_DEVICE_ID = 0
private const val STYLUS_DEVICE_ID = 1
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
index 5987550..a7951f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.stylus
+import android.app.Notification
import android.hardware.BatteryState
import android.hardware.input.InputManager
import android.os.Handler
@@ -28,10 +29,13 @@
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.whenever
+import junit.framework.Assert.assertEquals
import org.junit.Before
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.inOrder
import org.mockito.Mockito.times
@@ -46,6 +50,7 @@
@Mock lateinit var inputManager: InputManager
@Mock lateinit var handler: Handler
@Mock lateinit var btStylusDevice: InputDevice
+ @Captor lateinit var notificationCaptor: ArgumentCaptor<Notification>
private lateinit var stylusUsiPowerUi: StylusUsiPowerUI
@@ -70,7 +75,8 @@
fun updateBatteryState_capacityBelowThreshold_notifies() {
stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.1f))
- verify(notificationManager, times(1)).notify(eq(R.string.stylus_battery_low), any())
+ verify(notificationManager, times(1))
+ .notify(eq(R.string.stylus_battery_low_percentage), any())
verifyNoMoreInteractions(notificationManager)
}
@@ -78,7 +84,7 @@
fun updateBatteryState_capacityAboveThreshold_cancelsNotificattion() {
stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.8f))
- verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low)
+ verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low_percentage)
verifyNoMoreInteractions(notificationManager)
}
@@ -88,8 +94,9 @@
stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.8f))
inOrder(notificationManager).let {
- it.verify(notificationManager, times(1)).notify(eq(R.string.stylus_battery_low), any())
- it.verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low)
+ it.verify(notificationManager, times(1))
+ .notify(eq(R.string.stylus_battery_low_percentage), any())
+ it.verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low_percentage)
it.verifyNoMoreInteractions()
}
}
@@ -99,7 +106,16 @@
stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.1f))
stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.15f))
- verify(notificationManager, times(2)).notify(eq(R.string.stylus_battery_low), any())
+ verify(notificationManager, times(2))
+ .notify(eq(R.string.stylus_battery_low_percentage), notificationCaptor.capture())
+ assertEquals(
+ notificationCaptor.value.extras.getString(Notification.EXTRA_TITLE),
+ context.getString(R.string.stylus_battery_low_percentage, "15%")
+ )
+ assertEquals(
+ notificationCaptor.value.extras.getString(Notification.EXTRA_TEXT),
+ context.getString(R.string.stylus_battery_low_subtitle)
+ )
verifyNoMoreInteractions(notificationManager)
}
@@ -110,9 +126,11 @@
stylusUsiPowerUi.updateBatteryState(FixedCapacityBatteryState(0.1f))
inOrder(notificationManager).let {
- it.verify(notificationManager, times(1)).notify(eq(R.string.stylus_battery_low), any())
- it.verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low)
- it.verify(notificationManager, times(1)).notify(eq(R.string.stylus_battery_low), any())
+ it.verify(notificationManager, times(1))
+ .notify(eq(R.string.stylus_battery_low_percentage), any())
+ it.verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low_percentage)
+ it.verify(notificationManager, times(1))
+ .notify(eq(R.string.stylus_battery_low_percentage), any())
it.verifyNoMoreInteractions()
}
}
@@ -121,7 +139,7 @@
fun updateSuppression_noExistingNotification_cancelsNotification() {
stylusUsiPowerUi.updateSuppression(true)
- verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low)
+ verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low_percentage)
verifyNoMoreInteractions(notificationManager)
}
@@ -132,8 +150,9 @@
stylusUsiPowerUi.updateSuppression(true)
inOrder(notificationManager).let {
- it.verify(notificationManager, times(1)).notify(eq(R.string.stylus_battery_low), any())
- it.verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low)
+ it.verify(notificationManager, times(1))
+ .notify(eq(R.string.stylus_battery_low_percentage), any())
+ it.verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low_percentage)
it.verifyNoMoreInteractions()
}
}
@@ -156,7 +175,7 @@
stylusUsiPowerUi.refresh()
- verify(notificationManager).cancel(R.string.stylus_battery_low)
+ verify(notificationManager).cancel(R.string.stylus_battery_low_percentage)
}
class FixedCapacityBatteryState(private val capacity: Float) : BatteryState() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
index 89402de..30c4f97 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
@@ -29,6 +29,7 @@
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.shade.NotificationPanelViewController
+import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.LightRevealScrim
import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.unfold.util.FoldableDeviceStates
@@ -73,6 +74,8 @@
@Mock lateinit var viewTreeObserver: ViewTreeObserver
+ @Mock private lateinit var commandQueue: CommandQueue
+
@Captor private lateinit var foldStateListenerCaptor: ArgumentCaptor<FoldStateListener>
private lateinit var deviceStates: FoldableDeviceStates
@@ -102,7 +105,8 @@
}
keyguardRepository = FakeKeyguardRepository()
- val keyguardInteractor = KeyguardInteractor(repository = keyguardRepository)
+ val keyguardInteractor =
+ KeyguardInteractor(repository = keyguardRepository, commandQueue = commandQueue)
// Needs to be run on the main thread
runBlocking(IMMEDIATE) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
index 1a2ee18..7380ca4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
@@ -43,6 +43,7 @@
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.qs.user.UserSwitchDialogController
+import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
@@ -95,6 +96,7 @@
@Mock private lateinit var dialogShower: UserSwitchDialogController.DialogShower
@Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver
@Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
+ @Mock private lateinit var commandQueue: CommandQueue
private lateinit var underTest: UserInteractor
@@ -138,6 +140,7 @@
keyguardInteractor =
KeyguardInteractor(
repository = keyguardRepository,
+ commandQueue = commandQueue,
),
manager = manager,
applicationScope = testScope.backgroundScope,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
index 5d4c1cc..46f38ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
@@ -34,6 +34,7 @@
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
@@ -75,6 +76,7 @@
@Mock private lateinit var uiEventLogger: UiEventLogger
@Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver
@Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
+ @Mock private lateinit var commandQueue: CommandQueue
private lateinit var underTest: StatusBarUserChipViewModel
@@ -241,6 +243,7 @@
keyguardInteractor =
KeyguardInteractor(
repository = keyguardRepository,
+ commandQueue = commandQueue,
),
featureFlags =
FakeFeatureFlags().apply { set(Flags.FULL_SCREEN_USER_SWITCHER, false) },
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
index 0efede1..1d57d0b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
@@ -34,6 +34,7 @@
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.power.data.repository.FakePowerRepository
import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
@@ -76,6 +77,7 @@
@Mock private lateinit var uiEventLogger: UiEventLogger
@Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver
@Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
+ @Mock private lateinit var commandQueue: CommandQueue
private lateinit var underTest: UserSwitcherViewModel
@@ -142,6 +144,7 @@
keyguardInteractor =
KeyguardInteractor(
repository = keyguardRepository,
+ commandQueue = commandQueue,
),
featureFlags =
FakeFeatureFlags().apply {
@@ -170,273 +173,295 @@
}
@Test
- fun users() = testScope.runTest {
- val userInfos =
- listOf(
- UserInfo(
- /* id= */ 0,
- /* name= */ "zero",
- /* iconPath= */ "",
- /* flags= */ UserInfo.FLAG_PRIMARY or UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL,
- UserManager.USER_TYPE_FULL_SYSTEM,
- ),
- UserInfo(
- /* id= */ 1,
- /* name= */ "one",
- /* iconPath= */ "",
- /* flags= */ UserInfo.FLAG_FULL,
- UserManager.USER_TYPE_FULL_SYSTEM,
- ),
- UserInfo(
- /* id= */ 2,
- /* name= */ "two",
- /* iconPath= */ "",
- /* flags= */ UserInfo.FLAG_FULL,
- UserManager.USER_TYPE_FULL_SYSTEM,
- ),
- )
- userRepository.setUserInfos(userInfos)
- userRepository.setSelectedUserInfo(userInfos[0])
-
- val userViewModels = mutableListOf<List<UserViewModel>>()
- val job = launch(testDispatcher) { underTest.users.toList(userViewModels) }
-
- assertThat(userViewModels.last()).hasSize(3)
- assertUserViewModel(
- viewModel = userViewModels.last()[0],
- viewKey = 0,
- name = Text.Loaded("zero"),
- isSelectionMarkerVisible = true,
- )
- assertUserViewModel(
- viewModel = userViewModels.last()[1],
- viewKey = 1,
- name = Text.Loaded("one"),
- isSelectionMarkerVisible = false,
- )
- assertUserViewModel(
- viewModel = userViewModels.last()[2],
- viewKey = 2,
- name = Text.Loaded("two"),
- isSelectionMarkerVisible = false,
- )
- job.cancel()
- }
-
- @Test
- fun `maximumUserColumns - few users`() = testScope.runTest {
- setUsers(count = 2)
- val values = mutableListOf<Int>()
- val job = launch(testDispatcher) { underTest.maximumUserColumns.toList(values) }
-
- assertThat(values.last()).isEqualTo(4)
-
- job.cancel()
- }
-
- @Test
- fun `maximumUserColumns - many users`() = testScope.runTest {
- setUsers(count = 5)
- val values = mutableListOf<Int>()
- val job = launch(testDispatcher) { underTest.maximumUserColumns.toList(values) }
-
- assertThat(values.last()).isEqualTo(3)
- job.cancel()
- }
-
- @Test
- fun `isOpenMenuButtonVisible - has actions - true`() = testScope.runTest {
- setUsers(2)
-
- val isVisible = mutableListOf<Boolean>()
- val job = launch(testDispatcher) { underTest.isOpenMenuButtonVisible.toList(isVisible) }
-
- assertThat(isVisible.last()).isTrue()
- job.cancel()
- }
-
- @Test
- fun `isOpenMenuButtonVisible - no actions - false`() = testScope.runTest {
- val userInfos = setUsers(2)
- userRepository.setSelectedUserInfo(userInfos[1])
- keyguardRepository.setKeyguardShowing(true)
- whenever(manager.canAddMoreUsers(any())).thenReturn(false)
-
- val isVisible = mutableListOf<Boolean>()
- val job = launch(testDispatcher) { underTest.isOpenMenuButtonVisible.toList(isVisible) }
-
- assertThat(isVisible.last()).isFalse()
- job.cancel()
- }
-
- @Test
- fun menu() = testScope.runTest {
- val isMenuVisible = mutableListOf<Boolean>()
- val job = launch(testDispatcher) { underTest.isMenuVisible.toList(isMenuVisible) }
- assertThat(isMenuVisible.last()).isFalse()
-
- underTest.onOpenMenuButtonClicked()
- assertThat(isMenuVisible.last()).isTrue()
-
- underTest.onMenuClosed()
- assertThat(isMenuVisible.last()).isFalse()
-
- job.cancel()
- }
-
- @Test
- fun `menu actions`() = testScope.runTest {
- setUsers(2)
- val actions = mutableListOf<List<UserActionViewModel>>()
- val job = launch(testDispatcher) { underTest.menu.toList(actions) }
-
- assertThat(actions.last().map { it.viewKey })
- .isEqualTo(
+ fun users() =
+ testScope.runTest {
+ val userInfos =
listOf(
- UserActionModel.ENTER_GUEST_MODE.ordinal.toLong(),
- UserActionModel.ADD_USER.ordinal.toLong(),
- UserActionModel.ADD_SUPERVISED_USER.ordinal.toLong(),
- UserActionModel.NAVIGATE_TO_USER_MANAGEMENT.ordinal.toLong(),
+ UserInfo(
+ /* id= */ 0,
+ /* name= */ "zero",
+ /* iconPath= */ "",
+ /* flags= */ UserInfo.FLAG_PRIMARY or
+ UserInfo.FLAG_ADMIN or
+ UserInfo.FLAG_FULL,
+ UserManager.USER_TYPE_FULL_SYSTEM,
+ ),
+ UserInfo(
+ /* id= */ 1,
+ /* name= */ "one",
+ /* iconPath= */ "",
+ /* flags= */ UserInfo.FLAG_FULL,
+ UserManager.USER_TYPE_FULL_SYSTEM,
+ ),
+ UserInfo(
+ /* id= */ 2,
+ /* name= */ "two",
+ /* iconPath= */ "",
+ /* flags= */ UserInfo.FLAG_FULL,
+ UserManager.USER_TYPE_FULL_SYSTEM,
+ ),
)
- )
+ userRepository.setUserInfos(userInfos)
+ userRepository.setSelectedUserInfo(userInfos[0])
- job.cancel()
- }
+ val userViewModels = mutableListOf<List<UserViewModel>>()
+ val job = launch(testDispatcher) { underTest.users.toList(userViewModels) }
- @Test
- fun `isFinishRequested - finishes when user is switched`() = testScope.runTest {
- val userInfos = setUsers(count = 2)
- val isFinishRequested = mutableListOf<Boolean>()
- val job = launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
- assertThat(isFinishRequested.last()).isFalse()
-
- userRepository.setSelectedUserInfo(userInfos[1])
-
- assertThat(isFinishRequested.last()).isTrue()
-
- job.cancel()
- }
-
- @Test
- fun `isFinishRequested - finishes when the screen turns off`() = testScope.runTest {
- setUsers(count = 2)
- powerRepository.setInteractive(true)
- val isFinishRequested = mutableListOf<Boolean>()
- val job = launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
- assertThat(isFinishRequested.last()).isFalse()
-
- powerRepository.setInteractive(false)
-
- assertThat(isFinishRequested.last()).isTrue()
-
- job.cancel()
- }
-
- @Test
- fun `isFinishRequested - finishes when cancel button is clicked`() = testScope.runTest {
- setUsers(count = 2)
- powerRepository.setInteractive(true)
- val isFinishRequested = mutableListOf<Boolean>()
- val job = launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
- assertThat(isFinishRequested.last()).isFalse()
-
- underTest.onCancelButtonClicked()
-
- assertThat(isFinishRequested.last()).isTrue()
-
- underTest.onFinished()
-
- assertThat(isFinishRequested.last()).isFalse()
-
- job.cancel()
- }
-
- @Test
- fun `guest selected -- name is exit guest`() = testScope.runTest {
- val userInfos =
- listOf(
- UserInfo(
- /* id= */ 0,
- /* name= */ "zero",
- /* iconPath= */ "",
- /* flags= */ UserInfo.FLAG_PRIMARY or UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL,
- UserManager.USER_TYPE_FULL_SYSTEM,
- ),
- UserInfo(
- /* id= */ 1,
- /* name= */ "one",
- /* iconPath= */ "",
- /* flags= */ UserInfo.FLAG_FULL,
- UserManager.USER_TYPE_FULL_GUEST,
- ),
- )
-
- userRepository.setUserInfos(userInfos)
- userRepository.setSelectedUserInfo(userInfos[1])
-
- val userViewModels = mutableListOf<List<UserViewModel>>()
- val job = launch(testDispatcher) { underTest.users.toList(userViewModels) }
-
- assertThat(userViewModels.last()).hasSize(2)
- assertUserViewModel(
- viewModel = userViewModels.last()[0],
- viewKey = 0,
- name = Text.Loaded("zero"),
- isSelectionMarkerVisible = false,
- )
- assertUserViewModel(
- viewModel = userViewModels.last()[1],
- viewKey = 1,
- name = Text.Resource(
- com.android.settingslib.R.string.guest_exit_quick_settings_button
- ),
- isSelectionMarkerVisible = true,
- )
- job.cancel()
- }
-
- @Test
- fun `guest not selected -- name is guest`() = testScope.runTest {
- val userInfos =
- listOf(
- UserInfo(
- /* id= */ 0,
- /* name= */ "zero",
- /* iconPath= */ "",
- /* flags= */ UserInfo.FLAG_PRIMARY or UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL,
- UserManager.USER_TYPE_FULL_SYSTEM,
- ),
- UserInfo(
- /* id= */ 1,
- /* name= */ "one",
- /* iconPath= */ "",
- /* flags= */ UserInfo.FLAG_FULL,
- UserManager.USER_TYPE_FULL_GUEST,
- ),
- )
-
- userRepository.setUserInfos(userInfos)
- userRepository.setSelectedUserInfo(userInfos[0])
- runCurrent()
-
- val userViewModels = mutableListOf<List<UserViewModel>>()
- val job = launch(testDispatcher) { underTest.users.toList(userViewModels) }
-
- assertThat(userViewModels.last()).hasSize(2)
- assertUserViewModel(
+ assertThat(userViewModels.last()).hasSize(3)
+ assertUserViewModel(
viewModel = userViewModels.last()[0],
viewKey = 0,
name = Text.Loaded("zero"),
isSelectionMarkerVisible = true,
- )
- assertUserViewModel(
+ )
+ assertUserViewModel(
viewModel = userViewModels.last()[1],
viewKey = 1,
name = Text.Loaded("one"),
isSelectionMarkerVisible = false,
- )
- job.cancel()
- }
+ )
+ assertUserViewModel(
+ viewModel = userViewModels.last()[2],
+ viewKey = 2,
+ name = Text.Loaded("two"),
+ isSelectionMarkerVisible = false,
+ )
+ job.cancel()
+ }
+
+ @Test
+ fun `maximumUserColumns - few users`() =
+ testScope.runTest {
+ setUsers(count = 2)
+ val values = mutableListOf<Int>()
+ val job = launch(testDispatcher) { underTest.maximumUserColumns.toList(values) }
+
+ assertThat(values.last()).isEqualTo(4)
+
+ job.cancel()
+ }
+
+ @Test
+ fun `maximumUserColumns - many users`() =
+ testScope.runTest {
+ setUsers(count = 5)
+ val values = mutableListOf<Int>()
+ val job = launch(testDispatcher) { underTest.maximumUserColumns.toList(values) }
+
+ assertThat(values.last()).isEqualTo(3)
+ job.cancel()
+ }
+
+ @Test
+ fun `isOpenMenuButtonVisible - has actions - true`() =
+ testScope.runTest {
+ setUsers(2)
+
+ val isVisible = mutableListOf<Boolean>()
+ val job = launch(testDispatcher) { underTest.isOpenMenuButtonVisible.toList(isVisible) }
+
+ assertThat(isVisible.last()).isTrue()
+ job.cancel()
+ }
+
+ @Test
+ fun `isOpenMenuButtonVisible - no actions - false`() =
+ testScope.runTest {
+ val userInfos = setUsers(2)
+ userRepository.setSelectedUserInfo(userInfos[1])
+ keyguardRepository.setKeyguardShowing(true)
+ whenever(manager.canAddMoreUsers(any())).thenReturn(false)
+
+ val isVisible = mutableListOf<Boolean>()
+ val job = launch(testDispatcher) { underTest.isOpenMenuButtonVisible.toList(isVisible) }
+
+ assertThat(isVisible.last()).isFalse()
+ job.cancel()
+ }
+
+ @Test
+ fun menu() =
+ testScope.runTest {
+ val isMenuVisible = mutableListOf<Boolean>()
+ val job = launch(testDispatcher) { underTest.isMenuVisible.toList(isMenuVisible) }
+ assertThat(isMenuVisible.last()).isFalse()
+
+ underTest.onOpenMenuButtonClicked()
+ assertThat(isMenuVisible.last()).isTrue()
+
+ underTest.onMenuClosed()
+ assertThat(isMenuVisible.last()).isFalse()
+
+ job.cancel()
+ }
+
+ @Test
+ fun `menu actions`() =
+ testScope.runTest {
+ setUsers(2)
+ val actions = mutableListOf<List<UserActionViewModel>>()
+ val job = launch(testDispatcher) { underTest.menu.toList(actions) }
+
+ assertThat(actions.last().map { it.viewKey })
+ .isEqualTo(
+ listOf(
+ UserActionModel.ENTER_GUEST_MODE.ordinal.toLong(),
+ UserActionModel.ADD_USER.ordinal.toLong(),
+ UserActionModel.ADD_SUPERVISED_USER.ordinal.toLong(),
+ UserActionModel.NAVIGATE_TO_USER_MANAGEMENT.ordinal.toLong(),
+ )
+ )
+
+ job.cancel()
+ }
+
+ @Test
+ fun `isFinishRequested - finishes when user is switched`() =
+ testScope.runTest {
+ val userInfos = setUsers(count = 2)
+ val isFinishRequested = mutableListOf<Boolean>()
+ val job =
+ launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
+ assertThat(isFinishRequested.last()).isFalse()
+
+ userRepository.setSelectedUserInfo(userInfos[1])
+
+ assertThat(isFinishRequested.last()).isTrue()
+
+ job.cancel()
+ }
+
+ @Test
+ fun `isFinishRequested - finishes when the screen turns off`() =
+ testScope.runTest {
+ setUsers(count = 2)
+ powerRepository.setInteractive(true)
+ val isFinishRequested = mutableListOf<Boolean>()
+ val job =
+ launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
+ assertThat(isFinishRequested.last()).isFalse()
+
+ powerRepository.setInteractive(false)
+
+ assertThat(isFinishRequested.last()).isTrue()
+
+ job.cancel()
+ }
+
+ @Test
+ fun `isFinishRequested - finishes when cancel button is clicked`() =
+ testScope.runTest {
+ setUsers(count = 2)
+ powerRepository.setInteractive(true)
+ val isFinishRequested = mutableListOf<Boolean>()
+ val job =
+ launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
+ assertThat(isFinishRequested.last()).isFalse()
+
+ underTest.onCancelButtonClicked()
+
+ assertThat(isFinishRequested.last()).isTrue()
+
+ underTest.onFinished()
+
+ assertThat(isFinishRequested.last()).isFalse()
+
+ job.cancel()
+ }
+
+ @Test
+ fun `guest selected -- name is exit guest`() =
+ testScope.runTest {
+ val userInfos =
+ listOf(
+ UserInfo(
+ /* id= */ 0,
+ /* name= */ "zero",
+ /* iconPath= */ "",
+ /* flags= */ UserInfo.FLAG_PRIMARY or
+ UserInfo.FLAG_ADMIN or
+ UserInfo.FLAG_FULL,
+ UserManager.USER_TYPE_FULL_SYSTEM,
+ ),
+ UserInfo(
+ /* id= */ 1,
+ /* name= */ "one",
+ /* iconPath= */ "",
+ /* flags= */ UserInfo.FLAG_FULL,
+ UserManager.USER_TYPE_FULL_GUEST,
+ ),
+ )
+
+ userRepository.setUserInfos(userInfos)
+ userRepository.setSelectedUserInfo(userInfos[1])
+
+ val userViewModels = mutableListOf<List<UserViewModel>>()
+ val job = launch(testDispatcher) { underTest.users.toList(userViewModels) }
+
+ assertThat(userViewModels.last()).hasSize(2)
+ assertUserViewModel(
+ viewModel = userViewModels.last()[0],
+ viewKey = 0,
+ name = Text.Loaded("zero"),
+ isSelectionMarkerVisible = false,
+ )
+ assertUserViewModel(
+ viewModel = userViewModels.last()[1],
+ viewKey = 1,
+ name =
+ Text.Resource(
+ com.android.settingslib.R.string.guest_exit_quick_settings_button
+ ),
+ isSelectionMarkerVisible = true,
+ )
+ job.cancel()
+ }
+
+ @Test
+ fun `guest not selected -- name is guest`() =
+ testScope.runTest {
+ val userInfos =
+ listOf(
+ UserInfo(
+ /* id= */ 0,
+ /* name= */ "zero",
+ /* iconPath= */ "",
+ /* flags= */ UserInfo.FLAG_PRIMARY or
+ UserInfo.FLAG_ADMIN or
+ UserInfo.FLAG_FULL,
+ UserManager.USER_TYPE_FULL_SYSTEM,
+ ),
+ UserInfo(
+ /* id= */ 1,
+ /* name= */ "one",
+ /* iconPath= */ "",
+ /* flags= */ UserInfo.FLAG_FULL,
+ UserManager.USER_TYPE_FULL_GUEST,
+ ),
+ )
+
+ userRepository.setUserInfos(userInfos)
+ userRepository.setSelectedUserInfo(userInfos[0])
+ runCurrent()
+
+ val userViewModels = mutableListOf<List<UserViewModel>>()
+ val job = launch(testDispatcher) { underTest.users.toList(userViewModels) }
+
+ assertThat(userViewModels.last()).hasSize(2)
+ assertUserViewModel(
+ viewModel = userViewModels.last()[0],
+ viewKey = 0,
+ name = Text.Loaded("zero"),
+ isSelectionMarkerVisible = true,
+ )
+ assertUserViewModel(
+ viewModel = userViewModels.last()[1],
+ viewKey = 1,
+ name = Text.Loaded("one"),
+ isSelectionMarkerVisible = false,
+ )
+ job.cancel()
+ }
private suspend fun setUsers(count: Int): List<UserInfo> {
val userInfos =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index c3c6975..d419095 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -16,6 +16,7 @@
package com.android.systemui.volume;
+import static com.android.systemui.volume.Events.DISMISS_REASON_UNKNOWN;
import static com.android.systemui.volume.VolumeDialogControllerImpl.STREAMS;
import static junit.framework.Assert.assertEquals;
@@ -342,6 +343,15 @@
assertEquals(mDialog.mVolumeRingerMuteIconDrawableId, R.drawable.ic_volume_ringer_mute);
}
+ @Test
+ public void testDialogDismissAnimation_notifyVisibleIsNotCalledBeforeAnimation() {
+ mDialog.dismissH(DISMISS_REASON_UNKNOWN);
+ // notifyVisible(false) should not be called immediately but only after the dismiss
+ // animation has ended.
+ verify(mVolumeDialogController, times(0)).notifyVisible(false);
+ mDialog.getDialogView().animate().cancel();
+ }
+
/*
@Test
public void testContentDescriptions() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index 5b424a3..a537848 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -24,6 +24,7 @@
import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.wm.shell.bubbles.Bubble.KEY_APP_BUBBLE;
import static com.google.common.truth.Truth.assertThat;
@@ -228,6 +229,8 @@
private BubbleEntry mBubbleEntryUser11;
private BubbleEntry mBubbleEntry2User11;
+ private Intent mAppBubbleIntent;
+
@Mock
private ShellInit mShellInit;
@Mock
@@ -323,6 +326,9 @@
mBubbleEntry2User11 = BubblesManager.notifToBubbleEntry(
mNotificationTestHelper.createBubble(handle));
+ mAppBubbleIntent = new Intent(mContext, BubblesTestActivity.class);
+ mAppBubbleIntent.setPackage(mContext.getPackageName());
+
mZenModeConfig.suppressedVisualEffects = 0;
when(mZenModeController.getConfig()).thenReturn(mZenModeConfig);
@@ -1630,6 +1636,62 @@
any(Bubble.class), anyBoolean(), anyBoolean());
}
+ @Test
+ public void testShowOrHideAppBubble_addsAndExpand() {
+ assertThat(mBubbleController.isStackExpanded()).isFalse();
+ assertThat(mBubbleData.getBubbleInStackWithKey(KEY_APP_BUBBLE)).isNull();
+
+ mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+
+ verify(mBubbleController).inflateAndAdd(any(Bubble.class), /* suppressFlyout= */ eq(true),
+ /* showInShade= */ eq(false));
+ assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
+ assertThat(mBubbleController.isStackExpanded()).isTrue();
+ }
+
+ @Test
+ public void testShowOrHideAppBubble_expandIfCollapsed() {
+ mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+ mBubbleController.updateBubble(mBubbleEntry);
+ mBubbleController.collapseStack();
+ assertThat(mBubbleController.isStackExpanded()).isFalse();
+
+ // Calling this while collapsed will expand the app bubble
+ mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+
+ assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
+ assertThat(mBubbleController.isStackExpanded()).isTrue();
+ assertThat(mBubbleData.getBubbles().size()).isEqualTo(2);
+ }
+
+ @Test
+ public void testShowOrHideAppBubble_collapseIfSelected() {
+ mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+ assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
+ assertThat(mBubbleController.isStackExpanded()).isTrue();
+
+ // Calling this while the app bubble is expanded should collapse the stack
+ mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+
+ assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
+ assertThat(mBubbleController.isStackExpanded()).isFalse();
+ assertThat(mBubbleData.getBubbles().size()).isEqualTo(1);
+ }
+
+ @Test
+ public void testShowOrHideAppBubble_selectIfNotSelected() {
+ mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+ mBubbleController.updateBubble(mBubbleEntry);
+ mBubbleController.expandStackAndSelectBubble(mBubbleEntry);
+ assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(mBubbleEntry.getKey());
+ assertThat(mBubbleController.isStackExpanded()).isTrue();
+
+ mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+ assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
+ assertThat(mBubbleController.isStackExpanded()).isTrue();
+ assertThat(mBubbleData.getBubbles().size()).isEqualTo(2);
+ }
+
/** Creates a bubble using the userId and package. */
private Bubble createBubble(int userId, String pkg) {
final UserHandle userHandle = new UserHandle(userId);
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/MemoryTrackingTestCase.java b/packages/SystemUI/tests/utils/src/com/android/systemui/MemoryTrackingTestCase.java
index 3767fbe..3428553 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/MemoryTrackingTestCase.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/MemoryTrackingTestCase.java
@@ -40,24 +40,49 @@
public class MemoryTrackingTestCase extends SysuiTestCase {
private static File sFilesDir = null;
private static String sLatestTestClassName = null;
+ private static int sHeapCount = 0;
+ private static File sLatestBaselineHeapFile = null;
- @Before public void grabFilesDir() {
+ // Ideally, we would do this in @BeforeClass just once, but we need mContext to get the files
+ // dir, and that does not exist until @Before on each test method.
+ @Before
+ public void grabFilesDir() throws IOException {
+ // This should happen only once per suite
if (sFilesDir == null) {
sFilesDir = mContext.getFilesDir();
}
- sLatestTestClassName = getClass().getName();
+
+ // This will happen before the first test method in each class
+ if (sLatestTestClassName == null) {
+ sLatestTestClassName = getClass().getName();
+ sLatestBaselineHeapFile = dump("baseline" + (++sHeapCount), "before-test");
+ }
}
@AfterClass
public static void dumpHeap() throws IOException {
+ File afterTestHeap = dump(sLatestTestClassName, "after-test");
+ if (sLatestBaselineHeapFile != null && afterTestHeap != null) {
+ Log.w("MEMORY", "To compare heap to baseline (use go/ahat):");
+ Log.w("MEMORY", " adb pull " + sLatestBaselineHeapFile);
+ Log.w("MEMORY", " adb pull " + afterTestHeap);
+ Log.w("MEMORY",
+ " java -jar ahat.jar --baseline " + sLatestBaselineHeapFile.getName() + " "
+ + afterTestHeap.getName());
+ }
+ sLatestTestClassName = null;
+ }
+
+ private static File dump(String basename, String heapKind) throws IOException {
if (sFilesDir == null) {
Log.e("MEMORY", "Somehow no test cases??");
- return;
+ return null;
}
mockitoTearDown();
- Log.w("MEMORY", "about to dump heap");
- File path = new File(sFilesDir, sLatestTestClassName + ".ahprof");
+ Log.w("MEMORY", "about to dump " + heapKind + " heap");
+ File path = new File(sFilesDir, basename + ".ahprof");
Debug.dumpHprofData(path.getPath());
- Log.w("MEMORY", "did it! Location: " + path);
+ Log.w("MEMORY", "Success! Location: " + path);
+ return path;
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
index 39d2eca..15b4736 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
@@ -52,6 +52,9 @@
private val _isDozing = MutableStateFlow(false)
override val isDozing: Flow<Boolean> = _isDozing
+ private val _isAodAvailable = MutableStateFlow(false)
+ override val isAodAvailable: Flow<Boolean> = _isAodAvailable
+
private val _isDreaming = MutableStateFlow(false)
override val isDreaming: Flow<Boolean> = _isDreaming
@@ -126,6 +129,10 @@
_isDozing.value = isDozing
}
+ fun setAodAvailable(isAodAvailable: Boolean) {
+ _isAodAvailable.value = isAodAvailable
+ }
+
fun setDreamingWithOverlay(isDreaming: Boolean) {
_isDreamingWithOverlay.value = isDreaming
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index 05e305c..f4c6cc3 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -132,7 +132,7 @@
private static final String TRACE_WM = "WindowManagerInternal";
private static final int WAIT_WINDOWS_TIMEOUT_MILLIS = 5000;
- /** Display type for displays associated with the default user of th device. */
+ /** Display type for displays associated with the default user of the device. */
public static final int DISPLAY_TYPE_DEFAULT = 1 << 0;
/** Display type for displays associated with an AccessibilityDisplayProxy user. */
public static final int DISPLAY_TYPE_PROXY = 1 << 1;
@@ -1993,17 +1993,29 @@
private int resolveAccessibilityWindowIdLocked(int accessibilityWindowId) {
if (accessibilityWindowId == AccessibilityWindowInfo.ACTIVE_WINDOW_ID) {
- return mA11yWindowManager.getActiveWindowId(mSystemSupport.getCurrentUserIdLocked());
+ final int focusedWindowId =
+ mA11yWindowManager.getActiveWindowId(mSystemSupport.getCurrentUserIdLocked());
+ if (!mA11yWindowManager.windowIdBelongsToDisplayType(focusedWindowId, mDisplayTypes)) {
+ return AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
+ }
+ return focusedWindowId;
}
return accessibilityWindowId;
}
private int resolveAccessibilityWindowIdForFindFocusLocked(int windowId, int focusType) {
- if (windowId == AccessibilityWindowInfo.ACTIVE_WINDOW_ID) {
- return mA11yWindowManager.getActiveWindowId(mSystemSupport.getCurrentUserIdLocked());
- }
if (windowId == AccessibilityWindowInfo.ANY_WINDOW_ID) {
- return mA11yWindowManager.getFocusedWindowId(focusType);
+ final int focusedWindowId = mA11yWindowManager.getFocusedWindowId(focusType);
+ // If the caller is a proxy and the found window doesn't belong to a proxy display
+ // (or vice versa), then return null. This doesn't work if there are multiple active
+ // proxys, but in the future this code shouldn't be needed if input and a11y focus are
+ // properly split. (so we will deal with the issues if we see them).
+ //TODO(254545943): Remove this when there is user and proxy separation of input and a11y
+ // focus
+ if (!mA11yWindowManager.windowIdBelongsToDisplayType(focusedWindowId, mDisplayTypes)) {
+ return AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
+ }
+ return focusedWindowId;
}
return windowId;
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
index c050449e0..f0c6c4f 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
@@ -156,6 +156,30 @@
}
/**
+ * Returns {@code true} if the window belongs to a display of {@code displayTypes}.
+ */
+ public boolean windowIdBelongsToDisplayType(int focusedWindowId, int displayTypes) {
+ // UIAutomation wants focus from any display type.
+ final int displayTypeMask = DISPLAY_TYPE_PROXY | DISPLAY_TYPE_DEFAULT;
+ if ((displayTypes & displayTypeMask) == displayTypeMask) {
+ return true;
+ }
+ synchronized (mLock) {
+ final int count = mDisplayWindowsObservers.size();
+ for (int i = 0; i < count; i++) {
+ final DisplayWindowsObserver observer = mDisplayWindowsObservers.valueAt(i);
+ if (observer != null
+ && observer.findA11yWindowInfoByIdLocked(focusedWindowId) != null) {
+ return observer.mIsProxy
+ ? ((displayTypes & DISPLAY_TYPE_PROXY) != 0)
+ : (displayTypes & DISPLAY_TYPE_DEFAULT) != 0;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
* This class implements {@link WindowManagerInternal.WindowsForAccessibilityCallback} to
* receive {@link WindowInfo}s from window manager when there's an accessibility change in
* window and holds window lists information per display.
@@ -430,6 +454,7 @@
return;
}
windowInfo.title = attributes.getWindowTitle();
+ windowInfo.locales = attributes.getLocales();
}
private boolean shouldUpdateWindowsLocked(boolean forceSend,
@@ -756,6 +781,7 @@
reportedWindow.setPictureInPicture(window.inPictureInPicture);
reportedWindow.setDisplayId(window.displayId);
reportedWindow.setTaskId(window.taskId);
+ reportedWindow.setLocales(window.locales);
final int parentId = findWindowIdLocked(userId, window.parentToken);
if (parentId >= 0) {
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
index bb286e6..02e810f 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
@@ -410,9 +410,6 @@
public void onRequestMagnificationSpec(int displayId, int serviceId) {
final WindowMagnificationManager windowMagnificationManager;
synchronized (mLock) {
- if (serviceId == MAGNIFICATION_GESTURE_HANDLER_ID) {
- return;
- }
updateMagnificationButton(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
windowMagnificationManager = mWindowMagnificationMgr;
}
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index bce8812..7df4899 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -826,7 +826,8 @@
if (host != null) {
host.callbacks = null;
pruneHostLocked(host);
- mAppOpsManagerInternal.updateAppWidgetVisibility(host.getWidgetUids(), false);
+ mAppOpsManagerInternal.updateAppWidgetVisibility(host.getWidgetUidsIfBound(),
+ false);
}
}
}
@@ -897,12 +898,8 @@
Host host = lookupHostLocked(id);
if (host != null) {
- try {
- mAppOpsManagerInternal.updateAppWidgetVisibility(host.getWidgetUids(), false);
- } catch (NullPointerException e) {
- Slog.e(TAG, "setAppWidgetHidden(): Getting host uids: " + host.toString(), e);
- throw e;
- }
+ mAppOpsManagerInternal.updateAppWidgetVisibility(host.getWidgetUidsIfBound(),
+ false);
}
}
}
@@ -4370,14 +4367,15 @@
PendingHostUpdate.appWidgetRemoved(appWidgetId));
}
- public SparseArray<String> getWidgetUids() {
+ public SparseArray<String> getWidgetUidsIfBound() {
final SparseArray<String> uids = new SparseArray<>();
for (int i = widgets.size() - 1; i >= 0; i--) {
final Widget widget = widgets.get(i);
if (widget.provider == null) {
if (DEBUG) {
- Slog.e(TAG, "Widget with no provider " + widget.toString());
+ Slog.d(TAG, "Widget with no provider " + widget.toString());
}
+ continue;
}
final ProviderId providerId = widget.provider.id;
uids.put(providerId.uid, providerId.componentName.getPackageName());
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index 677871f..8c2c964 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -357,6 +357,7 @@
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.accessibilityTitle = context.getString(R.string.autofill_save_accessibility_title);
params.windowAnimations = R.style.AutofillSaveAnimation;
+ params.setTrustedOverlay();
show();
}
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
index 758345f..b0f2464 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
@@ -139,15 +139,6 @@
mActivityInterceptorCallback);
}
- @GuardedBy("mVirtualDeviceManagerLock")
- private boolean isValidVirtualDeviceLocked(IVirtualDevice virtualDevice) {
- try {
- return mVirtualDevices.contains(virtualDevice.getDeviceId());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
void onCameraAccessBlocked(int appUid) {
synchronized (mVirtualDeviceManagerLock) {
for (int i = 0; i < mVirtualDevices.size(); i++) {
@@ -347,6 +338,14 @@
return VirtualDeviceManager.DEVICE_ID_DEFAULT;
}
+ // Binder call
+ @Override
+ public boolean isValidVirtualDeviceId(int deviceId) {
+ synchronized (mVirtualDeviceManagerLock) {
+ return mVirtualDevices.contains(deviceId);
+ }
+ }
+
@Override // Binder call
public int getAudioPlaybackSessionId(int deviceId) {
synchronized (mVirtualDeviceManagerLock) {
@@ -445,13 +444,6 @@
private final ArraySet<Integer> mAllUidsOnVirtualDevice = new ArraySet<>();
@Override
- public boolean isValidVirtualDevice(IVirtualDevice virtualDevice) {
- synchronized (mVirtualDeviceManagerLock) {
- return isValidVirtualDeviceLocked(virtualDevice);
- }
- }
-
- @Override
public int getDeviceOwnerUid(int deviceId) {
synchronized (mVirtualDeviceManagerLock) {
VirtualDeviceImpl virtualDevice = mVirtualDevices.get(deviceId);
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 4d53b48..17b6f5d 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -158,8 +158,8 @@
"android.hardware.health-translate-java",
"android.hardware.light-V1-java",
"android.hardware.tv.cec-V1.1-java",
- "android.hardware.tv.cec-V1-java",
- "android.hardware.tv.hdmi-V1-java",
+ "android.hardware.tv.hdmi.cec-V1-java",
+ "android.hardware.tv.hdmi.connection-V1-java",
"android.hardware.weaver-V1.0-java",
"android.hardware.weaver-V2-java",
"android.hardware.biometrics.face-V1.0-java",
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 71a4c73..b41664f 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -189,15 +189,20 @@
private long mLastBatteryLevelChangedSentMs;
private Bundle mBatteryChangedOptions = BroadcastOptions.makeRemovingMatchingFilter(
- new IntentFilter(Intent.ACTION_BATTERY_CHANGED)).toBundle();
+ new IntentFilter(Intent.ACTION_BATTERY_CHANGED)).setDeferUntilActive(true)
+ .toBundle();
private Bundle mPowerConnectedOptions = BroadcastOptions.makeRemovingMatchingFilter(
- new IntentFilter(Intent.ACTION_POWER_DISCONNECTED)).toBundle();
+ new IntentFilter(Intent.ACTION_POWER_DISCONNECTED)).setDeferUntilActive(true)
+ .toBundle();
private Bundle mPowerDisconnectedOptions = BroadcastOptions.makeRemovingMatchingFilter(
- new IntentFilter(Intent.ACTION_POWER_CONNECTED)).toBundle();
+ new IntentFilter(Intent.ACTION_POWER_CONNECTED)).setDeferUntilActive(true)
+ .toBundle();
private Bundle mBatteryLowOptions = BroadcastOptions.makeRemovingMatchingFilter(
- new IntentFilter(Intent.ACTION_BATTERY_OKAY)).toBundle();
+ new IntentFilter(Intent.ACTION_BATTERY_OKAY)).setDeferUntilActive(true)
+ .toBundle();
private Bundle mBatteryOkayOptions = BroadcastOptions.makeRemovingMatchingFilter(
- new IntentFilter(Intent.ACTION_BATTERY_LOW)).toBundle();
+ new IntentFilter(Intent.ACTION_BATTERY_LOW)).setDeferUntilActive(true)
+ .toBundle();
private MetricsLogger mMetricsLogger;
diff --git a/services/core/java/com/android/server/BinaryTransparencyService.java b/services/core/java/com/android/server/BinaryTransparencyService.java
index 819c948..68722d2 100644
--- a/services/core/java/com/android/server/BinaryTransparencyService.java
+++ b/services/core/java/com/android/server/BinaryTransparencyService.java
@@ -531,27 +531,30 @@
pw.println("|--> Pre-installed package install location: "
+ origPackageFilepath);
- if (useSha256) {
- String sha256Digest = PackageUtils.computeSha256DigestForLargeFile(
- origPackageFilepath, PackageUtils.createLargeFileBuffer());
- pw.println("|--> Pre-installed package SHA-256 digest: "
- + sha256Digest);
- }
+ if (!origPackageFilepath.equals(APEX_PRELOAD_LOCATION_ERROR)) {
+ if (useSha256) {
+ String sha256Digest = PackageUtils.computeSha256DigestForLargeFile(
+ origPackageFilepath, PackageUtils.createLargeFileBuffer());
+ pw.println("|--> Pre-installed package SHA-256 digest: "
+ + sha256Digest);
+ }
-
- Map<Integer, byte[]> contentDigests = computeApkContentDigest(
- origPackageFilepath);
- if (contentDigests == null) {
- pw.println("ERROR: Failed to compute package content digest for "
- + origPackageFilepath);
- } else {
- for (Map.Entry<Integer, byte[]> entry : contentDigests.entrySet()) {
- Integer algorithmId = entry.getKey();
- byte[] contentDigest = entry.getValue();
- pw.println("|--> Pre-installed package content digest: "
- + HexEncoding.encodeToString(contentDigest, false));
- pw.println("|--> Pre-installed package content digest algorithm: "
- + translateContentDigestAlgorithmIdToString(algorithmId));
+ Map<Integer, byte[]> contentDigests = computeApkContentDigest(
+ origPackageFilepath);
+ if (contentDigests == null) {
+ pw.println("|--> ERROR: Failed to compute package content digest "
+ + "for " + origPackageFilepath);
+ } else {
+ for (Map.Entry<Integer, byte[]> entry : contentDigests.entrySet()) {
+ Integer algorithmId = entry.getKey();
+ byte[] contentDigest = entry.getValue();
+ pw.println("|--> Pre-installed package content digest: "
+ + HexEncoding.encodeToString(contentDigest, false));
+ pw.println("|--> Pre-installed package content digest "
+ + "algorithm: "
+ + translateContentDigestAlgorithmIdToString(
+ algorithmId));
+ }
}
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index fc6d30b..1bc312e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -159,6 +159,8 @@
import android.Manifest.permission;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.PermissionMethod;
+import android.annotation.PermissionName;
import android.annotation.UserIdInt;
import android.app.Activity;
import android.app.ActivityClient;
@@ -251,8 +253,6 @@
import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionInfo;
-import android.content.pm.PermissionMethod;
-import android.content.pm.PermissionName;
import android.content.pm.ProcessInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.ProviderInfoList;
@@ -399,7 +399,6 @@
import com.android.server.LocalManagerRegistry;
import com.android.server.LocalServices;
import com.android.server.LockGuard;
-import com.android.server.NetworkManagementInternal;
import com.android.server.PackageWatchdog;
import com.android.server.ServiceThread;
import com.android.server.SystemConfig;
@@ -417,6 +416,7 @@
import com.android.server.firewall.IntentFirewall;
import com.android.server.graphics.fonts.FontManagerInternal;
import com.android.server.job.JobSchedulerInternal;
+import com.android.server.net.NetworkManagementInternal;
import com.android.server.os.NativeTombstoneManager;
import com.android.server.pm.Computer;
import com.android.server.pm.Installer;
@@ -14108,8 +14108,16 @@
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
(sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
+ " ordered=" + ordered + " userid=" + userId);
- if ((resultTo != null) && !ordered && !mEnableModernQueue) {
- Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
+ if ((resultTo != null) && !ordered) {
+ if (!mEnableModernQueue) {
+ Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
+ }
+ if (!UserHandle.isCore(callingUid)) {
+ String msg = "Unauthorized unordered resultTo broadcast "
+ + intent + " sent from uid " + callingUid;
+ Slog.w(TAG, msg);
+ throw new SecurityException(msg);
+ }
}
userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
@@ -14190,6 +14198,18 @@
}
}
+ // resultTo broadcasts are always infinitely deferrable.
+ if ((resultTo != null) && !ordered && mEnableModernQueue) {
+ if (brOptions == null) {
+ brOptions = BroadcastOptions.makeBasic();
+ }
+ brOptions.setDeferUntilActive(true);
+ }
+
+ if (ordered && brOptions != null && brOptions.isDeferUntilActive()) {
+ throw new IllegalArgumentException("Ordered broadcasts can't be deferred until active");
+ }
+
// Verify that protected broadcasts are only being sent by system code,
// and that system code is only sending protected broadcasts.
final boolean isProtectedBroadcast;
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 80684bf..788c81c 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -2153,19 +2153,24 @@
boolean success;
String displaySuffix;
- if (displayId == Display.INVALID_DISPLAY) {
- success = mInterface.startUserInBackgroundWithListener(userId, waiter);
- displaySuffix = "";
- } else {
- if (!UserManager.isVisibleBackgroundUsersEnabled()) {
- pw.println("Not supported");
- return -1;
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "shell_runStartUser" + userId);
+ try {
+ if (displayId == Display.INVALID_DISPLAY) {
+ success = mInterface.startUserInBackgroundWithListener(userId, waiter);
+ displaySuffix = "";
+ } else {
+ if (!UserManager.isVisibleBackgroundUsersEnabled()) {
+ pw.println("Not supported");
+ return -1;
+ }
+ success = mInterface.startUserInBackgroundVisibleOnDisplay(userId, displayId);
+ displaySuffix = " on display " + displayId;
}
- success = mInterface.startUserInBackgroundVisibleOnDisplay(userId, displayId);
- displaySuffix = " on display " + displayId;
- }
- if (wait && success) {
- success = waiter.waitForFinish(USER_OPERATION_TIMEOUT_MS);
+ if (wait && success) {
+ success = waiter.waitForFinish(USER_OPERATION_TIMEOUT_MS);
+ }
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
if (success) {
diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
index fa7748b..41d9a11 100644
--- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
@@ -62,6 +62,7 @@
*/
// @NotThreadSafe
class BroadcastProcessQueue {
+ static final boolean VERBOSE = false;
final @NonNull BroadcastConstants constants;
final @NonNull String processName;
final int uid;
@@ -168,10 +169,14 @@
/**
* Count of pending broadcasts of these various flavors.
*/
+ private int mCountEnqueued;
+ private int mCountDeferred;
private int mCountForeground;
+ private int mCountForegroundDeferred;
private int mCountOrdered;
private int mCountAlarm;
private int mCountPrioritized;
+ private int mCountPrioritizedDeferred;
private int mCountInteractive;
private int mCountResultTo;
private int mCountInstrumented;
@@ -226,10 +231,10 @@
* used for ordered broadcasts and priority traunches.
*/
public void enqueueOrReplaceBroadcast(@NonNull BroadcastRecord record, int recordIndex,
- @NonNull BroadcastConsumer replacedBroadcastConsumer) {
+ @NonNull BroadcastConsumer replacedBroadcastConsumer, boolean wouldBeSkipped) {
if (record.isReplacePending()) {
final boolean didReplace = replaceBroadcast(record, recordIndex,
- replacedBroadcastConsumer);
+ replacedBroadcastConsumer, wouldBeSkipped);
if (didReplace) {
return;
}
@@ -240,13 +245,14 @@
SomeArgs newBroadcastArgs = SomeArgs.obtain();
newBroadcastArgs.arg1 = record;
newBroadcastArgs.argi1 = recordIndex;
+ newBroadcastArgs.argi2 = (wouldBeSkipped ? 1 : 0);
// Cross-broadcast prioritization policy: some broadcasts might warrant being
// issued ahead of others that are already pending, for example if this new
// broadcast is in a different delivery class or is tied to a direct user interaction
// with implicit responsiveness expectations.
getQueueForBroadcast(record).addLast(newBroadcastArgs);
- onBroadcastEnqueued(record, recordIndex);
+ onBroadcastEnqueued(record, recordIndex, wouldBeSkipped);
}
/**
@@ -258,11 +264,12 @@
* {@code false} otherwise.
*/
private boolean replaceBroadcast(@NonNull BroadcastRecord record, int recordIndex,
- @NonNull BroadcastConsumer replacedBroadcastConsumer) {
+ @NonNull BroadcastConsumer replacedBroadcastConsumer, boolean wouldBeSkipped) {
final int count = mPendingQueues.size();
for (int i = 0; i < count; ++i) {
final ArrayDeque<SomeArgs> queue = mPendingQueues.get(i);
- if (replaceBroadcastInQueue(queue, record, recordIndex, replacedBroadcastConsumer)) {
+ if (replaceBroadcastInQueue(queue, record, recordIndex,
+ replacedBroadcastConsumer, wouldBeSkipped)) {
return true;
}
}
@@ -279,13 +286,15 @@
*/
private boolean replaceBroadcastInQueue(@NonNull ArrayDeque<SomeArgs> queue,
@NonNull BroadcastRecord record, int recordIndex,
- @NonNull BroadcastConsumer replacedBroadcastConsumer) {
+ @NonNull BroadcastConsumer replacedBroadcastConsumer,
+ boolean wouldBeSkipped) {
final Iterator<SomeArgs> it = queue.descendingIterator();
final Object receiver = record.receivers.get(recordIndex);
while (it.hasNext()) {
final SomeArgs args = it.next();
final BroadcastRecord testRecord = (BroadcastRecord) args.arg1;
final int testRecordIndex = args.argi1;
+ final boolean testWouldBeSkipped = (args.argi2 == 1);
final Object testReceiver = testRecord.receivers.get(testRecordIndex);
if ((record.callingUid == testRecord.callingUid)
&& (record.userId == testRecord.userId)
@@ -295,9 +304,10 @@
// Exact match found; perform in-place swap
args.arg1 = record;
args.argi1 = recordIndex;
+ args.argi2 = (wouldBeSkipped ? 1 : 0);
record.copyEnqueueTimeFrom(testRecord);
- onBroadcastDequeued(testRecord, testRecordIndex);
- onBroadcastEnqueued(record, recordIndex);
+ onBroadcastDequeued(testRecord, testRecordIndex, testWouldBeSkipped);
+ onBroadcastEnqueued(record, recordIndex, wouldBeSkipped);
replacedBroadcastConsumer.accept(testRecord, testRecordIndex);
return true;
}
@@ -352,12 +362,13 @@
final SomeArgs args = it.next();
final BroadcastRecord record = (BroadcastRecord) args.arg1;
final int recordIndex = args.argi1;
+ final boolean recordWouldBeSkipped = (args.argi2 == 1);
if (predicate.test(record, recordIndex)) {
consumer.accept(record, recordIndex);
if (andRemove) {
args.recycle();
it.remove();
- onBroadcastDequeued(record, recordIndex);
+ onBroadcastDequeued(record, recordIndex, recordWouldBeSkipped);
}
didSomething = true;
}
@@ -423,7 +434,7 @@
}
public int getPreferredSchedulingGroupLocked() {
- if (mCountForeground > 0) {
+ if (mCountForeground > mCountForegroundDeferred) {
// We have a foreground broadcast somewhere down the queue, so
// boost priority until we drain them all
return ProcessList.SCHED_GROUP_DEFAULT;
@@ -469,10 +480,11 @@
final SomeArgs next = removeNextBroadcast();
mActive = (BroadcastRecord) next.arg1;
mActiveIndex = next.argi1;
+ final boolean wouldBeSkipped = (next.argi2 == 1);
mActiveCountSinceIdle++;
mActiveViaColdStart = false;
next.recycle();
- onBroadcastDequeued(mActive, mActiveIndex);
+ onBroadcastDequeued(mActive, mActiveIndex, wouldBeSkipped);
}
/**
@@ -489,8 +501,16 @@
/**
* Update summary statistics when the given record has been enqueued.
*/
- private void onBroadcastEnqueued(@NonNull BroadcastRecord record, int recordIndex) {
+ private void onBroadcastEnqueued(@NonNull BroadcastRecord record, int recordIndex,
+ boolean wouldBeSkipped) {
+ mCountEnqueued++;
+ if (record.deferUntilActive) {
+ mCountDeferred++;
+ }
if (record.isForeground()) {
+ if (record.deferUntilActive) {
+ mCountForegroundDeferred++;
+ }
mCountForeground++;
}
if (record.ordered) {
@@ -500,6 +520,9 @@
mCountAlarm++;
}
if (record.prioritized) {
+ if (record.deferUntilActive) {
+ mCountPrioritizedDeferred++;
+ }
mCountPrioritized++;
}
if (record.interactive) {
@@ -511,7 +534,8 @@
if (record.callerInstrumented) {
mCountInstrumented++;
}
- if (record.receivers.get(recordIndex) instanceof ResolveInfo) {
+ if (!wouldBeSkipped
+ && (record.receivers.get(recordIndex) instanceof ResolveInfo)) {
mCountManifest++;
}
invalidateRunnableAt();
@@ -520,8 +544,16 @@
/**
* Update summary statistics when the given record has been dequeued.
*/
- private void onBroadcastDequeued(@NonNull BroadcastRecord record, int recordIndex) {
+ private void onBroadcastDequeued(@NonNull BroadcastRecord record, int recordIndex,
+ boolean wouldBeSkipped) {
+ mCountEnqueued--;
+ if (record.deferUntilActive) {
+ mCountDeferred--;
+ }
if (record.isForeground()) {
+ if (record.deferUntilActive) {
+ mCountForegroundDeferred--;
+ }
mCountForeground--;
}
if (record.ordered) {
@@ -531,6 +563,9 @@
mCountAlarm--;
}
if (record.prioritized) {
+ if (record.deferUntilActive) {
+ mCountPrioritizedDeferred--;
+ }
mCountPrioritized--;
}
if (record.interactive) {
@@ -542,7 +577,8 @@
if (record.callerInstrumented) {
mCountInstrumented--;
}
- if (record.receivers.get(recordIndex) instanceof ResolveInfo) {
+ if (!wouldBeSkipped
+ && (record.receivers.get(recordIndex) instanceof ResolveInfo)) {
mCountManifest--;
}
invalidateRunnableAt();
@@ -741,6 +777,15 @@
return mRunnableAt != Long.MAX_VALUE;
}
+ public boolean isDeferredUntilActive() {
+ if (mRunnableAtInvalidated) updateRunnableAt();
+ return mRunnableAtReason == BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER;
+ }
+
+ public boolean hasDeferredBroadcasts() {
+ return (mCountDeferred > 0);
+ }
+
/**
* Return time at which this process is considered runnable. This is
* typically the time at which the next pending broadcast was first
@@ -776,6 +821,7 @@
static final int REASON_INSTRUMENTED = 5;
static final int REASON_PERSISTENT = 6;
static final int REASON_FORCE_DELAYED = 7;
+ static final int REASON_CACHED_INFINITE_DEFER = 8;
static final int REASON_CONTAINS_FOREGROUND = 10;
static final int REASON_CONTAINS_ORDERED = 11;
static final int REASON_CONTAINS_ALARM = 12;
@@ -794,6 +840,7 @@
REASON_INSTRUMENTED,
REASON_PERSISTENT,
REASON_FORCE_DELAYED,
+ REASON_CACHED_INFINITE_DEFER,
REASON_CONTAINS_FOREGROUND,
REASON_CONTAINS_ORDERED,
REASON_CONTAINS_ALARM,
@@ -816,6 +863,7 @@
case REASON_INSTRUMENTED: return "INSTRUMENTED";
case REASON_PERSISTENT: return "PERSISTENT";
case REASON_FORCE_DELAYED: return "FORCE_DELAYED";
+ case REASON_CACHED_INFINITE_DEFER: return "INFINITE_DEFER";
case REASON_CONTAINS_FOREGROUND: return "CONTAINS_FOREGROUND";
case REASON_CONTAINS_ORDERED: return "CONTAINS_ORDERED";
case REASON_CONTAINS_ALARM: return "CONTAINS_ALARM";
@@ -831,9 +879,16 @@
private boolean blockedOnOrderedDispatch(BroadcastRecord r, int index) {
final int blockedUntilTerminalCount = r.blockedUntilTerminalCount[index];
+ int existingDeferredCount = 0;
+ if (r.deferUntilActive) {
+ for (int i = 0; i < index; i++) {
+ if (r.deferredUntilActive[i]) existingDeferredCount++;
+ }
+ }
+
// We might be blocked waiting for other receivers to finish,
// typically for an ordered broadcast or priority traunches
- if (r.terminalCount < blockedUntilTerminalCount
+ if ((r.terminalCount + existingDeferredCount) < blockedUntilTerminalCount
&& !isDeliveryStateTerminal(r.getDeliveryState(index))) {
return true;
}
@@ -862,7 +917,7 @@
if (mForcedDelayedDurationMs > 0) {
mRunnableAt = runnableAt + mForcedDelayedDurationMs;
mRunnableAtReason = REASON_FORCE_DELAYED;
- } else if (mCountForeground > 0) {
+ } else if (mCountForeground > mCountForegroundDeferred) {
mRunnableAt = runnableAt + constants.DELAY_URGENT_MILLIS;
mRunnableAtReason = REASON_CONTAINS_FOREGROUND;
} else if (mCountInteractive > 0) {
@@ -880,12 +935,9 @@
} else if (mCountAlarm > 0) {
mRunnableAt = runnableAt;
mRunnableAtReason = REASON_CONTAINS_ALARM;
- } else if (mCountPrioritized > 0) {
+ } else if (mCountPrioritized > mCountPrioritizedDeferred) {
mRunnableAt = runnableAt;
mRunnableAtReason = REASON_CONTAINS_PRIORITIZED;
- } else if (mCountResultTo > 0) {
- mRunnableAt = runnableAt;
- mRunnableAtReason = REASON_CONTAINS_RESULT_TO;
} else if (mCountManifest > 0) {
mRunnableAt = runnableAt;
mRunnableAtReason = REASON_CONTAINS_MANIFEST;
@@ -893,8 +945,39 @@
mRunnableAt = runnableAt;
mRunnableAtReason = REASON_PERSISTENT;
} else if (mProcessCached) {
- mRunnableAt = runnableAt + constants.DELAY_CACHED_MILLIS;
- mRunnableAtReason = REASON_CACHED;
+ if (r.deferUntilActive) {
+ // All enqueued broadcasts are deferrable, defer
+ if (mCountDeferred == mCountEnqueued) {
+ mRunnableAt = Long.MAX_VALUE;
+ mRunnableAtReason = REASON_CACHED_INFINITE_DEFER;
+ } else {
+ // At least one enqueued broadcast isn't deferrable, repick time and reason
+ // for this record. If a later record is not deferrable and is one of these
+ // special cases, one of the cases above would have already caught that.
+ if (r.isForeground()) {
+ mRunnableAt = runnableAt + constants.DELAY_URGENT_MILLIS;
+ mRunnableAtReason = REASON_CONTAINS_FOREGROUND;
+ } else if (r.prioritized) {
+ mRunnableAt = runnableAt;
+ mRunnableAtReason = REASON_CONTAINS_PRIORITIZED;
+ } else if (r.resultTo != null) {
+ mRunnableAt = runnableAt;
+ mRunnableAtReason = REASON_CONTAINS_RESULT_TO;
+ } else {
+ mRunnableAt = runnableAt + constants.DELAY_CACHED_MILLIS;
+ mRunnableAtReason = REASON_CACHED;
+ }
+ }
+ } else {
+ // This record isn't deferrable
+ mRunnableAt = runnableAt + constants.DELAY_CACHED_MILLIS;
+ mRunnableAtReason = REASON_CACHED;
+ }
+ } else if (mCountResultTo > 0) {
+ // All resultTo broadcasts are infinitely deferrable, so if the app
+ // is already cached, they'll be deferred on the line above
+ mRunnableAt = runnableAt;
+ mRunnableAtReason = REASON_CONTAINS_RESULT_TO;
} else {
mRunnableAt = runnableAt + constants.DELAY_NORMAL_MILLIS;
mRunnableAtReason = REASON_NORMAL;
@@ -907,6 +990,15 @@
mRunnableAt = Math.min(mRunnableAt, runnableAt);
mRunnableAtReason = REASON_MAX_PENDING;
}
+
+ if (VERBOSE) {
+ Trace.instantForTrack(Trace.TRACE_TAG_ACTIVITY_MANAGER, "BroadcastQueue",
+ ((app != null) ? app.processName : "(null)")
+ + ":" + r.intent.toString() + ":"
+ + r.deferUntilActive
+ + ":" + mRunnableAt + " " + reasonToString(mRunnableAtReason)
+ + ":" + ((app != null) ? app.isCached() : "false"));
+ }
} else {
mRunnableAt = Long.MAX_VALUE;
mRunnableAtReason = REASON_EMPTY;
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
index a994b1d..d819bfc 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -385,6 +385,8 @@
// If app isn't running, and there's nothing in the queue, clean up
if (queue.isEmpty() && !queue.isActive() && !queue.isProcessWarm()) {
removeProcessQueue(queue.processName, queue.uid);
+ } else {
+ updateQueueDeferred(queue);
}
}
@@ -637,11 +639,34 @@
final ArraySet<BroadcastRecord> replacedBroadcasts = new ArraySet<>();
final BroadcastConsumer replacedBroadcastConsumer =
(record, i) -> replacedBroadcasts.add(record);
+ boolean enqueuedBroadcast = false;
+
for (int i = 0; i < r.receivers.size(); i++) {
final Object receiver = r.receivers.get(i);
final BroadcastProcessQueue queue = getOrCreateProcessQueue(
getReceiverProcessName(receiver), getReceiverUid(receiver));
- queue.enqueueOrReplaceBroadcast(r, i, replacedBroadcastConsumer);
+
+ boolean wouldBeSkipped = false;
+ if (receiver instanceof ResolveInfo) {
+ // If the app is running but would not have been started if the process weren't
+ // running, we're going to deliver the broadcast but mark that it's not a manifest
+ // broadcast that would have started the app. This allows BroadcastProcessQueue to
+ // defer the broadcast as though it were a normal runtime receiver.
+ wouldBeSkipped = (mSkipPolicy.shouldSkipMessage(r, receiver) != null);
+ if (wouldBeSkipped && queue.app == null && !queue.getActiveViaColdStart()) {
+ // Skip receiver if there's no running app, the app is not being started, and
+ // the app wouldn't be launched for this broadcast
+ setDeliveryState(null, null, r, i, receiver, BroadcastRecord.DELIVERY_SKIPPED,
+ "skipped by policy to avoid cold start");
+ continue;
+ }
+ }
+ enqueuedBroadcast = true;
+ queue.enqueueOrReplaceBroadcast(r, i, replacedBroadcastConsumer, wouldBeSkipped);
+ if (r.isDeferUntilActive() && queue.isDeferredUntilActive()) {
+ setDeliveryState(queue, null, r, i, receiver, BroadcastRecord.DELIVERY_DEFERRED,
+ "deferred at enqueue time");
+ }
updateRunnableList(queue);
enqueueUpdateRunningList();
}
@@ -651,7 +676,7 @@
skipAndCancelReplacedBroadcasts(replacedBroadcasts);
// If nothing to dispatch, send any pending result immediately
- if (r.receivers.isEmpty()) {
+ if (r.receivers.isEmpty() || !enqueuedBroadcast) {
scheduleResultTo(r);
notifyFinishBroadcast(r);
}
@@ -1195,11 +1220,19 @@
@NonNull Object receiver, @DeliveryState int newDeliveryState, String reason) {
final int cookie = traceBegin("setDeliveryState");
final int oldDeliveryState = getDeliveryState(r, index);
+ boolean checkFinished = false;
// Only apply state when we haven't already reached a terminal state;
// this is how we ignore racing timeout messages
if (!isDeliveryStateTerminal(oldDeliveryState)) {
r.setDeliveryState(index, newDeliveryState);
+ if (oldDeliveryState == BroadcastRecord.DELIVERY_DEFERRED) {
+ r.deferredCount--;
+ } else if (newDeliveryState == BroadcastRecord.DELIVERY_DEFERRED) {
+ // If we're deferring a broadcast, maybe that's enough to unblock the final callback
+ r.deferredCount++;
+ checkFinished = true;
+ }
}
// Emit any relevant tracing results when we're changing the delivery
@@ -1217,7 +1250,8 @@
// bookkeeping to update for ordered broadcasts
if (!isDeliveryStateTerminal(oldDeliveryState)
&& isDeliveryStateTerminal(newDeliveryState)) {
- if (newDeliveryState != BroadcastRecord.DELIVERY_DELIVERED) {
+ if (DEBUG_BROADCAST
+ && newDeliveryState != BroadcastRecord.DELIVERY_DELIVERED) {
logw("Delivery state of " + r + " to " + receiver
+ " via " + app + " changed from "
+ deliveryStateToString(oldDeliveryState) + " to "
@@ -1226,9 +1260,12 @@
r.terminalCount++;
notifyFinishReceiver(queue, r, index, receiver);
-
- // When entire ordered broadcast finished, deliver final result
- final boolean recordFinished = (r.terminalCount == r.receivers.size());
+ checkFinished = true;
+ }
+ // When entire ordered broadcast finished, deliver final result
+ if (checkFinished) {
+ final boolean recordFinished =
+ ((r.terminalCount + r.deferredCount) == r.receivers.size());
if (recordFinished) {
scheduleResultTo(r);
}
@@ -1329,6 +1366,16 @@
r.resultExtras = null;
};
+ private final BroadcastConsumer mBroadcastConsumerDefer = (r, i) -> {
+ setDeliveryState(null, null, r, i, r.receivers.get(i), BroadcastRecord.DELIVERY_DEFERRED,
+ "mBroadcastConsumerDefer");
+ };
+
+ private final BroadcastConsumer mBroadcastConsumerUndoDefer = (r, i) -> {
+ setDeliveryState(null, null, r, i, r.receivers.get(i), BroadcastRecord.DELIVERY_PENDING,
+ "mBroadcastConsumerUndoDefer");
+ };
+
/**
* Verify that all known {@link #mProcessQueues} are in the state tested by
* the given {@link Predicate}.
@@ -1392,6 +1439,21 @@
}
}
+ private void updateQueueDeferred(
+ @NonNull BroadcastProcessQueue leaf) {
+ if (leaf.isDeferredUntilActive()) {
+ leaf.forEachMatchingBroadcast((r, i) -> {
+ return r.deferUntilActive && (r.getDeliveryState(i)
+ == BroadcastRecord.DELIVERY_PENDING);
+ }, mBroadcastConsumerDefer, false);
+ } else if (leaf.hasDeferredBroadcasts()) {
+ leaf.forEachMatchingBroadcast((r, i) -> {
+ return r.deferUntilActive && (r.getDeliveryState(i)
+ == BroadcastRecord.DELIVERY_DEFERRED);
+ }, mBroadcastConsumerUndoDefer, false);
+ }
+ }
+
@Override
public void start(@NonNull ContentResolver resolver) {
mFgConstants.startObserving(mHandler, resolver);
@@ -1404,6 +1466,7 @@
BroadcastProcessQueue leaf = mProcessQueues.get(uid);
while (leaf != null) {
leaf.setProcessCached(cached);
+ updateQueueDeferred(leaf);
updateRunnableList(leaf);
leaf = leaf.processNameNext;
}
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 1d4d425..9679fb8 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -88,6 +88,7 @@
final boolean interactive; // originated from user interaction?
final boolean initialSticky; // initial broadcast from register to sticky?
final boolean prioritized; // contains more than one priority tranche
+ final boolean deferUntilActive; // infinitely deferrable broadcast
final int userId; // user id this broadcast was for
final @Nullable String resolvedType; // the resolved data type
final @Nullable String[] requiredPermissions; // permissions the caller has required
@@ -97,6 +98,7 @@
final @Nullable BroadcastOptions options; // BroadcastOptions supplied by caller
final @NonNull List<Object> receivers; // contains BroadcastFilter and ResolveInfo
final @DeliveryState int[] delivery; // delivery state of each receiver
+ final boolean[] deferredUntilActive; // whether each receiver is infinitely deferred
final int[] blockedUntilTerminalCount; // blocked until count of each receiver
@Nullable ProcessRecord resultToApp; // who receives final result if non-null
@Nullable IIntentReceiver resultTo; // who receives final result if non-null
@@ -130,6 +132,7 @@
int manifestCount; // number of manifest receivers dispatched.
int manifestSkipCount; // number of manifest receivers skipped.
int terminalCount; // number of receivers in terminal state.
+ int deferredCount; // number of receivers in deferred state.
@Nullable BroadcastQueue queue; // the outbound queue handling this broadcast
// if set to true, app's process will be temporarily allowed to start activities from background
@@ -168,6 +171,8 @@
static final int DELIVERY_SCHEDULED = 4;
/** Terminal state: failure to dispatch */
static final int DELIVERY_FAILURE = 5;
+ /** Intermediate state: currently deferred while app is cached */
+ static final int DELIVERY_DEFERRED = 6;
@IntDef(flag = false, prefix = { "DELIVERY_" }, value = {
DELIVERY_PENDING,
@@ -176,6 +181,7 @@
DELIVERY_TIMEOUT,
DELIVERY_SCHEDULED,
DELIVERY_FAILURE,
+ DELIVERY_DEFERRED,
})
@Retention(RetentionPolicy.SOURCE)
public @interface DeliveryState {}
@@ -188,6 +194,7 @@
case DELIVERY_TIMEOUT: return "TIMEOUT";
case DELIVERY_SCHEDULED: return "SCHEDULED";
case DELIVERY_FAILURE: return "FAILURE";
+ case DELIVERY_DEFERRED: return "DEFERRED";
default: return Integer.toString(deliveryState);
}
}
@@ -388,6 +395,8 @@
options = _options;
receivers = (_receivers != null) ? _receivers : EMPTY_RECEIVERS;
delivery = new int[_receivers != null ? _receivers.size() : 0];
+ deferUntilActive = options != null ? options.isDeferUntilActive() : false;
+ deferredUntilActive = new boolean[deferUntilActive ? delivery.length : 0];
blockedUntilTerminalCount = calculateBlockedUntilTerminalCount(receivers, _serialized);
scheduledTime = new long[delivery.length];
terminalTime = new long[delivery.length];
@@ -443,6 +452,8 @@
options = from.options;
receivers = from.receivers;
delivery = from.delivery;
+ deferUntilActive = from.deferUntilActive;
+ deferredUntilActive = from.deferredUntilActive;
blockedUntilTerminalCount = from.blockedUntilTerminalCount;
scheduledTime = from.scheduledTime;
terminalTime = from.terminalTime;
@@ -606,7 +617,7 @@
*/
void setDeliveryState(int index, @DeliveryState int deliveryState) {
delivery[index] = deliveryState;
-
+ if (deferUntilActive) deferredUntilActive[index] = false;
switch (deliveryState) {
case DELIVERY_DELIVERED:
case DELIVERY_SKIPPED:
@@ -617,6 +628,9 @@
case DELIVERY_SCHEDULED:
scheduledTime[index] = SystemClock.uptimeMillis();
break;
+ case DELIVERY_DEFERRED:
+ if (deferUntilActive) deferredUntilActive[index] = true;
+ break;
}
}
@@ -647,6 +661,10 @@
return (intent.getFlags() & Intent.FLAG_RECEIVER_OFFLOAD) != 0;
}
+ boolean isDeferUntilActive() {
+ return deferUntilActive;
+ }
+
/**
* Core policy determination about this broadcast's delivery prioritization
*/
diff --git a/services/core/java/com/android/server/am/BroadcastSkipPolicy.java b/services/core/java/com/android/server/am/BroadcastSkipPolicy.java
index 481ab17..6718319 100644
--- a/services/core/java/com/android/server/am/BroadcastSkipPolicy.java
+++ b/services/core/java/com/android/server/am/BroadcastSkipPolicy.java
@@ -229,12 +229,7 @@
return "Background execution disabled: receiving "
+ r.intent + " to "
+ component.flattenToShortString();
- } else if (((r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0)
- || (r.intent.getComponent() == null
- && r.intent.getPackage() == null
- && ((r.intent.getFlags()
- & Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0)
- && !isSignaturePerm(r.requiredPermissions))) {
+ } else if (disallowBackgroundStart(r)) {
mService.addBackgroundCheckViolationLocked(r.intent.getAction(),
component.getPackageName());
return "Background execution not allowed: receiving "
@@ -341,6 +336,18 @@
}
/**
+ * Determine if the given {@link BroadcastRecord} is eligible to launch processes.
+ */
+ public boolean disallowBackgroundStart(@NonNull BroadcastRecord r) {
+ return ((r.intent.getFlags() & Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0)
+ || (r.intent.getComponent() == null
+ && r.intent.getPackage() == null
+ && ((r.intent.getFlags()
+ & Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0)
+ && !isSignaturePerm(r.requiredPermissions));
+ }
+
+ /**
* Determine if the given {@link BroadcastRecord} is eligible to be sent to
* the given {@link BroadcastFilter}.
*
@@ -624,7 +631,7 @@
/**
* Return true if all given permissions are signature-only perms.
*/
- private boolean isSignaturePerm(String[] perms) {
+ private static boolean isSignaturePerm(String[] perms) {
if (perms == null) {
return false;
}
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index 4c10d58b..f54e2b0 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -1860,7 +1860,10 @@
mLastCompactionStats.remove(pid);
mLastCompactionStats.put(pid, memStats);
mCompactionStatsHistory.add(memStats);
- memStats.sendStat();
+ if (!forceCompaction) {
+ // Avoid polluting field metrics with forced compactions.
+ memStats.sendStat();
+ }
break;
default:
// We likely missed adding this category, it needs to be added
diff --git a/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java b/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java
index 5c18827..7d9b272 100644
--- a/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java
+++ b/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java
@@ -50,6 +50,8 @@
import com.android.server.infra.FrameworkResourcesServiceNameResolver;
import com.android.server.pm.KnownPackages;
+import com.google.android.collect.Sets;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -67,12 +69,10 @@
AmbientContextManagerPerUserService> {
private static final String TAG = AmbientContextManagerService.class.getSimpleName();
private static final String KEY_SERVICE_ENABLED = "service_enabled";
- private static final Set<Integer> DEFAULT_EVENT_SET = new HashSet<>(){{
- add(AmbientContextEvent.EVENT_COUGH);
- add(AmbientContextEvent.EVENT_SNORE);
- add(AmbientContextEvent.EVENT_BACK_DOUBLE_TAP);
- }
- };
+ private static final Set<Integer> DEFAULT_EVENT_SET = Sets.newHashSet(
+ AmbientContextEvent.EVENT_COUGH,
+ AmbientContextEvent.EVENT_SNORE,
+ AmbientContextEvent.EVENT_BACK_DOUBLE_TAP);
/** Default value in absence of {@link DeviceConfig} override. */
private static final boolean DEFAULT_SERVICE_ENABLED = true;
@@ -409,14 +409,6 @@
}
}
- private Set<Integer> intArrayToIntegerSet(int[] eventTypes) {
- Set<Integer> types = new HashSet<>();
- for (Integer i : eventTypes) {
- types.add(i);
- }
- return types;
- }
-
private AmbientContextManagerPerUserService.ServiceType getServiceType(String serviceName) {
final String wearableService = mContext.getResources()
.getString(R.string.config_defaultWearableSensingService);
@@ -513,6 +505,14 @@
return intArray;
}
+ private Set<Integer> intArrayToIntegerSet(int[] eventTypes) {
+ Set<Integer> types = new HashSet<>();
+ for (Integer i : eventTypes) {
+ types.add(i);
+ }
+ return types;
+ }
+
@NonNull
private static Integer[] intArrayToIntegerArray(@NonNull int[] integerSet) {
Integer[] intArray = new Integer[integerSet.length];
@@ -567,37 +567,24 @@
mContext.enforceCallingOrSelfPermission(
Manifest.permission.ACCESS_AMBIENT_CONTEXT_EVENT, TAG);
assertCalledByPackageOwner(packageName);
+
AmbientContextManagerPerUserService service =
getAmbientContextManagerPerUserServiceForEventTypes(
UserHandle.getCallingUserId(),
request.getEventTypes());
-
if (service == null) {
Slog.w(TAG, "onRegisterObserver unavailable user_id: "
+ UserHandle.getCallingUserId());
- }
-
- if (service.getServiceType() == ServiceType.DEFAULT && !mIsServiceEnabled) {
- Slog.d(TAG, "Service not available.");
- service.completeRegistration(observer,
- AmbientContextManager.STATUS_SERVICE_UNAVAILABLE);
- return;
- }
- if (service.getServiceType() == ServiceType.WEARABLE && !mIsWearableServiceEnabled) {
- Slog.d(TAG, "Wearable Service not available.");
- service.completeRegistration(observer,
- AmbientContextManager.STATUS_SERVICE_UNAVAILABLE);
- return;
- }
- if (containsMixedEvents(integerSetToIntArray(request.getEventTypes()))) {
- Slog.d(TAG, "AmbientContextEventRequest contains mixed events,"
- + " this is not supported.");
- service.completeRegistration(observer,
- AmbientContextManager.STATUS_NOT_SUPPORTED);
return;
}
- service.onRegisterObserver(request, packageName, observer);
+ int statusCode = checkStatusCode(
+ service, integerSetToIntArray(request.getEventTypes()));
+ if (statusCode == AmbientContextManager.STATUS_SUCCESS) {
+ service.onRegisterObserver(request, packageName, observer);
+ } else {
+ service.completeRegistration(observer, statusCode);
+ }
}
@Override
@@ -606,10 +593,10 @@
Manifest.permission.ACCESS_AMBIENT_CONTEXT_EVENT, TAG);
assertCalledByPackageOwner(callingPackage);
- AmbientContextManagerPerUserService service = null;
for (ClientRequest cr : mExistingClientRequests) {
if (cr.getPackageName().equals(callingPackage)) {
- service = getAmbientContextManagerPerUserServiceForEventTypes(
+ AmbientContextManagerPerUserService service =
+ getAmbientContextManagerPerUserServiceForEventTypes(
UserHandle.getCallingUserId(), cr.getRequest().getEventTypes());
if (service != null) {
service.onUnregisterObserver(callingPackage);
@@ -635,34 +622,18 @@
getAmbientContextManagerPerUserServiceForEventTypes(
UserHandle.getCallingUserId(), intArrayToIntegerSet(eventTypes));
if (service == null) {
- Slog.w(TAG, "onQueryServiceStatus unavailable user_id: "
+ Slog.w(TAG, "queryServiceStatus unavailable user_id: "
+ UserHandle.getCallingUserId());
- }
-
- if (service.getServiceType() == ServiceType.DEFAULT && !mIsServiceEnabled) {
- Slog.d(TAG, "Service not available.");
- service.sendStatusCallback(statusCallback,
- AmbientContextManager.STATUS_SERVICE_UNAVAILABLE);
- return;
- }
- if (service.getServiceType() == ServiceType.WEARABLE
- && !mIsWearableServiceEnabled) {
- Slog.d(TAG, "Wearable Service not available.");
- service.sendStatusCallback(statusCallback,
- AmbientContextManager.STATUS_SERVICE_UNAVAILABLE);
return;
}
- if (containsMixedEvents(eventTypes)) {
- Slog.d(TAG, "AmbientContextEventRequest contains mixed events,"
- + " this is not supported.");
- service.sendStatusCallback(statusCallback,
- AmbientContextManager.STATUS_NOT_SUPPORTED);
- return;
+ int statusCode = checkStatusCode(service, eventTypes);
+ if (statusCode == AmbientContextManager.STATUS_SUCCESS) {
+ service.onQueryServiceStatus(eventTypes, callingPackage,
+ statusCallback);
+ } else {
+ service.sendStatusCallback(statusCallback, statusCode);
}
-
- service.onQueryServiceStatus(eventTypes, callingPackage,
- statusCallback);
}
}
@@ -708,5 +679,22 @@
new AmbientContextShellCommand(AmbientContextManagerService.this).exec(
this, in, out, err, args, callback, resultReceiver);
}
+
+ private int checkStatusCode(AmbientContextManagerPerUserService service, int[] eventTypes) {
+ if (service.getServiceType() == ServiceType.DEFAULT && !mIsServiceEnabled) {
+ Slog.d(TAG, "Service not enabled.");
+ return AmbientContextManager.STATUS_SERVICE_UNAVAILABLE;
+ }
+ if (service.getServiceType() == ServiceType.WEARABLE && !mIsWearableServiceEnabled) {
+ Slog.d(TAG, "Wearable Service not available.");
+ return AmbientContextManager.STATUS_SERVICE_UNAVAILABLE;
+ }
+ if (containsMixedEvents(eventTypes)) {
+ Slog.d(TAG, "AmbientContextEventRequest contains mixed events,"
+ + " this is not supported.");
+ return AmbientContextManager.STATUS_NOT_SUPPORTED;
+ }
+ return AmbientContextManager.STATUS_SUCCESS;
+ }
}
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 78bff95..58ddd9c 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -3717,9 +3717,11 @@
setRingerMode(getNewRingerMode(stream, index, flags),
TAG + ".onSetStreamVolume", false /*external*/);
}
- // setting non-zero volume for a muted stream unmutes the stream and vice versa,
+ // setting non-zero volume for a muted stream unmutes the stream and vice versa
+ // (only when changing volume for the current device),
// except for BT SCO stream where only explicit mute is allowed to comply to BT requirements
- if (streamType != AudioSystem.STREAM_BLUETOOTH_SCO) {
+ if ((streamType != AudioSystem.STREAM_BLUETOOTH_SCO)
+ && (getDeviceForStream(stream) == device)) {
mStreamStates[stream].mute(index == 0);
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index cb409fe..0248010 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -125,7 +125,7 @@
return proto.getBytes();
}
- @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public List<FaceSensorPropertiesInternal> getSensorPropertiesInternal(
String opPackageName) {
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/ProgramInfoCache.java b/services/core/java/com/android/server/broadcastradio/aidl/ProgramInfoCache.java
index 39b1354..c9ae735 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/ProgramInfoCache.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/ProgramInfoCache.java
@@ -86,12 +86,8 @@
}
@VisibleForTesting
- boolean programInfosAreExactly(RadioManager.ProgramInfo... programInfos) {
- Map<ProgramSelector.Identifier, RadioManager.ProgramInfo> expectedMap = new ArrayMap<>();
- for (int i = 0; i < programInfos.length; i++) {
- expectedMap.put(programInfos[i].getSelector().getPrimaryId(), programInfos[i]);
- }
- return expectedMap.equals(mProgramInfoMap);
+ List<RadioManager.ProgramInfo> toProgramInfoList() {
+ return new ArrayList<>(mProgramInfoMap.values());
}
@Override
diff --git a/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java b/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
index e3ea1a6..974c04b 100644
--- a/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
+++ b/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
@@ -68,11 +68,6 @@
public abstract void onAppsOnVirtualDeviceChanged();
/**
- * Validate the virtual device.
- */
- public abstract boolean isValidVirtualDevice(IVirtualDevice virtualDevice);
-
- /**
* Gets the owner uid for a deviceId.
*
* @param deviceId which device we're asking about
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index dcc98e1..bde14ee 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -49,6 +49,7 @@
import android.content.IntentFilter;
import android.content.PeriodicSync;
import android.content.ServiceConnection;
+import android.content.SharedPreferences;
import android.content.SyncActivityTooManyDeletes;
import android.content.SyncAdapterType;
import android.content.SyncAdaptersCache;
@@ -205,13 +206,6 @@
*/
private static final long SYNC_DELAY_ON_CONFLICT = 10*1000; // 10 seconds
- /**
- * Generate job ids in the range [MIN_SYNC_JOB_ID, MAX_SYNC_JOB_ID) to avoid conflicts with
- * other jobs scheduled by the system process.
- */
- private static final int MIN_SYNC_JOB_ID = 100000;
- private static final int MAX_SYNC_JOB_ID = 110000;
-
private static final String SYNC_WAKE_LOCK_PREFIX = "*sync*/";
private static final String HANDLE_SYNC_ALARM_WAKE_LOCK = "SyncManagerHandleSyncAlarm";
private static final String SYNC_LOOP_WAKE_LOCK = "SyncLoopWakeLock";
@@ -229,6 +223,9 @@
private static final int SYNC_ADAPTER_CONNECTION_FLAGS = Context.BIND_AUTO_CREATE
| Context.BIND_NOT_FOREGROUND | Context.BIND_ALLOW_OOM_MANAGEMENT;
+ private static final String PREF_KEY_SYNC_JOB_NAMESPACE_MIGRATED =
+ "sync_job_namespace_migrated";
+
/** Singleton instance. */
@GuardedBy("SyncManager.class")
private static SyncManager sInstance;
@@ -242,12 +239,11 @@
volatile private PowerManager.WakeLock mSyncManagerWakeLock;
volatile private boolean mDataConnectionIsConnected = false;
- private volatile int mNextJobIdOffset = 0;
+ private volatile int mNextJobId = 0;
private final NotificationManager mNotificationMgr;
private final IBatteryStats mBatteryStats;
private JobScheduler mJobScheduler;
- private JobSchedulerInternal mJobSchedulerInternal;
private SyncStorageEngine mSyncStorageEngine;
@@ -281,24 +277,19 @@
}
private int getUnusedJobIdH() {
- final int maxNumSyncJobIds = MAX_SYNC_JOB_ID - MIN_SYNC_JOB_ID;
- final List<JobInfo> pendingJobs = mJobSchedulerInternal.getSystemScheduledPendingJobs();
- for (int i = 0; i < maxNumSyncJobIds; ++i) {
- int newJobId = MIN_SYNC_JOB_ID + ((mNextJobIdOffset + i) % maxNumSyncJobIds);
- if (!isJobIdInUseLockedH(newJobId, pendingJobs)) {
- mNextJobIdOffset = (mNextJobIdOffset + i + 1) % maxNumSyncJobIds;
- return newJobId;
- }
+ final List<JobInfo> pendingJobs = mJobScheduler.getAllPendingJobs();
+ while (isJobIdInUseLockedH(mNextJobId, pendingJobs)) {
+ // SyncManager jobs are placed in their own namespace. Since there's no chance of
+ // conflicting with other parts of the system, we can just keep incrementing until
+ // we find an unused ID.
+ mNextJobId++;
}
- // We've used all 10,000 intended job IDs.... We're probably in a world of pain right now :/
- Slog.wtf(TAG, "All " + maxNumSyncJobIds + " possible sync job IDs are taken :/");
- mNextJobIdOffset = (mNextJobIdOffset + 1) % maxNumSyncJobIds;
- return MIN_SYNC_JOB_ID + mNextJobIdOffset;
+ return mNextJobId;
}
private List<SyncOperation> getAllPendingSyncs() {
verifyJobScheduler();
- List<JobInfo> pendingJobs = mJobSchedulerInternal.getSystemScheduledPendingJobs();
+ List<JobInfo> pendingJobs = mJobScheduler.getAllPendingJobs();
final int numJobs = pendingJobs.size();
final List<SyncOperation> pendingSyncs = new ArrayList<>(numJobs);
for (int i = 0; i < numJobs; ++i) {
@@ -306,6 +297,8 @@
SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras());
if (op != null) {
pendingSyncs.add(op);
+ } else {
+ Slog.wtf(TAG, "Non-sync job inside of SyncManager's namespace");
}
}
return pendingSyncs;
@@ -491,6 +484,31 @@
});
}
+ /**
+ * Migrate syncs from the default job namespace to SyncManager's namespace if they haven't been
+ * migrated already.
+ */
+ private void migrateSyncJobNamespaceIfNeeded() {
+ final SharedPreferences prefs = mContext.getSharedPreferences(
+ mSyncStorageEngine.getSyncDir(), Context.MODE_PRIVATE);
+ if (prefs.getBoolean(PREF_KEY_SYNC_JOB_NAMESPACE_MIGRATED, false)) {
+ return;
+ }
+ final List<JobInfo> pendingJobs = getJobSchedulerInternal().getSystemScheduledPendingJobs();
+ final JobScheduler jobSchedulerDefaultNamespace =
+ mContext.getSystemService(JobScheduler.class);
+ for (int i = pendingJobs.size() - 1; i >= 0; --i) {
+ final JobInfo job = pendingJobs.get(i);
+ final SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras());
+ if (op != null) {
+ // This is a sync. Move it over to SyncManager's namespace.
+ mJobScheduler.schedule(job);
+ jobSchedulerDefaultNamespace.cancel(job.getId());
+ }
+ }
+ prefs.edit().putBoolean(PREF_KEY_SYNC_JOB_NAMESPACE_MIGRATED, true).apply();
+ }
+
private synchronized void verifyJobScheduler() {
if (mJobScheduler != null) {
return;
@@ -500,10 +518,12 @@
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.d(TAG, "initializing JobScheduler object.");
}
- mJobScheduler = (JobScheduler) mContext.getSystemService(
- Context.JOB_SCHEDULER_SERVICE);
- mJobSchedulerInternal = getJobSchedulerInternal();
- // Get all persisted syncs from JobScheduler
+ // Use a dedicated namespace to avoid conflicts with other jobs
+ // scheduled by the system process.
+ mJobScheduler = mContext.getSystemService(JobScheduler.class)
+ .forNamespace("SyncManager");
+ migrateSyncJobNamespaceIfNeeded();
+ // Get all persisted syncs from JobScheduler in the SyncManager namespace.
List<JobInfo> pendingJobs = mJobScheduler.getAllPendingJobs();
int numPersistedPeriodicSyncs = 0;
@@ -519,6 +539,8 @@
// shown on the settings activity.
mSyncStorageEngine.markPending(op.target, true);
}
+ } else {
+ Slog.wtf(TAG, "Non-sync job inside of SyncManager namespace");
}
}
final String summary = "Loaded persisted syncs: "
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index 9c1cf38..f7468fc 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -21,6 +21,7 @@
import android.accounts.Account;
import android.accounts.AccountAndUser;
import android.accounts.AccountManager;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.backup.BackupManager;
import android.content.ComponentName;
@@ -574,6 +575,11 @@
return sSyncStorageEngine;
}
+ @NonNull
+ File getSyncDir() {
+ return mSyncDir;
+ }
+
protected void setOnSyncRequestListener(OnSyncRequestListener listener) {
if (mSyncRequestListener == null) {
mSyncRequestListener = listener;
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 110eb1e..06b99f8 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -47,6 +47,7 @@
import android.app.AppOpsManager;
import android.app.compat.CompatChanges;
import android.companion.virtual.IVirtualDevice;
+import android.companion.virtual.VirtualDeviceManager;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.content.BroadcastReceiver;
@@ -108,6 +109,7 @@
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
import android.util.IntArray;
@@ -259,6 +261,13 @@
final SparseArray<Pair<IVirtualDevice, DisplayWindowPolicyController>>
mDisplayWindowPolicyControllers = new SparseArray<>();
+ /**
+ * Map of every internal primary display device {@link HighBrightnessModeMetadata}s indexed by
+ * {@link DisplayDevice#mUniqueId}.
+ */
+ public final ArrayMap<String, HighBrightnessModeMetadata> mHighBrightnessModeMetadataMap =
+ new ArrayMap<>();
+
// List of all currently registered display adapters.
private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
@@ -1273,12 +1282,17 @@
final Surface surface = virtualDisplayConfig.getSurface();
int flags = virtualDisplayConfig.getFlags();
if (virtualDevice != null) {
- final VirtualDeviceManagerInternal vdm =
- getLocalService(VirtualDeviceManagerInternal.class);
- if (!vdm.isValidVirtualDevice(virtualDevice)) {
- throw new SecurityException("Invalid virtual device");
+ final VirtualDeviceManager vdm = mContext.getSystemService(VirtualDeviceManager.class);
+ try {
+ if (!vdm.isValidVirtualDeviceId(virtualDevice.getDeviceId())) {
+ throw new SecurityException("Invalid virtual device");
+ }
+ } catch (RemoteException ex) {
+ throw new SecurityException("Unable to validate virtual device");
}
- flags |= vdm.getBaseVirtualDisplayFlags(virtualDevice);
+ final VirtualDeviceManagerInternal localVdm =
+ getLocalService(VirtualDeviceManagerInternal.class);
+ flags |= localVdm.getBaseVirtualDisplayFlags(virtualDevice);
}
if (surface != null && surface.isSingleBuffered()) {
@@ -1634,7 +1648,16 @@
DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId);
if (dpc != null) {
- dpc.onDisplayChanged();
+ final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
+ if (device == null) {
+ Slog.wtf(TAG, "Display Device is null in DisplayManagerService for display: "
+ + display.getDisplayIdLocked());
+ return;
+ }
+
+ final String uniqueId = device.getUniqueId();
+ HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId);
+ dpc.onDisplayChanged(hbmMetadata);
}
}
@@ -1692,7 +1715,15 @@
final int displayId = display.getDisplayIdLocked();
final DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId);
if (dpc != null) {
- dpc.onDisplayChanged();
+ final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
+ if (device == null) {
+ Slog.wtf(TAG, "Display Device is null in DisplayManagerService for display: "
+ + display.getDisplayIdLocked());
+ return;
+ }
+ final String uniqueId = device.getUniqueId();
+ HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId);
+ dpc.onDisplayChanged(hbmMetadata);
}
}
@@ -2645,6 +2676,31 @@
mLogicalDisplayMapper.forEachLocked(this::addDisplayPowerControllerLocked);
}
+ private HighBrightnessModeMetadata getHighBrightnessModeMetadata(LogicalDisplay display) {
+ final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
+ if (device == null) {
+ Slog.wtf(TAG, "Display Device is null in DisplayPowerController for display: "
+ + display.getDisplayIdLocked());
+ return null;
+ }
+
+ // HBM brightness mode is only applicable to internal physical displays.
+ if (display.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) {
+ return null;
+ }
+
+ final String uniqueId = device.getUniqueId();
+
+ if (mHighBrightnessModeMetadataMap.containsKey(uniqueId)) {
+ return mHighBrightnessModeMetadataMap.get(uniqueId);
+ }
+
+ // HBM Time info not present. Create a new one for this physical display.
+ HighBrightnessModeMetadata hbmInfo = new HighBrightnessModeMetadata();
+ mHighBrightnessModeMetadataMap.put(uniqueId, hbmInfo);
+ return hbmInfo;
+ }
+
@RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
private void addDisplayPowerControllerLocked(LogicalDisplay display) {
if (mPowerHandler == null) {
@@ -2660,17 +2716,23 @@
display, mSyncRoot);
final DisplayPowerControllerInterface displayPowerController;
+ // If display is internal and has a HighBrightnessModeMetadata mapping, use that.
+ // Or create a new one and use that.
+ // We also need to pass a mapping of the HighBrightnessModeTimeInfoMap to
+ // displayPowerController, so the hbm info can be correctly associated
+ // with the corresponding displaydevice.
+ HighBrightnessModeMetadata hbmMetadata = getHighBrightnessModeMetadata(display);
if (DeviceConfig.getBoolean("display_manager",
"use_newly_structured_display_power_controller", true)) {
displayPowerController = new DisplayPowerController2(
mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler,
mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting,
- () -> handleBrightnessChange(display));
+ () -> handleBrightnessChange(display), hbmMetadata);
} else {
displayPowerController = new DisplayPowerController(
mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler,
mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting,
- () -> handleBrightnessChange(display));
+ () -> handleBrightnessChange(display), hbmMetadata);
}
mDisplayPowerControllers.append(display.getDisplayIdLocked(), displayPowerController);
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 1b8f6e3..142ec68 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -388,6 +388,7 @@
private float[] mNitsRange;
private final HighBrightnessModeController mHbmController;
+ private final HighBrightnessModeMetadata mHighBrightnessModeMetadata;
private final BrightnessThrottler mBrightnessThrottler;
@@ -505,13 +506,14 @@
DisplayPowerCallbacks callbacks, Handler handler,
SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay,
BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting,
- Runnable onBrightnessChangeRunnable) {
+ Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata) {
mInjector = injector != null ? injector : new Injector();
mClock = mInjector.getClock();
mLogicalDisplay = logicalDisplay;
mDisplayId = mLogicalDisplay.getDisplayIdLocked();
mTag = "DisplayPowerController[" + mDisplayId + "]";
+ mHighBrightnessModeMetadata = hbmMetadata;
mSuspendBlockerIdUnfinishedBusiness = getSuspendBlockerUnfinishedBusinessId(mDisplayId);
mSuspendBlockerIdOnStateChanged = getSuspendBlockerOnStateChangedId(mDisplayId);
mSuspendBlockerIdProxPositive = getSuspendBlockerProxPositiveId(mDisplayId);
@@ -790,7 +792,7 @@
* Make sure DisplayManagerService.mSyncRoot is held when this is called
*/
@Override
- public void onDisplayChanged() {
+ public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata) {
final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
if (device == null) {
Slog.wtf(mTag, "Display Device is null in DisplayPowerController for display: "
@@ -812,11 +814,11 @@
mUniqueDisplayId = uniqueId;
mDisplayStatsId = mUniqueDisplayId.hashCode();
mDisplayDeviceConfig = config;
- loadFromDisplayDeviceConfig(token, info);
+ loadFromDisplayDeviceConfig(token, info, hbmMetadata);
- // Since the underlying display-device changed, we really don't know the
- // last command that was sent to change it's state. Lets assume it is off and we
- // trigger a change immediately.
+ /// Since the underlying display-device changed, we really don't know the
+ // last command that was sent to change it's state. Lets assume it is unknown so
+ // that we trigger a change immediately.
mPowerState.resetScreenState();
}
if (mIsEnabled != isEnabled || mIsInTransition != isInTransition) {
@@ -864,7 +866,8 @@
}
}
- private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info) {
+ private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info,
+ HighBrightnessModeMetadata hbmMetadata) {
// All properties that depend on the associated DisplayDevice and the DDC must be
// updated here.
loadBrightnessRampRates();
@@ -877,6 +880,7 @@
mBrightnessRampIncreaseMaxTimeMillis,
mBrightnessRampDecreaseMaxTimeMillis);
}
+ mHbmController.setHighBrightnessModeMetadata(hbmMetadata);
mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId,
mDisplayDeviceConfig.getHighBrightnessModeData(),
new HighBrightnessModeController.HdrBrightnessDeviceConfig() {
@@ -1961,7 +1965,7 @@
if (mAutomaticBrightnessController != null) {
mAutomaticBrightnessController.update();
}
- }, mContext);
+ }, mHighBrightnessModeMetadata, mContext);
}
private BrightnessThrottler createBrightnessThrottlerLocked() {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index bb8132f3..96342f3 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -328,6 +328,7 @@
private float[] mNitsRange;
private final HighBrightnessModeController mHbmController;
+ private final HighBrightnessModeMetadata mHighBrightnessModeMetadata;
private final BrightnessThrottler mBrightnessThrottler;
@@ -432,7 +433,7 @@
DisplayPowerCallbacks callbacks, Handler handler,
SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay,
BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting,
- Runnable onBrightnessChangeRunnable) {
+ Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata) {
mInjector = injector != null ? injector : new Injector();
mClock = mInjector.getClock();
@@ -448,6 +449,7 @@
mDisplayPowerProximityStateController = mInjector.getDisplayPowerProximityStateController(
mWakelockController, mDisplayDeviceConfig, mHandler.getLooper(),
() -> updatePowerState(), mDisplayId, mSensorManager);
+ mHighBrightnessModeMetadata = hbmMetadata;
mDisplayStateController = new DisplayStateController(mDisplayPowerProximityStateController);
mTag = "DisplayPowerController2[" + mDisplayId + "]";
@@ -707,7 +709,7 @@
* Make sure DisplayManagerService.mSyncRoot lock is held when this is called
*/
@Override
- public void onDisplayChanged() {
+ public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata) {
final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
if (device == null) {
Slog.wtf(mTag, "Display Device is null in DisplayPowerController2 for display: "
@@ -721,6 +723,7 @@
final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
final boolean isEnabled = mLogicalDisplay.isEnabledLocked();
final boolean isInTransition = mLogicalDisplay.isInTransitionLocked();
+
mHandler.post(() -> {
boolean changed = false;
if (mDisplayDevice != device) {
@@ -729,7 +732,7 @@
mUniqueDisplayId = uniqueId;
mDisplayStatsId = mUniqueDisplayId.hashCode();
mDisplayDeviceConfig = config;
- loadFromDisplayDeviceConfig(token, info);
+ loadFromDisplayDeviceConfig(token, info, hbmMetadata);
mDisplayPowerProximityStateController.notifyDisplayDeviceChanged(config);
// Since the underlying display-device changed, we really don't know the
@@ -778,7 +781,8 @@
}
}
- private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info) {
+ private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info,
+ HighBrightnessModeMetadata hbmMetadata) {
// All properties that depend on the associated DisplayDevice and the DDC must be
// updated here.
loadBrightnessRampRates();
@@ -790,6 +794,7 @@
mBrightnessRampIncreaseMaxTimeMillis,
mBrightnessRampDecreaseMaxTimeMillis);
}
+ mHbmController.setHighBrightnessModeMetadata(hbmMetadata);
mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId,
mDisplayDeviceConfig.getHighBrightnessModeData(),
new HighBrightnessModeController.HdrBrightnessDeviceConfig() {
@@ -1192,7 +1197,9 @@
&& Display.isDozeState(state);
final boolean autoBrightnessEnabled = mUseAutoBrightness
&& (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
- && Float.isNaN(brightnessState)
+ && (Float.isNaN(brightnessState)
+ || mBrightnessReasonTemp.getReason() == BrightnessReason.REASON_TEMPORARY
+ || mBrightnessReasonTemp.getReason() == BrightnessReason.REASON_BOOST)
&& mAutomaticBrightnessController != null;
final boolean autoBrightnessDisabledDueToDisplayOff = mUseAutoBrightness
&& !(state == Display.STATE_ON || autoBrightnessEnabledInDoze);
@@ -1740,7 +1747,7 @@
if (mAutomaticBrightnessController != null) {
mAutomaticBrightnessController.update();
}
- }, mContext);
+ }, mHighBrightnessModeMetadata, mContext);
}
private BrightnessThrottler createBrightnessThrottlerLocked() {
diff --git a/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java b/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java
index e750ee2..7b019846 100644
--- a/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java
+++ b/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java
@@ -31,10 +31,14 @@
public interface DisplayPowerControllerInterface {
/**
- * Notified when the display is changed. We use this to apply any changes that might be needed
+ * Notified when the display is changed.
+ * We use this to apply any changes that might be needed
* when displays get swapped on foldable devices.
+ * We also pass the High brightness mode metadata like
+ * remaining time and hbm events for the corresponding
+ * physical display, to update the values correctly.
*/
- void onDisplayChanged();
+ void onDisplayChanged(HighBrightnessModeMetadata hbmInfo);
/**
* Unregisters all listeners and interrupts all running threads; halting future work.
diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java
index 7d1396d..2c257a1 100644
--- a/services/core/java/com/android/server/display/DisplayPowerState.java
+++ b/services/core/java/com/android/server/display/DisplayPowerState.java
@@ -340,20 +340,12 @@
}
/**
- * Resets the screen state to {@link Display#STATE_OFF}. Even though we do not know the last
- * state that was sent to the underlying display-device, we assume it is off.
- *
- * We do not set the screen state to {@link Display#STATE_UNKNOWN} to avoid getting in the state
- * where PhotonicModulator holds onto the lock. This happens because we currently try to keep
- * the mScreenState and mPendingState in sync, however if the screenState is set to
- * {@link Display#STATE_UNKNOWN} here, mPendingState will get progressed to this, which will
- * force the PhotonicModulator thread to wait onto the lock to take it out of that state.
- * b/262294651 for more info.
+ * Resets the screen state to unknown. Useful when the underlying display-device changes for the
+ * LogicalDisplay and we do not know the last state that was sent to it.
*/
void resetScreenState() {
- mScreenState = Display.STATE_OFF;
+ mScreenState = Display.STATE_UNKNOWN;
mScreenReady = false;
- scheduleScreenUpdate();
}
private void scheduleScreenUpdate() {
@@ -514,6 +506,8 @@
boolean valid = state != Display.STATE_UNKNOWN && !Float.isNaN(brightnessState);
boolean changed = stateChanged || backlightChanged;
if (!valid || !changed) {
+ mStateChangeInProgress = false;
+ mBacklightChangeInProgress = false;
try {
mLock.wait();
} catch (InterruptedException ex) {
diff --git a/services/core/java/com/android/server/display/HbmEvent.java b/services/core/java/com/android/server/display/HbmEvent.java
new file mode 100644
index 0000000..5675e2f
--- /dev/null
+++ b/services/core/java/com/android/server/display/HbmEvent.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 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.server.display;
+
+
+/**
+ * Represents an event in which High Brightness Mode was enabled.
+ */
+class HbmEvent {
+ private long mStartTimeMillis;
+ private long mEndTimeMillis;
+
+ HbmEvent(long startTimeMillis, long endTimeMillis) {
+ this.mStartTimeMillis = startTimeMillis;
+ this.mEndTimeMillis = endTimeMillis;
+ }
+
+ public long getStartTimeMillis() {
+ return mStartTimeMillis;
+ }
+
+ public long getEndTimeMillis() {
+ return mEndTimeMillis;
+ }
+
+ @Override
+ public String toString() {
+ return "HbmEvent: {startTimeMillis:" + mStartTimeMillis + ", endTimeMillis: "
+ + mEndTimeMillis + "}, total: "
+ + ((mEndTimeMillis - mStartTimeMillis) / 1000) + "]";
+ }
+}
diff --git a/services/core/java/com/android/server/display/HighBrightnessModeController.java b/services/core/java/com/android/server/display/HighBrightnessModeController.java
index f98c7df..2c843a4 100644
--- a/services/core/java/com/android/server/display/HighBrightnessModeController.java
+++ b/services/core/java/com/android/server/display/HighBrightnessModeController.java
@@ -105,30 +105,23 @@
private int mHbmStatsState = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_OFF;
/**
- * If HBM is currently running, this is the start time for the current HBM session.
+ * If HBM is currently running, this is the start time and set of all events,
+ * for the current HBM session.
*/
- private long mRunningStartTimeMillis = -1;
-
- /**
- * Queue of previous HBM-events ordered from most recent to least recent.
- * Meant to store only the events that fall into the most recent
- * {@link HighBrightnessModeData#timeWindowMillis mHbmData.timeWindowMillis}.
- */
- private final ArrayDeque<HbmEvent> mEvents = new ArrayDeque<>();
-
+ private HighBrightnessModeMetadata mHighBrightnessModeMetadata = null;
HighBrightnessModeController(Handler handler, int width, int height, IBinder displayToken,
String displayUniqueId, float brightnessMin, float brightnessMax,
HighBrightnessModeData hbmData, HdrBrightnessDeviceConfig hdrBrightnessCfg,
- Runnable hbmChangeCallback, Context context) {
+ Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata, Context context) {
this(new Injector(), handler, width, height, displayToken, displayUniqueId, brightnessMin,
- brightnessMax, hbmData, hdrBrightnessCfg, hbmChangeCallback, context);
+ brightnessMax, hbmData, hdrBrightnessCfg, hbmChangeCallback, hbmMetadata, context);
}
@VisibleForTesting
HighBrightnessModeController(Injector injector, Handler handler, int width, int height,
IBinder displayToken, String displayUniqueId, float brightnessMin, float brightnessMax,
HighBrightnessModeData hbmData, HdrBrightnessDeviceConfig hdrBrightnessCfg,
- Runnable hbmChangeCallback, Context context) {
+ Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata, Context context) {
mInjector = injector;
mContext = context;
mClock = injector.getClock();
@@ -137,6 +130,7 @@
mBrightnessMin = brightnessMin;
mBrightnessMax = brightnessMax;
mHbmChangeCallback = hbmChangeCallback;
+ mHighBrightnessModeMetadata = hbmMetadata;
mSkinThermalStatusObserver = new SkinThermalStatusObserver(mInjector, mHandler);
mSettingsObserver = new SettingsObserver(mHandler);
mRecalcRunnable = this::recalculateTimeAllowance;
@@ -222,19 +216,22 @@
// If we are starting or ending a high brightness mode session, store the current
// session in mRunningStartTimeMillis, or the old one in mEvents.
- final boolean wasHbmDrainingAvailableTime = mRunningStartTimeMillis != -1;
+ final long runningStartTime = mHighBrightnessModeMetadata.getRunningStartTimeMillis();
+ final boolean wasHbmDrainingAvailableTime = runningStartTime != -1;
final boolean shouldHbmDrainAvailableTime = mBrightness > mHbmData.transitionPoint
&& !mIsHdrLayerPresent;
if (wasHbmDrainingAvailableTime != shouldHbmDrainAvailableTime) {
final long currentTime = mClock.uptimeMillis();
if (shouldHbmDrainAvailableTime) {
- mRunningStartTimeMillis = currentTime;
+ mHighBrightnessModeMetadata.setRunningStartTimeMillis(currentTime);
} else {
- mEvents.addFirst(new HbmEvent(mRunningStartTimeMillis, currentTime));
- mRunningStartTimeMillis = -1;
+ final HbmEvent hbmEvent = new HbmEvent(runningStartTime, currentTime);
+ mHighBrightnessModeMetadata.addHbmEvent(hbmEvent);
+ mHighBrightnessModeMetadata.setRunningStartTimeMillis(-1);
if (DEBUG) {
- Slog.d(TAG, "New HBM event: " + mEvents.peekFirst());
+ Slog.d(TAG, "New HBM event: "
+ + mHighBrightnessModeMetadata.getHbmEventQueue().peekFirst());
}
}
}
@@ -260,6 +257,10 @@
mSettingsObserver.stopObserving();
}
+ void setHighBrightnessModeMetadata(HighBrightnessModeMetadata hbmInfo) {
+ mHighBrightnessModeMetadata = hbmInfo;
+ }
+
void resetHbmData(int width, int height, IBinder displayToken, String displayUniqueId,
HighBrightnessModeData hbmData, HdrBrightnessDeviceConfig hdrBrightnessCfg) {
mWidth = width;
@@ -316,20 +317,22 @@
pw.println(" mBrightnessMax=" + mBrightnessMax);
pw.println(" remainingTime=" + calculateRemainingTime(mClock.uptimeMillis()));
pw.println(" mIsTimeAvailable= " + mIsTimeAvailable);
- pw.println(" mRunningStartTimeMillis=" + TimeUtils.formatUptime(mRunningStartTimeMillis));
+ pw.println(" mRunningStartTimeMillis="
+ + TimeUtils.formatUptime(mHighBrightnessModeMetadata.getRunningStartTimeMillis()));
pw.println(" mIsThermalStatusWithinLimit=" + mIsThermalStatusWithinLimit);
pw.println(" mIsBlockedByLowPowerMode=" + mIsBlockedByLowPowerMode);
pw.println(" width*height=" + mWidth + "*" + mHeight);
pw.println(" mEvents=");
final long currentTime = mClock.uptimeMillis();
long lastStartTime = currentTime;
- if (mRunningStartTimeMillis != -1) {
- lastStartTime = dumpHbmEvent(pw, new HbmEvent(mRunningStartTimeMillis, currentTime));
+ long runningStartTimeMillis = mHighBrightnessModeMetadata.getRunningStartTimeMillis();
+ if (runningStartTimeMillis != -1) {
+ lastStartTime = dumpHbmEvent(pw, new HbmEvent(runningStartTimeMillis, currentTime));
}
- for (HbmEvent event : mEvents) {
- if (lastStartTime > event.endTimeMillis) {
+ for (HbmEvent event : mHighBrightnessModeMetadata.getHbmEventQueue()) {
+ if (lastStartTime > event.getEndTimeMillis()) {
pw.println(" event: [normal brightness]: "
- + TimeUtils.formatDuration(lastStartTime - event.endTimeMillis));
+ + TimeUtils.formatDuration(lastStartTime - event.getEndTimeMillis()));
}
lastStartTime = dumpHbmEvent(pw, event);
}
@@ -338,12 +341,12 @@
}
private long dumpHbmEvent(PrintWriter pw, HbmEvent event) {
- final long duration = event.endTimeMillis - event.startTimeMillis;
+ final long duration = event.getEndTimeMillis() - event.getStartTimeMillis();
pw.println(" event: ["
- + TimeUtils.formatUptime(event.startTimeMillis) + ", "
- + TimeUtils.formatUptime(event.endTimeMillis) + "] ("
+ + TimeUtils.formatUptime(event.getStartTimeMillis()) + ", "
+ + TimeUtils.formatUptime(event.getEndTimeMillis()) + "] ("
+ TimeUtils.formatDuration(duration) + ")");
- return event.startTimeMillis;
+ return event.getStartTimeMillis();
}
private boolean isCurrentlyAllowed() {
@@ -372,13 +375,15 @@
// First, lets see how much time we've taken for any currently running
// session of HBM.
- if (mRunningStartTimeMillis > 0) {
- if (mRunningStartTimeMillis > currentTime) {
+ long runningStartTimeMillis = mHighBrightnessModeMetadata.getRunningStartTimeMillis();
+ if (runningStartTimeMillis > 0) {
+ if (runningStartTimeMillis > currentTime) {
Slog.e(TAG, "Start time set to the future. curr: " + currentTime
- + ", start: " + mRunningStartTimeMillis);
- mRunningStartTimeMillis = currentTime;
+ + ", start: " + runningStartTimeMillis);
+ mHighBrightnessModeMetadata.setRunningStartTimeMillis(currentTime);
+ runningStartTimeMillis = currentTime;
}
- timeAlreadyUsed = currentTime - mRunningStartTimeMillis;
+ timeAlreadyUsed = currentTime - runningStartTimeMillis;
}
if (DEBUG) {
@@ -387,18 +392,19 @@
// Next, lets iterate through the history of previous sessions and add those times.
final long windowstartTimeMillis = currentTime - mHbmData.timeWindowMillis;
- Iterator<HbmEvent> it = mEvents.iterator();
+ Iterator<HbmEvent> it = mHighBrightnessModeMetadata.getHbmEventQueue().iterator();
while (it.hasNext()) {
final HbmEvent event = it.next();
// If this event ended before the current Timing window, discard forever and ever.
- if (event.endTimeMillis < windowstartTimeMillis) {
+ if (event.getEndTimeMillis() < windowstartTimeMillis) {
it.remove();
continue;
}
- final long startTimeMillis = Math.max(event.startTimeMillis, windowstartTimeMillis);
- timeAlreadyUsed += event.endTimeMillis - startTimeMillis;
+ final long startTimeMillis = Math.max(event.getStartTimeMillis(),
+ windowstartTimeMillis);
+ timeAlreadyUsed += event.getEndTimeMillis() - startTimeMillis;
}
if (DEBUG) {
@@ -425,17 +431,18 @@
// Calculate the time at which we want to recalculate mIsTimeAvailable in case a lux or
// brightness change doesn't happen before then.
long nextTimeout = -1;
+ final ArrayDeque<HbmEvent> hbmEvents = mHighBrightnessModeMetadata.getHbmEventQueue();
if (mBrightness > mHbmData.transitionPoint) {
// if we're in high-lux now, timeout when we run out of allowed time.
nextTimeout = currentTime + remainingTime;
- } else if (!mIsTimeAvailable && mEvents.size() > 0) {
+ } else if (!mIsTimeAvailable && hbmEvents.size() > 0) {
// If we are not allowed...timeout when the oldest event moved outside of the timing
// window by at least minTime. Basically, we're calculating the soonest time we can
// get {@code timeMinMillis} back to us.
final long windowstartTimeMillis = currentTime - mHbmData.timeWindowMillis;
- final HbmEvent lastEvent = mEvents.peekLast();
+ final HbmEvent lastEvent = hbmEvents.peekLast();
final long startTimePlusMinMillis =
- Math.max(windowstartTimeMillis, lastEvent.startTimeMillis)
+ Math.max(windowstartTimeMillis, lastEvent.getStartTimeMillis())
+ mHbmData.timeMinMillis;
final long timeWhenMinIsGainedBack =
currentTime + (startTimePlusMinMillis - windowstartTimeMillis) - remainingTime;
@@ -459,9 +466,10 @@
+ ", mUnthrottledBrightness: " + mUnthrottledBrightness
+ ", mThrottlingReason: "
+ BrightnessInfo.briMaxReasonToString(mThrottlingReason)
- + ", RunningStartTimeMillis: " + mRunningStartTimeMillis
+ + ", RunningStartTimeMillis: "
+ + mHighBrightnessModeMetadata.getRunningStartTimeMillis()
+ ", nextTimeout: " + (nextTimeout != -1 ? (nextTimeout - currentTime) : -1)
- + ", events: " + mEvents);
+ + ", events: " + hbmEvents);
}
if (nextTimeout != -1) {
@@ -588,25 +596,6 @@
}
}
- /**
- * Represents an event in which High Brightness Mode was enabled.
- */
- private static class HbmEvent {
- public long startTimeMillis;
- public long endTimeMillis;
-
- HbmEvent(long startTimeMillis, long endTimeMillis) {
- this.startTimeMillis = startTimeMillis;
- this.endTimeMillis = endTimeMillis;
- }
-
- @Override
- public String toString() {
- return "[Event: {" + startTimeMillis + ", " + endTimeMillis + "}, total: "
- + ((endTimeMillis - startTimeMillis) / 1000) + "]";
- }
- }
-
@VisibleForTesting
class HdrListener extends SurfaceControlHdrLayerInfoListener {
@Override
diff --git a/services/core/java/com/android/server/display/HighBrightnessModeMetadata.java b/services/core/java/com/android/server/display/HighBrightnessModeMetadata.java
new file mode 100644
index 0000000..37234ff
--- /dev/null
+++ b/services/core/java/com/android/server/display/HighBrightnessModeMetadata.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 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.server.display;
+
+import java.util.ArrayDeque;
+
+
+/**
+ * Represents High Brightness Mode metadata associated
+ * with a specific internal physical display.
+ * Required for separately storing data like time information,
+ * and related events when display was in HBM mode per
+ * physical internal display.
+ */
+class HighBrightnessModeMetadata {
+ /**
+ * Queue of previous HBM-events ordered from most recent to least recent.
+ * Meant to store only the events that fall into the most recent
+ * {@link HighBrightnessModeData#timeWindowMillis mHbmData.timeWindowMillis}.
+ */
+ private final ArrayDeque<HbmEvent> mEvents = new ArrayDeque<>();
+
+ /**
+ * If HBM is currently running, this is the start time for the current HBM session.
+ */
+ private long mRunningStartTimeMillis = -1;
+
+ public long getRunningStartTimeMillis() {
+ return mRunningStartTimeMillis;
+ }
+
+ public void setRunningStartTimeMillis(long setTime) {
+ mRunningStartTimeMillis = setTime;
+ }
+
+ public ArrayDeque<HbmEvent> getHbmEventQueue() {
+ return mEvents;
+ }
+
+ public void addHbmEvent(HbmEvent hbmEvent) {
+ mEvents.addFirst(hbmEvent);
+ }
+}
+
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index a66cbb8..bb342ff 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -469,7 +469,7 @@
synchronized (mSyncRoot) {
mBootCompleted = true;
if (mPendingDeviceState != DeviceStateManager.INVALID_DEVICE_STATE) {
- setDeviceStateLocked(mPendingDeviceState, false);
+ setDeviceStateLocked(mPendingDeviceState, /* isOverrideActive= */ false);
}
}
}
diff --git a/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java
index f8063f3..7d759ca 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java
@@ -48,7 +48,6 @@
BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_TEMPORARY,
mTemporaryScreenBrightness,
mTemporaryScreenBrightness);
- mTemporaryScreenBrightness = Float.NaN;
return displayBrightnessState;
}
diff --git a/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java b/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java
index 11a4294..6cfe921 100644
--- a/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java
+++ b/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java
@@ -21,6 +21,7 @@
import android.app.IGrammaticalInflectionManager;
import android.content.Context;
import android.os.IBinder;
+import android.os.SystemProperties;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -34,6 +35,8 @@
public class GrammaticalInflectionService extends SystemService {
private final ActivityTaskManagerInternal mActivityTaskManagerInternal;
+ private static final String GRAMMATICAL_INFLECTION_ENABLED =
+ "i18n.grammatical_Inflection.enabled";
/**
* Initializes the system service.
@@ -67,6 +70,10 @@
private void setRequestedApplicationGrammaticalGender(
String appPackageName, int userId, int gender) {
+ if (!SystemProperties.getBoolean(GRAMMATICAL_INFLECTION_ENABLED, true)) {
+ return;
+ }
+
final ActivityTaskManagerInternal.PackageConfigurationUpdater updater =
mActivityTaskManagerInternal.createPackageConfigurationUpdater(appPackageName,
userId);
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index 5353092..6b5af88 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -619,6 +619,8 @@
})
@interface HpdSignalType {}
+ static final String DEVICE_CONFIG_FEATURE_FLAG_SOUNDBAR_MODE = "soundbar_mode";
+
private Constants() {
/* cannot be instantiated */
}
diff --git a/services/core/java/com/android/server/hdmi/DeviceConfigWrapper.java b/services/core/java/com/android/server/hdmi/DeviceConfigWrapper.java
new file mode 100644
index 0000000..f391897
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/DeviceConfigWrapper.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 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.server.hdmi;
+
+import android.provider.DeviceConfig;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Abstraction around {@link DeviceConfig} to allow faking DeviceConfig in tests.
+ */
+public class DeviceConfigWrapper {
+ private static final String TAG = "DeviceConfigWrapper";
+
+ boolean getBoolean(String name, boolean defaultValue) {
+ return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_HDMI_CONTROL, name, defaultValue);
+ }
+
+ void addOnPropertiesChangedListener(Executor mainExecutor,
+ DeviceConfig.OnPropertiesChangedListener onPropertiesChangedListener) {
+ DeviceConfig.addOnPropertiesChangedListener(
+ DeviceConfig.NAMESPACE_HDMI_CONTROL, mainExecutor, onPropertiesChangedListener);
+ }
+}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java
index d1354d1..ceb8785 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java
@@ -19,16 +19,16 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.hardware.hdmi.HdmiPortInfo;
-import android.hardware.tv.cec.CecMessage;
-import android.hardware.tv.cec.IHdmiCec;
-import android.hardware.tv.cec.IHdmiCecCallback;
import android.hardware.tv.cec.V1_0.HotplugEvent;
import android.hardware.tv.cec.V1_0.IHdmiCec.getPhysicalAddressCallback;
import android.hardware.tv.cec.V1_0.OptionKey;
import android.hardware.tv.cec.V1_0.Result;
import android.hardware.tv.cec.V1_0.SendMessageResult;
-import android.hardware.tv.hdmi.IHdmi;
-import android.hardware.tv.hdmi.IHdmiCallback;
+import android.hardware.tv.hdmi.cec.CecMessage;
+import android.hardware.tv.hdmi.cec.IHdmiCec;
+import android.hardware.tv.hdmi.cec.IHdmiCecCallback;
+import android.hardware.tv.hdmi.connection.IHdmiConnection;
+import android.hardware.tv.hdmi.connection.IHdmiConnectionCallback;
import android.icu.util.IllformedLocaleException;
import android.icu.util.ULocale;
import android.os.Binder;
@@ -184,7 +184,7 @@
if (controller != null) {
return controller;
}
- HdmiLogger.warning("Unable to use CEC and HDMI AIDL HALs");
+ HdmiLogger.warning("Unable to use CEC and HDMI Connection AIDL HALs");
controller = createWithNativeWrapper(service, new NativeWrapperImpl11(), atomWriter);
if (controller != null) {
@@ -911,14 +911,14 @@
private static final class NativeWrapperImplAidl
implements NativeWrapper, IBinder.DeathRecipient {
private IHdmiCec mHdmiCec;
- private IHdmi mHdmi;
+ private IHdmiConnection mHdmiConnection;
@Nullable private HdmiCecCallback mCallback;
private final Object mLock = new Object();
@Override
public String nativeInit() {
- return connectToHal() ? mHdmiCec.toString() + " " + mHdmi.toString() : null;
+ return connectToHal() ? mHdmiCec.toString() + " " + mHdmiConnection.toString() : null;
}
boolean connectToHal() {
@@ -935,15 +935,15 @@
HdmiLogger.error("Couldn't link to death : ", e);
}
- mHdmi =
- IHdmi.Stub.asInterface(
- ServiceManager.getService(IHdmi.DESCRIPTOR + "/default"));
- if (mHdmi == null) {
- HdmiLogger.error("Could not initialize HDMI AIDL HAL");
+ mHdmiConnection =
+ IHdmiConnection.Stub.asInterface(
+ ServiceManager.getService(IHdmiConnection.DESCRIPTOR + "/default"));
+ if (mHdmiConnection == null) {
+ HdmiLogger.error("Could not initialize HDMI Connection AIDL HAL");
return false;
}
try {
- mHdmi.asBinder().linkToDeath(this, 0);
+ mHdmiConnection.asBinder().linkToDeath(this, 0);
} catch (RemoteException e) {
HdmiLogger.error("Couldn't link to death : ", e);
}
@@ -954,8 +954,8 @@
public void binderDied() {
// One of the services died, try to reconnect to both.
mHdmiCec.asBinder().unlinkToDeath(this, 0);
- mHdmi.asBinder().unlinkToDeath(this, 0);
- HdmiLogger.error("HDMI or CEC service died, reconnecting");
+ mHdmiConnection.asBinder().unlinkToDeath(this, 0);
+ HdmiLogger.error("HDMI Connection or CEC service died, reconnecting");
connectToHal();
// Reconnect the callback
if (mCallback != null) {
@@ -974,7 +974,7 @@
}
try {
// Create an AIDL callback that can callback onHotplugEvent
- mHdmi.setCallback(new HdmiCallbackAidl(callback));
+ mHdmiConnection.setCallback(new HdmiConnectionCallbackAidl(callback));
} catch (RemoteException e) {
HdmiLogger.error("Couldn't initialise tv.hdmi callback : ", e);
}
@@ -1091,10 +1091,11 @@
@Override
public HdmiPortInfo[] nativeGetPortInfos() {
try {
- android.hardware.tv.hdmi.HdmiPortInfo[] hdmiPortInfos = mHdmi.getPortInfo();
+ android.hardware.tv.hdmi.connection.HdmiPortInfo[] hdmiPortInfos =
+ mHdmiConnection.getPortInfo();
HdmiPortInfo[] hdmiPortInfo = new HdmiPortInfo[hdmiPortInfos.length];
int i = 0;
- for (android.hardware.tv.hdmi.HdmiPortInfo portInfo : hdmiPortInfos) {
+ for (android.hardware.tv.hdmi.connection.HdmiPortInfo portInfo : hdmiPortInfos) {
hdmiPortInfo[i] =
new HdmiPortInfo(
portInfo.portId,
@@ -1116,7 +1117,7 @@
@Override
public boolean nativeIsConnected(int port) {
try {
- return mHdmi.isConnected(port);
+ return mHdmiConnection.isConnected(port);
} catch (RemoteException e) {
HdmiLogger.error("Failed to get connection info : ", e);
return false;
@@ -1624,10 +1625,10 @@
}
}
- private static final class HdmiCallbackAidl extends IHdmiCallback.Stub {
+ private static final class HdmiConnectionCallbackAidl extends IHdmiConnectionCallback.Stub {
private final HdmiCecCallback mHdmiCecCallback;
- HdmiCallbackAidl(HdmiCecCallback hdmiCecCallback) {
+ HdmiConnectionCallbackAidl(HdmiCecCallback hdmiCecCallback) {
mHdmiCecCallback = hdmiCecCallback;
}
@@ -1638,12 +1639,12 @@
@Override
public synchronized String getInterfaceHash() throws android.os.RemoteException {
- return IHdmiCallback.Stub.HASH;
+ return IHdmiConnectionCallback.Stub.HASH;
}
@Override
public int getInterfaceVersion() throws android.os.RemoteException {
- return IHdmiCallback.Stub.VERSION;
+ return IHdmiConnectionCallback.Stub.VERSION;
}
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index f66f8ea..f6566d8 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -86,6 +86,7 @@
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.provider.DeviceConfig;
import android.provider.Settings.Global;
import android.sysprop.HdmiProperties;
import android.text.TextUtils;
@@ -450,6 +451,9 @@
private boolean mWakeUpMessageReceived = false;
@ServiceThreadOnly
+ private boolean mSoundbarModeFeatureFlagEnabled = false;
+
+ @ServiceThreadOnly
private int mActivePortId = Constants.INVALID_PORT_ID;
// Set to true while the input change by MHL is allowed.
@@ -471,6 +475,9 @@
private TvInputManager mTvInputManager;
@Nullable
+ private DeviceConfigWrapper mDeviceConfig;
+
+ @Nullable
private PowerManagerWrapper mPowerManager;
@Nullable
@@ -525,6 +532,7 @@
mCecLocalDevices = deviceTypes;
mSettingsObserver = new SettingsObserver(mHandler);
mHdmiCecConfig = new HdmiCecConfig(context);
+ mDeviceConfig = new DeviceConfigWrapper();
mAudioDeviceVolumeManager = audioDeviceVolumeManager;
}
@@ -533,6 +541,7 @@
mCecLocalDevices = readDeviceTypes();
mSettingsObserver = new SettingsObserver(mHandler);
mHdmiCecConfig = new HdmiCecConfig(context);
+ mDeviceConfig = new DeviceConfigWrapper();
}
@VisibleForTesting
@@ -763,14 +772,6 @@
}
}
}, mServiceThreadExecutor);
- mHdmiCecConfig.registerChangeListener(HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE,
- new HdmiCecConfig.SettingChangeListener() {
- @Override
- public void onChange(String setting) {
- setSoundbarMode(mHdmiCecConfig.getIntValue(
- HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE));
- }
- }, mServiceThreadExecutor);
mHdmiCecConfig.registerChangeListener(
HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL,
new HdmiCecConfig.SettingChangeListener() {
@@ -819,9 +820,38 @@
HdmiControlManager.SETTING_NAME_EARC_ENABLED);
setEarcEnabled(enabled);
}
+ },
+ mServiceThreadExecutor);
+
+ mSoundbarModeFeatureFlagEnabled = mDeviceConfig.getBoolean(
+ Constants.DEVICE_CONFIG_FEATURE_FLAG_SOUNDBAR_MODE, false);
+
+ mDeviceConfig.addOnPropertiesChangedListener(getContext().getMainExecutor(),
+ new DeviceConfig.OnPropertiesChangedListener() {
+ @Override
+ public void onPropertiesChanged(DeviceConfig.Properties properties) {
+ mSoundbarModeFeatureFlagEnabled = properties.getBoolean(
+ Constants.DEVICE_CONFIG_FEATURE_FLAG_SOUNDBAR_MODE,
+ false);
+ boolean soundbarModeSetting = mHdmiCecConfig.getIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE)
+ == SOUNDBAR_MODE_ENABLED;
+ setSoundbarMode(soundbarModeSetting && mSoundbarModeFeatureFlagEnabled
+ ? SOUNDBAR_MODE_ENABLED : SOUNDBAR_MODE_DISABLED);
+ }
+ });
+ mHdmiCecConfig.registerChangeListener(HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE,
+ new HdmiCecConfig.SettingChangeListener() {
+ @Override
+ public void onChange(String setting) {
+ boolean soundbarModeSetting = mHdmiCecConfig.getIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE)
+ == SOUNDBAR_MODE_ENABLED;
+ setSoundbarMode(soundbarModeSetting && mSoundbarModeFeatureFlagEnabled
+ ? SOUNDBAR_MODE_ENABLED : SOUNDBAR_MODE_DISABLED);
+ }
}, mServiceThreadExecutor);
}
-
/** Returns true if the device screen is off */
boolean isScreenOff() {
return mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY).getState() == Display.STATE_OFF;
@@ -920,6 +950,11 @@
}
@VisibleForTesting
+ void setDeviceConfig(DeviceConfigWrapper deviceConfig) {
+ mDeviceConfig = deviceConfig;
+ }
+
+ @VisibleForTesting
void setPowerManager(PowerManagerWrapper powerManager) {
mPowerManager = powerManager;
}
@@ -929,6 +964,10 @@
mPowerManagerInternal = powerManagerInternal;
}
+ DeviceConfigWrapper getDeviceConfig() {
+ return mDeviceConfig;
+ }
+
PowerManagerWrapper getPowerManager() {
return mPowerManager;
}
@@ -1151,7 +1190,8 @@
if (mHdmiCecConfig.getIntValue(HdmiControlManager.CEC_SETTING_NAME_SOUNDBAR_MODE)
== SOUNDBAR_MODE_ENABLED
&& !allLocalDeviceTypes.contains(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM)
- && SystemProperties.getBoolean(Constants.PROPERTY_ARC_SUPPORT, true)) {
+ && SystemProperties.getBoolean(Constants.PROPERTY_ARC_SUPPORT, true)
+ && mSoundbarModeFeatureFlagEnabled) {
allLocalDeviceTypes.add(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
}
return allLocalDeviceTypes;
diff --git a/services/core/java/com/android/server/input/BatteryController.java b/services/core/java/com/android/server/input/BatteryController.java
index c99a7a0..993b4fd 100644
--- a/services/core/java/com/android/server/input/BatteryController.java
+++ b/services/core/java/com/android/server/input/BatteryController.java
@@ -31,6 +31,7 @@
import android.hardware.input.IInputDeviceBatteryState;
import android.hardware.input.InputManager;
import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
@@ -51,6 +52,7 @@
import java.util.Arrays;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -102,7 +104,7 @@
BatteryController(Context context, NativeInputManagerService nativeService, Looper looper) {
this(context, nativeService, looper, new UEventManager() {},
- new LocalBluetoothBatteryManager(context));
+ new LocalBluetoothBatteryManager(context, looper));
}
@VisibleForTesting
@@ -163,7 +165,7 @@
// This is the first listener that is monitoring this device.
monitor = new DeviceMonitor(deviceId);
mDeviceMonitors.put(deviceId, monitor);
- updateBluetoothMonitoring();
+ updateBluetoothBatteryMonitoring();
}
if (DEBUG) {
@@ -378,13 +380,26 @@
}
}
- private void handleBluetoothBatteryLevelChange(long eventTime, String address) {
+ private void handleBluetoothBatteryLevelChange(long eventTime, String address,
+ int batteryLevel) {
synchronized (mLock) {
final DeviceMonitor monitor = findIf(mDeviceMonitors, (m) ->
(m.mBluetoothDevice != null
&& address.equals(m.mBluetoothDevice.getAddress())));
if (monitor != null) {
- monitor.onBluetoothBatteryChanged(eventTime);
+ monitor.onBluetoothBatteryChanged(eventTime, batteryLevel);
+ }
+ }
+ }
+
+ private void handleBluetoothMetadataChange(@NonNull BluetoothDevice device, int key,
+ @Nullable byte[] value) {
+ synchronized (mLock) {
+ final DeviceMonitor monitor =
+ findIf(mDeviceMonitors, (m) -> device.equals(m.mBluetoothDevice));
+ if (monitor != null) {
+ final long eventTime = SystemClock.uptimeMillis();
+ monitor.onBluetoothMetadataChanged(eventTime, key, value);
}
}
}
@@ -514,31 +529,19 @@
isPresent ? mNative.getBatteryCapacity(deviceId) / 100.f : Float.NaN);
}
- // Queries the battery state of an input device from Bluetooth.
- private State queryBatteryStateFromBluetooth(int deviceId, long updateTime,
- @NonNull BluetoothDevice bluetoothDevice) {
- final int level = mBluetoothBatteryManager.getBatteryLevel(bluetoothDevice.getAddress());
- if (level == BluetoothDevice.BATTERY_LEVEL_BLUETOOTH_OFF
- || level == BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
- return new State(deviceId);
- }
- return new State(deviceId, updateTime, true /*isPresent*/, BatteryState.STATUS_UNKNOWN,
- level / 100.f);
- }
-
- private void updateBluetoothMonitoring() {
+ private void updateBluetoothBatteryMonitoring() {
synchronized (mLock) {
if (anyOf(mDeviceMonitors, (m) -> m.mBluetoothDevice != null)) {
// At least one input device being monitored is connected over Bluetooth.
if (mBluetoothBatteryListener == null) {
if (DEBUG) Slog.d(TAG, "Registering bluetooth battery listener");
mBluetoothBatteryListener = this::handleBluetoothBatteryLevelChange;
- mBluetoothBatteryManager.addListener(mBluetoothBatteryListener);
+ mBluetoothBatteryManager.addBatteryListener(mBluetoothBatteryListener);
}
} else if (mBluetoothBatteryListener != null) {
// No Bluetooth input devices are monitored, so remove the registered listener.
if (DEBUG) Slog.d(TAG, "Unregistering bluetooth battery listener");
- mBluetoothBatteryManager.removeListener(mBluetoothBatteryListener);
+ mBluetoothBatteryManager.removeBatteryListener(mBluetoothBatteryListener);
mBluetoothBatteryListener = null;
}
}
@@ -550,16 +553,23 @@
// Represents whether the input device has a sysfs battery node.
protected boolean mHasBattery = false;
- protected final State mBluetoothState;
@Nullable
private BluetoothDevice mBluetoothDevice;
+ long mBluetoothEventTime = 0;
+ // The battery level reported by the Bluetooth Hands-Free Profile (HPF) obtained through
+ // BluetoothDevice#getBatteryLevel().
+ int mBluetoothBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+ // The battery level and status reported through the Bluetooth device's metadata.
+ int mBluetoothMetadataBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+ int mBluetoothMetadataBatteryStatus = BatteryState.STATUS_UNKNOWN;
+ @Nullable
+ private BluetoothAdapter.OnMetadataChangedListener mBluetoothMetadataListener;
@Nullable
private UEventBatteryListener mUEventBatteryListener;
DeviceMonitor(int deviceId) {
mState = new State(deviceId);
- mBluetoothState = new State(deviceId);
// Load the initial battery state and start monitoring.
final long eventTime = SystemClock.uptimeMillis();
@@ -570,7 +580,7 @@
final State oldState = getBatteryStateForReporting();
changes.accept(eventTime);
final State newState = getBatteryStateForReporting();
- if (!oldState.equals(newState)) {
+ if (!oldState.equalsIgnoringUpdateTime(newState)) {
notifyAllListenersForDevice(newState);
}
}
@@ -594,13 +604,22 @@
final BluetoothDevice bluetoothDevice = getBluetoothDevice(deviceId);
if (!Objects.equals(mBluetoothDevice, bluetoothDevice)) {
if (DEBUG) {
- Slog.d(TAG, "Bluetooth device "
- + ((bluetoothDevice != null) ? "is" : "is not")
- + " now present for deviceId " + deviceId);
+ Slog.d(TAG, "Bluetooth device is now "
+ + ((bluetoothDevice != null) ? "" : "not")
+ + " present for deviceId " + deviceId);
}
+
+ mBluetoothBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+ stopBluetoothMetadataMonitoring();
+
mBluetoothDevice = bluetoothDevice;
- updateBluetoothMonitoring();
- updateBatteryStateFromBluetooth(eventTime);
+ updateBluetoothBatteryMonitoring();
+
+ if (mBluetoothDevice != null) {
+ mBluetoothBatteryLevel = mBluetoothBatteryManager.getBatteryLevel(
+ mBluetoothDevice.getAddress());
+ startBluetoothMetadataMonitoring(eventTime);
+ }
}
}
@@ -632,11 +651,39 @@
}
}
+ private void startBluetoothMetadataMonitoring(long eventTime) {
+ Objects.requireNonNull(mBluetoothDevice);
+
+ mBluetoothMetadataListener = BatteryController.this::handleBluetoothMetadataChange;
+ mBluetoothBatteryManager.addMetadataListener(mBluetoothDevice.getAddress(),
+ mBluetoothMetadataListener);
+ updateBluetoothMetadataState(eventTime, BluetoothDevice.METADATA_MAIN_BATTERY,
+ mBluetoothBatteryManager.getMetadata(mBluetoothDevice.getAddress(),
+ BluetoothDevice.METADATA_MAIN_BATTERY));
+ updateBluetoothMetadataState(eventTime, BluetoothDevice.METADATA_MAIN_CHARGING,
+ mBluetoothBatteryManager.getMetadata(mBluetoothDevice.getAddress(),
+ BluetoothDevice.METADATA_MAIN_CHARGING));
+ }
+
+ private void stopBluetoothMetadataMonitoring() {
+ if (mBluetoothMetadataListener == null) {
+ return;
+ }
+ Objects.requireNonNull(mBluetoothDevice);
+
+ mBluetoothBatteryManager.removeMetadataListener(
+ mBluetoothDevice.getAddress(), mBluetoothMetadataListener);
+ mBluetoothMetadataListener = null;
+ mBluetoothMetadataBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+ mBluetoothMetadataBatteryStatus = BatteryState.STATUS_UNKNOWN;
+ }
+
// This must be called when the device is no longer being monitored.
public void onMonitorDestroy() {
stopNativeMonitoring();
+ stopBluetoothMetadataMonitoring();
mBluetoothDevice = null;
- updateBluetoothMonitoring();
+ updateBluetoothBatteryMonitoring();
}
protected void updateBatteryStateFromNative(long eventTime) {
@@ -644,13 +691,6 @@
queryBatteryStateFromNative(mState.deviceId, eventTime, mHasBattery));
}
- protected void updateBatteryStateFromBluetooth(long eventTime) {
- final State bluetoothState = mBluetoothDevice == null ? new State(mState.deviceId)
- : queryBatteryStateFromBluetooth(mState.deviceId, eventTime,
- mBluetoothDevice);
- mBluetoothState.updateIfChanged(bluetoothState);
- }
-
public void onPoll(long eventTime) {
processChangesAndNotify(eventTime, this::updateBatteryStateFromNative);
}
@@ -659,8 +699,51 @@
processChangesAndNotify(eventTime, this::updateBatteryStateFromNative);
}
- public void onBluetoothBatteryChanged(long eventTime) {
- processChangesAndNotify(eventTime, this::updateBatteryStateFromBluetooth);
+ public void onBluetoothBatteryChanged(long eventTime, int bluetoothBatteryLevel) {
+ processChangesAndNotify(eventTime, (time) -> {
+ mBluetoothBatteryLevel = bluetoothBatteryLevel;
+ mBluetoothEventTime = time;
+ });
+ }
+
+ public void onBluetoothMetadataChanged(long eventTime, int key, @Nullable byte[] value) {
+ processChangesAndNotify(eventTime,
+ (time) -> updateBluetoothMetadataState(time, key, value));
+ }
+
+ private void updateBluetoothMetadataState(long eventTime, int key,
+ @Nullable byte[] value) {
+ switch (key) {
+ case BluetoothDevice.METADATA_MAIN_BATTERY:
+ mBluetoothEventTime = eventTime;
+ mBluetoothMetadataBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+ if (value != null) {
+ try {
+ mBluetoothMetadataBatteryLevel = Integer.parseInt(
+ new String(value));
+ } catch (NumberFormatException e) {
+ Slog.wtf(TAG,
+ "Failed to parse bluetooth METADATA_MAIN_BATTERY with "
+ + "value '"
+ + new String(value) + "' for device "
+ + mBluetoothDevice);
+ }
+ }
+ break;
+ case BluetoothDevice.METADATA_MAIN_CHARGING:
+ mBluetoothEventTime = eventTime;
+ if (value != null) {
+ mBluetoothMetadataBatteryStatus = Boolean.parseBoolean(
+ new String(value))
+ ? BatteryState.STATUS_CHARGING
+ : BatteryState.STATUS_DISCHARGING;
+ } else {
+ mBluetoothMetadataBatteryStatus = BatteryState.STATUS_UNKNOWN;
+ }
+ break;
+ default:
+ break;
+ }
}
public boolean requiresPolling() {
@@ -677,11 +760,25 @@
// Returns the current battery state that can be used to notify listeners BatteryController.
public State getBatteryStateForReporting() {
- // Give precedence to the Bluetooth battery state if it's present.
- if (mBluetoothState.isPresent) {
- return new State(mBluetoothState);
+ // Give precedence to the Bluetooth battery state, and fall back to the native state.
+ return Objects.requireNonNullElseGet(resolveBluetoothBatteryState(),
+ () -> new State(mState));
+ }
+
+ @Nullable
+ protected State resolveBluetoothBatteryState() {
+ final int level;
+ // Prefer battery level obtained from the metadata over the Bluetooth Hands-Free
+ // Profile (HFP).
+ if (mBluetoothMetadataBatteryLevel >= 0 && mBluetoothMetadataBatteryLevel <= 100) {
+ level = mBluetoothMetadataBatteryLevel;
+ } else if (mBluetoothBatteryLevel >= 0 && mBluetoothBatteryLevel <= 100) {
+ level = mBluetoothBatteryLevel;
+ } else {
+ return null;
}
- return new State(mState);
+ return new State(mState.deviceId, mBluetoothEventTime, true,
+ mBluetoothMetadataBatteryStatus, level / 100.f);
}
@Override
@@ -690,7 +787,7 @@
+ ", Name='" + getInputDeviceName(mState.deviceId) + "'"
+ ", NativeBattery=" + mState
+ ", UEventListener=" + (mUEventBatteryListener != null ? "added" : "none")
- + ", BluetoothBattery=" + mBluetoothState;
+ + ", BluetoothState=" + resolveBluetoothBatteryState();
}
}
@@ -775,12 +872,10 @@
@Override
public State getBatteryStateForReporting() {
- // Give precedence to the Bluetooth battery state if it's present.
- if (mBluetoothState.isPresent) {
- return new State(mBluetoothState);
- }
- return mValidityTimeoutCallback != null
- ? new State(mState) : new State(mState.deviceId);
+ // Give precedence to the Bluetooth battery state, and fall back to the native state.
+ return Objects.requireNonNullElseGet(resolveBluetoothBatteryState(),
+ () -> mValidityTimeoutCallback != null
+ ? new State(mState) : new State(mState.deviceId));
}
@Override
@@ -844,15 +939,24 @@
interface BluetoothBatteryManager {
@VisibleForTesting
interface BluetoothBatteryListener {
- void onBluetoothBatteryChanged(long eventTime, String address);
+ void onBluetoothBatteryChanged(long eventTime, String address, int batteryLevel);
}
- void addListener(BluetoothBatteryListener listener);
- void removeListener(BluetoothBatteryListener listener);
+ // Methods used for obtaining the Bluetooth battery level through Bluetooth HFP.
+ void addBatteryListener(BluetoothBatteryListener listener);
+ void removeBatteryListener(BluetoothBatteryListener listener);
int getBatteryLevel(String address);
+
+ // Methods used for obtaining the battery level through Bluetooth metadata.
+ void addMetadataListener(String address,
+ BluetoothAdapter.OnMetadataChangedListener listener);
+ void removeMetadataListener(String address,
+ BluetoothAdapter.OnMetadataChangedListener listener);
+ byte[] getMetadata(String address, int key);
}
private static class LocalBluetoothBatteryManager implements BluetoothBatteryManager {
private final Context mContext;
+ private final Executor mExecutor;
@Nullable
@GuardedBy("mBroadcastReceiver")
private BluetoothBatteryListener mRegisteredListener;
@@ -868,24 +972,25 @@
if (bluetoothDevice == null) {
return;
}
- // We do not use the EXTRA_LEVEL value. Instead, the battery level will be queried
- // from BluetoothDevice later so that we use a single source for the battery level.
+ final int batteryLevel = intent.getIntExtra(BluetoothDevice.EXTRA_BATTERY_LEVEL,
+ BluetoothDevice.BATTERY_LEVEL_UNKNOWN);
synchronized (mBroadcastReceiver) {
if (mRegisteredListener != null) {
final long eventTime = SystemClock.uptimeMillis();
mRegisteredListener.onBluetoothBatteryChanged(
- eventTime, bluetoothDevice.getAddress());
+ eventTime, bluetoothDevice.getAddress(), batteryLevel);
}
}
}
};
- LocalBluetoothBatteryManager(Context context) {
+ LocalBluetoothBatteryManager(Context context, Looper looper) {
mContext = context;
+ mExecutor = new HandlerExecutor(new Handler(looper));
}
@Override
- public void addListener(BluetoothBatteryListener listener) {
+ public void addBatteryListener(BluetoothBatteryListener listener) {
synchronized (mBroadcastReceiver) {
if (mRegisteredListener != null) {
throw new IllegalStateException(
@@ -898,7 +1003,7 @@
}
@Override
- public void removeListener(BluetoothBatteryListener listener) {
+ public void removeBatteryListener(BluetoothBatteryListener listener) {
synchronized (mBroadcastReceiver) {
if (!listener.equals(mRegisteredListener)) {
throw new IllegalStateException("Listener is not registered.");
@@ -912,6 +1017,28 @@
public int getBatteryLevel(String address) {
return getBluetoothDevice(mContext, address).getBatteryLevel();
}
+
+ @Override
+ public void addMetadataListener(String address,
+ BluetoothAdapter.OnMetadataChangedListener listener) {
+ Objects.requireNonNull(mContext.getSystemService(BluetoothManager.class))
+ .getAdapter().addOnMetadataChangedListener(
+ getBluetoothDevice(mContext, address), mExecutor,
+ listener);
+ }
+
+ @Override
+ public void removeMetadataListener(String address,
+ BluetoothAdapter.OnMetadataChangedListener listener) {
+ Objects.requireNonNull(mContext.getSystemService(BluetoothManager.class))
+ .getAdapter().removeOnMetadataChangedListener(
+ getBluetoothDevice(mContext, address), listener);
+ }
+
+ @Override
+ public byte[] getMetadata(String address, int key) {
+ return getBluetoothDevice(mContext, address).getMetadata(key);
+ }
}
// Helper class that adds copying and printing functionality to IInputDeviceBatteryState.
@@ -954,7 +1081,7 @@
this.capacity = capacity;
}
- private boolean equalsIgnoringUpdateTime(IInputDeviceBatteryState other) {
+ public boolean equalsIgnoringUpdateTime(IInputDeviceBatteryState other) {
long updateTime = this.updateTime;
this.updateTime = other.updateTime;
boolean eq = this.equals(other);
diff --git a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
new file mode 100644
index 0000000..86a0857
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2022 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.server.inputmethod;
+
+import static android.view.inputmethod.ImeTracker.DEBUG_IME_VISIBILITY;
+
+import static com.android.server.EventLogTags.IMF_HIDE_IME;
+import static com.android.server.EventLogTags.IMF_SHOW_IME;
+import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_HIDE_IME;
+import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_SHOW_IME;
+
+import android.annotation.Nullable;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.ResultReceiver;
+import android.util.EventLog;
+import android.util.Slog;
+import android.view.inputmethod.ImeTracker;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.inputmethod.InputMethodDebug;
+import com.android.internal.inputmethod.SoftInputShowHideReason;
+import com.android.server.LocalServices;
+import com.android.server.wm.WindowManagerInternal;
+
+import java.util.Objects;
+
+/**
+ * The default implementation of {@link ImeVisibilityApplier} used in
+ * {@link InputMethodManagerService}.
+ */
+final class DefaultImeVisibilityApplier implements ImeVisibilityApplier {
+
+ private static final String TAG = "DefaultImeVisibilityApplier";
+
+ private static final boolean DEBUG = InputMethodManagerService.DEBUG;
+
+ private InputMethodManagerService mService;
+
+ private final WindowManagerInternal mWindowManagerInternal;
+
+
+ DefaultImeVisibilityApplier(InputMethodManagerService service) {
+ mService = service;
+ mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
+ }
+
+ @GuardedBy("ImfLock.class")
+ @Override
+ public void performShowIme(IBinder windowToken, @Nullable ImeTracker.Token statsToken,
+ int showFlags, ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
+ final IInputMethodInvoker curMethod = mService.getCurMethodLocked();
+ if (curMethod != null) {
+ // create a placeholder token for IMS so that IMS cannot inject windows into client app.
+ final IBinder showInputToken = new Binder();
+ mService.setRequestImeTokenToWindow(windowToken, showInputToken);
+ if (DEBUG) {
+ Slog.v(TAG, "Calling " + curMethod + ".showSoftInput(" + showInputToken
+ + ", " + showFlags + ", " + resultReceiver + ") for reason: "
+ + InputMethodDebug.softInputDisplayReasonToString(reason));
+ }
+ // TODO(b/192412909): Check if we can always call onShowHideSoftInputRequested() or not.
+ if (curMethod.showSoftInput(showInputToken, statsToken, showFlags, resultReceiver)) {
+ if (DEBUG_IME_VISIBILITY) {
+ EventLog.writeEvent(IMF_SHOW_IME, statsToken.getTag(),
+ Objects.toString(mService.mCurFocusedWindow),
+ InputMethodDebug.softInputDisplayReasonToString(reason),
+ InputMethodDebug.softInputModeToString(
+ mService.mCurFocusedWindowSoftInputMode));
+ }
+ mService.onShowHideSoftInputRequested(true /* show */, windowToken, reason,
+ statsToken);
+ }
+ }
+ }
+
+ @GuardedBy("ImfLock.class")
+ @Override
+ public void performHideIme(IBinder windowToken, @Nullable ImeTracker.Token statsToken,
+ ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
+ final IInputMethodInvoker curMethod = mService.getCurMethodLocked();
+ if (curMethod != null) {
+ final Binder hideInputToken = new Binder();
+ mService.setRequestImeTokenToWindow(windowToken, hideInputToken);
+ // The IME will report its visible state again after the following message finally
+ // delivered to the IME process as an IPC. Hence the inconsistency between
+ // IMMS#mInputShown and IMMS#mImeWindowVis should be resolved spontaneously in
+ // the final state.
+ if (DEBUG) {
+ Slog.v(TAG, "Calling " + curMethod + ".hideSoftInput(0, " + hideInputToken
+ + ", " + resultReceiver + ") for reason: "
+ + InputMethodDebug.softInputDisplayReasonToString(reason));
+ }
+ // TODO(b/192412909): Check if we can always call onShowHideSoftInputRequested() or not.
+ if (curMethod.hideSoftInput(hideInputToken, statsToken, 0, resultReceiver)) {
+ if (DEBUG_IME_VISIBILITY) {
+ EventLog.writeEvent(IMF_HIDE_IME, statsToken.getTag(),
+ Objects.toString(mService.mCurFocusedWindow),
+ InputMethodDebug.softInputDisplayReasonToString(reason),
+ InputMethodDebug.softInputModeToString(
+ mService.mCurFocusedWindowSoftInputMode));
+ }
+ mService.onShowHideSoftInputRequested(false /* show */, windowToken, reason,
+ statsToken);
+ }
+ }
+ }
+
+ @GuardedBy("ImfLock.class")
+ @Override
+ public void applyImeVisibility(IBinder windowToken, @Nullable ImeTracker.Token statsToken,
+ @ImeVisibilityStateComputer.VisibilityState int state) {
+ switch (state) {
+ case STATE_SHOW_IME:
+ ImeTracker.get().onProgress(statsToken,
+ ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
+ // Send to window manager to show IME after IME layout finishes.
+ mWindowManagerInternal.showImePostLayout(windowToken, statsToken);
+ break;
+ case STATE_HIDE_IME:
+ if (mService.mCurFocusedWindowClient != null) {
+ ImeTracker.get().onProgress(statsToken,
+ ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
+ // IMMS only knows of focused window, not the actual IME target.
+ // e.g. it isn't aware of any window that has both
+ // NOT_FOCUSABLE, ALT_FOCUSABLE_IM flags set and can the IME target.
+ // Send it to window manager to hide IME from IME target window.
+ // TODO(b/139861270): send to mCurClient.client once IMMS is aware of
+ // actual IME target.
+ mWindowManagerInternal.hideIme(windowToken,
+ mService.mCurFocusedWindowClient.mSelfReportedDisplayId, statsToken);
+ } else {
+ ImeTracker.get().onFailed(statsToken,
+ ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid IME visibility state: " + state);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/inputmethod/ImeVisibilityApplier.java b/services/core/java/com/android/server/inputmethod/ImeVisibilityApplier.java
new file mode 100644
index 0000000..e97ec93
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/ImeVisibilityApplier.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2022 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.server.inputmethod;
+
+import android.annotation.Nullable;
+import android.os.IBinder;
+import android.os.ResultReceiver;
+import android.view.inputmethod.ImeTracker;
+
+import com.android.internal.inputmethod.SoftInputShowHideReason;
+
+/**
+ * Interface for IME visibility operations like show/hide and update Z-ordering relative to the IME
+ * targeted window.
+ */
+interface ImeVisibilityApplier {
+ /**
+ * Performs showing IME on top of the given window.
+ *
+ * @param windowToken The token of a window that currently has focus.
+ * @param statsToken A token that tracks the progress of an IME request.
+ * @param showFlags Provides additional operating flags to show IME.
+ * @param resultReceiver If non-null, this will be called back to the caller when
+ * it has processed request to tell what it has done.
+ * @param reason The reason for requesting to show IME.
+ */
+ default void performShowIme(IBinder windowToken, @Nullable ImeTracker.Token statsToken,
+ int showFlags, ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {}
+
+ /**
+ * Performs hiding IME to the given window
+ *
+ * @param windowToken The token of a window that currently has focus.
+ * @param statsToken A token that tracks the progress of an IME request.
+ * @param resultReceiver If non-null, this will be called back to the caller when
+ * it has processed request to tell what it has done.
+ * @param reason The reason for requesting to hide IME.
+ */
+ default void performHideIme(IBinder windowToken, @Nullable ImeTracker.Token statsToken,
+ ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {}
+
+ /**
+ * Applies the IME visibility from {@link android.inputmethodservice.InputMethodService} with
+ * according to the given visibility state.
+ *
+ * @param windowToken The token of a window for applying the IME visibility
+ * @param statsToken A token that tracks the progress of an IME request.
+ * @param state The new IME visibility state for the applier to handle
+ */
+ default void applyImeVisibility(IBinder windowToken, @Nullable ImeTracker.Token statsToken,
+ @ImeVisibilityStateComputer.VisibilityState int state) {}
+
+ /**
+ * Updates the IME Z-ordering relative to the given window.
+ *
+ * This used to adjust the IME relative layer of the window during
+ * {@link InputMethodManagerService} is in switching IME clients.
+ *
+ * @param windowToken The token of a window to update the Z-ordering relative to the IME.
+ */
+ default void updateImeLayeringByTarget(IBinder windowToken) {
+ // TODO: add a method in WindowManagerInternal to call DC#updateImeInputAndControlTarget
+ // here to end up updating IME layering after IMMS#attachNewInputLocked called.
+ }
+}
diff --git a/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java b/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
new file mode 100644
index 0000000..a2655f4
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
@@ -0,0 +1,424 @@
+/*
+ * Copyright (C) 2022 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.server.inputmethod;
+
+import static android.accessibilityservice.AccessibilityService.SHOW_MODE_HIDDEN;
+import static android.server.inputmethod.InputMethodManagerServiceProto.ACCESSIBILITY_REQUESTING_NO_SOFT_KEYBOARD;
+import static android.server.inputmethod.InputMethodManagerServiceProto.SHOW_EXPLICITLY_REQUESTED;
+import static android.server.inputmethod.InputMethodManagerServiceProto.SHOW_FORCED;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED;
+import static android.view.WindowManager.LayoutParams.SoftInputModeFlags;
+
+import static com.android.internal.inputmethod.InputMethodDebug.softInputModeToString;
+import static com.android.server.inputmethod.InputMethodManagerService.computeImeDisplayIdForTarget;
+
+import android.accessibilityservice.AccessibilityService;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.os.IBinder;
+import android.util.PrintWriterPrinter;
+import android.util.Printer;
+import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
+import android.view.WindowManager;
+import android.view.inputmethod.ImeTracker;
+import android.view.inputmethod.InputMethod;
+import android.view.inputmethod.InputMethodManager;
+
+import com.android.server.LocalServices;
+import com.android.server.wm.WindowManagerInternal;
+
+import java.io.PrintWriter;
+import java.util.WeakHashMap;
+
+/**
+ * A computer used by {@link InputMethodManagerService} that computes the IME visibility state
+ * according the given {@link ImeTargetWindowState} from the focused window or the app requested IME
+ * visibility from {@link InputMethodManager}.
+ */
+public final class ImeVisibilityStateComputer {
+
+ private static final String TAG = "ImeVisibilityStateComputer";
+
+ private static final boolean DEBUG = InputMethodManagerService.DEBUG;
+
+ private final InputMethodManagerService mService;
+ private final WindowManagerInternal mWindowManagerInternal;
+
+ final InputMethodManagerService.ImeDisplayValidator mImeDisplayValidator;
+
+ /**
+ * A map used to track the requested IME target window and its state. The key represents the
+ * token of the window and the value is the corresponding IME window state.
+ */
+ private final WeakHashMap<IBinder, ImeTargetWindowState> mRequestWindowStateMap =
+ new WeakHashMap<>();
+
+ /**
+ * Set if IME was explicitly told to show the input method.
+ *
+ * @see InputMethodManager#SHOW_IMPLICIT that we set the value is {@code false}.
+ * @see InputMethodManager#HIDE_IMPLICIT_ONLY that system will not hide IME when the value is
+ * {@code true}.
+ */
+ boolean mRequestedShowExplicitly;
+
+ /**
+ * Set if we were forced to be shown.
+ *
+ * @see InputMethodManager#SHOW_FORCED
+ * @see InputMethodManager#HIDE_NOT_ALWAYS
+ */
+ boolean mShowForced;
+
+ /** Represent the invalid IME visibility state */
+ public static final int STATE_INVALID = -1;
+
+ /** State to handle hiding the IME window requested by the app. */
+ public static final int STATE_HIDE_IME = 0;
+
+ /** State to handle showing the IME window requested by the app. */
+ public static final int STATE_SHOW_IME = 1;
+
+ /** State to handle showing the IME window with making the overlay window above it. */
+ public static final int STATE_SHOW_IME_ABOVE_OVERLAY = 2;
+
+ /** State to handle showing the IME window with making the overlay window behind it. */
+ public static final int STATE_SHOW_IME_BEHIND_OVERLAY = 3;
+
+ /** State to handle showing an IME preview surface during the app was loosing the IME focus */
+ public static final int STATE_SHOW_IME_SNAPSHOT = 4;
+ @IntDef({
+ STATE_INVALID,
+ STATE_HIDE_IME,
+ STATE_SHOW_IME,
+ STATE_SHOW_IME_ABOVE_OVERLAY,
+ STATE_SHOW_IME_BEHIND_OVERLAY,
+ STATE_SHOW_IME_SNAPSHOT,
+ })
+ @interface VisibilityState {}
+
+ /**
+ * The policy to configure the IME visibility.
+ */
+ private final ImeVisibilityPolicy mPolicy;
+
+ public ImeVisibilityStateComputer(InputMethodManagerService service) {
+ mService = service;
+ mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
+ mImeDisplayValidator = mWindowManagerInternal::getDisplayImePolicy;
+ mPolicy = new ImeVisibilityPolicy();
+ }
+
+ /**
+ * Called when {@link InputMethodManagerService} is processing the show IME request.
+ * @param statsToken The token for tracking this show request
+ * @param showFlags The additional operation flags to indicate whether this show request mode is
+ * implicit or explicit.
+ * @return {@code true} when the computer has proceed this show request operation.
+ */
+ boolean onImeShowFlags(@NonNull ImeTracker.Token statsToken, int showFlags) {
+ if (mPolicy.mA11yRequestingNoSoftKeyboard || mPolicy.mImeHiddenByDisplayPolicy) {
+ ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_ACCESSIBILITY);
+ return false;
+ }
+ ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_ACCESSIBILITY);
+ if ((showFlags & InputMethodManager.SHOW_FORCED) != 0) {
+ mRequestedShowExplicitly = true;
+ mShowForced = true;
+ } else if ((showFlags & InputMethodManager.SHOW_IMPLICIT) == 0) {
+ mRequestedShowExplicitly = true;
+ }
+ return true;
+ }
+
+ /**
+ * Called when {@link InputMethodManagerService} is processing the hide IME request.
+ * @param statsToken The token for tracking this hide request
+ * @param hideFlags The additional operation flags to indicate whether this hide request mode is
+ * implicit or explicit.
+ * @return {@code true} when the computer has proceed this hide request operations.
+ */
+ boolean canHideIme(@NonNull ImeTracker.Token statsToken, int hideFlags) {
+ if ((hideFlags & InputMethodManager.HIDE_IMPLICIT_ONLY) != 0
+ && (mRequestedShowExplicitly || mShowForced)) {
+ if (DEBUG) Slog.v(TAG, "Not hiding: explicit show not cancelled by non-explicit hide");
+ ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_HIDE_IMPLICIT);
+ return false;
+ }
+ if (mShowForced && (hideFlags & InputMethodManager.HIDE_NOT_ALWAYS) != 0) {
+ if (DEBUG) Slog.v(TAG, "Not hiding: forced show not cancelled by not-always hide");
+ ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_HIDE_NOT_ALWAYS);
+ return false;
+ }
+ ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_HIDE_NOT_ALWAYS);
+ return true;
+ }
+
+ int getImeShowFlags() {
+ int flags = 0;
+ if (mShowForced) {
+ flags |= InputMethod.SHOW_FORCED | InputMethod.SHOW_EXPLICIT;
+ } else if (mRequestedShowExplicitly) {
+ flags |= InputMethod.SHOW_EXPLICIT;
+ } else {
+ flags |= InputMethodManager.SHOW_IMPLICIT;
+ }
+ return flags;
+ }
+
+ void clearImeShowFlags() {
+ mRequestedShowExplicitly = false;
+ mShowForced = false;
+ }
+
+ int computeImeDisplayId(@NonNull ImeTargetWindowState state, int displayId) {
+ final int displayToShowIme = computeImeDisplayIdForTarget(displayId, mImeDisplayValidator);
+ state.setImeDisplayId(displayToShowIme);
+ final boolean imeHiddenByPolicy = displayToShowIme == INVALID_DISPLAY;
+ mPolicy.setImeHiddenByDisplayPolicy(imeHiddenByPolicy);
+ return displayToShowIme;
+ }
+
+ /**
+ * Request to show/hide IME from the given window.
+ *
+ * @param windowToken The window which requests to show/hide IME.
+ * @param showIme {@code true} means to show IME, {@code false} otherwise.
+ * Note that in the computer will take this option to compute the
+ * visibility state, it could be {@link #STATE_SHOW_IME} or
+ * {@link #STATE_HIDE_IME}.
+ */
+ void requestImeVisibility(IBinder windowToken, boolean showIme) {
+ final ImeTargetWindowState state = getOrCreateWindowState(windowToken);
+ state.setRequestedImeVisible(showIme);
+ setWindowState(windowToken, state);
+ }
+
+ ImeTargetWindowState getOrCreateWindowState(IBinder windowToken) {
+ ImeTargetWindowState state = mRequestWindowStateMap.get(windowToken);
+ if (state == null) {
+ state = new ImeTargetWindowState(SOFT_INPUT_STATE_UNSPECIFIED, false, false);
+ }
+ return state;
+ }
+
+ ImeTargetWindowState getWindowStateOrNull(IBinder windowToken) {
+ ImeTargetWindowState state = mRequestWindowStateMap.get(windowToken);
+ return state;
+ }
+
+ void setRequestImeTokenToWindow(IBinder windowToken, IBinder token) {
+ ImeTargetWindowState state = getWindowStateOrNull(windowToken);
+ if (state != null) {
+ state.setRequestImeToken(token);
+ setWindowState(windowToken, state);
+ }
+ }
+
+ void setWindowState(IBinder windowToken, ImeTargetWindowState newState) {
+ if (DEBUG) Slog.d(TAG, "setWindowState, windowToken=" + windowToken
+ + ", state=" + newState);
+ mRequestWindowStateMap.put(windowToken, newState);
+ }
+
+ IBinder getWindowTokenFrom(IBinder requestImeToken) {
+ for (IBinder windowToken : mRequestWindowStateMap.keySet()) {
+ final ImeTargetWindowState state = mRequestWindowStateMap.get(windowToken);
+ if (state.getRequestImeToken() == requestImeToken) {
+ return windowToken;
+ }
+ }
+ // Fallback to the focused window for some edge cases (e.g. relaunching the activity)
+ return mService.mCurFocusedWindow;
+ }
+
+ IBinder getWindowTokenFrom(ImeTargetWindowState windowState) {
+ for (IBinder windowToken : mRequestWindowStateMap.keySet()) {
+ final ImeTargetWindowState state = mRequestWindowStateMap.get(windowToken);
+ if (state == windowState) {
+ return windowToken;
+ }
+ }
+ return null;
+ }
+
+ boolean shouldRestoreImeVisibility(@NonNull ImeTargetWindowState state) {
+ final int softInputMode = state.getSoftInputModeState();
+ switch (softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE) {
+ case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN:
+ return false;
+ case WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN:
+ if ((softInputMode & SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
+ return false;
+ }
+ }
+ return mWindowManagerInternal.shouldRestoreImeVisibility(getWindowTokenFrom(state));
+ }
+
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
+ proto.write(SHOW_EXPLICITLY_REQUESTED, mRequestedShowExplicitly);
+ proto.write(SHOW_FORCED, mShowForced);
+ proto.write(ACCESSIBILITY_REQUESTING_NO_SOFT_KEYBOARD,
+ mPolicy.isA11yRequestNoSoftKeyboard());
+ }
+
+ void dump(PrintWriter pw) {
+ final Printer p = new PrintWriterPrinter(pw);
+ p.println(" mRequestedShowExplicitly=" + mRequestedShowExplicitly
+ + " mShowForced=" + mShowForced);
+ p.println(" mImeHiddenByDisplayPolicy=" + mPolicy.isImeHiddenByDisplayPolicy());
+ }
+
+ /**
+ * A settings class to manage all IME related visibility policies or settings.
+ *
+ * This is used for the visibility computer to manage and tell
+ * {@link InputMethodManagerService} if the requested IME visibility is valid from
+ * application call or the focus window.
+ */
+ static class ImeVisibilityPolicy {
+ /**
+ * {@code true} if the Ime policy has been set to
+ * {@link WindowManager#DISPLAY_IME_POLICY_HIDE}.
+ *
+ * This prevents the IME from showing when it otherwise may have shown.
+ */
+ private boolean mImeHiddenByDisplayPolicy;
+
+ /**
+ * Set when the accessibility service requests to hide IME by
+ * {@link AccessibilityService.SoftKeyboardController#setShowMode}
+ */
+ private boolean mA11yRequestingNoSoftKeyboard;
+
+ void setImeHiddenByDisplayPolicy(boolean hideIme) {
+ mImeHiddenByDisplayPolicy = hideIme;
+ }
+
+ boolean isImeHiddenByDisplayPolicy() {
+ return mImeHiddenByDisplayPolicy;
+ }
+
+ void setA11yRequestNoSoftKeyboard(int keyboardShowMode) {
+ mA11yRequestingNoSoftKeyboard =
+ (keyboardShowMode & AccessibilityService.SHOW_MODE_MASK) == SHOW_MODE_HIDDEN;
+ }
+
+ boolean isA11yRequestNoSoftKeyboard() {
+ return mA11yRequestingNoSoftKeyboard;
+ }
+ }
+
+ ImeVisibilityPolicy getImePolicy() {
+ return mPolicy;
+ }
+
+ /**
+ * A class that represents the current state of the IME target window.
+ */
+ static class ImeTargetWindowState {
+ ImeTargetWindowState(@SoftInputModeFlags int softInputModeState, boolean imeFocusChanged,
+ boolean hasFocusedEditor) {
+ mSoftInputModeState = softInputModeState;
+ mImeFocusChanged = imeFocusChanged;
+ mHasFocusedEditor = hasFocusedEditor;
+ }
+
+ /**
+ * Visibility state for this window. By default no state has been specified.
+ */
+ private final @SoftInputModeFlags int mSoftInputModeState;
+
+ /**
+ * {@code true} means the IME focus changed from the previous window, {@code false}
+ * otherwise.
+ */
+ private final boolean mImeFocusChanged;
+
+ /**
+ * {@code true} when the window has focused an editor, {@code false} otherwise.
+ */
+ private final boolean mHasFocusedEditor;
+
+ /**
+ * Set if the client has asked for the input method to be shown.
+ */
+ private boolean mRequestedImeVisible;
+
+ /**
+ * A identifier for knowing the requester of {@link InputMethodManager#showSoftInput} or
+ * {@link InputMethodManager#hideSoftInputFromWindow}.
+ */
+ private IBinder mRequestImeToken;
+
+ /**
+ * The IME target display id for which the latest startInput was called.
+ */
+ private int mImeDisplayId = DEFAULT_DISPLAY;
+
+ boolean hasImeFocusChanged() {
+ return mImeFocusChanged;
+ }
+
+ boolean hasEdiorFocused() {
+ return mHasFocusedEditor;
+ }
+
+ int getSoftInputModeState() {
+ return mSoftInputModeState;
+ }
+
+ private void setImeDisplayId(int imeDisplayId) {
+ mImeDisplayId = imeDisplayId;
+ }
+
+ int getImeDisplayId() {
+ return mImeDisplayId;
+ }
+
+ private void setRequestedImeVisible(boolean requestedImeVisible) {
+ mRequestedImeVisible = requestedImeVisible;
+ }
+
+ boolean isRequestedImeVisible() {
+ return mRequestedImeVisible;
+ }
+
+ void setRequestImeToken(IBinder token) {
+ mRequestImeToken = token;
+ }
+
+ IBinder getRequestImeToken() {
+ return mRequestImeToken;
+ }
+
+ @Override
+ public String toString() {
+ return "ImeTargetWindowState{ imeToken " + mRequestImeToken
+ + " imeFocusChanged " + mImeFocusChanged
+ + " hasEditorFocused " + mHasFocusedEditor
+ + " requestedImeVisible " + mRequestedImeVisible
+ + " imeDisplayId " + mImeDisplayId
+ + " softInputModeState " + softInputModeToString(mSoftInputModeState)
+ + "}";
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 5b9a663..2dbbb10 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -20,7 +20,6 @@
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
import static android.os.IServiceManager.DUMP_FLAG_PROTO;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
-import static android.server.inputmethod.InputMethodManagerServiceProto.ACCESSIBILITY_REQUESTING_NO_SOFT_KEYBOARD;
import static android.server.inputmethod.InputMethodManagerServiceProto.BACK_DISPOSITION;
import static android.server.inputmethod.InputMethodManagerServiceProto.BOUND_TO_METHOD;
import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_ATTRIBUTE;
@@ -39,8 +38,6 @@
import static android.server.inputmethod.InputMethodManagerServiceProto.IS_INTERACTIVE;
import static android.server.inputmethod.InputMethodManagerServiceProto.LAST_IME_TARGET_WINDOW_NAME;
import static android.server.inputmethod.InputMethodManagerServiceProto.LAST_SWITCH_USER_ID;
-import static android.server.inputmethod.InputMethodManagerServiceProto.SHOW_EXPLICITLY_REQUESTED;
-import static android.server.inputmethod.InputMethodManagerServiceProto.SHOW_FORCED;
import static android.server.inputmethod.InputMethodManagerServiceProto.SHOW_IME_WITH_HARD_KEYBOARD;
import static android.server.inputmethod.InputMethodManagerServiceProto.SHOW_REQUESTED;
import static android.server.inputmethod.InputMethodManagerServiceProto.SYSTEM_READY;
@@ -48,17 +45,14 @@
import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.DISPLAY_IME_POLICY_HIDE;
import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
-import static android.view.inputmethod.ImeTracker.DEBUG_IME_VISIBILITY;
-import static com.android.server.EventLogTags.IMF_HIDE_IME;
-import static com.android.server.EventLogTags.IMF_SHOW_IME;
+import static com.android.server.inputmethod.ImeVisibilityStateComputer.ImeTargetWindowState;
import static com.android.server.inputmethod.InputMethodBindingController.TIME_TO_RECONNECT;
import static com.android.server.inputmethod.InputMethodUtils.isSoftInputModeStateVisibleAllowed;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.Manifest;
-import android.accessibilityservice.AccessibilityService;
import android.annotation.AnyThread;
import android.annotation.BinderThread;
import android.annotation.DrawableRes;
@@ -126,7 +120,6 @@
import android.view.InputChannel;
import android.view.InputDevice;
import android.view.MotionEvent;
-import android.view.View;
import android.view.WindowManager;
import android.view.WindowManager.DisplayImePolicy;
import android.view.WindowManager.LayoutParams;
@@ -299,6 +292,12 @@
@NonNull private final InputMethodBindingController mBindingController;
@NonNull private final AutofillSuggestionsController mAutofillController;
+ @GuardedBy("ImfLock.class")
+ @NonNull private final ImeVisibilityStateComputer mVisibilityStateComputer;
+
+ @GuardedBy("ImfLock.class")
+ @NonNull private final DefaultImeVisibilityApplier mVisibilityApplier;
+
/**
* Cache the result of {@code LocalServices.getService(AudioManagerInternal.class)}.
*
@@ -530,13 +529,6 @@
}
/**
- * {@code true} if the Ime policy has been set to {@link WindowManager#DISPLAY_IME_POLICY_HIDE}.
- *
- * This prevents the IME from showing when it otherwise may have shown.
- */
- boolean mImeHiddenByDisplayPolicy;
-
- /**
* The client that is currently bound to an input method.
*/
private ClientState mCurClient;
@@ -638,16 +630,6 @@
private boolean mShowRequested;
/**
- * Set if we were explicitly told to show the input method.
- */
- boolean mShowExplicitlyRequested;
-
- /**
- * Set if we were forced to be shown.
- */
- boolean mShowForced;
-
- /**
* Set if we last told the input method to show itself.
*/
private boolean mInputShown;
@@ -709,8 +691,6 @@
*/
private static final int FALLBACK_DISPLAY_ID = DEFAULT_DISPLAY;
- final ImeDisplayValidator mImeDisplayValidator;
-
/**
* If non-null, this is the input method service we are currently connected
* to.
@@ -786,7 +766,6 @@
int mImeWindowVis;
private LocaleList mLastSystemLocales;
- private boolean mAccessibilityRequestingNoSoftKeyboard;
private final MyPackageMonitor mMyPackageMonitor = new MyPackageMonitor();
private final String mSlotIme;
@@ -974,22 +953,6 @@
}
/**
- * Map of generated token to windowToken that is requesting
- * {@link InputMethodManager#showSoftInput(View, int)}.
- * This map tracks origin of showSoftInput requests.
- */
- @GuardedBy("ImfLock.class")
- private final WeakHashMap<IBinder, IBinder> mShowRequestWindowMap = new WeakHashMap<>();
-
- /**
- * Map of generated token to windowToken that is requesting
- * {@link InputMethodManager#hideSoftInputFromWindow(IBinder, int)}.
- * This map tracks origin of hideSoftInput requests.
- */
- @GuardedBy("ImfLock.class")
- private final WeakHashMap<IBinder, IBinder> mHideRequestWindowMap = new WeakHashMap<>();
-
- /**
* A ring buffer to store the history of {@link StartInputInfo}.
*/
private static final class StartInputHistory {
@@ -1207,11 +1170,10 @@
} else if (accessibilityRequestingNoImeUri.equals(uri)) {
final int accessibilitySoftKeyboardSetting = Settings.Secure.getIntForUser(
mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0 /* def */, mUserId);
- mAccessibilityRequestingNoSoftKeyboard =
- (accessibilitySoftKeyboardSetting & AccessibilityService.SHOW_MODE_MASK)
- == AccessibilityService.SHOW_MODE_HIDDEN;
- if (mAccessibilityRequestingNoSoftKeyboard) {
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0, mUserId);
+ mVisibilityStateComputer.getImePolicy().setA11yRequestNoSoftKeyboard(
+ accessibilitySoftKeyboardSetting);
+ if (mVisibilityStateComputer.getImePolicy().isA11yRequestNoSoftKeyboard()) {
final boolean showRequested = mShowRequested;
hideCurrentInputLocked(mCurFocusedWindow, null /* statsToken */,
0 /* flags */, null /* resultReceiver */,
@@ -1722,7 +1684,6 @@
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
mImePlatformCompatUtils = new ImePlatformCompatUtils();
mInputMethodDeviceConfigs = new InputMethodDeviceConfigs();
- mImeDisplayValidator = mWindowManagerInternal::getDisplayImePolicy;
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
@@ -1747,6 +1708,10 @@
? bindingControllerForTesting
: new InputMethodBindingController(this);
mAutofillController = new AutofillSuggestionsController(this);
+
+ mVisibilityStateComputer = new ImeVisibilityStateComputer(this);
+ mVisibilityApplier = new DefaultImeVisibilityApplier(this);
+
mPreventImeStartupUnlessTextEditor = mRes.getBoolean(
com.android.internal.R.bool.config_preventImeStartupUnlessTextEditor);
mNonPreemptibleInputMethods = mRes.getStringArray(
@@ -2340,29 +2305,6 @@
}
@GuardedBy("ImfLock.class")
- private int getImeShowFlagsLocked() {
- int flags = 0;
- if (mShowForced) {
- flags |= InputMethod.SHOW_FORCED
- | InputMethod.SHOW_EXPLICIT;
- } else if (mShowExplicitlyRequested) {
- flags |= InputMethod.SHOW_EXPLICIT;
- }
- return flags;
- }
-
- @GuardedBy("ImfLock.class")
- private int getAppShowFlagsLocked() {
- int flags = 0;
- if (mShowForced) {
- flags |= InputMethodManager.SHOW_FORCED;
- } else if (!mShowExplicitlyRequested) {
- flags |= InputMethodManager.SHOW_IMPLICIT;
- }
- return flags;
- }
-
- @GuardedBy("ImfLock.class")
@NonNull
InputBindResult attachNewInputLocked(@StartInputReason int startInputReason, boolean initial) {
if (!mBoundToMethod) {
@@ -2403,7 +2345,8 @@
// Re-use current statsToken, if it exists.
final ImeTracker.Token statsToken = mCurStatsToken;
mCurStatsToken = null;
- showCurrentInputLocked(mCurFocusedWindow, statsToken, getAppShowFlagsLocked(),
+ showCurrentInputLocked(mCurFocusedWindow, statsToken,
+ mVisibilityStateComputer.getImeShowFlags(),
null /* resultReceiver */, SoftInputShowHideReason.ATTACH_NEW_INPUT);
}
@@ -2518,17 +2461,20 @@
// Compute the final shown display ID with validated cs.selfReportedDisplayId for this
// session & other conditions.
- mDisplayIdToShowIme = computeImeDisplayIdForTarget(cs.mSelfReportedDisplayId,
- mImeDisplayValidator);
+ ImeTargetWindowState winState = mVisibilityStateComputer.getWindowStateOrNull(
+ mCurFocusedWindow);
+ if (winState == null) {
+ return InputBindResult.NOT_IME_TARGET_WINDOW;
+ }
+ final int csDisplayId = cs.mSelfReportedDisplayId;
+ mDisplayIdToShowIme = mVisibilityStateComputer.computeImeDisplayId(winState, csDisplayId);
- if (mDisplayIdToShowIme == INVALID_DISPLAY) {
- mImeHiddenByDisplayPolicy = true;
+ if (mVisibilityStateComputer.getImePolicy().isImeHiddenByDisplayPolicy()) {
hideCurrentInputLocked(mCurFocusedWindow, null /* statsToken */, 0 /* flags */,
null /* resultReceiver */,
SoftInputShowHideReason.HIDE_DISPLAY_IME_POLICY_HIDE);
return InputBindResult.NO_IME;
}
- mImeHiddenByDisplayPolicy = false;
if (mCurClient != cs) {
prepareClientSwitchLocked(cs);
@@ -3385,6 +3331,11 @@
}
}
+ @GuardedBy("ImfLock.class")
+ void setRequestImeTokenToWindow(IBinder windowToken, IBinder token) {
+ mVisibilityStateComputer.setRequestImeTokenToWindow(windowToken, token);
+ }
+
@BinderThread
@Override
public void reportPerceptibleAsync(IBinder windowToken, boolean perceptible) {
@@ -3419,18 +3370,11 @@
ImeTracker.ORIGIN_SERVER_START_INPUT, reason);
}
+ // TODO(b/246309664): make mShowRequested as per-window state.
mShowRequested = true;
- if (mAccessibilityRequestingNoSoftKeyboard || mImeHiddenByDisplayPolicy) {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_ACCESSIBILITY);
- return false;
- }
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_ACCESSIBILITY);
- if ((flags & InputMethodManager.SHOW_FORCED) != 0) {
- mShowExplicitlyRequested = true;
- mShowForced = true;
- } else if ((flags & InputMethodManager.SHOW_IMPLICIT) == 0) {
- mShowExplicitlyRequested = true;
+ if (!mVisibilityStateComputer.onImeShowFlags(statsToken, flags)) {
+ return false;
}
if (!mSystemReady) {
@@ -3439,39 +3383,25 @@
}
ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_SYSTEM_READY);
+ mVisibilityStateComputer.requestImeVisibility(windowToken, true);
+
+ // Ensure binding the connection when IME is going to show.
mBindingController.setCurrentMethodVisible();
final IInputMethodInvoker curMethod = getCurMethodLocked();
+ ImeTracker.get().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
if (curMethod != null) {
- // create a placeholder token for IMS so that IMS cannot inject windows into client app.
- Binder showInputToken = new Binder();
- mShowRequestWindowMap.put(showInputToken, windowToken);
- ImeTracker.get().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_HAS_IME);
mCurStatsToken = null;
- final int showFlags = getImeShowFlagsLocked();
- if (DEBUG) {
- Slog.v(TAG, "Calling " + curMethod + ".showSoftInput(" + showInputToken
- + ", " + showFlags + ", " + resultReceiver + ") for reason: "
- + InputMethodDebug.softInputDisplayReasonToString(reason));
- }
if (lastClickToolType != MotionEvent.TOOL_TYPE_UNKNOWN) {
curMethod.updateEditorToolType(lastClickToolType);
}
- // TODO(b/192412909): Check if we can always call onShowHideSoftInputRequested() or not.
- if (curMethod.showSoftInput(showInputToken, statsToken, showFlags, resultReceiver)) {
- if (DEBUG_IME_VISIBILITY) {
- EventLog.writeEvent(IMF_SHOW_IME, statsToken.getTag(),
- Objects.toString(mCurFocusedWindow),
- InputMethodDebug.softInputDisplayReasonToString(reason),
- InputMethodDebug.softInputModeToString(mCurFocusedWindowSoftInputMode));
- }
- onShowHideSoftInputRequested(true /* show */, windowToken, reason, statsToken);
- }
+ mVisibilityApplier.performShowIme(windowToken, statsToken,
+ mVisibilityStateComputer.getImeShowFlags(), resultReceiver, reason);
+ // TODO(b/246309664): make mInputShown tracked by the Ime visibility computer.
mInputShown = true;
return true;
} else {
- ImeTracker.get().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
mCurStatsToken = statsToken;
}
@@ -3527,20 +3457,9 @@
ImeTracker.ORIGIN_SERVER_HIDE_INPUT, reason);
}
- if ((flags & InputMethodManager.HIDE_IMPLICIT_ONLY) != 0
- && (mShowExplicitlyRequested || mShowForced)) {
- if (DEBUG) Slog.v(TAG, "Not hiding: explicit show not cancelled by non-explicit hide");
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_HIDE_IMPLICIT);
+ if (!mVisibilityStateComputer.canHideIme(statsToken, flags)) {
return false;
}
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_HIDE_IMPLICIT);
-
- if (mShowForced && (flags & InputMethodManager.HIDE_NOT_ALWAYS) != 0) {
- if (DEBUG) Slog.v(TAG, "Not hiding: forced show not cancelled by not-always hide");
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_HIDE_NOT_ALWAYS);
- return false;
- }
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_HIDE_NOT_ALWAYS);
// There is a chance that IMM#hideSoftInput() is called in a transient state where
// IMMS#InputShown is already updated to be true whereas IMMS#mImeWindowVis is still waiting
@@ -3549,49 +3468,30 @@
// application process as a valid request, and have even promised such a behavior with CTS
// since Android Eclair. That's why we need to accept IMM#hideSoftInput() even when only
// IMMS#InputShown indicates that the software keyboard is shown.
- // TODO: Clean up, IMMS#mInputShown, IMMS#mImeWindowVis and mShowRequested.
+ // TODO(b/246309664): Clean up, IMMS#mInputShown, IMMS#mImeWindowVis and mShowRequested.
IInputMethodInvoker curMethod = getCurMethodLocked();
final boolean shouldHideSoftInput = (curMethod != null)
&& (mInputShown || (mImeWindowVis & InputMethodService.IME_ACTIVE) != 0);
- boolean res;
+
+ mVisibilityStateComputer.requestImeVisibility(windowToken, false);
if (shouldHideSoftInput) {
- final Binder hideInputToken = new Binder();
- mHideRequestWindowMap.put(hideInputToken, windowToken);
// The IME will report its visible state again after the following message finally
// delivered to the IME process as an IPC. Hence the inconsistency between
// IMMS#mInputShown and IMMS#mImeWindowVis should be resolved spontaneously in
// the final state.
ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE);
- if (DEBUG) {
- Slog.v(TAG, "Calling " + curMethod + ".hideSoftInput(0, " + hideInputToken
- + ", " + resultReceiver + ") for reason: "
- + InputMethodDebug.softInputDisplayReasonToString(reason));
- }
- // TODO(b/192412909): Check if we can always call onShowHideSoftInputRequested() or not.
- if (curMethod.hideSoftInput(hideInputToken, statsToken, 0 /* flags */,
- resultReceiver)) {
- if (DEBUG_IME_VISIBILITY) {
- EventLog.writeEvent(IMF_HIDE_IME, statsToken.getTag(),
- Objects.toString(mCurFocusedWindow),
- InputMethodDebug.softInputDisplayReasonToString(reason),
- InputMethodDebug.softInputModeToString(mCurFocusedWindowSoftInputMode));
- }
- onShowHideSoftInputRequested(false /* show */, windowToken, reason, statsToken);
- }
- res = true;
+ mVisibilityApplier.performHideIme(windowToken, statsToken, resultReceiver, reason);
} else {
ImeTracker.get().onCancelled(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE);
- res = false;
}
mBindingController.setCurrentMethodNotVisible();
+ mVisibilityStateComputer.clearImeShowFlags();
mInputShown = false;
mShowRequested = false;
- mShowExplicitlyRequested = false;
- mShowForced = false;
// Cancel existing statsToken for show IME as we got a hide request.
ImeTracker.get().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
mCurStatsToken = null;
- return res;
+ return shouldHideSoftInput;
}
private boolean isImeClientFocused(IBinder windowToken, ClientState cs) {
@@ -3738,8 +3638,9 @@
// In case mShowForced flag affects the next client to keep IME visible, when the current
// client is leaving due to the next focused client, we clear mShowForced flag when the
// next client's targetSdkVersion is T or higher.
- if (mCurFocusedWindow != windowToken && mShowForced && shouldClearFlag) {
- mShowForced = false;
+ final boolean showForced = mVisibilityStateComputer.mShowForced;
+ if (mCurFocusedWindow != windowToken && showForced && shouldClearFlag) {
+ mVisibilityStateComputer.mShowForced = false;
}
// cross-profile access is always allowed here to allow profile-switching.
@@ -3763,6 +3664,12 @@
final boolean startInputByWinGainedFocus =
(startInputFlags & StartInputFlags.WINDOW_GAINED_FOCUS) != 0;
+ // Init the focused window state (e.g. whether the editor has focused or IME focus has
+ // changed from another window).
+ final ImeTargetWindowState windowState = new ImeTargetWindowState(
+ softInputMode, !sameWindowFocused, isTextEditor);
+ mVisibilityStateComputer.setWindowState(windowToken, windowState);
+
if (sameWindowFocused && isTextEditor) {
if (DEBUG) {
Slog.w(TAG, "Window already focused, ignoring focus gain of: " + client
@@ -3812,7 +3719,7 @@
// Because the app might leverage these flags to hide soft-keyboard with showing their own
// UI for input.
if (isTextEditor && editorInfo != null
- && shouldRestoreImeVisibility(windowToken, softInputMode)) {
+ && mVisibilityStateComputer.shouldRestoreImeVisibility(windowState)) {
if (DEBUG) Slog.v(TAG, "Will show input to restore visibility");
res = startInputUncheckedLocked(cs, inputContext, remoteAccessibilityInputConnection,
editorInfo, startInputFlags, startInputReason, unverifiedTargetSdkVersion,
@@ -4001,19 +3908,6 @@
return true;
}
- private boolean shouldRestoreImeVisibility(IBinder windowToken,
- @SoftInputModeFlags int softInputMode) {
- switch (softInputMode & LayoutParams.SOFT_INPUT_MASK_STATE) {
- case LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN:
- return false;
- case LayoutParams.SOFT_INPUT_STATE_HIDDEN:
- if ((softInputMode & LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
- return false;
- }
- }
- return mWindowManagerInternal.shouldRestoreImeVisibility(windowToken);
- }
-
@GuardedBy("ImfLock.class")
private boolean canShowInputMethodPickerLocked(IInputMethodClient client) {
final int uid = Binder.getCallingUid();
@@ -4746,8 +4640,7 @@
}
proto.write(CUR_ID, getCurIdLocked());
proto.write(SHOW_REQUESTED, mShowRequested);
- proto.write(SHOW_EXPLICITLY_REQUESTED, mShowExplicitlyRequested);
- proto.write(SHOW_FORCED, mShowForced);
+ mVisibilityStateComputer.dumpDebug(proto, fieldId);
proto.write(INPUT_SHOWN, mInputShown);
proto.write(IN_FULLSCREEN_MODE, mInFullscreenMode);
proto.write(CUR_TOKEN, Objects.toString(getCurTokenLocked()));
@@ -4760,8 +4653,6 @@
proto.write(BACK_DISPOSITION, mBackDisposition);
proto.write(IME_WINDOW_VISIBILITY, mImeWindowVis);
proto.write(SHOW_IME_WITH_HARD_KEYBOARD, mMenuController.getShowImeWithHardKeyboard());
- proto.write(ACCESSIBILITY_REQUESTING_NO_SOFT_KEYBOARD,
- mAccessibilityRequestingNoSoftKeyboard);
proto.end(token);
}
}
@@ -4795,25 +4686,10 @@
ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
return;
}
- if (!setVisible) {
- if (mCurClient != null) {
- ImeTracker.get().onProgress(statsToken,
- ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
-
- mWindowManagerInternal.hideIme(
- mHideRequestWindowMap.get(windowToken),
- mCurClient.mSelfReportedDisplayId, statsToken);
- } else {
- ImeTracker.get().onFailed(statsToken,
- ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
- }
- } else {
- ImeTracker.get().onProgress(statsToken,
- ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
- // Send to window manager to show IME after IME layout finishes.
- mWindowManagerInternal.showImePostLayout(mShowRequestWindowMap.get(windowToken),
- statsToken);
- }
+ final IBinder requestToken = mVisibilityStateComputer.getWindowTokenFrom(windowToken);
+ mVisibilityApplier.applyImeVisibility(requestToken, statsToken,
+ setVisible ? ImeVisibilityStateComputer.STATE_SHOW_IME
+ : ImeVisibilityStateComputer.STATE_HIDE_IME);
}
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
@@ -4857,7 +4733,7 @@
/** Called right after {@link com.android.internal.inputmethod.IInputMethod#showSoftInput}. */
@GuardedBy("ImfLock.class")
- private void onShowHideSoftInputRequested(boolean show, IBinder requestToken,
+ void onShowHideSoftInputRequested(boolean show, IBinder requestToken,
@SoftInputShowHideReason int reason, @Nullable ImeTracker.Token statsToken) {
final WindowManagerInternal.ImeTargetInfo info =
mWindowManagerInternal.onToggleImeRequested(
@@ -5988,14 +5864,11 @@
method = getCurMethodLocked();
p.println(" mCurMethod=" + getCurMethodLocked());
p.println(" mEnabledSession=" + mEnabledSession);
- p.println(" mShowRequested=" + mShowRequested
- + " mShowExplicitlyRequested=" + mShowExplicitlyRequested
- + " mShowForced=" + mShowForced
- + " mInputShown=" + mInputShown);
+ p.println(" mShowRequested=" + mShowRequested + " mInputShown=" + mInputShown);
+ mVisibilityStateComputer.dump(pw);
p.println(" mInFullscreenMode=" + mInFullscreenMode);
p.println(" mSystemReady=" + mSystemReady + " mInteractive=" + mIsInteractive);
p.println(" mSettingsObserver=" + mSettingsObserver);
- p.println(" mImeHiddenByDisplayPolicy=" + mImeHiddenByDisplayPolicy);
p.println(" mStylusIds=" + (mStylusIds != null
? Arrays.toString(mStylusIds.toArray()) : ""));
p.println(" mSwitchingController:");
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
index 4d525da..9b42cfc 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
@@ -36,6 +36,7 @@
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
import android.os.Handler;
import android.os.PowerManager;
import android.os.SystemClock;
@@ -103,12 +104,12 @@
/**
* Number of boots until we consider the escrow data to be stale for the purposes of metrics.
- * <p>
- * If the delta between the current boot number and the boot number stored when the mechanism
+ *
+ * <p>If the delta between the current boot number and the boot number stored when the mechanism
* was armed is under this number and the escrow mechanism fails, we report it as a failure of
* the mechanism.
- * <p>
- * If the delta over this number and escrow fails, we will not report the metric as failed
+ *
+ * <p>If the delta over this number and escrow fails, we will not report the metric as failed
* since there most likely was some other issue if the device rebooted several times before
* getting to the escrow restore code.
*/
@@ -120,8 +121,11 @@
*/
private static final int DEFAULT_LOAD_ESCROW_DATA_RETRY_COUNT = 3;
private static final int DEFAULT_LOAD_ESCROW_DATA_RETRY_INTERVAL_SECONDS = 30;
+
// 3 minutes. It's enough for the default 3 retries with 30 seconds interval
- private static final int DEFAULT_WAKE_LOCK_TIMEOUT_MILLIS = 180_000;
+ private static final int DEFAULT_LOAD_ESCROW_BASE_TIMEOUT_MILLIS = 180_000;
+ // 5 seconds. An extension of the overall RoR timeout to account for overhead.
+ private static final int DEFAULT_LOAD_ESCROW_TIMEOUT_EXTENSION_MILLIS = 5000;
@IntDef(prefix = {"ERROR_"}, value = {
ERROR_NONE,
@@ -133,6 +137,7 @@
ERROR_PROVIDER_MISMATCH,
ERROR_KEYSTORE_FAILURE,
ERROR_NO_NETWORK,
+ ERROR_TIMEOUT_EXHAUSTED,
})
@Retention(RetentionPolicy.SOURCE)
@interface RebootEscrowErrorCode {
@@ -147,6 +152,7 @@
static final int ERROR_PROVIDER_MISMATCH = 6;
static final int ERROR_KEYSTORE_FAILURE = 7;
static final int ERROR_NO_NETWORK = 8;
+ static final int ERROR_TIMEOUT_EXHAUSTED = 9;
private @RebootEscrowErrorCode int mLoadEscrowDataErrorCode = ERROR_NONE;
@@ -168,6 +174,15 @@
/** Notified when mRebootEscrowReady changes. */
private RebootEscrowListener mRebootEscrowListener;
+ /** Set when unlocking reboot escrow times out. */
+ private boolean mRebootEscrowTimedOut = false;
+
+ /**
+ * Set when {@link #loadRebootEscrowDataWithRetry} is called to ensure the function is only
+ * called once.
+ */
+ private boolean mLoadEscrowDataWithRetry = false;
+
/**
* Hold this lock when checking or generating the reboot escrow key.
*/
@@ -192,6 +207,7 @@
PowerManager.WakeLock mWakeLock;
+ private ConnectivityManager.NetworkCallback mNetworkCallback;
interface Callbacks {
boolean isUserSecure(int userId);
@@ -246,6 +262,11 @@
"server_based_ror_enabled", false);
}
+ public boolean waitForInternet() {
+ return DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_OTA, "wait_for_internet_ror", false);
+ }
+
public boolean isNetworkConnected() {
final ConnectivityManager connectivityManager =
mContext.getSystemService(ConnectivityManager.class);
@@ -263,6 +284,38 @@
NetworkCapabilities.NET_CAPABILITY_VALIDATED);
}
+ /**
+ * Request network with internet connectivity with timeout.
+ *
+ * @param networkCallback callback to be executed if connectivity manager exists.
+ * @return true if success
+ */
+ public boolean requestNetworkWithInternet(
+ ConnectivityManager.NetworkCallback networkCallback) {
+ final ConnectivityManager connectivityManager =
+ mContext.getSystemService(ConnectivityManager.class);
+ if (connectivityManager == null) {
+ return false;
+ }
+ NetworkRequest request =
+ new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ .build();
+
+ connectivityManager.requestNetwork(
+ request, networkCallback, getLoadEscrowTimeoutMillis());
+ return true;
+ }
+
+ public void stopRequestingNetwork(ConnectivityManager.NetworkCallback networkCallback) {
+ final ConnectivityManager connectivityManager =
+ mContext.getSystemService(ConnectivityManager.class);
+ if (connectivityManager == null) {
+ return;
+ }
+ connectivityManager.unregisterNetworkCallback(networkCallback);
+ }
+
public Context getContext() {
return mContext;
}
@@ -318,6 +371,16 @@
DEFAULT_LOAD_ESCROW_DATA_RETRY_INTERVAL_SECONDS);
}
+ @VisibleForTesting
+ public int getLoadEscrowTimeoutMillis() {
+ return DEFAULT_LOAD_ESCROW_BASE_TIMEOUT_MILLIS;
+ }
+
+ @VisibleForTesting
+ public int getWakeLockTimeoutMillis() {
+ return getLoadEscrowTimeoutMillis() + DEFAULT_LOAD_ESCROW_TIMEOUT_EXTENSION_MILLIS;
+ }
+
public void reportMetric(boolean success, int errorCode, int serviceType, int attemptCount,
int escrowDurationInSeconds, int vbmetaDigestStatus,
int durationSinceBootCompleteInSeconds) {
@@ -351,13 +414,37 @@
mKeyStoreManager = injector.getKeyStoreManager();
}
- private void onGetRebootEscrowKeyFailed(List<UserInfo> users, int attemptCount) {
+ /** Wrapper function to set error code serialized through handler, */
+ private void setLoadEscrowDataErrorCode(@RebootEscrowErrorCode int value, Handler handler) {
+ if (mInjector.waitForInternet()) {
+ mInjector.post(
+ handler,
+ () -> {
+ mLoadEscrowDataErrorCode = value;
+ });
+ } else {
+ mLoadEscrowDataErrorCode = value;
+ }
+ }
+
+ /** Wrapper function to compare and set error code serialized through handler. */
+ private void compareAndSetLoadEscrowDataErrorCode(
+ @RebootEscrowErrorCode int expectedValue,
+ @RebootEscrowErrorCode int newValue,
+ Handler handler) {
+ if (expectedValue == mLoadEscrowDataErrorCode) {
+ setLoadEscrowDataErrorCode(newValue, handler);
+ }
+ }
+
+ private void onGetRebootEscrowKeyFailed(
+ List<UserInfo> users, int attemptCount, Handler retryHandler) {
Slog.w(TAG, "Had reboot escrow data for users, but no key; removing escrow storage.");
for (UserInfo user : users) {
mStorage.removeRebootEscrow(user.id);
}
- onEscrowRestoreComplete(false, attemptCount);
+ onEscrowRestoreComplete(false, attemptCount, retryHandler);
}
void loadRebootEscrowDataIfAvailable(Handler retryHandler) {
@@ -380,39 +467,130 @@
mWakeLock = mInjector.getWakeLock();
if (mWakeLock != null) {
mWakeLock.setReferenceCounted(false);
- mWakeLock.acquire(DEFAULT_WAKE_LOCK_TIMEOUT_MILLIS);
+ mWakeLock.acquire(mInjector.getWakeLockTimeoutMillis());
+ }
+
+ if (mInjector.waitForInternet()) {
+ // Timeout to stop retrying same as the wake lock timeout.
+ mInjector.postDelayed(
+ retryHandler,
+ () -> {
+ mRebootEscrowTimedOut = true;
+ },
+ mInjector.getLoadEscrowTimeoutMillis());
+
+ mInjector.post(
+ retryHandler,
+ () -> loadRebootEscrowDataOnInternet(retryHandler, users, rebootEscrowUsers));
+ return;
}
mInjector.post(retryHandler, () -> loadRebootEscrowDataWithRetry(
retryHandler, 0, users, rebootEscrowUsers));
}
- void scheduleLoadRebootEscrowDataOrFail(Handler retryHandler, int attemptNumber,
- List<UserInfo> users, List<UserInfo> rebootEscrowUsers) {
+ void scheduleLoadRebootEscrowDataOrFail(
+ Handler retryHandler,
+ int attemptNumber,
+ List<UserInfo> users,
+ List<UserInfo> rebootEscrowUsers) {
Objects.requireNonNull(retryHandler);
final int retryLimit = mInjector.getLoadEscrowDataRetryLimit();
final int retryIntervalInSeconds = mInjector.getLoadEscrowDataRetryIntervalSeconds();
- if (attemptNumber < retryLimit) {
+ if (attemptNumber < retryLimit && !mRebootEscrowTimedOut) {
Slog.i(TAG, "Scheduling loadRebootEscrowData retry number: " + attemptNumber);
mInjector.postDelayed(retryHandler, () -> loadRebootEscrowDataWithRetry(
- retryHandler, attemptNumber, users, rebootEscrowUsers),
+ retryHandler, attemptNumber, users, rebootEscrowUsers),
retryIntervalInSeconds * 1000);
return;
}
+ if (mInjector.waitForInternet()) {
+ if (mRebootEscrowTimedOut) {
+ Slog.w(TAG, "Failed to load reboot escrow data within timeout");
+ compareAndSetLoadEscrowDataErrorCode(
+ ERROR_NONE, ERROR_TIMEOUT_EXHAUSTED, retryHandler);
+ } else {
+ Slog.w(
+ TAG,
+ "Failed to load reboot escrow data after " + attemptNumber + " attempts");
+ compareAndSetLoadEscrowDataErrorCode(
+ ERROR_NONE, ERROR_RETRY_COUNT_EXHAUSTED, retryHandler);
+ }
+ onGetRebootEscrowKeyFailed(users, attemptNumber, retryHandler);
+ return;
+ }
+
Slog.w(TAG, "Failed to load reboot escrow data after " + attemptNumber + " attempts");
if (mInjector.serverBasedResumeOnReboot() && !mInjector.isNetworkConnected()) {
mLoadEscrowDataErrorCode = ERROR_NO_NETWORK;
} else {
mLoadEscrowDataErrorCode = ERROR_RETRY_COUNT_EXHAUSTED;
}
- onGetRebootEscrowKeyFailed(users, attemptNumber);
+ onGetRebootEscrowKeyFailed(users, attemptNumber, retryHandler);
}
- void loadRebootEscrowDataWithRetry(Handler retryHandler, int attemptNumber,
- List<UserInfo> users, List<UserInfo> rebootEscrowUsers) {
+ void loadRebootEscrowDataOnInternet(
+ Handler retryHandler, List<UserInfo> users, List<UserInfo> rebootEscrowUsers) {
+
+ // HAL-Based RoR does not require network connectivity.
+ if (!mInjector.serverBasedResumeOnReboot()) {
+ loadRebootEscrowDataWithRetry(
+ retryHandler, /* attemptNumber = */ 0, users, rebootEscrowUsers);
+ return;
+ }
+
+ mNetworkCallback =
+ new ConnectivityManager.NetworkCallback() {
+ @Override
+ public void onAvailable(Network network) {
+ compareAndSetLoadEscrowDataErrorCode(
+ ERROR_NO_NETWORK, ERROR_NONE, retryHandler);
+
+ if (!mLoadEscrowDataWithRetry) {
+ mLoadEscrowDataWithRetry = true;
+ // Only kickoff retry mechanism on first onAvailable call.
+ loadRebootEscrowDataWithRetry(
+ retryHandler,
+ /* attemptNumber = */ 0,
+ users,
+ rebootEscrowUsers);
+ }
+ }
+
+ @Override
+ public void onUnavailable() {
+ Slog.w(TAG, "Failed to connect to network within timeout");
+ compareAndSetLoadEscrowDataErrorCode(
+ ERROR_NONE, ERROR_NO_NETWORK, retryHandler);
+ onGetRebootEscrowKeyFailed(users, /* attemptCount= */ 0, retryHandler);
+ }
+
+ @Override
+ public void onLost(Network lostNetwork) {
+ // TODO(b/231660348): If network is lost, wait for network to become
+ // available again.
+ Slog.w(TAG, "Network lost, still attempting to load escrow key.");
+ compareAndSetLoadEscrowDataErrorCode(
+ ERROR_NONE, ERROR_NO_NETWORK, retryHandler);
+ }
+ };
+
+ // Fallback to retrying without waiting for internet on failure.
+ boolean success = mInjector.requestNetworkWithInternet(mNetworkCallback);
+ if (!success) {
+ loadRebootEscrowDataWithRetry(
+ retryHandler, /* attemptNumber = */ 0, users, rebootEscrowUsers);
+ }
+ }
+
+ void loadRebootEscrowDataWithRetry(
+ Handler retryHandler,
+ int attemptNumber,
+ List<UserInfo> users,
+ List<UserInfo> rebootEscrowUsers) {
// Fetch the key from keystore to decrypt the escrow data & escrow key; this key is
// generated before reboot. Note that we will clear the escrow key even if the keystore key
// is null.
@@ -423,7 +601,7 @@
RebootEscrowKey escrowKey;
try {
- escrowKey = getAndClearRebootEscrowKey(kk);
+ escrowKey = getAndClearRebootEscrowKey(kk, retryHandler);
} catch (IOException e) {
Slog.i(TAG, "Failed to load escrow key, scheduling retry.", e);
scheduleLoadRebootEscrowDataOrFail(retryHandler, attemptNumber + 1, users,
@@ -438,12 +616,12 @@
? RebootEscrowProviderInterface.TYPE_SERVER_BASED
: RebootEscrowProviderInterface.TYPE_HAL;
if (providerType != mStorage.getInt(REBOOT_ESCROW_KEY_PROVIDER, -1, USER_SYSTEM)) {
- mLoadEscrowDataErrorCode = ERROR_PROVIDER_MISMATCH;
+ setLoadEscrowDataErrorCode(ERROR_PROVIDER_MISMATCH, retryHandler);
} else {
- mLoadEscrowDataErrorCode = ERROR_LOAD_ESCROW_KEY;
+ setLoadEscrowDataErrorCode(ERROR_LOAD_ESCROW_KEY, retryHandler);
}
}
- onGetRebootEscrowKeyFailed(users, attemptNumber + 1);
+ onGetRebootEscrowKeyFailed(users, attemptNumber + 1, retryHandler);
return;
}
@@ -454,10 +632,10 @@
allUsersUnlocked &= restoreRebootEscrowForUser(user.id, escrowKey, kk);
}
- if (!allUsersUnlocked && mLoadEscrowDataErrorCode == ERROR_NONE) {
- mLoadEscrowDataErrorCode = ERROR_UNLOCK_ALL_USERS;
+ if (!allUsersUnlocked) {
+ compareAndSetLoadEscrowDataErrorCode(ERROR_NONE, ERROR_UNLOCK_ALL_USERS, retryHandler);
}
- onEscrowRestoreComplete(allUsersUnlocked, attemptNumber + 1);
+ onEscrowRestoreComplete(allUsersUnlocked, attemptNumber + 1, retryHandler);
}
private void clearMetricsStorage() {
@@ -497,7 +675,8 @@
.REBOOT_ESCROW_RECOVERY_REPORTED__VBMETA_DIGEST_STATUS__MISMATCH;
}
- private void reportMetricOnRestoreComplete(boolean success, int attemptCount) {
+ private void reportMetricOnRestoreComplete(
+ boolean success, int attemptCount, Handler retryHandler) {
int serviceType = mInjector.serverBasedResumeOnReboot()
? FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED__TYPE__SERVER_BASED
: FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED__TYPE__HAL;
@@ -511,52 +690,69 @@
}
int vbmetaDigestStatus = getVbmetaDigestStatusOnRestoreComplete();
- if (!success && mLoadEscrowDataErrorCode == ERROR_NONE) {
- mLoadEscrowDataErrorCode = ERROR_UNKNOWN;
+ if (!success) {
+ compareAndSetLoadEscrowDataErrorCode(ERROR_NONE, ERROR_UNKNOWN, retryHandler);
}
- Slog.i(TAG, "Reporting RoR recovery metrics, success: " + success + ", service type: "
- + serviceType + ", error code: " + mLoadEscrowDataErrorCode);
+ Slog.i(
+ TAG,
+ "Reporting RoR recovery metrics, success: "
+ + success
+ + ", service type: "
+ + serviceType
+ + ", error code: "
+ + mLoadEscrowDataErrorCode);
// TODO(179105110) report the duration since boot complete.
- mInjector.reportMetric(success, mLoadEscrowDataErrorCode, serviceType, attemptCount,
- escrowDurationInSeconds, vbmetaDigestStatus, -1);
+ mInjector.reportMetric(
+ success,
+ mLoadEscrowDataErrorCode,
+ serviceType,
+ attemptCount,
+ escrowDurationInSeconds,
+ vbmetaDigestStatus,
+ -1);
- mLoadEscrowDataErrorCode = ERROR_NONE;
+ setLoadEscrowDataErrorCode(ERROR_NONE, retryHandler);
}
- private void onEscrowRestoreComplete(boolean success, int attemptCount) {
+ private void onEscrowRestoreComplete(boolean success, int attemptCount, Handler retryHandler) {
int previousBootCount = mStorage.getInt(REBOOT_ESCROW_ARMED_KEY, -1, USER_SYSTEM);
int bootCountDelta = mInjector.getBootCount() - previousBootCount;
if (success || (previousBootCount != -1 && bootCountDelta <= BOOT_COUNT_TOLERANCE)) {
- reportMetricOnRestoreComplete(success, attemptCount);
+ reportMetricOnRestoreComplete(success, attemptCount, retryHandler);
}
-
// Clear the old key in keystore. A new key will be generated by new RoR requests.
mKeyStoreManager.clearKeyStoreEncryptionKey();
// Clear the saved reboot escrow provider
mInjector.clearRebootEscrowProvider();
clearMetricsStorage();
+ if (mNetworkCallback != null) {
+ mInjector.stopRequestingNetwork(mNetworkCallback);
+ }
+
if (mWakeLock != null) {
mWakeLock.release();
}
}
- private RebootEscrowKey getAndClearRebootEscrowKey(SecretKey kk) throws IOException {
+ private RebootEscrowKey getAndClearRebootEscrowKey(SecretKey kk, Handler retryHandler)
+ throws IOException {
RebootEscrowProviderInterface rebootEscrowProvider =
mInjector.createRebootEscrowProviderIfNeeded();
if (rebootEscrowProvider == null) {
- Slog.w(TAG,
+ Slog.w(
+ TAG,
"Had reboot escrow data for users, but RebootEscrowProvider is unavailable");
- mLoadEscrowDataErrorCode = ERROR_NO_PROVIDER;
+ setLoadEscrowDataErrorCode(ERROR_NO_PROVIDER, retryHandler);
return null;
}
// Server based RoR always need the decryption key from keystore.
if (rebootEscrowProvider.getType() == RebootEscrowProviderInterface.TYPE_SERVER_BASED
&& kk == null) {
- mLoadEscrowDataErrorCode = ERROR_KEYSTORE_FAILURE;
+ setLoadEscrowDataErrorCode(ERROR_KEYSTORE_FAILURE, retryHandler);
return null;
}
@@ -870,6 +1066,9 @@
pw.print("mRebootEscrowListener=");
pw.println(mRebootEscrowListener);
+ pw.print("mLoadEscrowDataErrorCode=");
+ pw.println(mLoadEscrowDataErrorCode);
+
boolean keySet;
synchronized (mKeyGenerationLock) {
keySet = mPendingRebootEscrowKey != null;
diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
index e1a990d..c90554d 100644
--- a/services/core/java/com/android/server/media/BluetoothRouteProvider.java
+++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
@@ -59,17 +59,9 @@
private static final String HEARING_AID_ROUTE_ID_PREFIX = "HEARING_AID_";
private static final String LE_AUDIO_ROUTE_ID_PREFIX = "LE_AUDIO_";
- @SuppressWarnings("WeakerAccess") /* synthetic access */
// Maps hardware address to BluetoothRouteInfo
- final Map<String, BluetoothRouteInfo> mBluetoothRoutes = new HashMap<>();
- @SuppressWarnings("WeakerAccess") /* synthetic access */
- final List<BluetoothRouteInfo> mActiveRoutes = new ArrayList<>();
- @SuppressWarnings("WeakerAccess") /* synthetic access */
- BluetoothA2dp mA2dpProfile;
- @SuppressWarnings("WeakerAccess") /* synthetic access */
- BluetoothHearingAid mHearingAidProfile;
- @SuppressWarnings("WeakerAccess") /* synthetic access */
- BluetoothLeAudio mLeAudioProfile;
+ private final Map<String, BluetoothRouteInfo> mBluetoothRoutes = new HashMap<>();
+ private final List<BluetoothRouteInfo> mActiveRoutes = new ArrayList<>();
// Route type -> volume map
private final SparseIntArray mVolumeMap = new SparseIntArray();
@@ -83,6 +75,10 @@
private final BroadcastReceiver mBroadcastReceiver = new BluetoothBroadcastReceiver();
private final BluetoothProfileListener mProfileListener = new BluetoothProfileListener();
+ private BluetoothA2dp mA2dpProfile;
+ private BluetoothHearingAid mHearingAidProfile;
+ private BluetoothLeAudio mLeAudioProfile;
+
/**
* Create an instance of {@link BluetoothRouteProvider}.
* It may return {@code null} if Bluetooth is not supported on this hardware platform.
@@ -109,7 +105,7 @@
buildBluetoothRoutes();
}
- public void start(UserHandle user) {
+ void start(UserHandle user) {
mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.A2DP);
mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEARING_AID);
mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.LE_AUDIO);
@@ -133,7 +129,7 @@
mIntentFilter, null, null);
}
- public void stop() {
+ void stop() {
mContext.unregisterReceiver(mBroadcastReceiver);
}
@@ -144,7 +140,7 @@
* @param routeId the id of the Bluetooth device. {@code null} denotes to clear the use of
* BT routes.
*/
- public void transferTo(@Nullable String routeId) {
+ void transferTo(@Nullable String routeId) {
if (routeId == null) {
clearActiveDevices();
return;
@@ -158,7 +154,7 @@
}
if (mBluetoothAdapter != null) {
- mBluetoothAdapter.setActiveDevice(btRouteInfo.btDevice, ACTIVE_DEVICE_AUDIO);
+ mBluetoothAdapter.setActiveDevice(btRouteInfo.mBtDevice, ACTIVE_DEVICE_AUDIO);
}
}
@@ -183,7 +179,7 @@
for (BluetoothDevice device : bondedDevices) {
if (device.isConnected()) {
BluetoothRouteInfo newBtRoute = createBluetoothRoute(device);
- if (newBtRoute.connectedProfiles.size() > 0) {
+ if (newBtRoute.mConnectedProfiles.size() > 0) {
mBluetoothRoutes.put(device.getAddress(), newBtRoute);
}
}
@@ -195,14 +191,14 @@
MediaRoute2Info getSelectedRoute() {
// For now, active routes can be multiple only when a pair of hearing aid devices is active.
// Let the first active device represent them.
- return (mActiveRoutes.isEmpty() ? null : mActiveRoutes.get(0).route);
+ return (mActiveRoutes.isEmpty() ? null : mActiveRoutes.get(0).mRoute);
}
@NonNull
List<MediaRoute2Info> getTransferableRoutes() {
List<MediaRoute2Info> routes = getAllBluetoothRoutes();
for (BluetoothRouteInfo btRoute : mActiveRoutes) {
- routes.remove(btRoute.route);
+ routes.remove(btRoute.mRoute);
}
return routes;
}
@@ -220,11 +216,11 @@
for (BluetoothRouteInfo btRoute : mBluetoothRoutes.values()) {
// A pair of hearing aid devices or having the same hardware address
- if (routeIds.contains(btRoute.route.getId())) {
+ if (routeIds.contains(btRoute.mRoute.getId())) {
continue;
}
- routes.add(btRoute.route);
- routeIds.add(btRoute.route.getId());
+ routes.add(btRoute.mRoute);
+ routeIds.add(btRoute.mRoute.getId());
}
return routes;
}
@@ -234,7 +230,7 @@
return null;
}
for (BluetoothRouteInfo btRouteInfo : mBluetoothRoutes.values()) {
- if (TextUtils.equals(btRouteInfo.route.getId(), routeId)) {
+ if (TextUtils.equals(btRouteInfo.mRoute.getId(), routeId)) {
return btRouteInfo;
}
}
@@ -246,7 +242,7 @@
*
* @return true if devices can be handled by the provider.
*/
- public boolean updateVolumeForDevices(int devices, int volume) {
+ boolean updateVolumeForDevices(int devices, int volume) {
int routeType;
if ((devices & (AudioSystem.DEVICE_OUT_HEARING_AID)) != 0) {
routeType = MediaRoute2Info.TYPE_HEARING_AID;
@@ -263,10 +259,10 @@
boolean shouldNotify = false;
for (BluetoothRouteInfo btRoute : mActiveRoutes) {
- if (btRoute.route.getType() != routeType) {
+ if (btRoute.mRoute.getType() != routeType) {
continue;
}
- btRoute.route = new MediaRoute2Info.Builder(btRoute.route)
+ btRoute.mRoute = new MediaRoute2Info.Builder(btRoute.mRoute)
.setVolume(volume)
.build();
shouldNotify = true;
@@ -285,7 +281,7 @@
private BluetoothRouteInfo createBluetoothRoute(BluetoothDevice device) {
BluetoothRouteInfo newBtRoute = new BluetoothRouteInfo();
- newBtRoute.btDevice = device;
+ newBtRoute.mBtDevice = device;
String routeId = device.getAddress();
String deviceName = device.getName();
@@ -293,26 +289,26 @@
deviceName = mContext.getResources().getText(R.string.unknownName).toString();
}
int type = MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
- newBtRoute.connectedProfiles = new SparseBooleanArray();
+ newBtRoute.mConnectedProfiles = new SparseBooleanArray();
if (mA2dpProfile != null && mA2dpProfile.getConnectedDevices().contains(device)) {
- newBtRoute.connectedProfiles.put(BluetoothProfile.A2DP, true);
+ newBtRoute.mConnectedProfiles.put(BluetoothProfile.A2DP, true);
}
if (mHearingAidProfile != null
&& mHearingAidProfile.getConnectedDevices().contains(device)) {
- newBtRoute.connectedProfiles.put(BluetoothProfile.HEARING_AID, true);
+ newBtRoute.mConnectedProfiles.put(BluetoothProfile.HEARING_AID, true);
// Intentionally assign the same ID for a pair of devices to publish only one of them.
routeId = HEARING_AID_ROUTE_ID_PREFIX + mHearingAidProfile.getHiSyncId(device);
type = MediaRoute2Info.TYPE_HEARING_AID;
}
if (mLeAudioProfile != null
&& mLeAudioProfile.getConnectedDevices().contains(device)) {
- newBtRoute.connectedProfiles.put(BluetoothProfile.LE_AUDIO, true);
+ newBtRoute.mConnectedProfiles.put(BluetoothProfile.LE_AUDIO, true);
routeId = LE_AUDIO_ROUTE_ID_PREFIX + mLeAudioProfile.getGroupId(device);
type = MediaRoute2Info.TYPE_BLE_HEADSET;
}
// Current volume will be set when connected.
- newBtRoute.route = new MediaRoute2Info.Builder(routeId, deviceName)
+ newBtRoute.mRoute = new MediaRoute2Info.Builder(routeId, deviceName)
.addFeature(MediaRoute2Info.FEATURE_LIVE_AUDIO)
.addFeature(MediaRoute2Info.FEATURE_LOCAL_PLAYBACK)
.setConnectionState(MediaRoute2Info.CONNECTION_STATE_DISCONNECTED)
@@ -332,18 +328,18 @@
Slog.w(TAG, "setRouteConnectionState: route shouldn't be null");
return;
}
- if (btRoute.route.getConnectionState() == state) {
+ if (btRoute.mRoute.getConnectionState() == state) {
return;
}
- MediaRoute2Info.Builder builder = new MediaRoute2Info.Builder(btRoute.route)
+ MediaRoute2Info.Builder builder = new MediaRoute2Info.Builder(btRoute.mRoute)
.setConnectionState(state);
builder.setType(btRoute.getRouteType());
if (state == MediaRoute2Info.CONNECTION_STATE_CONNECTED) {
builder.setVolume(mVolumeMap.get(btRoute.getRouteType(), 0));
}
- btRoute.route = builder.build();
+ btRoute.mRoute = builder.build();
}
private void addActiveRoute(BluetoothRouteInfo btRoute) {
@@ -352,7 +348,7 @@
return;
}
if (DEBUG) {
- Log.d(TAG, "Adding active route: " + btRoute.route);
+ Log.d(TAG, "Adding active route: " + btRoute.mRoute);
}
if (mActiveRoutes.contains(btRoute)) {
Slog.w(TAG, "addActiveRoute: btRoute is already added.");
@@ -364,7 +360,7 @@
private void removeActiveRoute(BluetoothRouteInfo btRoute) {
if (DEBUG) {
- Log.d(TAG, "Removing active route: " + btRoute.route);
+ Log.d(TAG, "Removing active route: " + btRoute.mRoute);
}
if (mActiveRoutes.remove(btRoute)) {
setRouteConnectionState(btRoute, STATE_DISCONNECTED);
@@ -378,7 +374,7 @@
Iterator<BluetoothRouteInfo> iter = mActiveRoutes.iterator();
while (iter.hasNext()) {
BluetoothRouteInfo btRoute = iter.next();
- if (btRoute.route.getType() == type) {
+ if (btRoute.mRoute.getType() == type) {
iter.remove();
setRouteConnectionState(btRoute, STATE_DISCONNECTED);
}
@@ -398,9 +394,9 @@
// A bluetooth route with the same route ID should be added.
for (BluetoothRouteInfo btRoute : mBluetoothRoutes.values()) {
- if (TextUtils.equals(btRoute.route.getId(), activeBtRoute.route.getId())
- && !TextUtils.equals(btRoute.btDevice.getAddress(),
- activeBtRoute.btDevice.getAddress())) {
+ if (TextUtils.equals(btRoute.mRoute.getId(), activeBtRoute.mRoute.getId())
+ && !TextUtils.equals(btRoute.mBtDevice.getAddress(),
+ activeBtRoute.mBtDevice.getAddress())) {
addActiveRoute(btRoute);
}
}
@@ -425,19 +421,19 @@
void onBluetoothRoutesUpdated(@NonNull List<MediaRoute2Info> routes);
}
- private class BluetoothRouteInfo {
- public BluetoothDevice btDevice;
- public MediaRoute2Info route;
- public SparseBooleanArray connectedProfiles;
+ private static class BluetoothRouteInfo {
+ private BluetoothDevice mBtDevice;
+ private MediaRoute2Info mRoute;
+ private SparseBooleanArray mConnectedProfiles;
@MediaRoute2Info.Type
int getRouteType() {
// Let hearing aid profile have a priority.
- if (connectedProfiles.get(BluetoothProfile.HEARING_AID, false)) {
+ if (mConnectedProfiles.get(BluetoothProfile.HEARING_AID, false)) {
return MediaRoute2Info.TYPE_HEARING_AID;
}
- if (connectedProfiles.get(BluetoothProfile.LE_AUDIO, false)) {
+ if (mConnectedProfiles.get(BluetoothProfile.LE_AUDIO, false)) {
return MediaRoute2Info.TYPE_BLE_HEADSET;
}
@@ -447,6 +443,7 @@
// These callbacks run on the main thread.
private final class BluetoothProfileListener implements BluetoothProfile.ServiceListener {
+ @Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
List<BluetoothDevice> activeDevices;
switch (profile) {
@@ -480,6 +477,7 @@
notifyBluetoothRoutesUpdated();
}
+ @Override
public void onServiceDisconnected(int profile) {
switch (profile) {
case BluetoothProfile.A2DP:
@@ -496,6 +494,7 @@
}
}
}
+
private class BluetoothBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
@@ -514,6 +513,7 @@
}
private class AdapterStateChangedReceiver implements BluetoothEventReceiver {
+ @Override
public void onReceive(Context context, Intent intent, BluetoothDevice device) {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
if (state == BluetoothAdapter.STATE_OFF
@@ -573,18 +573,18 @@
if (state == BluetoothProfile.STATE_CONNECTED) {
if (btRoute == null) {
btRoute = createBluetoothRoute(device);
- if (btRoute.connectedProfiles.size() > 0) {
+ if (btRoute.mConnectedProfiles.size() > 0) {
mBluetoothRoutes.put(device.getAddress(), btRoute);
notifyBluetoothRoutesUpdated();
}
} else {
- btRoute.connectedProfiles.put(profile, true);
+ btRoute.mConnectedProfiles.put(profile, true);
}
} else if (state == BluetoothProfile.STATE_DISCONNECTING
|| state == BluetoothProfile.STATE_DISCONNECTED) {
if (btRoute != null) {
- btRoute.connectedProfiles.delete(profile);
- if (btRoute.connectedProfiles.size() == 0) {
+ btRoute.mConnectedProfiles.delete(profile);
+ if (btRoute.mConnectedProfiles.size() == 0) {
removeActiveRoute(mBluetoothRoutes.remove(device.getAddress()));
notifyBluetoothRoutesUpdated();
}
diff --git a/services/core/java/com/android/server/NetworkManagementInternal.java b/services/core/java/com/android/server/net/NetworkManagementInternal.java
similarity index 96%
rename from services/core/java/com/android/server/NetworkManagementInternal.java
rename to services/core/java/com/android/server/net/NetworkManagementInternal.java
index f53c454..4926960 100644
--- a/services/core/java/com/android/server/NetworkManagementInternal.java
+++ b/services/core/java/com/android/server/net/NetworkManagementInternal.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.net;
/**
* NetworkManagement local system service interface.
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/net/NetworkManagementService.java
similarity index 99%
rename from services/core/java/com/android/server/NetworkManagementService.java
rename to services/core/java/com/android/server/net/NetworkManagementService.java
index fc26f09..acfa665 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/net/NetworkManagementService.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.net;
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE;
@@ -82,6 +82,8 @@
import com.android.internal.util.Preconditions;
import com.android.net.module.util.NetdUtils;
import com.android.net.module.util.NetdUtils.ModifyOperation;
+import com.android.server.FgThread;
+import com.android.server.LocalServices;
import com.google.android.collect.Maps;
diff --git a/services/core/java/com/android/server/net/TEST_MAPPING b/services/core/java/com/android/server/net/TEST_MAPPING
index 4ccf09e..e0376ed 100644
--- a/services/core/java/com/android/server/net/TEST_MAPPING
+++ b/services/core/java/com/android/server/net/TEST_MAPPING
@@ -15,7 +15,7 @@
"presubmit": [
{
"name": "FrameworksServicesTests",
- "file_patterns": ["(/|^)NetworkPolicy[^/]*\\.java"],
+ "file_patterns": ["(/|^)Network(Policy|Management)[^/]*\\.java"],
"options": [
{
"include-filter": "com.android.server.net."
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 1bbcc83..5ab9f38 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -1007,6 +1007,7 @@
channel.setAllowBubbles(existing != null
? existing.getAllowBubbles()
: NotificationChannel.DEFAULT_ALLOW_BUBBLE);
+ channel.setImportantConversation(false);
}
clearLockedFieldsLocked(channel);
diff --git a/services/core/java/com/android/server/pm/AppDataHelper.java b/services/core/java/com/android/server/pm/AppDataHelper.java
index abaff4a..d252d40 100644
--- a/services/core/java/com/android/server/pm/AppDataHelper.java
+++ b/services/core/java/com/android/server/pm/AppDataHelper.java
@@ -616,6 +616,7 @@
Slog.w(TAG, String.valueOf(e));
}
mPm.getDexManager().notifyPackageDataDestroyed(pkg.getPackageName(), userId);
+ mPm.getDynamicCodeLogger().notifyPackageDataDestroyed(pkg.getPackageName(), userId);
}
}
diff --git a/services/core/java/com/android/server/pm/AppsFilterImpl.java b/services/core/java/com/android/server/pm/AppsFilterImpl.java
index 5ff1909b..ac8ff21 100644
--- a/services/core/java/com/android/server/pm/AppsFilterImpl.java
+++ b/services/core/java/com/android/server/pm/AppsFilterImpl.java
@@ -32,6 +32,7 @@
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED__EVENT_TYPE__PACKAGE_DELETED;
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED__EVENT_TYPE__PACKAGE_REPLACED;
import static com.android.server.pm.AppsFilterUtils.canQueryAsInstaller;
+import static com.android.server.pm.AppsFilterUtils.canQueryAsUpdateOwner;
import static com.android.server.pm.AppsFilterUtils.canQueryViaComponents;
import static com.android.server.pm.AppsFilterUtils.canQueryViaPackage;
import static com.android.server.pm.AppsFilterUtils.canQueryViaUsesLibrary;
@@ -670,7 +671,8 @@
}
}
if (canQueryViaPackage(existingPkg, newPkg)
- || canQueryAsInstaller(existingSetting, newPkg)) {
+ || canQueryAsInstaller(existingSetting, newPkg)
+ || canQueryAsUpdateOwner(existingSetting, newPkg)) {
synchronized (mQueriesViaPackageLock) {
mQueriesViaPackage.add(existingSetting.getAppId(),
newPkgSetting.getAppId());
@@ -697,7 +699,8 @@
}
}
if (canQueryViaPackage(newPkg, existingPkg)
- || canQueryAsInstaller(newPkgSetting, existingPkg)) {
+ || canQueryAsInstaller(newPkgSetting, existingPkg)
+ || canQueryAsUpdateOwner(newPkgSetting, existingPkg)) {
synchronized (mQueriesViaPackageLock) {
mQueriesViaPackage.add(newPkgSetting.getAppId(),
existingSetting.getAppId());
diff --git a/services/core/java/com/android/server/pm/AppsFilterUtils.java b/services/core/java/com/android/server/pm/AppsFilterUtils.java
index 8da1d21..d38b83f 100644
--- a/services/core/java/com/android/server/pm/AppsFilterUtils.java
+++ b/services/core/java/com/android/server/pm/AppsFilterUtils.java
@@ -91,6 +91,15 @@
return false;
}
+ public static boolean canQueryAsUpdateOwner(PackageStateInternal querying,
+ AndroidPackage potentialTarget) {
+ final InstallSource installSource = querying.getInstallSource();
+ if (potentialTarget.getPackageName().equals(installSource.mUpdateOwnerPackageName)) {
+ return true;
+ }
+ return false;
+ }
+
public static boolean canQueryViaUsesLibrary(AndroidPackage querying,
AndroidPackage potentialTarget) {
if (potentialTarget.getLibraryNames().isEmpty()) {
diff --git a/services/core/java/com/android/server/pm/BroadcastHelper.java b/services/core/java/com/android/server/pm/BroadcastHelper.java
index d6233c7..98d6081 100644
--- a/services/core/java/com/android/server/pm/BroadcastHelper.java
+++ b/services/core/java/com/android/server/pm/BroadcastHelper.java
@@ -51,7 +51,6 @@
import com.android.internal.util.ArrayUtils;
import java.util.ArrayList;
-import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Supplier;
@@ -334,6 +333,13 @@
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
packageName, extras, 0, null, null, userIds, instantUserIds,
broadcastAllowlist, null /* filterExtrasForReceiver */, null);
+ // Send to PermissionController for all new users, even if it may not be running for some
+ // users
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
+ packageName, extras, 0,
+ mContext.getPackageManager().getPermissionControllerPackageName(),
+ null, userIds, instantUserIds,
+ broadcastAllowlist, null /* filterExtrasForReceiver */, null);
}
public void sendFirstLaunchBroadcast(String pkgName, String installerPkg,
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 0eac9ef..c6700e6 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -4981,6 +4981,7 @@
String installerPackageName;
String initiatingPackageName;
String originatingPackageName;
+ String updateOwnerPackageName;
final InstallSource installSource = getInstallSource(packageName, callingUid, userId);
if (installSource == null) {
@@ -4996,6 +4997,15 @@
}
}
+ updateOwnerPackageName = installSource.mUpdateOwnerPackageName;
+ if (updateOwnerPackageName != null) {
+ final PackageStateInternal ps = mSettings.getPackage(updateOwnerPackageName);
+ if (ps == null
+ || shouldFilterApplicationIncludingUninstalled(ps, callingUid, userId)) {
+ updateOwnerPackageName = null;
+ }
+ }
+
if (installSource.mIsInitiatingPackageUninstalled) {
// We can't check visibility in the usual way, since the initiating package is no
// longer present. So we apply simpler rules to whether to expose the info:
@@ -5052,7 +5062,8 @@
}
return new InstallSourceInfo(initiatingPackageName, initiatingPackageSigningInfo,
- originatingPackageName, installerPackageName, installSource.mPackageSource);
+ originatingPackageName, installerPackageName, updateOwnerPackageName,
+ installSource.mPackageSource);
}
@PackageManager.EnabledState
diff --git a/services/core/java/com/android/server/pm/CrossProfileIntentResolverEngine.java b/services/core/java/com/android/server/pm/CrossProfileIntentResolverEngine.java
index 1e0822d..397fdd8 100644
--- a/services/core/java/com/android/server/pm/CrossProfileIntentResolverEngine.java
+++ b/services/core/java/com/android/server/pm/CrossProfileIntentResolverEngine.java
@@ -30,6 +30,7 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
+import android.content.pm.UserProperties;
import android.os.Process;
import android.text.TextUtils;
import android.util.Pair;
@@ -147,8 +148,6 @@
return crossProfileDomainInfos;
}
- UserInfo userInfo = mUserManagerInternal.getUserInfo(userId);
-
// Grouping the CrossProfileIntentFilters based on targerId
SparseArray<List<CrossProfileIntentFilter>> crossProfileIntentFiltersByUser =
new SparseArray<>();
@@ -183,11 +182,9 @@
continue;
}
- UserInfo targetUserInfo = mUserManagerInternal.getUserInfo(targetUserId);
-
// Choosing strategy based on source and target user
CrossProfileResolver crossProfileResolver =
- chooseCrossProfileResolver(computer, userInfo, targetUserInfo);
+ chooseCrossProfileResolver(computer, userId, targetUserId);
/*
If {@link CrossProfileResolver} is available for source,target pair we will call it to
@@ -234,23 +231,21 @@
/**
* Returns {@link CrossProfileResolver} strategy based on source and target user
* @param computer {@link Computer} instance used for resolution by {@link ComponentResolverApi}
- * @param sourceUserInfo source user
- * @param targetUserInfo target user
+ * @param sourceUserId source user
+ * @param targetUserId target user
* @return {@code CrossProfileResolver} which has value if source and target have
* strategy configured otherwise null.
*/
@SuppressWarnings("unused")
private CrossProfileResolver chooseCrossProfileResolver(@NonNull Computer computer,
- UserInfo sourceUserInfo, UserInfo targetUserInfo) {
- //todo change isCloneProfile to user properties b/241532322
+ @UserIdInt int sourceUserId, @UserIdInt int targetUserId) {
/**
- * If source or target user is clone profile, using {@link CloneProfileResolver}
- * We would allow CloneProfileResolver only if flag
- * SETTINGS_ALLOW_INTENT_REDIRECTION_FOR_CLONE_PROFILE is enabled
+ * If source or target user is clone profile, using {@link NoFilteringResolver}
+ * We would return NoFilteringResolver only if it is allowed(feature flag is set).
*/
- if (sourceUserInfo.isCloneProfile() || targetUserInfo.isCloneProfile()) {
- if (CloneProfileResolver.isIntentRedirectionForCloneProfileAllowed()) {
- return new CloneProfileResolver(computer.getComponentResolver(),
+ if (shouldUseNoFilteringResolver(sourceUserId, targetUserId)) {
+ if (NoFilteringResolver.isIntentRedirectionAllowed()) {
+ return new NoFilteringResolver(computer.getComponentResolver(),
mUserManager);
} else {
return null;
@@ -624,7 +619,6 @@
categorizeResolveInfoByTargetUser, int sourceUserId, int highestApprovalLevel) {
List<CrossProfileDomainInfo> crossProfileDomainInfos = new ArrayList<>();
- UserInfo sourceUserInfo = mUserManagerInternal.getUserInfo(sourceUserId);
for (int index = 0; index < categorizeResolveInfoByTargetUser.size(); index++) {
@@ -634,8 +628,8 @@
} else {
// finding cross profile strategy based on source and target user
CrossProfileResolver crossProfileIntentResolver =
- chooseCrossProfileResolver(computer, sourceUserInfo, mUserManagerInternal
- .getUserInfo(categorizeResolveInfoByTargetUser.keyAt(index)));
+ chooseCrossProfileResolver(computer, sourceUserId,
+ categorizeResolveInfoByTargetUser.keyAt(index));
// if strategy is available call it and add its filtered results
if (crossProfileIntentResolver != null) {
crossProfileDomainInfos.addAll(crossProfileIntentResolver
@@ -678,4 +672,32 @@
&& crossProfileDomainInfos.get(0).mResolveInfo != null
&& crossProfileDomainInfos.get(0).mResolveInfo.priority >= 0;
}
+
+ /**
+ * Deciding if we need to user {@link NoFilteringResolver} based on source and target user
+ * @param sourceUserId id of initiating user
+ * @param targetUserId id of cross profile linked user
+ * @return true if {@link NoFilteringResolver} is applicable in this case.
+ */
+ private boolean shouldUseNoFilteringResolver(@UserIdInt int sourceUserId,
+ @UserIdInt int targetUserId) {
+ return isNoFilteringPropertyConfiguredForUser(sourceUserId)
+ || isNoFilteringPropertyConfiguredForUser(targetUserId);
+ }
+
+ /**
+ * Check if configure property for cross profile intent resolution strategy for user is
+ * {@link UserProperties#CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_NO_FILTERING}
+ * @param userId id of user to check for property
+ * @return true if user have property set to
+ * {@link UserProperties#CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_NO_FILTERING}
+ */
+ private boolean isNoFilteringPropertyConfiguredForUser(@UserIdInt int userId) {
+ if (!mUserManager.isProfile(userId)) return false;
+ UserProperties userProperties = mUserManagerInternal.getUserProperties(userId);
+ if (userProperties == null) return false;
+
+ return userProperties.getCrossProfileIntentResolutionStrategy()
+ == UserProperties.CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_NO_FILTERING;
+ }
}
diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java
index 39aa9c1..cf447a7 100644
--- a/services/core/java/com/android/server/pm/DexOptHelper.java
+++ b/services/core/java/com/android/server/pm/DexOptHelper.java
@@ -41,6 +41,7 @@
import android.annotation.RequiresPermission;
import android.app.ActivityManager;
import android.app.AppGlobals;
+import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.content.pm.SharedLibraryInfo;
@@ -84,8 +85,10 @@
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
+import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
@@ -416,17 +419,22 @@
return true;
}
+ @DexOptResult int dexoptStatus;
if (options.isDexoptOnlySecondaryDex()) {
- // TODO(b/251903639): Call into ART Service.
- try {
- return mPm.getDexManager().dexoptSecondaryDex(options);
- } catch (LegacyDexoptDisabledException e) {
- throw new RuntimeException(e);
+ Optional<Integer> artSrvRes = performDexOptWithArtService(options, 0 /* extraFlags */);
+ if (artSrvRes.isPresent()) {
+ dexoptStatus = artSrvRes.get();
+ } else {
+ try {
+ return mPm.getDexManager().dexoptSecondaryDex(options);
+ } catch (LegacyDexoptDisabledException e) {
+ throw new RuntimeException(e);
+ }
}
} else {
- int dexoptStatus = performDexOptWithStatus(options);
- return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
+ dexoptStatus = performDexOptWithStatus(options);
}
+ return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
}
/**
@@ -455,7 +463,8 @@
// if the package can now be considered up to date for the given filter.
@DexOptResult
private int performDexOptInternal(DexoptOptions options) {
- Optional<Integer> artSrvRes = performDexOptWithArtService(options);
+ Optional<Integer> artSrvRes =
+ performDexOptWithArtService(options, ArtFlags.FLAG_SHOULD_INCLUDE_DEPENDENCIES);
if (artSrvRes.isPresent()) {
return artSrvRes.get();
}
@@ -492,7 +501,8 @@
* @return a {@link DexOptResult}, or empty if the request isn't supported so that it is
* necessary to fall back to the legacy code paths.
*/
- private Optional<Integer> performDexOptWithArtService(DexoptOptions options) {
+ private Optional<Integer> performDexOptWithArtService(DexoptOptions options,
+ /*@OptimizeFlags*/ int extraFlags) {
ArtManagerLocal artManager = getArtManagerLocal();
if (artManager == null) {
return Optional.empty();
@@ -512,18 +522,11 @@
return Optional.of(PackageDexOptimizer.DEX_OPT_SKIPPED);
}
- // TODO(b/245301593): Delete the conditional when ART Service supports
- // FLAG_SHOULD_INCLUDE_DEPENDENCIES and we can just set it unconditionally.
- /*@OptimizeFlags*/ int extraFlags = ops.getUsesLibraries().isEmpty()
- ? 0
- : ArtFlags.FLAG_SHOULD_INCLUDE_DEPENDENCIES;
-
OptimizeParams params = options.convertToOptimizeParams(extraFlags);
if (params == null) {
return Optional.empty();
}
- // TODO(b/251903639): Either remove controlDexOptBlocking, or don't ignore it here.
OptimizeResult result;
try {
result = artManager.optimizePackage(snapshot, options.getPackageName(), params);
@@ -532,21 +535,6 @@
return Optional.empty();
}
- // TODO(b/251903639): Move this to ArtManagerLocal.addOptimizePackageDoneCallback when
- // it is implemented.
- for (OptimizeResult.PackageOptimizeResult pkgRes : result.getPackageOptimizeResults()) {
- PackageState ps = snapshot.getPackageState(pkgRes.getPackageName());
- AndroidPackage ap = ps != null ? ps.getAndroidPackage() : null;
- if (ap != null) {
- CompilerStats.PackageStats stats = mPm.getOrCreateCompilerPackageStats(ap);
- for (OptimizeResult.DexContainerFileOptimizeResult dexRes :
- pkgRes.getDexContainerFileOptimizeResults()) {
- stats.setCompileTime(
- dexRes.getDexContainerFile(), dexRes.getDex2oatWallTimeMillis());
- }
- }
- }
-
return Optional.of(convertToDexOptResult(result));
}
}
@@ -555,9 +543,9 @@
private int performDexOptInternalWithDependenciesLI(
AndroidPackage p, @NonNull PackageStateInternal pkgSetting, DexoptOptions options)
throws LegacyDexoptDisabledException {
- // System server gets a special path.
if (PLATFORM_PACKAGE_NAME.equals(p.getPackageName())) {
- return mPm.getDexManager().dexoptSystemServer(options);
+ // This needs to be done in odrefresh in early boot, for security reasons.
+ throw new IllegalArgumentException("Cannot dexopt the system server");
}
// Select the dex optimizer based on the force parameter.
@@ -628,7 +616,8 @@
// performDexOptWithArtService ignores the snapshot and takes its own, so it can race with
// the package checks above, but at worst the effect is only a bit less friendly error
// below.
- Optional<Integer> artSrvRes = performDexOptWithArtService(options);
+ Optional<Integer> artSrvRes =
+ performDexOptWithArtService(options, ArtFlags.FLAG_SHOULD_INCLUDE_DEPENDENCIES);
int res;
if (artSrvRes.isPresent()) {
res = artSrvRes.get();
@@ -965,6 +954,51 @@
}
}
+ private static class OptimizePackageDoneHandler
+ implements ArtManagerLocal.OptimizePackageDoneCallback {
+ @NonNull private final PackageManagerService mPm;
+
+ OptimizePackageDoneHandler(@NonNull PackageManagerService pm) { mPm = pm; }
+
+ /**
+ * Called after every package optimization operation done by {@link ArtManagerLocal}.
+ */
+ @Override
+ public void onOptimizePackageDone(@NonNull OptimizeResult result) {
+ for (OptimizeResult.PackageOptimizeResult pkgRes : result.getPackageOptimizeResults()) {
+ CompilerStats.PackageStats stats =
+ mPm.getOrCreateCompilerPackageStats(pkgRes.getPackageName());
+ for (OptimizeResult.DexContainerFileOptimizeResult dexRes :
+ pkgRes.getDexContainerFileOptimizeResults()) {
+ stats.setCompileTime(
+ dexRes.getDexContainerFile(), dexRes.getDex2oatWallTimeMillis());
+ }
+ }
+
+ synchronized (mPm.mLock) {
+ mPm.getPackageUsage().maybeWriteAsync(mPm.mSettings.getPackagesLocked());
+ mPm.mCompilerStats.maybeWriteAsync();
+ }
+ }
+ }
+
+ /**
+ * Initializes {@link ArtManagerLocal} before {@link getArtManagerLocal} is called.
+ */
+ public static void initializeArtManagerLocal(
+ @NonNull Context systemContext, @NonNull PackageManagerService pm) {
+ if (!useArtService()) {
+ return;
+ }
+
+ ArtManagerLocal artManager = new ArtManagerLocal(systemContext);
+ // There doesn't appear to be any checks that @NonNull is heeded, so use requireNonNull
+ // below to ensure we don't store away a null that we'll fail on later.
+ artManager.addOptimizePackageDoneCallback(false /* onlyIncludeUpdates */,
+ Runnable::run, new OptimizePackageDoneHandler(Objects.requireNonNull(pm)));
+ LocalManagerRegistry.addManager(ArtManagerLocal.class, artManager);
+ }
+
/**
* Returns {@link ArtManagerLocal} if ART Service should be used for package optimization.
*/
diff --git a/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java b/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java
index b4bcd5b..cae7079 100644
--- a/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java
+++ b/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java
@@ -27,13 +27,17 @@
import android.util.EventLog;
import android.util.Log;
+import com.android.server.LocalManagerRegistry;
import com.android.server.LocalServices;
+import com.android.server.art.DexUseManagerLocal;
+import com.android.server.art.model.DexContainerFileUseInfo;
import com.android.server.pm.dex.DynamicCodeLogger;
import libcore.util.HexEncoding;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -137,6 +141,28 @@
return LocalServices.getService(PackageManagerInternal.class).getDynamicCodeLogger();
}
+ private static void syncDataFromArtService(DynamicCodeLogger dynamicCodeLogger) {
+ DexUseManagerLocal dexUseManagerLocal = DexOptHelper.getDexUseManagerLocal();
+ if (dexUseManagerLocal == null) {
+ // ART Service is not enabled.
+ return;
+ }
+ PackageManagerLocal packageManagerLocal =
+ Objects.requireNonNull(LocalManagerRegistry.getManager(PackageManagerLocal.class));
+ try (PackageManagerLocal.UnfilteredSnapshot snapshot =
+ packageManagerLocal.withUnfilteredSnapshot()) {
+ for (String owningPackageName : snapshot.getPackageStates().keySet()) {
+ for (DexContainerFileUseInfo info :
+ dexUseManagerLocal.getSecondaryDexContainerFileUseInfo(owningPackageName)) {
+ for (String loadingPackageName : info.getLoadingPackages()) {
+ dynamicCodeLogger.recordDex(info.getUserHandle().getIdentifier(),
+ info.getDexContainerFile(), owningPackageName, loadingPackageName);
+ }
+ }
+ }
+ }
+ }
+
private class IdleLoggingThread extends Thread {
private final JobParameters mParams;
@@ -152,6 +178,7 @@
}
DynamicCodeLogger dynamicCodeLogger = getDynamicCodeLogger();
+ syncDataFromArtService(dynamicCodeLogger);
for (String packageName : dynamicCodeLogger.getAllPackagesWithDynamicCodeLoading()) {
if (mIdleLoggingStopRequested) {
Log.w(TAG, "Stopping IdleLoggingJob run at scheduler request");
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 6f7484e..ac4da2e 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -311,10 +311,15 @@
pkgSetting.setForceQueryableOverride(true);
}
- // If this is part of a standard install, set the initiating package name, else rely on
- // previous device state.
InstallSource installSource = request.getInstallSource();
+ final boolean isApex = (scanFlags & SCAN_AS_APEX) != 0;
+ final String updateOwnerFromSysconfig = isApex || !pkgSetting.isSystem() ? null
+ : mPm.mInjector.getSystemConfig().getSystemAppUpdateOwnerPackageName(
+ parsedPackage.getPackageName());
+ // For new install (standard install), the installSource isn't null.
if (installSource != null) {
+ // If this is part of a standard install, set the initiating package name, else rely on
+ // previous device state.
if (installSource.mInitiatingPackageName != null) {
final PackageSetting ips = mPm.mSettings.getPackageLPr(
installSource.mInitiatingPackageName);
@@ -323,7 +328,41 @@
ips.getSignatures());
}
}
+
+ // Handle the update ownership enforcement for APK
+ if (updateOwnerFromSysconfig != null) {
+ // For system app, we always use the update owner from sysconfig if presented.
+ installSource = installSource.setUpdateOwnerPackageName(updateOwnerFromSysconfig);
+ } else if (!parsedPackage.isAllowUpdateOwnership()) {
+ // If the app wants to opt-out of the update ownership enforcement via manifest,
+ // it overrides the installer's use of #setRequestUpdateOwnership.
+ installSource = installSource.setUpdateOwnerPackageName(null);
+ } else if (!isApex) {
+ final boolean isUpdate = oldPkgSetting != null;
+ final String oldUpdateOwner =
+ isUpdate ? oldPkgSetting.getInstallSource().mUpdateOwnerPackageName : null;
+ final boolean isUpdateOwnershipEnabled = oldUpdateOwner != null;
+ final boolean isRequestUpdateOwnership = (request.getInstallFlags()
+ & PackageManager.INSTALL_REQUEST_UPDATE_OWNERSHIP) != 0;
+
+ // Here we assign the update owner for the package, and the rules are:
+ // -. If the installer doesn't request update ownership on initial installation,
+ // keep the update owner as null.
+ // -. If the installer doesn't want to be the owner to provide the subsequent
+ // update (doesn't request to be the update owner), e.g., non-store installer
+ // (file manager), ADB, or DO/PO, we should not update the owner.
+ // -. Else, the installer requests update ownership on initial installation or
+ // update, we use installSource.mUpdateOwnerPackageName as the update owner.
+ if (!isRequestUpdateOwnership || (isUpdate && !isUpdateOwnershipEnabled)) {
+ installSource = installSource.setUpdateOwnerPackageName(oldUpdateOwner);
+ }
+ }
+
pkgSetting.setInstallSource(installSource);
+ // non-standard install (addForInit and install existing packages), installSource is null.
+ } else if (updateOwnerFromSysconfig != null) {
+ // For system app, we always use the update owner from sysconfig if presented.
+ pkgSetting.setUpdateOwnerPackage(updateOwnerFromSysconfig);
}
if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
@@ -1039,15 +1078,48 @@
DeviceConfig.getInt(DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE,
"MinInstallableTargetSdk__min_installable_target_sdk",
0);
- if (parsedPackage.getTargetSdkVersion() < minInstallableTargetSdk) {
+
+ // Skip enforcement when the bypass flag is set
+ boolean bypassLowTargetSdkBlock =
+ ((installFlags & PackageManager.INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK) != 0);
+
+ // Skip enforcement for tests that were installed from adb
+ if (!bypassLowTargetSdkBlock
+ && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) {
+ bypassLowTargetSdkBlock = true;
+ }
+
+ // Skip enforcement if the installer package name is not set
+ // (e.g. "pm install" from shell)
+ if (!bypassLowTargetSdkBlock) {
+ if (request.getInstallerPackageName() == null) {
+ bypassLowTargetSdkBlock = true;
+ } else {
+ // Also skip if the install is occurring from an app that was installed from adb
+ if (mContext
+ .getPackageManager()
+ .getInstallerPackageName(request.getInstallerPackageName()) == null) {
+ bypassLowTargetSdkBlock = true;
+ }
+ }
+ }
+
+ // Skip enforcement when the testOnly flag is set
+ if (!bypassLowTargetSdkBlock && parsedPackage.isTestOnly()) {
+ bypassLowTargetSdkBlock = true;
+ }
+
+ // Enforce the low target sdk install block except when
+ // the --bypass-low-target-sdk-block is set for the install
+ if (!bypassLowTargetSdkBlock
+ && parsedPackage.getTargetSdkVersion() < minInstallableTargetSdk) {
Slog.w(TAG, "App " + parsedPackage.getPackageName()
+ " targets deprecated sdk version");
throw new PrepareFailure(INSTALL_FAILED_DEPRECATED_SDK_VERSION,
- "App package must target at least version "
- + minInstallableTargetSdk);
+ "App package must target at least SDK version "
+ + minInstallableTargetSdk + ", but found "
+ + parsedPackage.getTargetSdkVersion());
}
- } else {
- Slog.i(TAG, "Minimum installable target sdk enforcement not enabled");
}
// Instant apps have several additional install-time checks.
@@ -2755,6 +2827,12 @@
installerPackageName, null /*finishedReceiver*/,
updateUserIds, instantUserIds, null /* broadcastAllowList */, null);
}
+ // Send to PermissionController for all update users, even if it may not be running
+ // for some users
+ mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
+ extras, 0 /*flags*/,
+ mPm.mRequiredPermissionControllerPackage, null /*finishedReceiver*/,
+ updateUserIds, instantUserIds, null /* broadcastAllowList */, null);
// Notify required verifier(s) that are not the installer of record for the package.
for (String verifierPackageName : mPm.mRequiredVerifierPackages) {
if (verifierPackageName != null && !verifierPackageName.equals(
diff --git a/services/core/java/com/android/server/pm/InstallSource.java b/services/core/java/com/android/server/pm/InstallSource.java
index dde9905..65bde51 100644
--- a/services/core/java/com/android/server/pm/InstallSource.java
+++ b/services/core/java/com/android/server/pm/InstallSource.java
@@ -34,12 +34,18 @@
* An instance of InstallSource representing an absence of knowledge of the source of
* a package. Used in preference to null.
*/
- static final InstallSource EMPTY = new InstallSource(null, null, null, INVALID_UID, null,
- false, false, null, PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
+ static final InstallSource EMPTY = new InstallSource(null /* initiatingPackageName */,
+ null /* originatingPackageName */, null /* installerPackageName */, INVALID_UID,
+ null /* updateOwnerPackageName */, null /* installerAttributionTag */,
+ false /* isOrphaned */, false /* isInitiatingPackageUninstalled */,
+ null /* initiatingPackageSignatures */, PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
/** We also memoize this case because it is common - all un-updated system apps. */
private static final InstallSource EMPTY_ORPHANED = new InstallSource(
- null, null, null, INVALID_UID, null, true, false, null,
+ null /* initiatingPackageName */, null /* originatingPackageName */,
+ null /* installerPackageName */, INVALID_UID, null /* updateOwnerPackageName */,
+ null /* installerAttributionTag */, true /* isOrphaned */,
+ false /* isInitiatingPackageUninstalled */, null /* initiatingPackageSignatures */,
PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
/**
@@ -73,6 +79,13 @@
final String mInstallerPackageName;
/**
+ * Package name of the app that requested the installer ownership. Note that this may be
+ * modified.
+ */
+ @Nullable
+ final String mUpdateOwnerPackageName;
+
+ /**
* UID of the installer package, corresponding to the {@link #mInstallerPackageName}.
*/
final int mInstallerPackageUid;
@@ -96,55 +109,64 @@
static InstallSource create(@Nullable String initiatingPackageName,
@Nullable String originatingPackageName, @Nullable String installerPackageName,
- int installerPackageUid, @Nullable String installerAttributionTag, boolean isOrphaned,
+ int installerPackageUid, @Nullable String updateOwnerPackageName,
+ @Nullable String installerAttributionTag, boolean isOrphaned,
boolean isInitiatingPackageUninstalled) {
return create(initiatingPackageName, originatingPackageName, installerPackageName,
- installerPackageUid, installerAttributionTag,
+ installerPackageUid, updateOwnerPackageName, installerAttributionTag,
PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED, isOrphaned,
isInitiatingPackageUninstalled);
}
static InstallSource create(@Nullable String initiatingPackageName,
@Nullable String originatingPackageName, @Nullable String installerPackageName,
- int installerPackageUid, @Nullable String installerAttributionTag, int packageSource) {
+ int installerPackageUid, @Nullable String updateOwnerPackageName,
+ @Nullable String installerAttributionTag, int packageSource) {
return create(initiatingPackageName, originatingPackageName, installerPackageName,
- installerPackageUid, installerAttributionTag, packageSource, false, false);
+ installerPackageUid, updateOwnerPackageName, installerAttributionTag,
+ packageSource, false /* isOrphaned */, false /* isInitiatingPackageUninstalled */);
}
static InstallSource create(@Nullable String initiatingPackageName,
@Nullable String originatingPackageName, @Nullable String installerPackageName,
- int installerPackageUid, @Nullable String installerAttributionTag, int packageSource,
- boolean isOrphaned, boolean isInitiatingPackageUninstalled) {
+ int installerPackageUid, @Nullable String updateOwnerPackageName,
+ @Nullable String installerAttributionTag, int packageSource, boolean isOrphaned,
+ boolean isInitiatingPackageUninstalled) {
return createInternal(
intern(initiatingPackageName),
intern(originatingPackageName),
intern(installerPackageName),
installerPackageUid,
+ intern(updateOwnerPackageName),
installerAttributionTag,
packageSource,
- isOrphaned, isInitiatingPackageUninstalled, null);
+ isOrphaned, isInitiatingPackageUninstalled,
+ null /* initiatingPackageSignatures */);
}
private static InstallSource createInternal(@Nullable String initiatingPackageName,
@Nullable String originatingPackageName, @Nullable String installerPackageName,
- int installerPackageUid, @Nullable String installerAttributionTag, int packageSource,
- boolean isOrphaned, boolean isInitiatingPackageUninstalled,
+ int installerPackageUid, @Nullable String updateOwnerPackageName,
+ @Nullable String installerAttributionTag, int packageSource, boolean isOrphaned,
+ boolean isInitiatingPackageUninstalled,
@Nullable PackageSignatures initiatingPackageSignatures) {
if (initiatingPackageName == null && originatingPackageName == null
- && installerPackageName == null && initiatingPackageSignatures == null
+ && installerPackageName == null && updateOwnerPackageName == null
+ && initiatingPackageSignatures == null
&& !isInitiatingPackageUninstalled
&& packageSource == PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED) {
return isOrphaned ? EMPTY_ORPHANED : EMPTY;
}
return new InstallSource(initiatingPackageName, originatingPackageName,
- installerPackageName, installerPackageUid, installerAttributionTag, isOrphaned,
- isInitiatingPackageUninstalled, initiatingPackageSignatures, packageSource
+ installerPackageName, installerPackageUid, updateOwnerPackageName,
+ installerAttributionTag, isOrphaned, isInitiatingPackageUninstalled,
+ initiatingPackageSignatures, packageSource
);
}
private InstallSource(@Nullable String initiatingPackageName,
@Nullable String originatingPackageName, @Nullable String installerPackageName,
- int installerPackageUid,
+ int installerPackageUid, @Nullable String updateOwnerPackageName,
@Nullable String installerAttributionTag, boolean isOrphaned,
boolean isInitiatingPackageUninstalled,
@Nullable PackageSignatures initiatingPackageSignatures,
@@ -157,6 +179,7 @@
mOriginatingPackageName = originatingPackageName;
mInstallerPackageName = installerPackageName;
mInstallerPackageUid = installerPackageUid;
+ mUpdateOwnerPackageName = updateOwnerPackageName;
mInstallerAttributionTag = installerAttributionTag;
mIsOrphaned = isOrphaned;
mIsInitiatingPackageUninstalled = isInitiatingPackageUninstalled;
@@ -174,9 +197,23 @@
return this;
}
return createInternal(mInitiatingPackageName, mOriginatingPackageName,
- intern(installerPackageName), installerPackageUid, mInstallerAttributionTag,
- mPackageSource, mIsOrphaned, mIsInitiatingPackageUninstalled,
- mInitiatingPackageSignatures);
+ intern(installerPackageName), installerPackageUid, mUpdateOwnerPackageName,
+ mInstallerAttributionTag, mPackageSource, mIsOrphaned,
+ mIsInitiatingPackageUninstalled, mInitiatingPackageSignatures);
+ }
+
+ /**
+ * Return an InstallSource the same as this one except with the specified
+ * {@link #mUpdateOwnerPackageName}.
+ */
+ InstallSource setUpdateOwnerPackageName(@Nullable String updateOwnerPackageName) {
+ if (Objects.equals(updateOwnerPackageName, mUpdateOwnerPackageName)) {
+ return this;
+ }
+ return createInternal(mInitiatingPackageName, mOriginatingPackageName,
+ mInstallerPackageName, mInstallerPackageUid, intern(updateOwnerPackageName),
+ mInstallerAttributionTag, mPackageSource, mIsOrphaned,
+ mIsInitiatingPackageUninstalled, mInitiatingPackageSignatures);
}
/**
@@ -188,8 +225,8 @@
return this;
}
return createInternal(mInitiatingPackageName, mOriginatingPackageName,
- mInstallerPackageName,
- mInstallerPackageUid, mInstallerAttributionTag, mPackageSource, isOrphaned,
+ mInstallerPackageName, mInstallerPackageUid, mUpdateOwnerPackageName,
+ mInstallerAttributionTag, mPackageSource, isOrphaned,
mIsInitiatingPackageUninstalled, mInitiatingPackageSignatures);
}
@@ -202,8 +239,8 @@
return this;
}
return createInternal(mInitiatingPackageName, mOriginatingPackageName,
- mInstallerPackageName,
- mInstallerPackageUid, mInstallerAttributionTag, mPackageSource, mIsOrphaned,
+ mInstallerPackageName, mInstallerPackageUid, mUpdateOwnerPackageName,
+ mInstallerAttributionTag, mPackageSource, mIsOrphaned,
mIsInitiatingPackageUninstalled, signatures);
}
@@ -220,6 +257,7 @@
boolean isInitiatingPackageUninstalled = mIsInitiatingPackageUninstalled;
String originatingPackageName = mOriginatingPackageName;
String installerPackageName = mInstallerPackageName;
+ String updateOwnerPackageName = mUpdateOwnerPackageName;
int installerPackageUid = mInstallerPackageUid;
boolean isOrphaned = mIsOrphaned;
@@ -242,13 +280,18 @@
isOrphaned = true;
modified = true;
}
+ if (packageName.equals(updateOwnerPackageName)) {
+ updateOwnerPackageName = null;
+ modified = true;
+ }
if (!modified) {
return this;
}
return createInternal(mInitiatingPackageName, originatingPackageName, installerPackageName,
- installerPackageUid, null, mPackageSource, isOrphaned,
+ installerPackageUid, updateOwnerPackageName,
+ null /* installerAttributionTag */, mPackageSource, isOrphaned,
isInitiatingPackageUninstalled, mInitiatingPackageSignatures);
}
diff --git a/services/core/java/com/android/server/pm/CloneProfileResolver.java b/services/core/java/com/android/server/pm/NoFilteringResolver.java
similarity index 89%
rename from services/core/java/com/android/server/pm/CloneProfileResolver.java
rename to services/core/java/com/android/server/pm/NoFilteringResolver.java
index 73036f1..492f915 100644
--- a/services/core/java/com/android/server/pm/CloneProfileResolver.java
+++ b/services/core/java/com/android/server/pm/NoFilteringResolver.java
@@ -30,9 +30,10 @@
import java.util.function.Function;
/**
- * Cross Profile intent resolution strategy used for and to clone profile.
+ * Intent resolution strategy used when no filtering is required. As of now, the known use-case is
+ * clone profile.
*/
-public class CloneProfileResolver extends CrossProfileResolver {
+public class NoFilteringResolver extends CrossProfileResolver {
/**
* Feature flag to allow/restrict intent redirection from/to clone profile.
@@ -48,7 +49,7 @@
* Returns true if intent redirection for clone profile feature flag is set
* @return value of flag allow_intent_redirection_for_clone_profile
*/
- public static boolean isIntentRedirectionForCloneProfileAllowed() {
+ public static boolean isIntentRedirectionAllowed() {
final long token = Binder.clearCallingIdentity();
try {
return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_APP_CLONING,
@@ -58,13 +59,13 @@
}
}
- public CloneProfileResolver(ComponentResolverApi componentResolver,
+ public NoFilteringResolver(ComponentResolverApi componentResolver,
UserManagerService userManagerService) {
super(componentResolver, userManagerService);
}
/**
- * This is resolution strategy for Clone Profile.
+ * This is resolution strategy for when no filtering is required.
* In case of clone profile, the profile is supposed to be transparent to end user. To end user
* clone and owner profile should be part of same user space. Hence, the resolution strategy
* would resolve intent in both profile and return combined result without any filtering of the
@@ -105,8 +106,8 @@
}
/**
- * As clone and owner profile are going to be part of the same userspace, we need no filtering
- * out of any clone profile's result
+ * In case of Clone profile, the clone and owner profile are going to be part of the same
+ * userspace, we need no filtering out of any clone profile's result.
* @param intent request
* @param crossProfileDomainInfos resolved in target user
* @param flags for intent resolution
@@ -119,7 +120,7 @@
public List<CrossProfileDomainInfo> filterResolveInfoWithDomainPreferredActivity(Intent intent,
List<CrossProfileDomainInfo> crossProfileDomainInfos, long flags, int sourceUserId,
int targetUserId, int highestApprovalLevel) {
- // no filtering for clone profile
+ // no filtering
return crossProfileDomainInfos;
}
}
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 0a71892..f708fbb 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -59,7 +59,6 @@
import android.os.Trace;
import android.os.UserHandle;
import android.os.WorkSource;
-import android.os.storage.StorageManager;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
@@ -184,10 +183,13 @@
}
boolean canOptimizePackage(@NonNull AndroidPackage pkg) {
+ // The system package has to be optimized during early boot by odrefresh instead.
+ if (PLATFORM_PACKAGE_NAME.equals(pkg.getPackageName())) {
+ return false;
+ }
+
// We do not dexopt a package with no code.
- // Note that the system package is marked as having no code, however we can
- // still optimize it via dexoptSystemServerPath.
- if (!PLATFORM_PACKAGE_NAME.equals(pkg.getPackageName()) && !pkg.isHasCode()) {
+ if (!pkg.isHasCode()) {
return false;
}
@@ -223,8 +225,8 @@
PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options)
throws LegacyDexoptDisabledException {
if (PLATFORM_PACKAGE_NAME.equals(pkg.getPackageName())) {
- throw new IllegalArgumentException("System server dexopting should be done via "
- + " DexManager and PackageDexOptimizer#dexoptSystemServerPath");
+ throw new IllegalArgumentException(
+ "System server dexopting should be done via odrefresh");
}
if (pkg.getUid() == -1) {
throw new IllegalArgumentException("Dexopt for " + pkg.getPackageName()
@@ -523,65 +525,6 @@
}
}
- /**
- * Perform dexopt (if needed) on a system server code path).
- */
- @GuardedBy("mInstallLock")
- @DexOptResult
- public int dexoptSystemServerPath(String dexPath, PackageDexUsage.DexUseInfo dexUseInfo,
- DexoptOptions options) throws LegacyDexoptDisabledException {
- int dexoptFlags = DEXOPT_PUBLIC
- | (options.isBootComplete() ? DEXOPT_BOOTCOMPLETE : 0)
- | (options.isDexoptIdleBackgroundJob() ? DEXOPT_IDLE_BACKGROUND_JOB : 0);
-
- int result = DEX_OPT_SKIPPED;
- for (String isa : dexUseInfo.getLoaderIsas()) {
- int dexoptNeeded = getDexoptNeeded(
- PackageManagerService.PLATFORM_PACKAGE_NAME,
- dexPath,
- isa,
- options.getCompilerFilter(),
- dexUseInfo.getClassLoaderContext(),
- PROFILE_ANALYSIS_DONT_OPTIMIZE_EMPTY_PROFILES,
- /* downgrade= */ false,
- dexoptFlags,
- /* oatDir= */ null);
-
- if (dexoptNeeded == DexFile.NO_DEXOPT_NEEDED) {
- continue;
- }
- try {
- synchronized (mInstallLock) {
- boolean completed = getInstallerLI().dexopt(
- dexPath,
- android.os.Process.SYSTEM_UID,
- /* pkgName= */ "android",
- isa,
- dexoptNeeded,
- /* outputPath= */ null,
- dexoptFlags,
- options.getCompilerFilter(),
- StorageManager.UUID_PRIVATE_INTERNAL,
- dexUseInfo.getClassLoaderContext(),
- /* seInfo= */ null,
- /* downgrade= */ false,
- /* targetSdkVersion= */ 0,
- /* profileName= */ null,
- /* dexMetadataPath= */ null,
- getReasonName(options.getCompilationReason()));
- if (!completed) {
- return DEX_OPT_CANCELLED;
- }
- }
- } catch (InstallerException e) {
- Slog.w(TAG, "Failed to dexopt", e);
- return DEX_OPT_FAILED;
- }
- result = DEX_OPT_PERFORMED;
- }
- return result;
- }
-
private String getAugmentedReasonName(int compilationReason, boolean useDexMetadata) {
String annotation = useDexMetadata
? ArtManagerService.DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION : "";
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 8c5bab6..239853c 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -878,9 +878,14 @@
requestedInstallerPackageName = null;
}
+ if (isApex || mContext.checkCallingOrSelfPermission(
+ Manifest.permission.ENFORCE_UPDATE_OWNERSHIP) == PackageManager.PERMISSION_DENIED) {
+ params.installFlags &= ~PackageManager.INSTALL_REQUEST_UPDATE_OWNERSHIP;
+ }
+
InstallSource installSource = InstallSource.create(installerPackageName,
originatingPackageName, requestedInstallerPackageName, requestedInstallerPackageUid,
- installerAttributionTag, params.packageSource);
+ requestedInstallerPackageName, installerAttributionTag, params.packageSource);
session = new PackageInstallerSession(mInternalCallback, mContext, mPm, this,
mSilentUpdatePolicy, mInstallThread.getLooper(), mStagingManager, sessionId,
userId, callingUid, installSource, params, createdMillis, 0L, stageDir, stageCid,
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 0556c3b..350f5ef 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -89,6 +89,7 @@
import android.content.pm.PackageInstaller.PreapprovalDetails;
import android.content.pm.PackageInstaller.SessionInfo;
import android.content.pm.PackageInstaller.SessionParams;
+import android.content.pm.PackageInstaller.UserActionReason;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.PackageInfoFlags;
import android.content.pm.PackageManagerInternal;
@@ -226,6 +227,7 @@
private static final String ATTR_USER_ID = "userId";
private static final String ATTR_INSTALLER_PACKAGE_NAME = "installerPackageName";
private static final String ATTR_INSTALLER_PACKAGE_UID = "installerPackageUid";
+ private static final String ATTR_UPDATE_OWNER_PACKAGE_NAME = "updateOwnererPackageName";
private static final String ATTR_INSTALLER_ATTRIBUTION_TAG = "installerAttributionTag";
private static final String ATTR_INSTALLER_UID = "installerUid";
private static final String ATTR_INITIATING_PACKAGE_NAME =
@@ -446,6 +448,9 @@
@GuardedBy("mLock")
private boolean mHasDeviceAdminReceiver;
+ @GuardedBy("mLock")
+ private int mUserActionRequirement;
+
static class FileEntry {
private final int mIndex;
private final InstallationFile mFile;
@@ -842,10 +847,17 @@
private static final int USER_ACTION_NOT_NEEDED = 0;
private static final int USER_ACTION_REQUIRED = 1;
private static final int USER_ACTION_PENDING_APK_PARSING = 2;
+ private static final int USER_ACTION_REQUIRED_UPDATE_OWNER_CHANGED = 3;
+ private static final int USER_ACTION_REQUIRED_UPDATE_OWNER_RETAINED = 4;
- @IntDef({USER_ACTION_NOT_NEEDED, USER_ACTION_REQUIRED, USER_ACTION_PENDING_APK_PARSING})
- @interface
- UserActionRequirement {}
+ @IntDef({
+ USER_ACTION_NOT_NEEDED,
+ USER_ACTION_REQUIRED,
+ USER_ACTION_PENDING_APK_PARSING,
+ USER_ACTION_REQUIRED_UPDATE_OWNER_CHANGED,
+ USER_ACTION_REQUIRED_UPDATE_OWNER_RETAINED
+ })
+ @interface UserActionRequirement {}
/**
* Checks if the permissions still need to be confirmed.
@@ -899,8 +911,13 @@
final String existingInstallerPackageName = existingInstallSourceInfo != null
? existingInstallSourceInfo.getInstallingPackageName()
: null;
+ final String existingUpdateOwnerPackageName = existingInstallSourceInfo != null
+ ? existingInstallSourceInfo.getUpdateOwnerPackageName()
+ : null;
final boolean isInstallerOfRecord = isUpdate
&& Objects.equals(existingInstallerPackageName, getInstallerPackageName());
+ final boolean isUpdateOwner = Objects.equals(existingUpdateOwnerPackageName,
+ getInstallerPackageName());
final boolean isSelfUpdate = targetPackageUid == mInstallerUid;
final boolean isPermissionGranted = isInstallPermissionGranted
|| (isUpdatePermissionGranted && isUpdate)
@@ -908,16 +925,35 @@
|| (isInstallDpcPackagesPermissionGranted && hasDeviceAdminReceiver);
final boolean isInstallerRoot = (mInstallerUid == Process.ROOT_UID);
final boolean isInstallerSystem = (mInstallerUid == Process.SYSTEM_UID);
+ final boolean isInstallerShell = (mInstallerUid == Process.SHELL_UID);
+ final boolean isUpdateOwnershipEnforcementEnabled =
+ mPm.isUpdateOwnershipEnforcementAvailable()
+ && existingUpdateOwnerPackageName != null;
- // Device owners and affiliated profile owners are allowed to silently install packages, so
+ // Device owners and affiliated profile owners are allowed to silently install packages, so
// the permission check is waived if the installer is the device owner.
- final boolean noUserActionNecessary = isPermissionGranted || isInstallerRoot
- || isInstallerSystem || isInstallerDeviceOwnerOrAffiliatedProfileOwner();
+ final boolean noUserActionNecessary = isInstallerRoot || isInstallerSystem
+ || isInstallerDeviceOwnerOrAffiliatedProfileOwner();
if (noUserActionNecessary) {
return USER_ACTION_NOT_NEEDED;
}
+ if (isUpdateOwnershipEnforcementEnabled
+ && !isApexSession()
+ && !isUpdateOwner
+ && !isInstallerShell) {
+ final boolean isRequestUpdateOwner =
+ (params.installFlags & PackageManager.INSTALL_REQUEST_UPDATE_OWNERSHIP) != 0;
+
+ return isRequestUpdateOwner ? USER_ACTION_REQUIRED_UPDATE_OWNER_CHANGED
+ : USER_ACTION_REQUIRED_UPDATE_OWNER_RETAINED;
+ }
+
+ if (isPermissionGranted) {
+ return USER_ACTION_NOT_NEEDED;
+ }
+
if (snapshot.isInstallDisabledForPackage(getInstallerPackageName(), mInstallerUid,
userId)) {
// show the installer to account for device policy or unknown sources use cases
@@ -926,13 +962,20 @@
if (params.requireUserAction == SessionParams.USER_ACTION_NOT_REQUIRED
&& isUpdateWithoutUserActionPermissionGranted
- && (isInstallerOfRecord || isSelfUpdate)) {
+ && ((isUpdateOwnershipEnforcementEnabled ? isUpdateOwner
+ : isInstallerOfRecord) || isSelfUpdate)) {
return USER_ACTION_PENDING_APK_PARSING;
}
return USER_ACTION_REQUIRED;
}
+ private void updateUserActionRequirement(int requirement) {
+ synchronized (mLock) {
+ mUserActionRequirement = requirement;
+ }
+ }
+
@SuppressWarnings("GuardedBy" /*mPm.mInstaller is {@code final} field*/)
public PackageInstallerSession(PackageInstallerService.InternalCallback callback,
Context context, PackageManagerService pm,
@@ -1121,6 +1164,7 @@
info.installerUid = mInstallerUid;
info.packageSource = params.packageSource;
info.keepApplicationEnabledSetting = params.keepApplicationEnabledSetting;
+ info.pendingUserActionReason = userActionRequirementToReason(mUserActionRequirement);
}
return info;
}
@@ -1798,6 +1842,60 @@
dispatchSessionSealed();
}
+ @Override
+ public void seal() {
+ assertNotChild("seal");
+ assertCallerIsOwnerOrRoot();
+ try {
+ sealInternal();
+ for (var child : getChildSessions()) {
+ child.sealInternal();
+ }
+ } catch (PackageManagerException e) {
+ throw new IllegalStateException("Package is not valid", e);
+ }
+ }
+
+ private void sealInternal() throws PackageManagerException {
+ synchronized (mLock) {
+ sealLocked();
+ }
+ }
+
+ @Override
+ public List<String> fetchPackageNames() {
+ assertNotChild("fetchPackageNames");
+ assertCallerIsOwnerOrRoot();
+ var sessions = getSelfOrChildSessions();
+ var result = new ArrayList<String>(sessions.size());
+ for (var s : sessions) {
+ result.add(s.fetchPackageName());
+ }
+ return result;
+ }
+
+ private String fetchPackageName() {
+ assertSealed("fetchPackageName");
+ synchronized (mLock) {
+ final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
+ final List<File> addedFiles = getAddedApksLocked();
+ for (File addedFile : addedFiles) {
+ final ParseResult<ApkLite> result =
+ ApkLiteParseUtils.parseApkLite(input.reset(), addedFile, 0);
+ if (result.isError()) {
+ throw new IllegalStateException(
+ "Can't parse package for session=" + sessionId, result.getException());
+ }
+ final ApkLite apk = result.getResult();
+ var packageName = apk.getPackageName();
+ if (packageName != null) {
+ return packageName;
+ }
+ }
+ throw new IllegalStateException("Can't fetch package name for session=" + sessionId);
+ }
+ }
+
/**
* Kicks off the install flow. The first step is to persist 'sealed' flags
* to prevent mutations of hard links created later.
@@ -2051,6 +2149,11 @@
}
}
+ @NonNull
+ private List<PackageInstallerSession> getSelfOrChildSessions() {
+ return isMultiPackage() ? getChildSessions() : Collections.singletonList(this);
+ }
+
/**
* Seal the session to prevent further modification.
*
@@ -2205,8 +2308,9 @@
}
mInstallerUid = newOwnerAppInfo.uid;
- mInstallSource = InstallSource.create(packageName, null, packageName,
- mInstallerUid, null, params.packageSource);
+ mInstallSource = InstallSource.create(packageName, null /* originatingPackageName */,
+ packageName, mInstallerUid, packageName, null /* installerAttributionTag */,
+ params.packageSource);
}
}
@@ -2220,7 +2324,10 @@
@UserActionRequirement int userActionRequirement = USER_ACTION_NOT_NEEDED;
// TODO(b/159331446): Move this to makeSessionActiveForInstall and update javadoc
userActionRequirement = session.computeUserActionRequirement();
- if (userActionRequirement == USER_ACTION_REQUIRED) {
+ session.updateUserActionRequirement(userActionRequirement);
+ if (userActionRequirement == USER_ACTION_REQUIRED
+ || userActionRequirement == USER_ACTION_REQUIRED_UPDATE_OWNER_CHANGED
+ || userActionRequirement == USER_ACTION_REQUIRED_UPDATE_OWNER_RETAINED) {
session.sendPendingUserActionIntent(target);
return true;
}
@@ -2253,6 +2360,18 @@
return false;
}
+ private static @UserActionReason int userActionRequirementToReason(
+ @UserActionRequirement int requirement) {
+ switch (requirement) {
+ case USER_ACTION_REQUIRED_UPDATE_OWNER_CHANGED:
+ return PackageInstaller.REASON_OWNERSHIP_CHANGED;
+ case USER_ACTION_REQUIRED_UPDATE_OWNER_RETAINED:
+ return PackageInstaller.REASON_REMIND_OWNERSHIP;
+ default:
+ return PackageInstaller.REASON_CONFIRM_PACKAGE_CHANGE;
+ }
+ }
+
/**
* Find out any session needs user action.
*
@@ -4438,6 +4557,11 @@
return params.keepApplicationEnabledSetting;
}
+ @Override
+ public boolean isRequestUpdateOwnership() {
+ return (params.installFlags & PackageManager.INSTALL_REQUEST_UPDATE_OWNERSHIP) != 0;
+ }
+
void setSessionReady() {
synchronized (mLock) {
// Do not allow destroyed/failed session to change state
@@ -4774,6 +4898,8 @@
writeStringAttribute(out, ATTR_INSTALLER_PACKAGE_NAME,
mInstallSource.mInstallerPackageName);
out.attributeInt(null, ATTR_INSTALLER_PACKAGE_UID, mInstallSource.mInstallerPackageUid);
+ writeStringAttribute(out, ATTR_UPDATE_OWNER_PACKAGE_NAME,
+ mInstallSource.mUpdateOwnerPackageName);
writeStringAttribute(out, ATTR_INSTALLER_ATTRIBUTION_TAG,
mInstallSource.mInstallerAttributionTag);
out.attributeInt(null, ATTR_INSTALLER_UID, mInstallerUid);
@@ -4941,6 +5067,8 @@
final String installerPackageName = readStringAttribute(in, ATTR_INSTALLER_PACKAGE_NAME);
final int installPackageUid = in.getAttributeInt(null, ATTR_INSTALLER_PACKAGE_UID,
INVALID_UID);
+ final String updateOwnerPackageName = readStringAttribute(in,
+ ATTR_UPDATE_OWNER_PACKAGE_NAME);
final String installerAttributionTag = readStringAttribute(in,
ATTR_INSTALLER_ATTRIBUTION_TAG);
final int installerUid = in.getAttributeInt(null, ATTR_INSTALLER_UID, pm.snapshotComputer()
@@ -5113,7 +5241,7 @@
InstallSource installSource = InstallSource.create(installInitiatingPackageName,
installOriginatingPackageName, installerPackageName, installPackageUid,
- installerAttributionTag, params.packageSource);
+ updateOwnerPackageName, installerAttributionTag, params.packageSource);
return new PackageInstallerSession(callback, context, pm, sessionProvider,
silentUpdatePolicy, installerThread, stagingManager, sessionId, userId,
installerUid, installSource, params, createdMillis, committedMillis, stageDir,
diff --git a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
index 04f5e56..99fff72 100644
--- a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
+++ b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
@@ -49,7 +49,6 @@
import com.android.server.pm.Installer.LegacyDexoptDisabledException;
import com.android.server.pm.dex.DexManager;
-import com.android.server.pm.dex.DynamicCodeLogger;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageStateInternal;
@@ -773,10 +772,4 @@
public final void shutdown() {
mService.shutdown();
}
-
- @Override
- @Deprecated
- public final DynamicCodeLogger getDynamicCodeLogger() {
- return getDexManager().getDynamicCodeLogger();
- }
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 399e32a..92bbb7e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -204,6 +204,7 @@
import com.android.server.pm.dex.ArtManagerService;
import com.android.server.pm.dex.ArtUtils;
import com.android.server.pm.dex.DexManager;
+import com.android.server.pm.dex.DynamicCodeLogger;
import com.android.server.pm.dex.ViewCompiler;
import com.android.server.pm.local.PackageManagerLocalImpl;
import com.android.server.pm.parsing.PackageInfoUtils;
@@ -793,6 +794,7 @@
// DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
// is used by other apps).
private final DexManager mDexManager;
+ private final DynamicCodeLogger mDynamicCodeLogger;
final ViewCompiler mViewCompiler;
@@ -1529,7 +1531,8 @@
(i, pm) -> new PackageDexOptimizer(i.getInstaller(), i.getInstallLock(),
i.getContext(), "*dexopt*"),
(i, pm) -> new DexManager(i.getContext(), i.getPackageDexOptimizer(),
- i.getInstaller(), i.getInstallLock()),
+ i.getInstaller(), i.getInstallLock(), i.getDynamicCodeLogger()),
+ (i, pm) -> new DynamicCodeLogger(i.getInstaller()),
(i, pm) -> new ArtManagerService(i.getContext(), i.getInstaller(),
i.getInstallLock()),
(i, pm) -> ApexManager.getInstance(),
@@ -1711,6 +1714,7 @@
mDefaultAppProvider = testParams.defaultAppProvider;
mLegacyPermissionManager = testParams.legacyPermissionManagerInternal;
mDexManager = testParams.dexManager;
+ mDynamicCodeLogger = testParams.dynamicCodeLogger;
mFactoryTest = testParams.factoryTest;
mIncrementalManager = testParams.incrementalManager;
mInstallerService = testParams.installerService;
@@ -1889,6 +1893,7 @@
mPackageDexOptimizer = injector.getPackageDexOptimizer();
mDexManager = injector.getDexManager();
+ mDynamicCodeLogger = injector.getDynamicCodeLogger();
mBackgroundDexOptService = injector.getBackgroundDexOptService();
mArtManagerService = injector.getArtManagerService();
mMoveCallbacks = new MovePackageHelper.MoveCallbacks(FgThread.get().getLooper());
@@ -2316,6 +2321,7 @@
.getList());
}
mDexManager.load(userPackages);
+ mDynamicCodeLogger.load(userPackages);
if (mIsUpgrade) {
FrameworkStatsLog.write(
FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
@@ -2980,9 +2986,14 @@
return mDexManager;
}
+ /*package*/ DynamicCodeLogger getDynamicCodeLogger() {
+ return mDynamicCodeLogger;
+ }
+
public void shutdown() {
mCompilerStats.writeNow();
mDexManager.writePackageDexUsageNow();
+ mDynamicCodeLogger.writeNow();
PackageWatchdog.getInstance(mContext).writeNow();
synchronized (mLock) {
@@ -4285,6 +4296,11 @@
// Prune unused static shared libraries which have been cached a period of time
schedulePruneUnusedStaticSharedLibraries(false /* delay */);
+
+ DexUseManagerLocal dexUseManager = DexOptHelper.getDexUseManagerLocal();
+ if (dexUseManager != null) {
+ dexUseManager.systemReady();
+ }
}
//TODO: b/111402650
@@ -6008,6 +6024,42 @@
}
@Override
+ public void relinquishUpdateOwnership(String targetPackage) {
+ final int callingUid = Binder.getCallingUid();
+ final int callingUserId = UserHandle.getUserId(callingUid);
+ final Computer snapshot = snapshotComputer();
+
+ final PackageStateInternal targetPackageState =
+ snapshot.getPackageStateForInstalledAndFiltered(targetPackage, callingUid,
+ callingUserId);
+ if (targetPackageState == null) {
+ throw new IllegalArgumentException("Unknown target package: " + targetPackage);
+ }
+
+ final String targetUpdateOwnerPackageName =
+ targetPackageState.getInstallSource().mUpdateOwnerPackageName;
+ final PackageStateInternal targetUpdateOwnerPkgSetting =
+ targetUpdateOwnerPackageName == null ? null
+ : snapshot.getPackageStateInternal(targetUpdateOwnerPackageName);
+
+ if (targetUpdateOwnerPkgSetting == null) {
+ return;
+ }
+
+ final int callingAppId = UserHandle.getAppId(callingUid);
+ final int targetUpdateOwnerAppId = targetUpdateOwnerPkgSetting.getAppId();
+ if (callingAppId != Process.SYSTEM_UID
+ && callingAppId != Process.SHELL_UID
+ && callingAppId != targetUpdateOwnerAppId) {
+ throw new SecurityException("Caller is not the current update owner.");
+ }
+
+ commitPackageStateMutation(null /* initialState */, targetPackage,
+ state -> state.setUpdateOwner(null /* updateOwnerPackageName */));
+ scheduleWriteSettings();
+ }
+
+ @Override
public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
if (HIDE_EPHEMERAL_APIS) {
return true;
@@ -6341,6 +6393,12 @@
return mDexManager;
}
+ @NonNull
+ @Override
+ public DynamicCodeLogger getDynamicCodeLogger() {
+ return mDynamicCodeLogger;
+ }
+
@Override
public boolean isPlatformSigned(String packageName) {
PackageStateInternal packageState = snapshot().getPackageStateInternal(packageName);
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java b/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java
index 76e6e45f..eb033cb 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java
@@ -30,6 +30,7 @@
import com.android.server.compat.PlatformCompat;
import com.android.server.pm.dex.ArtManagerService;
import com.android.server.pm.dex.DexManager;
+import com.android.server.pm.dex.DynamicCodeLogger;
import com.android.server.pm.dex.ViewCompiler;
import com.android.server.pm.parsing.PackageParser2;
import com.android.server.pm.permission.LegacyPermissionManagerInternal;
@@ -106,6 +107,7 @@
private final Singleton<PackageDexOptimizer>
mPackageDexOptimizerProducer;
private final Singleton<DexManager> mDexManagerProducer;
+ private final Singleton<DynamicCodeLogger> mDynamicCodeLoggerProducer;
private final Singleton<ArtManagerService>
mArtManagerServiceProducer;
private final Singleton<ApexManager> mApexManagerProducer;
@@ -154,6 +156,7 @@
Producer<SystemConfig> systemConfigProducer,
Producer<PackageDexOptimizer> packageDexOptimizerProducer,
Producer<DexManager> dexManagerProducer,
+ Producer<DynamicCodeLogger> dynamicCodeLoggerProducer,
Producer<ArtManagerService> artManagerServiceProducer,
Producer<ApexManager> apexManagerProducer,
Producer<ViewCompiler> viewCompilerProducer,
@@ -200,6 +203,7 @@
mPackageDexOptimizerProducer = new Singleton<>(
packageDexOptimizerProducer);
mDexManagerProducer = new Singleton<>(dexManagerProducer);
+ mDynamicCodeLoggerProducer = new Singleton<>(dynamicCodeLoggerProducer);
mArtManagerServiceProducer = new Singleton<>(
artManagerServiceProducer);
mApexManagerProducer = new Singleton<>(apexManagerProducer);
@@ -314,6 +318,10 @@
return mDexManagerProducer.get(this, mPackageManager);
}
+ public DynamicCodeLogger getDynamicCodeLogger() {
+ return mDynamicCodeLoggerProducer.get(this, mPackageManager);
+ }
+
public ArtManagerService getArtManagerService() {
return mArtManagerServiceProducer.get(this, mPackageManager);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceTestParams.java b/services/core/java/com/android/server/pm/PackageManagerServiceTestParams.java
index bffbb84..0c617ae 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceTestParams.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceTestParams.java
@@ -32,6 +32,7 @@
import com.android.internal.content.om.OverlayConfig;
import com.android.server.pm.dex.ArtManagerService;
import com.android.server.pm.dex.DexManager;
+import com.android.server.pm.dex.DynamicCodeLogger;
import com.android.server.pm.dex.ViewCompiler;
import com.android.server.pm.parsing.PackageParser2;
import com.android.server.pm.permission.LegacyPermissionManagerInternal;
@@ -49,6 +50,7 @@
public int defParseFlags;
public DefaultAppProvider defaultAppProvider;
public DexManager dexManager;
+ public DynamicCodeLogger dynamicCodeLogger;
public List<ScanPartition> dirsToScanAsSystem;
public boolean factoryTest;
public ArrayMap<String, FeatureInfo> availableFeatures;
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index a72ae56..0de1a4e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -33,6 +33,7 @@
import static com.android.server.pm.PackageManagerService.STUB_SUFFIX;
import static com.android.server.pm.PackageManagerService.TAG;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
@@ -113,6 +114,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.nio.file.Path;
import java.security.SecureRandom;
import java.security.cert.CertificateEncodingException;
@@ -148,6 +151,29 @@
ThreadLocal.withInitial(() -> false);
/**
+ * Type used with {@link #canJoinSharedUserId(String, SigningDetails, SharedUserSetting, int)}
+ * when the package attempting to join the sharedUserId is a new install.
+ */
+ public static final int SHARED_USER_ID_JOIN_TYPE_INSTALL = 0;
+ /**
+ * Type used with {@link #canJoinSharedUserId(String, SigningDetails, SharedUserSetting, int)}
+ * when the package attempting to join the sharedUserId is an update.
+ */
+ public static final int SHARED_USER_ID_JOIN_TYPE_UPDATE = 1;
+ /**
+ * Type used with {@link #canJoinSharedUserId(String, SigningDetails, SharedUserSetting, int)}
+ * when the package attempting to join the sharedUserId is a part of the system image.
+ */
+ public static final int SHARED_USER_ID_JOIN_TYPE_SYSTEM = 2;
+ @IntDef(prefix = { "TYPE_" }, value = {
+ SHARED_USER_ID_JOIN_TYPE_INSTALL,
+ SHARED_USER_ID_JOIN_TYPE_UPDATE,
+ SHARED_USER_ID_JOIN_TYPE_SYSTEM,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SharedUserIdJoinType {}
+
+ /**
* Components of apps targeting Android T and above will stop receiving intents from
* external callers that do not match its declared intent filters.
*
@@ -575,17 +601,9 @@
// the older ones. We check to see if either the new package is signed by an older cert
// with which the current sharedUser is ok, or if it is signed by a newer one, and is ok
// with being sharedUser with the existing signing cert.
- boolean match = canJoinSharedUserId(parsedSignatures,
- sharedUserSetting.getSigningDetails());
- // Special case: if the sharedUserId capability check failed it could be due to this
- // being the only package in the sharedUserId so far and the lineage being updated to
- // deny the sharedUserId capability of the previous key in the lineage.
- final ArraySet<PackageStateInternal> susPackageStates =
- (ArraySet<PackageStateInternal>) sharedUserSetting.getPackageStates();
- if (!match && susPackageStates.size() == 1
- && susPackageStates.valueAt(0).getPackageName().equals(packageName)) {
- match = true;
- }
+ boolean match = canJoinSharedUserId(packageName, parsedSignatures, sharedUserSetting,
+ pkgSetting.getSigningDetails().getSignatures() != null
+ ? SHARED_USER_ID_JOIN_TYPE_UPDATE : SHARED_USER_ID_JOIN_TYPE_INSTALL);
if (!match && compareCompat) {
match = matchSignaturesCompat(
packageName, sharedUserSetting.signatures, parsedSignatures);
@@ -608,36 +626,6 @@
+ " has no signatures that match those in shared user "
+ sharedUserSetting.name + "; ignoring!");
}
- // It is possible that this package contains a lineage that blocks sharedUserId access
- // to an already installed package in the sharedUserId signed with a previous key.
- // Iterate over all of the packages in the sharedUserId and ensure any that are signed
- // with a key in this package's lineage have the SHARED_USER_ID capability granted.
- if (parsedSignatures.hasPastSigningCertificates()) {
- for (int i = 0; i < susPackageStates.size(); i++) {
- PackageStateInternal shUidPkgSetting = susPackageStates.valueAt(i);
- // if the current package in the sharedUserId is the package being updated then
- // skip this check as the update may revoke the sharedUserId capability from
- // the key with which this app was previously signed.
- if (packageName.equals(shUidPkgSetting.getPackageName())) {
- continue;
- }
- SigningDetails shUidSigningDetails =
- shUidPkgSetting.getSigningDetails();
- // The capability check only needs to be performed against the package if it is
- // signed with a key that is in the lineage of the package being installed.
- if (parsedSignatures.hasAncestor(shUidSigningDetails)) {
- if (!parsedSignatures.checkCapability(shUidSigningDetails,
- SigningDetails.CertCapabilities.SHARED_USER_ID)) {
- throw new PackageManagerException(
- INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
- "Package " + packageName
- + " revoked the sharedUserId capability from the"
- + " signing key used to sign "
- + shUidPkgSetting.getPackageName());
- }
- }
- }
- }
// If the lineage of this package diverges from the lineage of the sharedUserId then
// do not allow the installation to proceed.
if (!parsedSignatures.hasCommonAncestor(
@@ -651,25 +639,97 @@
}
/**
- * Returns whether the package with {@code packageSigningDetails} can join the sharedUserId
- * with {@code sharedUserSigningDetails}.
+ * Returns whether the package {@code packageName} can join the sharedUserId based on the
+ * settings in {@code sharedUserSetting}.
* <p>
* A sharedUserId maintains a shared {@link SigningDetails} containing the full lineage and
* capabilities for each package in the sharedUserId. A package can join the sharedUserId if
* its current signer is the same as the shared signer, or if the current signer of either
* is in the signing lineage of the other with the {@link
* SigningDetails.CertCapabilities#SHARED_USER_ID} capability granted to that previous signer
- * in the lineage.
+ * in the lineage. In the case of a key compromise, an app signed with a lineage revoking
+ * this capability from a previous signing key can still join the sharedUserId with another
+ * app signed with this previous key if the joining app is being updated; however, a new
+ * install will not be allowed until all apps have rotated off the key with the capability
+ * revoked.
*
+ * @param packageName the name of the package seeking to join the sharedUserId
* @param packageSigningDetails the {@code SigningDetails} of the package seeking to join the
- * sharedUserId
- * @param sharedUserSigningDetails the {@code SigningDetails} of the sharedUserId
+ * sharedUserId
+ * @param sharedUserSetting the {@code SharedUserSetting} for the sharedUserId {@code
+ * packageName} is seeking to join
+ * @param joinType the type of join (install, update, system, etc)
* @return true if the package seeking to join the sharedUserId meets the requirements
*/
- public static boolean canJoinSharedUserId(@NonNull SigningDetails packageSigningDetails,
- @NonNull SigningDetails sharedUserSigningDetails) {
- return packageSigningDetails.checkCapability(sharedUserSigningDetails, SHARED_USER_ID)
- || sharedUserSigningDetails.checkCapability(packageSigningDetails, SHARED_USER_ID);
+ public static boolean canJoinSharedUserId(@NonNull String packageName,
+ @NonNull SigningDetails packageSigningDetails,
+ @NonNull SharedUserSetting sharedUserSetting, @SharedUserIdJoinType int joinType) {
+ SigningDetails sharedUserSigningDetails = sharedUserSetting.getSigningDetails();
+ boolean capabilityGranted =
+ packageSigningDetails.checkCapability(sharedUserSigningDetails, SHARED_USER_ID)
+ || sharedUserSigningDetails.checkCapability(packageSigningDetails,
+ SHARED_USER_ID);
+
+ // If the current signer for either the package or the sharedUserId is the current signer
+ // of the other or in the lineage of the other with the SHARED_USER_ID capability granted,
+ // then a system and update join type can proceed; an install join type is not allowed here
+ // since the sharedUserId may contain packages that are signed with a key untrusted by
+ // the new package.
+ if (capabilityGranted && joinType != SHARED_USER_ID_JOIN_TYPE_INSTALL) {
+ return true;
+ }
+
+ // If the package is signed with a key that is no longer trusted by the sharedUserId, then
+ // the join should not be allowed unless this is a system join type; system packages can
+ // join the sharedUserId as long as they share a common lineage.
+ if (!capabilityGranted && sharedUserSigningDetails.hasAncestor(packageSigningDetails)) {
+ if (joinType == SHARED_USER_ID_JOIN_TYPE_SYSTEM) {
+ return true;
+ }
+ return false;
+ }
+
+ // If the package is signed with a rotated key that no longer trusts the sharedUserId key,
+ // then allow system and update join types to rotate away from an untrusted key; install
+ // join types are not allowed since a new package that doesn't trust a previous key
+ // shouldn't be allowed to join until all packages in the sharedUserId have rotated off the
+ // untrusted key.
+ if (!capabilityGranted && packageSigningDetails.hasAncestor(sharedUserSigningDetails)) {
+ if (joinType != SHARED_USER_ID_JOIN_TYPE_INSTALL) {
+ return true;
+ }
+ return false;
+ }
+
+ // If the capability is not granted and the package signatures are not an ancestor
+ // or descendant of the sharedUserId signatures, then do not allow any join type to join
+ // the sharedUserId since there are no common signatures.
+ if (!capabilityGranted) {
+ return false;
+ }
+
+ // At this point this is a new install with the capability granted; ensure the current
+ // packages in the sharedUserId are all signed by a key trusted by the new package.
+ final ArraySet<PackageStateInternal> susPackageStates =
+ (ArraySet<PackageStateInternal>) sharedUserSetting.getPackageStates();
+ if (packageSigningDetails.hasPastSigningCertificates()) {
+ for (PackageStateInternal shUidPkgSetting : susPackageStates) {
+ SigningDetails shUidSigningDetails = shUidPkgSetting.getSigningDetails();
+ // The capability check only needs to be performed against the package if it is
+ // signed with a key that is in the lineage of the package being installed.
+ if (packageSigningDetails.hasAncestor(shUidSigningDetails)) {
+ if (!packageSigningDetails.checkCapability(shUidSigningDetails,
+ SigningDetails.CertCapabilities.SHARED_USER_ID)) {
+ Slog.d(TAG, "Package " + packageName
+ + " revoked the sharedUserId capability from the"
+ + " signing key used to sign "
+ + shUidPkgSetting.getPackageName());
+ return false;
+ }
+ }
+ }
+ }
+ return true;
}
/**
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 6af1d0f..849cbeb 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -172,6 +172,11 @@
SUPPORTED_PERMISSION_FLAGS.put("revoke-when-requested",
FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
}
+ // For backward compatibility. DO NOT add new commands here. New ART Service commands should be
+ // added under the "art" namespace.
+ private static final Set<String> ART_SERVICE_COMMANDS = Set.of("compile",
+ "reconcile-secondary-dex-files", "force-dex-opt", "bg-dexopt-job",
+ "cancel-bg-dexopt-job", "delete-dexopt", "dump-profiles", "snapshot-profile", "art");
final IPackageManager mInterface;
final LegacyPermissionManagerInternal mLegacyPermissionManager;
@@ -250,22 +255,6 @@
return runMovePackage();
case "move-primary-storage":
return runMovePrimaryStorage();
- case "compile":
- return runCompile();
- case "reconcile-secondary-dex-files":
- return runreconcileSecondaryDexFiles();
- case "force-dex-opt":
- return runForceDexOpt();
- case "bg-dexopt-job":
- return runBgDexOpt();
- case "cancel-bg-dexopt-job":
- return cancelBgDexOptJob();
- case "delete-dexopt":
- return runDeleteDexOpt();
- case "dump-profiles":
- return runDumpProfiles();
- case "snapshot-profile":
- return runSnapshotProfile();
case "uninstall":
return runUninstall();
case "clear":
@@ -355,9 +344,19 @@
return runBypassAllowedApexUpdateCheck();
case "set-silent-updates-policy":
return runSetSilentUpdatesPolicy();
- case "art":
- return runArtSubCommand();
default: {
+ if (ART_SERVICE_COMMANDS.contains(cmd)) {
+ if (DexOptHelper.useArtService()) {
+ return runArtServiceCommand();
+ } else {
+ try {
+ return runLegacyDexoptCommand(cmd);
+ } catch (LegacyDexoptDisabledException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
Boolean domainVerificationResult =
mDomainVerificationShell.runCommand(this, cmd);
if (domainVerificationResult != null) {
@@ -381,12 +380,39 @@
}
} catch (RemoteException e) {
pw.println("Remote exception: " + e);
- } catch (ManagerNotFoundException e) {
- pw.println(e);
}
return -1;
}
+ private int runLegacyDexoptCommand(@NonNull String cmd)
+ throws RemoteException, LegacyDexoptDisabledException {
+ Installer.checkLegacyDexoptDisabled();
+ switch (cmd) {
+ case "compile":
+ return runCompile();
+ case "reconcile-secondary-dex-files":
+ return runreconcileSecondaryDexFiles();
+ case "force-dex-opt":
+ return runForceDexOpt();
+ case "bg-dexopt-job":
+ return runBgDexOpt();
+ case "cancel-bg-dexopt-job":
+ return cancelBgDexOptJob();
+ case "delete-dexopt":
+ return runDeleteDexOpt();
+ case "dump-profiles":
+ return runDumpProfiles();
+ case "snapshot-profile":
+ return runSnapshotProfile();
+ case "art":
+ getOutPrintWriter().println("ART Service not enabled");
+ return -1;
+ default:
+ // Can't happen.
+ throw new IllegalArgumentException();
+ }
+ }
+
/**
* Shows module info
*
@@ -3023,6 +3049,10 @@
case UserManager.REMOVE_RESULT_ALREADY_BEING_REMOVED:
getOutPrintWriter().printf("Success: user %d is already being removed\n", userId);
return 0;
+ case UserManager.REMOVE_RESULT_ERROR_MAIN_USER_PERMANENT_ADMIN:
+ getOutPrintWriter().printf("Error: user %d is a permanent admin main user\n",
+ userId);
+ return 1;
default:
getErrPrintWriter().printf("Error: couldn't remove or mark ephemeral user id %d\n",
userId);
@@ -3207,6 +3237,15 @@
case "--install-reason":
sessionParams.installReason = Integer.parseInt(getNextArg());
break;
+ case "--update-ownership":
+ if (params.installerPackageName == null) {
+ // Enabling update ownership enforcement needs an installer. Since the
+ // default installer is null when using adb install, that effectively
+ // disable this enforcement.
+ params.installerPackageName = "com.android.shell";
+ }
+ sessionParams.installFlags |= PackageManager.INSTALL_REQUEST_UPDATE_OWNERSHIP;
+ break;
case "--force-uuid":
sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID;
sessionParams.volumeUuid = getNextArg();
@@ -3254,6 +3293,10 @@
case "--skip-enable":
sessionParams.setKeepApplicationEnabledSetting();
break;
+ case "--bypass-low-target-sdk-block":
+ sessionParams.installFlags |=
+ PackageManager.INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK;
+ break;
default:
throw new IllegalArgumentException("Unknown option " + opt);
}
@@ -3475,17 +3518,18 @@
return 1;
}
- private int runArtSubCommand() throws ManagerNotFoundException {
- // Remove the first arg "art" and forward to ART module.
- String[] args = getAllArgs();
- args = Arrays.copyOfRange(args, 1, args.length);
+ private int runArtServiceCommand() {
try (var in = ParcelFileDescriptor.dup(getInFileDescriptor());
var out = ParcelFileDescriptor.dup(getOutFileDescriptor());
var err = ParcelFileDescriptor.dup(getErrFileDescriptor())) {
return LocalManagerRegistry.getManagerOrThrow(ArtManagerLocal.class)
- .handleShellCommand(getTarget(), in, out, err, args);
+ .handleShellCommand(getTarget(), in, out, err, getAllArgs());
} catch (IOException e) {
throw new IllegalStateException(e);
+ } catch (ManagerNotFoundException e) {
+ PrintWriter epw = getErrPrintWriter();
+ epw.println("ART Service is not ready. Please try again later");
+ return -1;
}
}
@@ -4091,6 +4135,7 @@
pw.println(" --install-reason: indicates why the app is being installed:");
pw.println(" 0=unknown, 1=admin policy, 2=device restore,");
pw.println(" 3=device setup, 4=user request");
+ pw.println(" --update-ownership: request the update ownership enforcement");
pw.println(" --force-uuid: force install on to disk volume with given UUID");
pw.println(" --apex: install an .apex file, not an .apk");
pw.println(" --staged-ready-timeout: By default, staged sessions wait "
@@ -4114,7 +4159,7 @@
pw.println(" [--referrer URI] [--abi ABI_NAME] [--force-sdk]");
pw.println(" [--preload] [--instant] [--full] [--dont-kill]");
pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [--apex] [-S BYTES]");
- pw.println(" [--multi-package] [--staged]");
+ pw.println(" [--multi-package] [--staged] [--update-ownership]");
pw.println(" Like \"install\", but starts an install session. Use \"install-write\"");
pw.println(" to push data into the session, and \"install-commit\" to finish.");
pw.println("");
@@ -4253,6 +4298,76 @@
pw.println("");
pw.println(" get-max-running-users");
pw.println("");
+ pw.println(" set-home-activity [--user USER_ID] TARGET-COMPONENT");
+ pw.println(" Set the default home activity (aka launcher).");
+ pw.println(" TARGET-COMPONENT can be a package name (com.package.my) or a full");
+ pw.println(" component (com.package.my/component.name). However, only the package name");
+ pw.println(" matters: the actual component used will be determined automatically from");
+ pw.println(" the package.");
+ pw.println("");
+ pw.println(" set-installer PACKAGE INSTALLER");
+ pw.println(" Set installer package name");
+ pw.println("");
+ pw.println(" get-instantapp-resolver");
+ pw.println(
+ " Return the name of the component that is the current instant app installer.");
+ pw.println("");
+ pw.println(" set-harmful-app-warning [--user <USER_ID>] <PACKAGE> [<WARNING>]");
+ pw.println(" Mark the app as harmful with the given warning message.");
+ pw.println("");
+ pw.println(" get-harmful-app-warning [--user <USER_ID>] <PACKAGE>");
+ pw.println(" Return the harmful app warning message for the given app, if present");
+ pw.println();
+ pw.println(" uninstall-system-updates [<PACKAGE>]");
+ pw.println(" Removes updates to the given system application and falls back to its");
+ pw.println(" /system version. Does nothing if the given package is not a system app.");
+ pw.println(" If no package is specified, removes updates to all system applications.");
+ pw.println("");
+ pw.println(" get-moduleinfo [--all | --installed] [module-name]");
+ pw.println(" Displays module info. If module-name is specified only that info is shown");
+ pw.println(" By default, without any argument only installed modules are shown.");
+ pw.println(" --all: show all module info");
+ pw.println(" --installed: show only installed modules");
+ pw.println("");
+ pw.println(" log-visibility [--enable|--disable] <PACKAGE>");
+ pw.println(" Turns on debug logging when visibility is blocked for the given package.");
+ pw.println(" --enable: turn on debug logging (default)");
+ pw.println(" --disable: turn off debug logging");
+ pw.println("");
+ pw.println(" set-silent-updates-policy [--allow-unlimited-silent-updates <INSTALLER>]");
+ pw.println(" [--throttle-time <SECONDS>] [--reset]");
+ pw.println(" Sets the policies of the silent updates.");
+ pw.println(" --allow-unlimited-silent-updates: allows unlimited silent updated");
+ pw.println(" installation requests from the installer without the throttle time.");
+ pw.println(" --throttle-time: update the silent updates throttle time in seconds.");
+ pw.println(" --reset: restore the installer and throttle time to the default, and");
+ pw.println(" clear tracks of silent updates in the system.");
+ pw.println("");
+ if (DexOptHelper.useArtService()) {
+ printArtServiceHelp();
+ } else {
+ printLegacyDexoptHelp();
+ }
+ pw.println("");
+ mDomainVerificationShell.printHelp(pw);
+ pw.println("");
+ Intent.printIntentArgsHelp(pw, "");
+ }
+
+ private void printArtServiceHelp() {
+ final var ipw = new IndentingPrintWriter(getOutPrintWriter(), " " /* singleIndent */);
+ ipw.increaseIndent();
+ try {
+ LocalManagerRegistry.getManagerOrThrow(ArtManagerLocal.class)
+ .printShellCommandHelp(ipw);
+ } catch (ManagerNotFoundException e) {
+ ipw.println("ART Service is not ready. Please try again later");
+ }
+ ipw.decreaseIndent();
+ }
+
+ private void printLegacyDexoptHelp() {
+ final PrintWriter pw = getOutPrintWriter();
pw.println(" compile [-m MODE | -r REASON] [-f] [-c] [--split SPLIT_NAME]");
pw.println(" [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)");
pw.println(" Trigger compilation of TARGET-PACKAGE or all packages if \"-a\". Options are:");
@@ -4325,57 +4440,6 @@
pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION
+ "TARGET-PACKAGE[-code-path].prof");
pw.println(" If TARGET-PACKAGE=android it will take a snapshot of the boot image");
- pw.println("");
- pw.println(" set-home-activity [--user USER_ID] TARGET-COMPONENT");
- pw.println(" Set the default home activity (aka launcher).");
- pw.println(" TARGET-COMPONENT can be a package name (com.package.my) or a full");
- pw.println(" component (com.package.my/component.name). However, only the package name");
- pw.println(" matters: the actual component used will be determined automatically from");
- pw.println(" the package.");
- pw.println("");
- pw.println(" set-installer PACKAGE INSTALLER");
- pw.println(" Set installer package name");
- pw.println("");
- pw.println(" get-instantapp-resolver");
- pw.println(" Return the name of the component that is the current instant app installer.");
- pw.println("");
- pw.println(" set-harmful-app-warning [--user <USER_ID>] <PACKAGE> [<WARNING>]");
- pw.println(" Mark the app as harmful with the given warning message.");
- pw.println("");
- pw.println(" get-harmful-app-warning [--user <USER_ID>] <PACKAGE>");
- pw.println(" Return the harmful app warning message for the given app, if present");
- pw.println();
- pw.println(" uninstall-system-updates [<PACKAGE>]");
- pw.println(" Removes updates to the given system application and falls back to its");
- pw.println(" /system version. Does nothing if the given package is not a system app.");
- pw.println(" If no package is specified, removes updates to all system applications.");
- pw.println("");
- pw.println(" get-moduleinfo [--all | --installed] [module-name]");
- pw.println(" Displays module info. If module-name is specified only that info is shown");
- pw.println(" By default, without any argument only installed modules are shown.");
- pw.println(" --all: show all module info");
- pw.println(" --installed: show only installed modules");
- pw.println("");
- pw.println(" log-visibility [--enable|--disable] <PACKAGE>");
- pw.println(" Turns on debug logging when visibility is blocked for the given package.");
- pw.println(" --enable: turn on debug logging (default)");
- pw.println(" --disable: turn off debug logging");
- pw.println("");
- pw.println(" set-silent-updates-policy [--allow-unlimited-silent-updates <INSTALLER>]");
- pw.println(" [--throttle-time <SECONDS>] [--reset]");
- pw.println(" Sets the policies of the silent updates.");
- pw.println(" --allow-unlimited-silent-updates: allows unlimited silent updated");
- pw.println(" installation requests from the installer without the throttle time.");
- pw.println(" --throttle-time: update the silent updates throttle time in seconds.");
- pw.println(" --reset: restore the installer and throttle time to the default, and");
- pw.println(" clear tracks of silent updates in the system.");
- pw.println("");
- pw.println(" art [<SUB-COMMANDS>]");
- pw.println(" Invokes ART services commands. (Run `pm art help` for details.)");
- pw.println("");
- mDomainVerificationShell.printHelp(pw);
- pw.println("");
- Intent.printIntentArgsHelp(pw , "");
}
private static class LocalIntentReceiver {
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 877b112..6562de96 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -300,6 +300,8 @@
installSource.mInitiatingPackageName);
proto.write(PackageProto.InstallSourceProto.ORIGINATING_PACKAGE_NAME,
installSource.mOriginatingPackageName);
+ proto.write(PackageProto.InstallSourceProto.UPDATE_OWNER_PACKAGE_NAME,
+ installSource.mUpdateOwnerPackageName);
proto.end(sourceToken);
}
proto.write(PackageProto.StatesProto.IS_LOADING, isLoading());
@@ -368,6 +370,12 @@
return this;
}
+ public PackageSetting setUpdateOwnerPackage(@Nullable String updateOwnerPackageName) {
+ installSource = installSource.setUpdateOwnerPackageName(updateOwnerPackageName);
+ onChanged();
+ return this;
+ }
+
public PackageSetting setInstallSource(InstallSource installSource) {
this.installSource = Objects.requireNonNull(installSource);
onChanged();
diff --git a/services/core/java/com/android/server/pm/ReconcilePackageUtils.java b/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
index 99bcbc9..58dcb02 100644
--- a/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
+++ b/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
@@ -213,8 +213,9 @@
if (sharedUserSetting != null) {
if (sharedUserSetting.signaturesChanged != null
&& !PackageManagerServiceUtils.canJoinSharedUserId(
- parsedPackage.getSigningDetails(),
- sharedUserSetting.getSigningDetails())) {
+ parsedPackage.getPackageName(), parsedPackage.getSigningDetails(),
+ sharedUserSetting,
+ PackageManagerServiceUtils.SHARED_USER_ID_JOIN_TYPE_SYSTEM)) {
if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 29) {
// Mismatched signatures is an error and silently skipping system
// packages will likely break the device in unforeseen ways.
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 6ebef20..97fb0c2 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -3050,6 +3050,9 @@
if (installSource.mInstallerPackageUid != INVALID_UID) {
serializer.attributeInt(null, "installerUid", installSource.mInstallerPackageUid);
}
+ if (installSource.mUpdateOwnerPackageName != null) {
+ serializer.attribute(null, "updateOwner", installSource.mUpdateOwnerPackageName);
+ }
if (installSource.mInstallerAttributionTag != null) {
serializer.attribute(null, "installerAttributionTag",
installSource.mInstallerAttributionTag);
@@ -3880,6 +3883,7 @@
String systemStr = null;
String installerPackageName = null;
int installerPackageUid = INVALID_UID;
+ String updateOwnerPackageName = null;
String installerAttributionTag = null;
int packageSource = PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED;
boolean isOrphaned = false;
@@ -3923,6 +3927,7 @@
versionCode = parser.getAttributeLong(null, "version", 0);
installerPackageName = parser.getAttributeValue(null, "installer");
installerPackageUid = parser.getAttributeInt(null, "installerUid", INVALID_UID);
+ updateOwnerPackageName = parser.getAttributeValue(null, "updateOwner");
installerAttributionTag = parser.getAttributeValue(null, "installerAttributionTag");
packageSource = parser.getAttributeInt(null, "packageSource",
PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
@@ -4065,8 +4070,9 @@
if (packageSetting != null) {
InstallSource installSource = InstallSource.create(
installInitiatingPackageName, installOriginatingPackageName,
- installerPackageName, installerPackageUid, installerAttributionTag,
- packageSource, isOrphaned, installInitiatorUninstalled);
+ installerPackageName, installerPackageUid, updateOwnerPackageName,
+ installerAttributionTag, packageSource, isOrphaned,
+ installInitiatorUninstalled);
packageSetting.setInstallSource(installSource)
.setVolumeUuid(volumeUuid)
.setCategoryOverride(categoryHint)
@@ -4734,6 +4740,8 @@
pw.print(ps.getInstallSource().mInstallerPackageName != null
? ps.getInstallSource().mInstallerPackageName : "?");
pw.print(ps.getInstallSource().mInstallerPackageUid);
+ pw.print(ps.getInstallSource().mUpdateOwnerPackageName != null
+ ? ps.getInstallSource().mUpdateOwnerPackageName : "?");
pw.print(ps.getInstallSource().mInstallerAttributionTag != null
? "(" + ps.getInstallSource().mInstallerAttributionTag + ")" : "");
pw.print(",");
@@ -5017,6 +5025,10 @@
pw.print(prefix); pw.print(" installerPackageUid=");
pw.println(ps.getInstallSource().mInstallerPackageUid);
}
+ if (ps.getInstallSource().mUpdateOwnerPackageName != null) {
+ pw.print(prefix); pw.print(" updateOwnerPackageName=");
+ pw.println(ps.getInstallSource().mUpdateOwnerPackageName);
+ }
if (ps.getInstallSource().mInstallerAttributionTag != null) {
pw.print(prefix); pw.print(" installerAttributionTag=");
pw.println(ps.getInstallSource().mInstallerAttributionTag);
diff --git a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
index d2ce23e..9987867 100644
--- a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
+++ b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
@@ -17,6 +17,7 @@
package com.android.server.pm;
import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
+import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_LIBRARY_BAD_CERTIFICATE_DIGEST;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
import static com.android.server.pm.PackageManagerService.SCAN_BOOTING;
@@ -1035,8 +1036,17 @@
} else {
// lib signing cert could have rotated beyond the one expected, check to see
// if the new one has been blessed by the old
- byte[] digestBytes = HexEncoding.decode(
- expectedCertDigests[0], false /* allowSingleChar */);
+ final byte[] digestBytes;
+ try {
+ digestBytes = HexEncoding.decode(
+ expectedCertDigests[0], false /* allowSingleChar */);
+ } catch (IllegalArgumentException e) {
+ throw new PackageManagerException(
+ INSTALL_FAILED_SHARED_LIBRARY_BAD_CERTIFICATE_DIGEST,
+ "Package " + packageName + " declares bad certificate digest "
+ + "for " + libraryType + " library " + libName
+ + "; failing!");
+ }
if (!libPkg.hasSha256Certificate(digestBytes)) {
throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
"Package " + packageName + " requires differently signed "
diff --git a/services/core/java/com/android/server/pm/UserManagerInternal.java b/services/core/java/com/android/server/pm/UserManagerInternal.java
index 2ae8b52..7b15e76 100644
--- a/services/core/java/com/android/server/pm/UserManagerInternal.java
+++ b/services/core/java/com/android/server/pm/UserManagerInternal.java
@@ -388,8 +388,8 @@
* and the user is {@link UserManager#isUserVisible() visible}.
*
* <p><b>NOTE: </b>this method is meant to be used only by {@code UserController} (when a user
- * is started). If other clients (like {@code CarService} need to explicitly change the user /
- * display assignment, we'll need to provide other APIs.
+ * is started); for extra unassignments, callers should call {@link
+ * #assignUserToExtraDisplay(int, int)} instead.
*
* <p><b>NOTE: </b>this method doesn't validate if the display exists, it's up to the caller to
* pass a valid display id.
@@ -398,15 +398,43 @@
@UserIdInt int profileGroupId, @UserStartMode int userStartMode, int displayId);
/**
+ * Assigns an extra display to the given user, so the user is visible on that display.
+ *
+ * <p>This method is meant to be used on automotive builds where a passenger zone has more than
+ * one display (for example, the "main" display and a smaller display used for input).
+ *
+ * <p><b>NOTE: </b>this call will be ignored on devices that do not
+ * {@link UserManager#isVisibleBackgroundUsersSupported() support visible background users}.
+ *
+ * @return whether the operation succeeded, in which case the user would be visible on the
+ * display.
+ */
+ public abstract boolean assignUserToExtraDisplay(@UserIdInt int userId, int displayId);
+
+ /**
* Unassigns a user from its current display when it's stopping.
*
* <p><b>NOTE: </b>this method is meant to be used only by {@code UserController} (when a user
- * is stopped). If other clients (like {@code CarService} need to explicitly change the user /
- * display assignment, we'll need to provide other APIs.
+ * is stopped); for extra unassignments, callers should call
+ * {@link #unassignUserFromExtraDisplay(int, int)} instead.
*/
public abstract void unassignUserFromDisplayOnStop(@UserIdInt int userId);
/**
+ * Unassigns the extra display from the given user.
+ *
+ * <p>This method is meant to be used on automotive builds where a passenger zone has more than
+ * one display (for example, the "main" display and a smaller display used for input).
+ *
+ * <p><b>NOTE: </b>this call will be ignored on devices that do not
+ * {@link UserManager#isVisibleBackgroundUsersSupported() support visible background users}.
+ *
+ * @return whether the operation succeeded, i.e., the user was previously
+ * {@link #assignUserToExtraDisplay(int, int) assigned to an extra display}.
+ */
+ public abstract boolean unassignUserFromExtraDisplay(@UserIdInt int userId, int displayId);
+
+ /**
* Returns {@code true} if the user is visible (as defined by
* {@link UserManager#isUserVisible()}.
*/
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 6bac905..a8cf8cb 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1476,20 +1476,15 @@
@Override
public void revokeUserAdmin(@UserIdInt int userId) {
checkManageUserAndAcrossUsersFullPermission("revoke admin privileges");
-
synchronized (mPackagesLock) {
- UserInfo info;
synchronized (mUsersLock) {
- info = getUserInfoLU(userId);
- }
- if (info == null || !info.isAdmin()) {
- // Exit if no user found with that id, or the user is not an Admin.
- return;
- }
-
- info.flags ^= UserInfo.FLAG_ADMIN;
- synchronized (mUsersLock) {
- writeUserLP(getUserDataLU(info.id));
+ UserData user = getUserDataLU(userId);
+ if (user == null || !user.info.isAdmin()) {
+ // Exit if no user found with that id, or the user is not an Admin.
+ return;
+ }
+ user.info.flags ^= UserInfo.FLAG_ADMIN;
+ writeUserLP(user);
}
}
}
@@ -5426,6 +5421,12 @@
return false;
}
+ if (isNonRemovableMainUser(userData.info)) {
+ Slog.e(LOG_TAG, "Main user cannot be removed when "
+ + "it's a permanent admin user.");
+ return false;
+ }
+
if (mRemovingUserIds.get(userId)) {
Slog.e(LOG_TAG, TextUtils.formatSimple(
"User %d is already scheduled for removal.", userId));
@@ -5530,6 +5531,12 @@
return UserManager.REMOVE_RESULT_ERROR_USER_NOT_FOUND;
}
+ if (isNonRemovableMainUser(userData.info)) {
+ Slog.e(LOG_TAG, "Main user cannot be removed when "
+ + "it's a permanent admin user.");
+ return UserManager.REMOVE_RESULT_ERROR_MAIN_USER_PERMANENT_ADMIN;
+ }
+
if (mRemovingUserIds.get(userId)) {
Slog.e(LOG_TAG, "User " + userId + " is already scheduled for removal.");
return UserManager.REMOVE_RESULT_ALREADY_BEING_REMOVED;
@@ -6748,7 +6755,7 @@
public void removeAllUsers() {
if (UserHandle.USER_SYSTEM == getCurrentUserId()) {
// Remove the non-system users straight away.
- removeNonSystemUsers();
+ removeAllUsersExceptSystemAndPermanentAdminMain();
} else {
// Switch to the system user first and then remove the other users.
BroadcastReceiver userSwitchedReceiver = new BroadcastReceiver() {
@@ -6760,7 +6767,7 @@
return;
}
mContext.unregisterReceiver(this);
- removeNonSystemUsers();
+ removeAllUsersExceptSystemAndPermanentAdminMain();
}
};
IntentFilter userSwitchedFilter = new IntentFilter();
@@ -7015,6 +7022,16 @@
}
@Override
+ public boolean assignUserToExtraDisplay(int userId, int displayId) {
+ return mUserVisibilityMediator.assignUserToExtraDisplay(userId, displayId);
+ }
+
+ @Override
+ public boolean unassignUserFromExtraDisplay(int userId, int displayId) {
+ return mUserVisibilityMediator.unassignUserFromExtraDisplay(userId, displayId);
+ }
+
+ @Override
public void unassignUserFromDisplayOnStop(@UserIdInt int userId) {
mUserVisibilityMediator.unassignUserFromDisplayOnStop(userId);
}
@@ -7113,14 +7130,14 @@
throw new UserManager.CheckedUserOperationException(message, userOperationResult);
}
- /* Remove all the users except of the system one. */
- private void removeNonSystemUsers() {
+ /* Remove all the users except the system and permanent admin main.*/
+ private void removeAllUsersExceptSystemAndPermanentAdminMain() {
ArrayList<UserInfo> usersToRemove = new ArrayList<>();
synchronized (mUsersLock) {
final int userSize = mUsers.size();
for (int i = 0; i < userSize; i++) {
UserInfo ui = mUsers.valueAt(i).info;
- if (ui.id != UserHandle.USER_SYSTEM) {
+ if (ui.id != UserHandle.USER_SYSTEM && !isNonRemovableMainUser(ui)) {
usersToRemove.add(ui);
}
}
@@ -7249,4 +7266,22 @@
return mAmInternal;
}
+ /**
+ * Returns true, when user has {@link UserInfo#FLAG_MAIN} and system property
+ * {@link com.android.internal.R.bool.isMainUserPermanentAdmin} is true.
+ */
+ private boolean isNonRemovableMainUser(UserInfo userInfo) {
+ return userInfo.isMain() && isMainUserPermanentAdmin();
+ }
+
+ /**
+ * Returns true, when {@link com.android.internal.R.bool.isMainUserPermanentAdmin} is true.
+ * If the main user is a permanent admin user it can't be deleted
+ * or downgraded to non-admin status.
+ */
+ private static boolean isMainUserPermanentAdmin() {
+ return Resources.getSystem()
+ .getBoolean(com.android.internal.R.bool.config_isMainUserPermanentAdmin);
+ }
+
}
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 27d74d5..214fd61 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -149,7 +149,8 @@
UserManager.DISALLOW_WIFI_DIRECT,
UserManager.DISALLOW_ADD_WIFI_CONFIG,
UserManager.DISALLOW_CELLULAR_2G,
- UserManager.DISALLOW_ULTRA_WIDEBAND_RADIO
+ UserManager.DISALLOW_ULTRA_WIDEBAND_RADIO,
+ UserManager.DISALLOW_CONFIG_DEFAULT_APPS
});
public static final Set<String> DEPRECATED_USER_RESTRICTIONS = Sets.newArraySet(
diff --git a/services/core/java/com/android/server/pm/UserTypeFactory.java b/services/core/java/com/android/server/pm/UserTypeFactory.java
index 9b337adf..edb2a4be3b 100644
--- a/services/core/java/com/android/server/pm/UserTypeFactory.java
+++ b/services/core/java/com/android/server/pm/UserTypeFactory.java
@@ -133,7 +133,9 @@
.setUseParentsContacts(true)
.setUpdateCrossProfileIntentFiltersOnOTA(true)
.setCrossProfileIntentFilterAccessControl(
- UserProperties.CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM));
+ UserProperties.CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM)
+ .setCrossProfileIntentResolutionStrategy(UserProperties
+ .CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_NO_FILTERING));
}
/**
diff --git a/services/core/java/com/android/server/pm/UserVisibilityMediator.java b/services/core/java/com/android/server/pm/UserVisibilityMediator.java
index d8e4dac..66d390f 100644
--- a/services/core/java/com/android/server/pm/UserVisibilityMediator.java
+++ b/services/core/java/com/android/server/pm/UserVisibilityMediator.java
@@ -19,6 +19,7 @@
import static android.os.UserHandle.USER_NULL;
import static android.os.UserHandle.USER_SYSTEM;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_FAILURE;
import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE;
@@ -113,7 +114,18 @@
*/
@Nullable
@GuardedBy("mLock")
- private final SparseIntArray mUsersOnDisplaysMap;
+ private final SparseIntArray mUsersAssignedToDisplayOnStart;
+
+ /**
+ * Map of extra (i.e., not assigned on start, but by explicit calls to
+ * {@link #assignUserToExtraDisplay(int, int)}) displays assigned to user (key is display id,
+ * value is user id).
+ *
+ * <p>Only set when {@code mUsersOnSecondaryDisplaysEnabled} is {@code true}.
+ */
+ @Nullable
+ @GuardedBy("mLock")
+ private final SparseIntArray mExtraDisplaysAssignedToUsers;
/**
* Mapping from each started user to its profile group.
@@ -137,7 +149,13 @@
@VisibleForTesting
UserVisibilityMediator(boolean backgroundUsersOnDisplaysEnabled, Handler handler) {
mVisibleBackgroundUsersEnabled = backgroundUsersOnDisplaysEnabled;
- mUsersOnDisplaysMap = mVisibleBackgroundUsersEnabled ? new SparseIntArray() : null;
+ if (mVisibleBackgroundUsersEnabled) {
+ mUsersAssignedToDisplayOnStart = new SparseIntArray();
+ mExtraDisplaysAssignedToUsers = new SparseIntArray();
+ } else {
+ mUsersAssignedToDisplayOnStart = null;
+ mExtraDisplaysAssignedToUsers = null;
+ }
mHandler = handler;
// TODO(b/242195409): might need to change this if boot logic is refactored for HSUM devices
mStartedProfileGroupIds.put(INITIAL_CURRENT_USER_ID, INITIAL_CURRENT_USER_ID);
@@ -207,7 +225,7 @@
if (DBG) {
Slogf.d(TAG, "adding user / display mapping (%d -> %d)", userId, displayId);
}
- mUsersOnDisplaysMap.put(userId, displayId);
+ mUsersAssignedToDisplayOnStart.put(userId, displayId);
break;
case SECONDARY_DISPLAY_MAPPING_NOT_NEEDED:
if (DBG) {
@@ -341,9 +359,9 @@
}
// Check if display is available
- for (int i = 0; i < mUsersOnDisplaysMap.size(); i++) {
- int assignedUserId = mUsersOnDisplaysMap.keyAt(i);
- int assignedDisplayId = mUsersOnDisplaysMap.valueAt(i);
+ for (int i = 0; i < mUsersAssignedToDisplayOnStart.size(); i++) {
+ int assignedUserId = mUsersAssignedToDisplayOnStart.keyAt(i);
+ int assignedDisplayId = mUsersAssignedToDisplayOnStart.valueAt(i);
if (DBG) {
Slogf.d(TAG, "%d: assignedUserId=%d, assignedDisplayId=%d",
i, assignedUserId, assignedDisplayId);
@@ -363,6 +381,100 @@
}
/**
+ * See {@link UserManagerInternal#assignUserToExtraDisplay(int, int)}.
+ */
+ public boolean assignUserToExtraDisplay(@UserIdInt int userId, int displayId) {
+ if (DBG) {
+ Slogf.d(TAG, "assignUserToExtraDisplay(%d, %d)", userId, displayId);
+ }
+ if (!mVisibleBackgroundUsersEnabled) {
+ Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): called when not supported", userId,
+ displayId);
+ return false;
+ }
+ if (displayId == INVALID_DISPLAY) {
+ Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): called with INVALID_DISPLAY", userId,
+ displayId);
+ return false;
+ }
+ if (displayId == DEFAULT_DISPLAY) {
+ Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): DEFAULT_DISPLAY is automatically "
+ + "assigned to current user", userId, displayId);
+ return false;
+ }
+
+ synchronized (mLock) {
+ if (!isUserVisible(userId)) {
+ Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): failed because user is not visible",
+ userId, displayId);
+ return false;
+ }
+ if (isStartedProfile(userId)) {
+ Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): failed because user is a profile",
+ userId, displayId);
+ return false;
+ }
+
+ if (mExtraDisplaysAssignedToUsers.get(displayId, USER_NULL) == userId) {
+ Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): failed because user is already "
+ + "assigned to that display", userId, displayId);
+ return false;
+ }
+
+ int userAssignedToDisplay = getUserAssignedToDisplay(displayId,
+ /* returnCurrentUserByDefault= */ false);
+ if (userAssignedToDisplay != USER_NULL) {
+ Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): failed because display was assigned"
+ + " to user %d on start", userId, displayId, userAssignedToDisplay);
+ return false;
+ }
+ userAssignedToDisplay = mExtraDisplaysAssignedToUsers.get(userId, USER_NULL);
+ if (userAssignedToDisplay != USER_NULL) {
+ Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): failed because user %d was already "
+ + "assigned that extra display", userId, displayId, userAssignedToDisplay);
+ return false;
+ }
+ if (DBG) {
+ Slogf.d(TAG, "addding %d -> %d to map", displayId, userId);
+ }
+ mExtraDisplaysAssignedToUsers.put(displayId, userId);
+ }
+ return true;
+ }
+
+ /**
+ * See {@link UserManagerInternal#unassignUserFromExtraDisplay(int, int)}.
+ */
+ public boolean unassignUserFromExtraDisplay(@UserIdInt int userId, int displayId) {
+ if (DBG) {
+ Slogf.d(TAG, "unassignUserFromExtraDisplay(%d, %d)", userId, displayId);
+ }
+ if (!mVisibleBackgroundUsersEnabled) {
+ Slogf.w(TAG, "unassignUserFromExtraDisplay(%d, %d): called when not supported",
+ userId, displayId);
+ return false;
+ }
+ synchronized (mLock) {
+ int assignedUserId = mExtraDisplaysAssignedToUsers.get(displayId, USER_NULL);
+ if (assignedUserId == USER_NULL) {
+ Slogf.w(TAG, "unassignUserFromExtraDisplay(%d, %d): not assigned to any user",
+ userId, displayId);
+ return false;
+ }
+ if (assignedUserId != userId) {
+ Slogf.w(TAG, "unassignUserFromExtraDisplay(%d, %d): was assigned to user %d",
+ userId, displayId, assignedUserId);
+ return false;
+ }
+ if (DBG) {
+ Slogf.d(TAG, "removing %d from map", displayId);
+ }
+ mExtraDisplaysAssignedToUsers.delete(displayId);
+ }
+ return true;
+ }
+
+ /**
* See {@link UserManagerInternal#unassignUserFromDisplayOnStop(int)}.
*/
public void unassignUserFromDisplayOnStop(@UserIdInt int userId) {
@@ -373,7 +485,7 @@
synchronized (mLock) {
visibleUsersBefore = getVisibleUsers();
- unassignUserFromDisplayOnStopLocked(userId);
+ unassignUserFromAllDisplaysOnStopLocked(userId);
visibleUsersAfter = getVisibleUsers();
}
@@ -381,7 +493,7 @@
}
@GuardedBy("mLock")
- private void unassignUserFromDisplayOnStopLocked(@UserIdInt int userId) {
+ private void unassignUserFromAllDisplaysOnStopLocked(@UserIdInt int userId) {
if (DBG) {
Slogf.d(TAG, "Removing %d from mStartedProfileGroupIds (%s)", userId,
mStartedProfileGroupIds);
@@ -395,10 +507,21 @@
return;
}
if (DBG) {
- Slogf.d(TAG, "Removing %d from mUsersOnSecondaryDisplays (%s)", userId,
- mUsersOnDisplaysMap);
+ Slogf.d(TAG, "Removing user %d from mUsersOnDisplaysMap (%s)", userId,
+ mUsersAssignedToDisplayOnStart);
}
- mUsersOnDisplaysMap.delete(userId);
+ mUsersAssignedToDisplayOnStart.delete(userId);
+
+ // Remove extra displays as well
+ for (int i = mExtraDisplaysAssignedToUsers.size() - 1; i >= 0; i--) {
+ if (mExtraDisplaysAssignedToUsers.valueAt(i) == userId) {
+ if (DBG) {
+ Slogf.d(TAG, "Removing display %d from mExtraDisplaysAssignedToUsers (%s)",
+ mExtraDisplaysAssignedToUsers.keyAt(i), mExtraDisplaysAssignedToUsers);
+ }
+ mExtraDisplaysAssignedToUsers.removeAt(i);
+ }
+ }
}
/**
@@ -424,7 +547,7 @@
boolean visible;
synchronized (mLock) {
- visible = mUsersOnDisplaysMap.indexOfKey(userId) >= 0;
+ visible = mUsersAssignedToDisplayOnStart.indexOfKey(userId) >= 0;
}
if (DBG) {
Slogf.d(TAG, "isUserVisible(%d): %b from mapping", userId, visible);
@@ -448,7 +571,12 @@
}
synchronized (mLock) {
- return mUsersOnDisplaysMap.get(userId, Display.INVALID_DISPLAY) == displayId;
+ if (mUsersAssignedToDisplayOnStart.get(userId, Display.INVALID_DISPLAY) == displayId) {
+ // User assigned to display on start
+ return true;
+ }
+ // Check for extra assignment
+ return mExtraDisplaysAssignedToUsers.get(displayId, USER_NULL) == userId;
}
}
@@ -465,24 +593,34 @@
}
synchronized (mLock) {
- return mUsersOnDisplaysMap.get(userId, Display.INVALID_DISPLAY);
+ return mUsersAssignedToDisplayOnStart.get(userId, Display.INVALID_DISPLAY);
}
}
/**
* See {@link UserManagerInternal#getUserAssignedToDisplay(int)}.
*/
- public int getUserAssignedToDisplay(@UserIdInt int displayId) {
- if (displayId == Display.DEFAULT_DISPLAY || !mVisibleBackgroundUsersEnabled) {
+ public @UserIdInt int getUserAssignedToDisplay(@UserIdInt int displayId) {
+ return getUserAssignedToDisplay(displayId, /* returnCurrentUserByDefault= */ true);
+ }
+
+ /**
+ * Gets the user explicitly assigned to a display, or the current user when no user is assigned
+ * to it (and {@code returnCurrentUserByDefault} is {@code true}).
+ */
+ private @UserIdInt int getUserAssignedToDisplay(@UserIdInt int displayId,
+ boolean returnCurrentUserByDefault) {
+ if (returnCurrentUserByDefault
+ && (displayId == Display.DEFAULT_DISPLAY || !mVisibleBackgroundUsersEnabled)) {
return getCurrentUserId();
}
synchronized (mLock) {
- for (int i = 0; i < mUsersOnDisplaysMap.size(); i++) {
- if (mUsersOnDisplaysMap.valueAt(i) != displayId) {
+ for (int i = 0; i < mUsersAssignedToDisplayOnStart.size(); i++) {
+ if (mUsersAssignedToDisplayOnStart.valueAt(i) != displayId) {
continue;
}
- int userId = mUsersOnDisplaysMap.keyAt(i);
+ int userId = mUsersAssignedToDisplayOnStart.keyAt(i);
if (!isStartedProfile(userId)) {
return userId;
} else if (DBG) {
@@ -491,6 +629,13 @@
}
}
}
+ if (!returnCurrentUserByDefault) {
+ if (DBG) {
+ Slogf.d(TAG, "getUserAssignedToDisplay(%d): no user assigned to display, returning "
+ + "USER_NULL instead", displayId);
+ }
+ return USER_NULL;
+ }
int currentUserId = getCurrentUserId();
if (DBG) {
@@ -618,9 +763,11 @@
ipw.print("Supports visible background users on displays: ");
ipw.println(mVisibleBackgroundUsersEnabled);
- if (mUsersOnDisplaysMap != null) {
- dumpSparseIntArray(ipw, mUsersOnDisplaysMap, "user / display", "u", "d");
- }
+ dumpSparseIntArray(ipw, mUsersAssignedToDisplayOnStart, "user / display", "u", "d");
+
+ dumpSparseIntArray(ipw, mExtraDisplaysAssignedToUsers, "extra display / user",
+ "d", "u");
+
int numberListeners = mListeners.size();
ipw.print("Number of listeners: ");
ipw.println(numberListeners);
@@ -638,8 +785,14 @@
ipw.decreaseIndent();
}
- private static void dumpSparseIntArray(IndentingPrintWriter ipw, SparseIntArray array,
+ private static void dumpSparseIntArray(IndentingPrintWriter ipw, @Nullable SparseIntArray array,
String arrayDescription, String keyName, String valueName) {
+ if (array == null) {
+ ipw.print("No ");
+ ipw.print(arrayDescription);
+ ipw.println(" mappings");
+ return;
+ }
ipw.print("Number of ");
ipw.print(arrayDescription);
ipw.print(" mappings: ");
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index fbf7409..7f0c3f9 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -126,20 +126,21 @@
private static int DEX_SEARCH_FOUND_SECONDARY = 3; // dex file is a secondary dex
public DexManager(Context context, PackageDexOptimizer pdo, Installer installer,
- Object installLock) {
- this(context, pdo, installer, installLock, null);
+ Object installLock, DynamicCodeLogger dynamicCodeLogger) {
+ this(context, pdo, installer, installLock, dynamicCodeLogger, null);
}
@VisibleForTesting
public DexManager(Context context, PackageDexOptimizer pdo, Installer installer,
- Object installLock, @Nullable IPackageManager packageManager) {
+ Object installLock, DynamicCodeLogger dynamicCodeLogger,
+ @Nullable IPackageManager packageManager) {
mContext = context;
mPackageCodeLocationsCache = new HashMap<>();
mPackageDexUsage = new PackageDexUsage();
mPackageDexOptimizer = pdo;
mInstaller = installer;
mInstallLock = installLock;
- mDynamicCodeLogger = new DynamicCodeLogger(installer);
+ mDynamicCodeLogger = dynamicCodeLogger;
mPackageManager = packageManager;
// This is currently checked to handle tests that pass in a null context.
@@ -169,10 +170,6 @@
return mPackageManager;
}
- public DynamicCodeLogger getDynamicCodeLogger() {
- return mDynamicCodeLogger;
- }
-
/**
* Notify about dex files loads.
* Note that this method is invoked when apps load dex files and it should
@@ -328,7 +325,6 @@
loadInternal(existingPackages);
} catch (RuntimeException e) {
mPackageDexUsage.clear();
- mDynamicCodeLogger.clear();
Slog.w(TAG, "Exception while loading. Starting with a fresh state.", e);
}
}
@@ -379,12 +375,10 @@
if (mPackageDexUsage.removePackage(packageName)) {
mPackageDexUsage.maybeWriteAsync();
}
- mDynamicCodeLogger.removePackage(packageName);
} else {
if (mPackageDexUsage.removeUserPackage(packageName, userId)) {
mPackageDexUsage.maybeWriteAsync();
}
- mDynamicCodeLogger.removeUserPackage(packageName, userId);
}
}
@@ -463,14 +457,6 @@
Slog.w(TAG, "Exception while loading package dex usage. "
+ "Starting with a fresh state.", e);
}
-
- try {
- mDynamicCodeLogger.readAndSync(packageToUsersMap);
- } catch (RuntimeException e) {
- mDynamicCodeLogger.clear();
- Slog.w(TAG, "Exception while loading package dynamic code usage. "
- + "Starting with a fresh state.", e);
- }
}
/**
@@ -565,89 +551,6 @@
}
/**
- * Performs dexopt on system server dex files.
- *
- * <p>Verfifies that the package name is {@link PackageManagerService#PLATFORM_PACKAGE_NAME}.
- *
- * @return
- * <p>PackageDexOptimizer.DEX_OPT_SKIPPED if dexopt was skipped because no system server
- * files were recorded or if no dexopt was needed.
- * <p>PackageDexOptimizer.DEX_OPT_FAILED if any dexopt operation failed.
- * <p>PackageDexOptimizer.DEX_OPT_PERFORMED if all dexopt operations succeeded.
- */
- public int dexoptSystemServer(DexoptOptions options) throws LegacyDexoptDisabledException {
- // TODO(b/254043366): Clean this up.
- if (!isPlatformPackage(options.getPackageName())) {
- Slog.wtf(TAG, "Non system server package used when trying to dexopt system server:"
- + options.getPackageName());
- return PackageDexOptimizer.DEX_OPT_FAILED;
- }
-
- // Override compiler filter for system server to the expected one.
- //
- // We could let the caller do this every time the invoke PackageManagerServer#dexopt.
- // However, there are a few places were this will need to be done which creates
- // redundancy and the danger of overlooking the config (and thus generating code that will
- // waste storage and time).
- DexoptOptions overriddenOptions = options.overrideCompilerFilter(
- SYSTEM_SERVER_COMPILER_FILTER);
-
- PackageDexOptimizer pdo = getPackageDexOptimizer(overriddenOptions);
- String packageName = overriddenOptions.getPackageName();
- PackageUseInfo useInfo = getPackageUseInfoOrDefault(packageName);
- if (useInfo.getDexUseInfoMap().isEmpty()) {
- if (DEBUG) {
- Slog.d(TAG, "No dex files recorded for system server");
- }
- // Nothing to compile, return true.
- return PackageDexOptimizer.DEX_OPT_SKIPPED;
- }
-
- boolean usageUpdated = false;
- int result = PackageDexOptimizer.DEX_OPT_SKIPPED;
- for (Map.Entry<String, DexUseInfo> entry : useInfo.getDexUseInfoMap().entrySet()) {
- String dexPath = entry.getKey();
- DexUseInfo dexUseInfo = entry.getValue();
- if (!Files.exists(Paths.get(dexPath))) {
- if (DEBUG) {
- Slog.w(TAG, "A dex file previously loaded by System Server does not exist "
- + " anymore: " + dexPath);
- }
- usageUpdated = mPackageDexUsage.removeDexFile(
- packageName, dexPath, dexUseInfo.getOwnerUserId()) || usageUpdated;
- continue;
- }
-
- if (dexUseInfo.isUnsupportedClassLoaderContext()
- || dexUseInfo.isVariableClassLoaderContext()) {
- String debugMsg = dexUseInfo.isUnsupportedClassLoaderContext()
- ? "unsupported"
- : "variable";
- Slog.w(TAG, "Skipping dexopt for system server path loaded with " + debugMsg
- + " class loader context: " + dexPath);
- continue;
- }
-
- int newResult = pdo.dexoptSystemServerPath(dexPath, dexUseInfo, overriddenOptions);
-
- // The end result is:
- // - FAILED if any path failed,
- // - PERFORMED if at least one path needed compilation,
- // - SKIPPED when all paths are up to date
- if ((result != PackageDexOptimizer.DEX_OPT_FAILED)
- && (newResult != PackageDexOptimizer.DEX_OPT_SKIPPED)) {
- result = newResult;
- }
- }
-
- if (usageUpdated) {
- mPackageDexUsage.maybeWriteAsync();
- }
-
- return result;
- }
-
- /**
* Select the dex optimizer based on the force parameter.
* Forced compilation is done through ForcedUpdatePackageDexOptimizer which will adjust
* the necessary dexopt flags to make sure that compilation is not skipped. This avoid
@@ -902,7 +805,6 @@
*/
public void writePackageDexUsageNow() {
mPackageDexUsage.writeNow();
- mDynamicCodeLogger.writeNow();
}
/**
diff --git a/services/core/java/com/android/server/pm/dex/DynamicCodeLogger.java b/services/core/java/com/android/server/pm/dex/DynamicCodeLogger.java
index 9b94e99..da8fafa 100644
--- a/services/core/java/com/android/server/pm/dex/DynamicCodeLogger.java
+++ b/services/core/java/com/android/server/pm/dex/DynamicCodeLogger.java
@@ -43,6 +43,9 @@
import java.io.File;
import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -64,7 +67,7 @@
private final PackageDynamicCodeLoading mPackageDynamicCodeLoading;
private final Installer mInstaller;
- DynamicCodeLogger(Installer installer) {
+ public DynamicCodeLogger(Installer installer) {
mInstaller = installer;
mPackageDynamicCodeLoading = new PackageDynamicCodeLoading();
}
@@ -220,8 +223,12 @@
EventLog.writeEvent(SNET_TAG, subtag, uid, message);
}
- void recordDex(int loaderUserId, String dexPath, String owningPackageName,
- String loadingPackageName) {
+ /**
+ * Records that an app running in the specified uid has executed dex code from the file at
+ * {@code path}.
+ */
+ public void recordDex(
+ int loaderUserId, String dexPath, String owningPackageName, String loadingPackageName) {
if (mPackageDynamicCodeLoading.record(owningPackageName, dexPath,
FILE_TYPE_DEX, loaderUserId, loadingPackageName)) {
mPackageDynamicCodeLoading.maybeWriteAsync();
@@ -229,8 +236,8 @@
}
/**
- * Record that an app running in the specified uid has executed native code from the file at
- * {@param path}.
+ * Records that an app running in the specified uid has executed native code from the file at
+ * {@code path}.
*/
public void recordNative(int loadingUid, String path) {
String[] packages;
@@ -274,7 +281,39 @@
mPackageDynamicCodeLoading.syncData(packageToUsersMap);
}
- void writeNow() {
+ /** Writes the in-memory dynamic code information to disk right away. */
+ public void writeNow() {
mPackageDynamicCodeLoading.writeNow();
}
+
+ /** Reads the dynamic code information from disk. */
+ public void load(Map<Integer, List<PackageInfo>> userToPackagesMap) {
+ // Compute a reverse map.
+ Map<String, Set<Integer>> packageToUsersMap = new HashMap<>();
+ for (Map.Entry<Integer, List<PackageInfo>> entry : userToPackagesMap.entrySet()) {
+ List<PackageInfo> packageInfoList = entry.getValue();
+ int userId = entry.getKey();
+ for (PackageInfo pi : packageInfoList) {
+ Set<Integer> users =
+ packageToUsersMap.computeIfAbsent(pi.packageName, k -> new HashSet<>());
+ users.add(userId);
+ }
+ }
+
+ readAndSync(packageToUsersMap);
+ }
+
+ /**
+ * Notifies that the user {@code userId} data for package {@code packageName} was destroyed.
+ * This will remove all dynamic code information associated with the package for the given user.
+ * {@code userId} is allowed to be {@code UserHandle.USER_ALL} in which case
+ * all dynamic code information for the package will be removed.
+ */
+ public void notifyPackageDataDestroyed(String packageName, int userId) {
+ if (userId == UserHandle.USER_ALL) {
+ removePackage(packageName);
+ } else {
+ removeUserPackage(packageName, userId);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java b/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java
index 1778e57..d7c4a09 100644
--- a/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java
+++ b/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java
@@ -1810,6 +1810,11 @@
}
@Override
+ public boolean isAllowUpdateOwnership() {
+ return getBoolean2(Booleans2.ALLOW_UPDATE_OWNERSHIP);
+ }
+
+ @Override
public boolean isVmSafeMode() {
return getBoolean(Booleans.VM_SAFE_MODE);
}
@@ -2513,6 +2518,11 @@
}
@Override
+ public PackageImpl setAllowUpdateOwnership(boolean value) {
+ return setBoolean2(Booleans2.ALLOW_UPDATE_OWNERSHIP, value);
+ }
+
+ @Override
public PackageImpl sortActivities() {
Collections.sort(this.activities, ORDER_COMPARATOR);
return this;
@@ -3726,5 +3736,6 @@
private static final long STUB = 1L;
private static final long APEX = 1L << 1;
+ private static final long ALLOW_UPDATE_OWNERSHIP = 1L << 2;
}
}
diff --git a/services/core/java/com/android/server/pm/permission/Permission.java b/services/core/java/com/android/server/pm/permission/Permission.java
index f3b9246..c81d6d7 100644
--- a/services/core/java/com/android/server/pm/permission/Permission.java
+++ b/services/core/java/com/android/server/pm/permission/Permission.java
@@ -105,6 +105,15 @@
mType = type;
}
+ public Permission(@NonNull PermissionInfo permissionInfo, @PermissionType int type,
+ boolean reconciled, int uid, int[] gids, boolean gidsPerUser) {
+ this(permissionInfo, type);
+ mReconciled = reconciled;
+ mUid = uid;
+ mGids = gids;
+ mGidsPerUser = gidsPerUser;
+ }
+
@NonNull
public PermissionInfo getPermissionInfo() {
return mPermissionInfo;
diff --git a/services/core/java/com/android/server/pm/pkg/AndroidPackage.java b/services/core/java/com/android/server/pm/pkg/AndroidPackage.java
index 78091bc..ad73873 100644
--- a/services/core/java/com/android/server/pm/pkg/AndroidPackage.java
+++ b/services/core/java/com/android/server/pm/pkg/AndroidPackage.java
@@ -1483,4 +1483,10 @@
* @hide
*/
boolean isVisibleToInstantApps();
+
+ /**
+ * @see R.styleable#AndroidManifest_allowUpdateOwnership
+ * @hide
+ */
+ boolean isAllowUpdateOwnership();
}
diff --git a/services/core/java/com/android/server/pm/pkg/mutate/PackageStateMutator.java b/services/core/java/com/android/server/pm/pkg/mutate/PackageStateMutator.java
index 4a8ef96..5947d47 100644
--- a/services/core/java/com/android/server/pm/pkg/mutate/PackageStateMutator.java
+++ b/services/core/java/com/android/server/pm/pkg/mutate/PackageStateMutator.java
@@ -291,6 +291,15 @@
return this;
}
+ @NonNull
+ @Override
+ public PackageStateWrite setUpdateOwner(@NonNull String updateOwnerPackageName) {
+ if (mState != null) {
+ mState.setUpdateOwnerPackage(updateOwnerPackageName);
+ }
+ return this;
+ }
+
private static class UserStateWriteWrapper implements PackageUserStateWrite {
@Nullable
diff --git a/services/core/java/com/android/server/pm/pkg/mutate/PackageStateWrite.java b/services/core/java/com/android/server/pm/pkg/mutate/PackageStateWrite.java
index dc9cd3b..c610c02 100644
--- a/services/core/java/com/android/server/pm/pkg/mutate/PackageStateWrite.java
+++ b/services/core/java/com/android/server/pm/pkg/mutate/PackageStateWrite.java
@@ -57,4 +57,7 @@
@NonNull
PackageStateWrite setInstaller(@Nullable String installerPackageName, int installerPackageUid);
+
+ @NonNull
+ PackageStateWrite setUpdateOwner(@Nullable String updateOwnerPackageName);
}
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java
index 69f2716..bb36758 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java
@@ -387,6 +387,8 @@
ParsingPackage setLocaleConfigRes(int localeConfigRes);
+ ParsingPackage setAllowUpdateOwnership(boolean value);
+
/**
* Sets the trusted host certificates of apps that are allowed to embed activities of this
* application.
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
index 995b9e5..31f291f 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
@@ -219,6 +219,7 @@
public static final int PARSE_DEFAULT_INSTALL_LOCATION =
PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
public static final int PARSE_DEFAULT_TARGET_SANDBOX = 1;
+ public static final boolean PARSE_DEFAULT_ALLOW_UPDATE_OWNERSHIP = true;
/**
* If set to true, we will only allow package files that exactly match the DTD. Otherwise, we
@@ -247,6 +248,9 @@
private static final String MAX_NUM_COMPONENTS_ERR_MSG =
"Total number of components has exceeded the maximum number: " + MAX_NUM_COMPONENTS;
+ /** The maximum permission name length. */
+ private static final int MAX_PERMISSION_NAME_LENGTH = 512;
+
@IntDef(flag = true, prefix = { "PARSE_" }, value = {
PARSE_CHATTY,
PARSE_COLLECT_CERTIFICATES,
@@ -883,7 +887,9 @@
.setTargetSandboxVersion(anInteger(PARSE_DEFAULT_TARGET_SANDBOX,
R.styleable.AndroidManifest_targetSandboxVersion, sa))
/* Set the global "on SD card" flag */
- .setExternalStorage((flags & PARSE_EXTERNAL_STORAGE) != 0);
+ .setExternalStorage((flags & PARSE_EXTERNAL_STORAGE) != 0)
+ .setAllowUpdateOwnership(bool(PARSE_DEFAULT_ALLOW_UPDATE_OWNERSHIP,
+ R.styleable.AndroidManifest_allowUpdateOwnership, sa));
boolean foundApp = false;
final int depth = parser.getDepth();
@@ -1260,6 +1266,11 @@
// that may change.
String name = sa.getNonResourceString(
R.styleable.AndroidManifestUsesPermission_name);
+ if (TextUtils.length(name) > MAX_PERMISSION_NAME_LENGTH) {
+ return input.error(INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "The name in the <uses-permission> is greater than "
+ + MAX_PERMISSION_NAME_LENGTH);
+ }
int minSdkVersion = parseMinOrMaxSdkVersion(sa,
R.styleable.AndroidManifestUsesPermission_minSdkVersion,
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 884d5d6..c29ab09 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -3229,8 +3229,7 @@
}
final PowerGroup powerGroup = mPowerGroups.get(groupId);
wakefulness = powerGroup.getWakefulnessLocked();
- if ((wakefulness == WAKEFULNESS_DREAMING || wakefulness == WAKEFULNESS_DOZING) &&
- powerGroup.isSandmanSummonedLocked() && powerGroup.isReadyLocked()) {
+ if (powerGroup.isSandmanSummonedLocked() && powerGroup.isReadyLocked()) {
startDreaming = canDreamLocked(powerGroup) || canDozeLocked(powerGroup);
powerGroup.setSandmanSummonedLocked(/* isSandmanSummoned= */ false);
} else {
diff --git a/services/core/java/com/android/server/security/rkp/RemoteProvisioningRegistration.java b/services/core/java/com/android/server/security/rkp/RemoteProvisioningRegistration.java
index 868f34b..0e92709 100644
--- a/services/core/java/com/android/server/security/rkp/RemoteProvisioningRegistration.java
+++ b/services/core/java/com/android/server/security/rkp/RemoteProvisioningRegistration.java
@@ -21,10 +21,12 @@
import android.os.OutcomeReceiver;
import android.security.rkp.IGetKeyCallback;
import android.security.rkp.IRegistration;
+import android.security.rkp.IStoreUpgradedKeyCallback;
import android.security.rkp.service.RegistrationProxy;
import android.security.rkp.service.RemotelyProvisionedKey;
import android.util.Log;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
@@ -36,8 +38,10 @@
*/
final class RemoteProvisioningRegistration extends IRegistration.Stub {
static final String TAG = RemoteProvisioningService.TAG;
- private final ConcurrentHashMap<IGetKeyCallback, CancellationSignal> mOperations =
+ private final ConcurrentHashMap<IGetKeyCallback, CancellationSignal> mGetKeyOperations =
new ConcurrentHashMap<>();
+ private final Set<IStoreUpgradedKeyCallback> mStoreUpgradedKeyOperations =
+ ConcurrentHashMap.newKeySet();
private final RegistrationProxy mRegistration;
private final Executor mExecutor;
@@ -49,7 +53,7 @@
@Override
public void onResult(RemotelyProvisionedKey result) {
- mOperations.remove(mCallback);
+ mGetKeyOperations.remove(mCallback);
Log.i(TAG, "Successfully fetched key for client " + mCallback.hashCode());
android.security.rkp.RemotelyProvisionedKey parcelable =
new android.security.rkp.RemotelyProvisionedKey();
@@ -60,7 +64,7 @@
@Override
public void onError(Exception e) {
- mOperations.remove(mCallback);
+ mGetKeyOperations.remove(mCallback);
if (e instanceof OperationCanceledException) {
Log.i(TAG, "Operation cancelled for client " + mCallback.hashCode());
wrapCallback(mCallback::onCancel);
@@ -79,7 +83,7 @@
@Override
public void getKey(int keyId, IGetKeyCallback callback) {
CancellationSignal cancellationSignal = new CancellationSignal();
- if (mOperations.putIfAbsent(callback, cancellationSignal) != null) {
+ if (mGetKeyOperations.putIfAbsent(callback, cancellationSignal) != null) {
Log.e(TAG, "Client can only request one call at a time " + callback.hashCode());
throw new IllegalArgumentException(
"Callback is already associated with an existing operation: "
@@ -92,14 +96,14 @@
new GetKeyReceiver(callback));
} catch (Exception e) {
Log.e(TAG, "getKeyAsync threw an exception for client " + callback.hashCode(), e);
- mOperations.remove(callback);
+ mGetKeyOperations.remove(callback);
wrapCallback(() -> callback.onError(e.getMessage()));
}
}
@Override
public void cancelGetKey(IGetKeyCallback callback) {
- CancellationSignal cancellationSignal = mOperations.remove(callback);
+ CancellationSignal cancellationSignal = mGetKeyOperations.remove(callback);
if (cancellationSignal == null) {
throw new IllegalArgumentException(
"Invalid client in cancelGetKey: " + callback.hashCode());
@@ -110,9 +114,35 @@
}
@Override
- public void storeUpgradedKey(byte[] oldKeyBlob, byte[] newKeyBlob) {
- // TODO(b/262748535)
- Log.e(TAG, "RegistrationBinder.storeUpgradedKey NOT YET IMPLEMENTED");
+ public void storeUpgradedKeyAsync(byte[] oldKeyBlob, byte[] newKeyBlob,
+ IStoreUpgradedKeyCallback callback) {
+ if (!mStoreUpgradedKeyOperations.add(callback)) {
+ throw new IllegalArgumentException(
+ "Callback is already associated with an existing operation: "
+ + callback.hashCode());
+ }
+
+ try {
+ mRegistration.storeUpgradedKeyAsync(oldKeyBlob, newKeyBlob, mExecutor,
+ new OutcomeReceiver<>() {
+ @Override
+ public void onResult(Void result) {
+ mStoreUpgradedKeyOperations.remove(callback);
+ wrapCallback(callback::onSuccess);
+ }
+
+ @Override
+ public void onError(Exception e) {
+ mStoreUpgradedKeyOperations.remove(callback);
+ wrapCallback(() -> callback.onError(e.getMessage()));
+ }
+ });
+ } catch (Exception e) {
+ Log.e(TAG, "storeUpgradedKeyAsync threw an exception for client "
+ + callback.hashCode(), e);
+ mStoreUpgradedKeyOperations.remove(callback);
+ wrapCallback(() -> callback.onError(e.getMessage()));
+ }
}
interface CallbackRunner {
diff --git a/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java b/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java
index 41824de..b0d301e 100644
--- a/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java
+++ b/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java
@@ -16,6 +16,7 @@
package com.android.server.timedetector;
+import android.annotation.ElapsedRealtimeLong;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -39,12 +40,14 @@
import android.os.ShellCallback;
import android.os.SystemClock;
import android.provider.Settings;
+import android.util.IndentingPrintWriter;
import android.util.LocalLog;
import android.util.Log;
import android.util.NtpTrustedTime;
import android.util.NtpTrustedTime.TimeResult;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
@@ -52,12 +55,17 @@
import java.io.PrintWriter;
import java.time.Duration;
import java.util.Objects;
+import java.util.function.Supplier;
/**
- * Monitors the network time. If looking up the network time fails for some reason, it tries a few
- * times with a short interval and then resets to checking on longer intervals.
+ * Refreshes network time periodically, when network connectivity becomes available and when the
+ * user enables automatic time detection.
*
- * <p>When available, the time is always suggested to the {@link
+ * <p>For periodic requests, this service attempts to leave an interval between successful requests.
+ * If a request fails, it retries a number of times with a "short" interval and then resets to the
+ * normal interval. The process then repeats.
+ *
+ * <p>When a valid network time is available, the time is always suggested to the {@link
* com.android.server.timedetector.TimeDetectorService} where it may be used to set the device
* system clock, depending on user settings and what other signals are available.
*/
@@ -72,25 +80,11 @@
private final Object mLock = new Object();
private final Context mContext;
- private final NtpTrustedTime mNtpTrustedTime;
- private final AlarmManager mAlarmManager;
- private final TimeDetectorInternal mTimeDetectorInternal;
private final ConnectivityManager mCM;
- private final PendingIntent mPendingPollIntent;
private final PowerManager.WakeLock mWakeLock;
-
- // Normal polling frequency
- private final int mNormalPollingIntervalMillis;
- // Try-again polling interval, in case the network request failed
- private final int mShortPollingIntervalMillis;
- // Number of times to try again
- private final int mTryAgainTimesMax;
-
- /**
- * A log that records the decisions to fetch a network time update.
- * This is logged in bug reports to assist with debugging issues with network time suggestions.
- */
- private final LocalLog mLocalLog = new LocalLog(30, false /* useLocalTimestamps */);
+ private final NtpTrustedTime mNtpTrustedTime;
+ private final Engine.RefreshCallbacks mRefreshCallbacks;
+ private final Engine mEngine;
// Blocking NTP lookup is done using this handler
private final Handler mHandler;
@@ -100,33 +94,43 @@
@Nullable
private Network mDefaultNetwork = null;
- // Keeps track of how many quick attempts were made to fetch NTP time.
- // During bootup, the network may not have been up yet, or it's taking time for the
- // connection to happen.
- // This field is only updated and accessed by the mHandler thread (except dump()).
- @GuardedBy("mLock")
- private int mTryAgainCounter;
-
public NetworkTimeUpdateService(@NonNull Context context) {
mContext = Objects.requireNonNull(context);
- mAlarmManager = mContext.getSystemService(AlarmManager.class);
- mTimeDetectorInternal = LocalServices.getService(TimeDetectorInternal.class);
mCM = mContext.getSystemService(ConnectivityManager.class);
mWakeLock = context.getSystemService(PowerManager.class).newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, TAG);
mNtpTrustedTime = NtpTrustedTime.getInstance(context);
- mTryAgainTimesMax = mContext.getResources().getInteger(
+ Supplier<Long> elapsedRealtimeMillisSupplier = SystemClock::elapsedRealtime;
+ int tryAgainTimesMax = mContext.getResources().getInteger(
com.android.internal.R.integer.config_ntpRetry);
- mNormalPollingIntervalMillis = mContext.getResources().getInteger(
+ int normalPollingIntervalMillis = mContext.getResources().getInteger(
com.android.internal.R.integer.config_ntpPollingInterval);
- mShortPollingIntervalMillis = mContext.getResources().getInteger(
+ int shortPollingIntervalMillis = mContext.getResources().getInteger(
com.android.internal.R.integer.config_ntpPollingIntervalShorter);
+ mEngine = new EngineImpl(elapsedRealtimeMillisSupplier, normalPollingIntervalMillis,
+ shortPollingIntervalMillis, tryAgainTimesMax, mNtpTrustedTime);
+ AlarmManager alarmManager = mContext.getSystemService(AlarmManager.class);
+ TimeDetectorInternal timeDetectorInternal =
+ LocalServices.getService(TimeDetectorInternal.class);
// Broadcast alarms sent by system are immutable
Intent pollIntent = new Intent(ACTION_POLL, null);
- mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST,
+ PendingIntent pendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST,
pollIntent, PendingIntent.FLAG_IMMUTABLE);
+ mRefreshCallbacks = new Engine.RefreshCallbacks() {
+ @Override
+ public void scheduleNextRefresh(@ElapsedRealtimeLong long elapsedRealtimeMillis) {
+ alarmManager.cancel(pendingPollIntent);
+ alarmManager.set(
+ AlarmManager.ELAPSED_REALTIME, elapsedRealtimeMillis, pendingPollIntent);
+ }
+
+ @Override
+ public void submitSuggestion(NetworkTimeSuggestion suggestion) {
+ timeDetectorInternal.suggestNetworkTime(suggestion);
+ }
+ };
HandlerThread thread = new HandlerThread(TAG);
thread.start();
@@ -217,12 +221,7 @@
}
if (network == null) return false;
- boolean success = mNtpTrustedTime.forceRefresh(network);
- if (success) {
- makeNetworkTimeSuggestion(mNtpTrustedTime.getCachedTimeResult(),
- "Origin: NetworkTimeUpdateService: forceRefreshForTests");
- }
- return success;
+ return mEngine.forceRefreshForTests(network, mRefreshCallbacks);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -238,96 +237,12 @@
mWakeLock.acquire();
try {
- onPollNetworkTimeUnderWakeLock(network, reason);
+ mEngine.refreshIfRequiredAndReschedule(network, reason, mRefreshCallbacks);
} finally {
mWakeLock.release();
}
}
- private void onPollNetworkTimeUnderWakeLock(
- @NonNull Network network, @NonNull String reason) {
- long currentElapsedRealtimeMillis = SystemClock.elapsedRealtime();
-
- final int maxNetworkTimeAgeMillis = mNormalPollingIntervalMillis;
- // Force an NTP fix when outdated
- NtpTrustedTime.TimeResult cachedNtpResult = mNtpTrustedTime.getCachedTimeResult();
- if (cachedNtpResult == null
- || cachedNtpResult.getAgeMillis(currentElapsedRealtimeMillis)
- >= maxNetworkTimeAgeMillis) {
- if (DBG) Log.d(TAG, "Stale NTP fix; forcing refresh using network=" + network);
- boolean success = mNtpTrustedTime.forceRefresh(network);
- if (success) {
- synchronized (mLock) {
- mTryAgainCounter = 0;
- }
- } else {
- String logMsg = "forceRefresh() returned false:"
- + " cachedNtpResult=" + cachedNtpResult
- + ", currentElapsedRealtimeMillis=" + currentElapsedRealtimeMillis;
-
- if (DBG) {
- Log.d(TAG, logMsg);
- }
- mLocalLog.log(logMsg);
- }
-
- cachedNtpResult = mNtpTrustedTime.getCachedTimeResult();
- }
-
- if (cachedNtpResult != null
- && cachedNtpResult.getAgeMillis(currentElapsedRealtimeMillis)
- < maxNetworkTimeAgeMillis) {
- // Obtained fresh fix; schedule next normal update
- scheduleNextRefresh(mNormalPollingIntervalMillis
- - cachedNtpResult.getAgeMillis(currentElapsedRealtimeMillis));
-
- makeNetworkTimeSuggestion(cachedNtpResult, reason);
- } else {
- synchronized (mLock) {
- // No fresh fix; schedule retry
- mTryAgainCounter++;
- if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) {
- scheduleNextRefresh(mShortPollingIntervalMillis);
- } else {
- // Try much later
- String logMsg = "mTryAgainTimesMax exceeded,"
- + " cachedNtpResult=" + cachedNtpResult;
- if (DBG) {
- Log.d(TAG, logMsg);
- }
- mLocalLog.log(logMsg);
- mTryAgainCounter = 0;
-
- scheduleNextRefresh(mNormalPollingIntervalMillis);
- }
- }
- }
- }
-
- /** Suggests the time to the time detector. It may choose use it to set the system clock. */
- private void makeNetworkTimeSuggestion(
- @NonNull TimeResult ntpResult, @NonNull String debugInfo) {
- UnixEpochTime timeSignal = new UnixEpochTime(
- ntpResult.getElapsedRealtimeMillis(), ntpResult.getTimeMillis());
- NetworkTimeSuggestion timeSuggestion =
- new NetworkTimeSuggestion(timeSignal, ntpResult.getUncertaintyMillis());
- timeSuggestion.addDebugInfo(debugInfo);
- timeSuggestion.addDebugInfo(ntpResult.toString());
- mTimeDetectorInternal.suggestNetworkTime(timeSuggestion);
- }
-
- /**
- * Cancel old alarm and starts a new one for the specified interval.
- *
- * @param delayMillis when to trigger the alarm, starting from now.
- */
- private void scheduleNextRefresh(long delayMillis) {
- mAlarmManager.cancel(mPendingPollIntent);
- long now = SystemClock.elapsedRealtime();
- long next = now + delayMillis;
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent);
- }
-
// All callbacks will be invoked using mHandler because of how the callback is registered.
private class NetworkTimeUpdateCallback extends NetworkCallback {
@Override
@@ -385,21 +300,10 @@
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
- pw.println("mNormalPollingIntervalMillis="
- + Duration.ofMillis(mNormalPollingIntervalMillis));
- pw.println("mShortPollingIntervalMillis="
- + Duration.ofMillis(mShortPollingIntervalMillis));
- pw.println("mTryAgainTimesMax=" + mTryAgainTimesMax);
synchronized (mLock) {
pw.println("mDefaultNetwork=" + mDefaultNetwork);
- pw.println("mTryAgainCounter=" + mTryAgainCounter);
}
- pw.println();
- pw.println("NtpTrustedTime:");
- mNtpTrustedTime.dump(pw);
- pw.println();
- pw.println("Local logs:");
- mLocalLog.dump(fd, pw, args);
+ mEngine.dump(pw);
pw.println();
}
@@ -409,4 +313,204 @@
new NetworkTimeUpdateServiceShellCommand(this).exec(
this, in, out, err, args, callback, resultReceiver);
}
+
+ /**
+ * The interface the service uses to interact with the time refresh logic.
+ * Extracted for testing.
+ */
+ @VisibleForTesting
+ interface Engine {
+ interface RefreshCallbacks {
+ void scheduleNextRefresh(@ElapsedRealtimeLong long elapsedRealtimeMillis);
+
+ void submitSuggestion(@NonNull NetworkTimeSuggestion suggestion);
+ }
+
+ /**
+ * Forces the engine to refresh the network time (for tests). See {@link
+ * NetworkTimeUpdateService#forceRefreshForTests()}. This is a blocking call. This method
+ * must not schedule any calls.
+ */
+ boolean forceRefreshForTests(
+ @NonNull Network network, @NonNull RefreshCallbacks refreshCallbacks);
+
+ /**
+ * Attempts to refresh the network time if required, i.e. if there isn't a recent-enough
+ * network time available. It must also schedule the next call. This is a blocking call.
+ *
+ * @param network the network to use
+ * @param reason the reason for the refresh (for logging)
+ */
+ void refreshIfRequiredAndReschedule(@NonNull Network network, @NonNull String reason,
+ @NonNull RefreshCallbacks refreshCallbacks);
+
+ void dump(@NonNull PrintWriter pw);
+ }
+
+ @VisibleForTesting
+ static class EngineImpl implements Engine {
+
+ /**
+ * A log that records the decisions to fetch a network time update.
+ * This is logged in bug reports to assist with debugging issues with network time
+ * suggestions.
+ */
+ @NonNull
+ private final LocalLog mLocalDebugLog = new LocalLog(30, false /* useLocalTimestamps */);
+
+ private final int mNormalPollingIntervalMillis;
+ private final int mShortPollingIntervalMillis;
+ private final int mTryAgainTimesMax;
+ private final NtpTrustedTime mNtpTrustedTime;
+
+ /**
+ * Keeps track of successive time refresh failures have occurred. This is reset to zero when
+ * time refresh is successful or if the number exceeds (a non-negative) {@link
+ * #mTryAgainTimesMax}.
+ */
+ @GuardedBy("this")
+ private int mTryAgainCounter;
+
+ private final Supplier<Long> mElapsedRealtimeMillisSupplier;
+
+ @VisibleForTesting
+ EngineImpl(@NonNull Supplier<Long> elapsedRealtimeMillisSupplier,
+ int normalPollingIntervalMillis, int shortPollingIntervalMillis,
+ int tryAgainTimesMax, @NonNull NtpTrustedTime ntpTrustedTime) {
+ mElapsedRealtimeMillisSupplier = Objects.requireNonNull(elapsedRealtimeMillisSupplier);
+ mNormalPollingIntervalMillis = normalPollingIntervalMillis;
+ mShortPollingIntervalMillis = shortPollingIntervalMillis;
+ mTryAgainTimesMax = tryAgainTimesMax;
+ mNtpTrustedTime = Objects.requireNonNull(ntpTrustedTime);
+ }
+
+ @Override
+ public boolean forceRefreshForTests(
+ @NonNull Network network, @NonNull RefreshCallbacks refreshCallbacks) {
+ boolean success = mNtpTrustedTime.forceRefresh(network);
+ logToDebugAndDumpsys("forceRefreshForTests: success=" + success);
+
+ if (success) {
+ makeNetworkTimeSuggestion(mNtpTrustedTime.getCachedTimeResult(),
+ "EngineImpl.forceRefreshForTests()", refreshCallbacks);
+ }
+ return success;
+ }
+
+ @Override
+ public void refreshIfRequiredAndReschedule(
+ @NonNull Network network, @NonNull String reason,
+ @NonNull RefreshCallbacks refreshCallbacks) {
+ long currentElapsedRealtimeMillis = mElapsedRealtimeMillisSupplier.get();
+
+ final int maxNetworkTimeAgeMillis = mNormalPollingIntervalMillis;
+ // Force an NTP fix when outdated
+ NtpTrustedTime.TimeResult initialTimeResult = mNtpTrustedTime.getCachedTimeResult();
+ if (calculateTimeResultAgeMillis(initialTimeResult, currentElapsedRealtimeMillis)
+ >= maxNetworkTimeAgeMillis) {
+ if (DBG) Log.d(TAG, "Stale NTP fix; forcing refresh using network=" + network);
+ boolean successful = mNtpTrustedTime.forceRefresh(network);
+ if (successful) {
+ synchronized (this) {
+ mTryAgainCounter = 0;
+ }
+ } else {
+ String logMsg = "forceRefresh() returned false:"
+ + " initialTimeResult=" + initialTimeResult
+ + ", currentElapsedRealtimeMillis=" + currentElapsedRealtimeMillis;
+ logToDebugAndDumpsys(logMsg);
+ }
+ }
+
+ synchronized (this) {
+ long nextPollDelayMillis;
+ NtpTrustedTime.TimeResult latestTimeResult = mNtpTrustedTime.getCachedTimeResult();
+ if (calculateTimeResultAgeMillis(latestTimeResult, currentElapsedRealtimeMillis)
+ < maxNetworkTimeAgeMillis) {
+ // Obtained fresh fix; schedule next normal update
+ nextPollDelayMillis = mNormalPollingIntervalMillis
+ - latestTimeResult.getAgeMillis(currentElapsedRealtimeMillis);
+
+ makeNetworkTimeSuggestion(latestTimeResult, reason, refreshCallbacks);
+ } else {
+ // No fresh fix; schedule retry
+ mTryAgainCounter++;
+ if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) {
+ nextPollDelayMillis = mShortPollingIntervalMillis;
+ } else {
+ // Try much later
+ mTryAgainCounter = 0;
+
+ nextPollDelayMillis = mNormalPollingIntervalMillis;
+ }
+ }
+ long nextRefreshElapsedRealtimeMillis =
+ currentElapsedRealtimeMillis + nextPollDelayMillis;
+ refreshCallbacks.scheduleNextRefresh(nextRefreshElapsedRealtimeMillis);
+
+ logToDebugAndDumpsys("refreshIfRequiredAndReschedule:"
+ + " network=" + network
+ + ", reason=" + reason
+ + ", currentElapsedRealtimeMillis=" + currentElapsedRealtimeMillis
+ + ", initialTimeResult=" + initialTimeResult
+ + ", latestTimeResult=" + latestTimeResult
+ + ", mTryAgainCounter=" + mTryAgainCounter
+ + ", nextPollDelayMillis=" + nextPollDelayMillis
+ + ", nextRefreshElapsedRealtimeMillis="
+ + Duration.ofMillis(nextRefreshElapsedRealtimeMillis)
+ + " (" + nextRefreshElapsedRealtimeMillis + ")");
+ }
+ }
+
+ private static long calculateTimeResultAgeMillis(
+ @Nullable TimeResult timeResult,
+ @ElapsedRealtimeLong long currentElapsedRealtimeMillis) {
+ return timeResult == null ? Long.MAX_VALUE
+ : timeResult.getAgeMillis(currentElapsedRealtimeMillis);
+ }
+
+ /** Suggests the time to the time detector. It may choose use it to set the system clock. */
+ private void makeNetworkTimeSuggestion(@NonNull TimeResult ntpResult,
+ @NonNull String debugInfo, @NonNull RefreshCallbacks refreshCallbacks) {
+ UnixEpochTime timeSignal = new UnixEpochTime(
+ ntpResult.getElapsedRealtimeMillis(), ntpResult.getTimeMillis());
+ NetworkTimeSuggestion timeSuggestion =
+ new NetworkTimeSuggestion(timeSignal, ntpResult.getUncertaintyMillis());
+ timeSuggestion.addDebugInfo(debugInfo);
+ timeSuggestion.addDebugInfo(ntpResult.toString());
+ refreshCallbacks.submitSuggestion(timeSuggestion);
+ }
+
+ @Override
+ public void dump(PrintWriter pw) {
+ IndentingPrintWriter ipw = new IndentingPrintWriter(pw);
+ ipw.println("mNormalPollingIntervalMillis=" + mNormalPollingIntervalMillis);
+ ipw.println("mShortPollingIntervalMillis=" + mShortPollingIntervalMillis);
+ ipw.println("mTryAgainTimesMax=" + mTryAgainTimesMax);
+
+ synchronized (this) {
+ ipw.println("mTryAgainCounter=" + mTryAgainCounter);
+ }
+ ipw.println();
+
+ ipw.println("NtpTrustedTime:");
+ ipw.increaseIndent();
+ mNtpTrustedTime.dump(ipw);
+ ipw.decreaseIndent();
+ ipw.println();
+
+ ipw.println("Debug log:");
+ ipw.increaseIndent();
+ mLocalDebugLog.dump(ipw);
+ ipw.decreaseIndent();
+ ipw.println();
+ }
+
+ private void logToDebugAndDumpsys(String logMsg) {
+ if (DBG) {
+ Log.d(TAG, logMsg);
+ }
+ mLocalDebugLog.log(logMsg);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorService.java b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
index 1be9074..3e23953 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorService.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
@@ -143,7 +143,7 @@
return getTimeCapabilitiesAndConfig(userId);
}
- TimeCapabilitiesAndConfig getTimeCapabilitiesAndConfig(@UserIdInt int userId) {
+ private TimeCapabilitiesAndConfig getTimeCapabilitiesAndConfig(@UserIdInt int userId) {
enforceManageTimeDetectorPermission();
final long token = mCallerIdentityInjector.clearCallingIdentity();
@@ -163,6 +163,9 @@
return updateConfiguration(callingUserId, configuration);
}
+ /**
+ * Updates the user's configuration. Exposed for use by {@link TimeDetectorShellCommand}.
+ */
boolean updateConfiguration(@UserIdInt int userId, @NonNull TimeConfiguration configuration) {
// Resolve constants like USER_CURRENT to the true user ID as needed.
int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
@@ -256,7 +259,7 @@
}
}
- void handleConfigurationInternalChangedOnHandlerThread() {
+ private void handleConfigurationInternalChangedOnHandlerThread() {
// Configuration has changed, but each user may have a different view of the configuration.
// It's possible that this will cause unnecessary notifications but that shouldn't be a
// problem.
@@ -287,6 +290,10 @@
}
}
+ /**
+ * Sets the system time state. See {@link TimeState} for details. For use by {@link
+ * TimeDetectorShellCommand}.
+ */
void setTimeState(@NonNull TimeState timeState) {
enforceManageTimeDetectorPermission();
@@ -353,6 +360,9 @@
}
}
+ /**
+ * Suggests network time with permission checks. For use by {@link TimeDetectorShellCommand}.
+ */
void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSignal) {
enforceSuggestNetworkTimePermission();
Objects.requireNonNull(timeSignal);
@@ -360,6 +370,23 @@
mHandler.post(() -> mTimeDetectorStrategy.suggestNetworkTime(timeSignal));
}
+ /**
+ * Clears the cached network time information. For use during tests to simulate when no network
+ * time has been made available. For use by {@link TimeDetectorShellCommand}.
+ *
+ * <p>This operation takes place in the calling thread.
+ */
+ void clearNetworkTime() {
+ enforceSuggestNetworkTimePermission();
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mTimeDetectorStrategy.clearLatestNetworkSuggestion();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
@Override
public UnixEpochTime latestNetworkTime() {
NetworkTimeSuggestion suggestion = getLatestNetworkSuggestion();
@@ -388,6 +415,9 @@
}
}
+ /**
+ * Suggests GNSS time with permission checks. For use by {@link TimeDetectorShellCommand}.
+ */
void suggestGnssTime(@NonNull GnssTimeSuggestion timeSignal) {
enforceSuggestGnssTimePermission();
Objects.requireNonNull(timeSignal);
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java b/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java
index 990c00f..cce5709 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java
@@ -15,7 +15,9 @@
*/
package com.android.server.timedetector;
+import static android.app.timedetector.TimeDetector.SHELL_COMMAND_CLEAR_NETWORK_TIME;
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_CONFIRM_TIME;
+import static android.app.timedetector.TimeDetector.SHELL_COMMAND_GET_NETWORK_TIME;
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_GET_TIME_STATE;
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_IS_AUTO_DETECTION_ENABLED;
import static android.app.timedetector.TimeDetector.SHELL_COMMAND_SERVICE_NAME;
@@ -70,6 +72,10 @@
return runSuggestTelephonyTime();
case SHELL_COMMAND_SUGGEST_NETWORK_TIME:
return runSuggestNetworkTime();
+ case SHELL_COMMAND_GET_NETWORK_TIME:
+ return runGetNetworkTime();
+ case SHELL_COMMAND_CLEAR_NETWORK_TIME:
+ return runClearNetworkTime();
case SHELL_COMMAND_SUGGEST_GNSS_TIME:
return runSuggestGnssTime();
case SHELL_COMMAND_SUGGEST_EXTERNAL_TIME:
@@ -122,6 +128,18 @@
mInterface::suggestNetworkTime);
}
+ private int runGetNetworkTime() {
+ NetworkTimeSuggestion networkTimeSuggestion = mInterface.getLatestNetworkSuggestion();
+ final PrintWriter pw = getOutPrintWriter();
+ pw.println(networkTimeSuggestion);
+ return 0;
+ }
+
+ private int runClearNetworkTime() {
+ mInterface.clearNetworkTime();
+ return 0;
+ }
+
private int runSuggestGnssTime() {
return runSuggestTime(
() -> GnssTimeSuggestion.parseCommandLineArg(this),
@@ -196,6 +214,10 @@
pw.printf(" Sets the current time state for tests.\n");
pw.printf(" %s <unix epoch time options>\n", SHELL_COMMAND_CONFIRM_TIME);
pw.printf(" Tries to confirms the time, raising the confidence.\n");
+ pw.printf(" %s\n", SHELL_COMMAND_GET_NETWORK_TIME);
+ pw.printf(" Prints the network time information held by the detector.\n");
+ pw.printf(" %s\n", SHELL_COMMAND_CLEAR_NETWORK_TIME);
+ pw.printf(" Clears the network time information held by the detector.\n");
pw.println();
ManualTimeSuggestion.printCommandLineOpts(pw);
pw.println();
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
index 03f236d..9dca6ec 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.time.ExternalTimeSuggestion;
import android.app.time.TimeState;
@@ -103,6 +104,20 @@
/** Processes the suggested time from network sources. */
void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSuggestion);
+ /**
+ * Returns the latest (accepted) network time suggestion. Returns {@code null} if there isn't
+ * one.
+ */
+ @Nullable
+ NetworkTimeSuggestion getLatestNetworkSuggestion();
+
+ /**
+ * Clears the latest network time suggestion, leaving none. The remaining time signals from
+ * other sources will be reassessed causing the device's time to be updated if config and
+ * settings allow.
+ */
+ void clearLatestNetworkSuggestion();
+
/** Processes the suggested time from gnss sources. */
void suggestGnssTime(@NonNull GnssTimeSuggestion timeSuggestion);
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
index 13ec753..09bb803 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
@@ -316,6 +316,21 @@
}
@Override
+ @Nullable
+ public synchronized NetworkTimeSuggestion getLatestNetworkSuggestion() {
+ return mLastNetworkSuggestion.get();
+ }
+
+ @Override
+ public synchronized void clearLatestNetworkSuggestion() {
+ mLastNetworkSuggestion.set(null);
+
+ // The loss of network time may change the time signal to use to set the system clock.
+ String reason = "Network time cleared";
+ doAutoTimeDetection(reason);
+ }
+
+ @Override
@NonNull
public synchronized TimeState getTimeState() {
boolean userShouldConfirmTime = mEnvironment.systemClockConfidence() < TIME_CONFIDENCE_HIGH;
@@ -1068,15 +1083,6 @@
*/
@VisibleForTesting
@Nullable
- public synchronized NetworkTimeSuggestion getLatestNetworkSuggestion() {
- return mLastNetworkSuggestion.get();
- }
-
- /**
- * A method used to inspect state during tests. Not intended for general use.
- */
- @VisibleForTesting
- @Nullable
public synchronized GnssTimeSuggestion getLatestGnssSuggestion() {
return mLastGnssSuggestion.get();
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperData.java b/services/core/java/com/android/server/wallpaper/WallpaperData.java
new file mode 100644
index 0000000..79de282
--- /dev/null
+++ b/services/core/java/com/android/server/wallpaper/WallpaperData.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2023 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.server.wallpaper;
+
+import static android.app.WallpaperManager.FLAG_LOCK;
+
+import static com.android.server.wallpaper.WallpaperManagerService.WALLPAPER;
+import static com.android.server.wallpaper.WallpaperManagerService.WALLPAPER_CROP;
+import static com.android.server.wallpaper.WallpaperManagerService.WALLPAPER_LOCK_CROP;
+import static com.android.server.wallpaper.WallpaperManagerService.WALLPAPER_LOCK_ORIG;
+import static com.android.server.wallpaper.WallpaperUtils.getWallpaperDir;
+
+import android.app.IWallpaperManagerCallback;
+import android.app.WallpaperColors;
+import android.app.WallpaperManager.SetWallpaperFlags;
+import android.content.ComponentName;
+import android.graphics.Rect;
+import android.os.RemoteCallbackList;
+import android.util.ArrayMap;
+
+import java.io.File;
+
+/**
+ * The main wallpaper data model, used internally by the {@link WallpaperManagerService}. <br>
+ * An instance of this class contains all the information about a wallpaper.
+ */
+class WallpaperData {
+
+ int userId;
+
+ final File wallpaperFile; // source image
+ final File cropFile; // eventual destination
+
+ /**
+ * True while the client is writing a new wallpaper
+ */
+ boolean imageWallpaperPending;
+
+ /**
+ * Which wallpaper is set. Flag values are from {@link SetWallpaperFlags}.
+ */
+ int mWhich;
+
+ /**
+ * Callback once the set + crop is finished
+ */
+ IWallpaperManagerCallback setComplete;
+
+ /**
+ * Is the OS allowed to back up this wallpaper imagery?
+ */
+ boolean allowBackup;
+
+ /**
+ * Resource name if using a picture from the wallpaper gallery
+ */
+ String name = "";
+
+ /**
+ * The component name of the currently set live wallpaper.
+ */
+ ComponentName wallpaperComponent;
+
+ /**
+ * The component name of the wallpaper that should be set next.
+ */
+ ComponentName nextWallpaperComponent;
+
+ /**
+ * The ID of this wallpaper
+ */
+ int wallpaperId;
+
+ /**
+ * Primary colors histogram
+ */
+ WallpaperColors primaryColors;
+
+ /**
+ * If the wallpaper was set from a foreground app (instead of from a background service).
+ */
+ public boolean fromForegroundApp;
+
+ WallpaperManagerService.WallpaperConnection connection;
+ long lastDiedTime;
+ boolean wallpaperUpdating;
+ WallpaperManagerService.WallpaperObserver wallpaperObserver;
+
+ /**
+ * The dim amount to be applied to the wallpaper.
+ */
+ float mWallpaperDimAmount = 0.0f;
+
+ /**
+ * A map to keep track of the dimming set by different applications. The key is the calling
+ * UID and the value is the dim amount.
+ */
+ ArrayMap<Integer, Float> mUidToDimAmount = new ArrayMap<>();
+
+ /**
+ * Whether we need to extract the wallpaper colors again to calculate the dark hints
+ * after dimming is applied.
+ */
+ boolean mIsColorExtractedFromDim;
+
+ /**
+ * List of callbacks registered they should each be notified when the wallpaper is changed.
+ */
+ RemoteCallbackList<IWallpaperManagerCallback> callbacks = new RemoteCallbackList<>();
+
+ /**
+ * The crop hint supplied for displaying a subset of the source image
+ */
+ final Rect cropHint = new Rect(0, 0, 0, 0);
+
+ WallpaperData(int userId, File wallpaperDir, String inputFileName, String cropFileName) {
+ this.userId = userId;
+ wallpaperFile = new File(wallpaperDir, inputFileName);
+ cropFile = new File(wallpaperDir, cropFileName);
+ }
+
+ WallpaperData(int userId, @SetWallpaperFlags int wallpaperType) {
+ this(userId, getWallpaperDir(userId),
+ (wallpaperType == FLAG_LOCK) ? WALLPAPER_LOCK_ORIG : WALLPAPER,
+ (wallpaperType == FLAG_LOCK) ? WALLPAPER_LOCK_CROP : WALLPAPER_CROP);
+ }
+
+ // Called during initialization of a given user's wallpaper bookkeeping
+ boolean cropExists() {
+ return cropFile.exists();
+ }
+
+ boolean sourceExists() {
+ return wallpaperFile.exists();
+ }
+}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index cee7864..3d59b7b 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -32,6 +32,8 @@
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static com.android.server.wallpaper.WallpaperUtils.getWallpaperDir;
+
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityOptions;
@@ -71,7 +73,6 @@
import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
-import android.os.Environment;
import android.os.FileObserver;
import android.os.FileUtils;
import android.os.Handler;
@@ -149,6 +150,7 @@
private static final boolean DEBUG = false;
private static final boolean DEBUG_LIVE = true;
private static final boolean DEBUG_CROP = true;
+
private static final @NonNull RectF LOCAL_COLOR_BOUNDS =
new RectF(0, 0, 1, 1);
@@ -921,112 +923,6 @@
private boolean mInAmbientMode;
private LocalColorRepository mLocalColorRepo = new LocalColorRepository();
- static class WallpaperData {
-
- int userId;
-
- final File wallpaperFile; // source image
- final File cropFile; // eventual destination
-
- /**
- * True while the client is writing a new wallpaper
- */
- boolean imageWallpaperPending;
-
- /**
- * Which wallpaper is set. Flag values are from {@link SetWallpaperFlags}.
- */
- int mWhich;
-
- /**
- * Callback once the set + crop is finished
- */
- IWallpaperManagerCallback setComplete;
-
- /**
- * Is the OS allowed to back up this wallpaper imagery?
- */
- boolean allowBackup;
-
- /**
- * Resource name if using a picture from the wallpaper gallery
- */
- String name = "";
-
- /**
- * The component name of the currently set live wallpaper.
- */
- ComponentName wallpaperComponent;
-
- /**
- * The component name of the wallpaper that should be set next.
- */
- ComponentName nextWallpaperComponent;
-
- /**
- * The ID of this wallpaper
- */
- int wallpaperId;
-
- /**
- * Primary colors histogram
- */
- WallpaperColors primaryColors;
-
- /**
- * If the wallpaper was set from a foreground app (instead of from a background service).
- */
- public boolean fromForegroundApp;
-
- WallpaperConnection connection;
- long lastDiedTime;
- boolean wallpaperUpdating;
- WallpaperObserver wallpaperObserver;
-
- /**
- * The dim amount to be applied to the wallpaper.
- */
- float mWallpaperDimAmount = 0.0f;
-
- /**
- * A map to keep track of the dimming set by different applications. The key is the calling
- * UID and the value is the dim amount.
- */
- ArrayMap<Integer, Float> mUidToDimAmount = new ArrayMap<>();
-
- /**
- * Whether we need to extract the wallpaper colors again to calculate the dark hints
- * after dimming is applied.
- */
- boolean mIsColorExtractedFromDim;
-
- /**
- * List of callbacks registered they should each be notified when the wallpaper is changed.
- */
- private RemoteCallbackList<IWallpaperManagerCallback> callbacks
- = new RemoteCallbackList<IWallpaperManagerCallback>();
-
- /**
- * The crop hint supplied for displaying a subset of the source image
- */
- final Rect cropHint = new Rect(0, 0, 0, 0);
-
- WallpaperData(int userId, File wallpaperDir, String inputFileName, String cropFileName) {
- this.userId = userId;
- wallpaperFile = new File(wallpaperDir, inputFileName);
- cropFile = new File(wallpaperDir, cropFileName);
- }
-
- // Called during initialization of a given user's wallpaper bookkeeping
- boolean cropExists() {
- return cropFile.exists();
- }
-
- boolean sourceExists() {
- return wallpaperFile.exists();
- }
- }
-
@VisibleForTesting
static final class DisplayData {
int mWidth = -1;
@@ -1784,10 +1680,6 @@
getWallpaperSafeLocked(UserHandle.USER_SYSTEM, FLAG_SYSTEM);
}
- File getWallpaperDir(int userId) {
- return Environment.getUserSystemDirectory(userId);
- }
-
@Override
protected void finalize() throws Throwable {
super.finalize();
@@ -1928,9 +1820,7 @@
}
private void clearWallpaperData(int userID, int wallpaperType) {
- final WallpaperData wallpaper = new WallpaperData(userID, getWallpaperDir(userID),
- (wallpaperType == FLAG_LOCK) ? WALLPAPER_LOCK_ORIG : WALLPAPER,
- (wallpaperType == FLAG_LOCK) ? WALLPAPER_LOCK_CROP : WALLPAPER_CROP);
+ final WallpaperData wallpaper = new WallpaperData(userID, wallpaperType);
if (wallpaper.sourceExists()) {
wallpaper.wallpaperFile.delete();
}
@@ -2050,9 +1940,7 @@
// while locked, so pretend like the component was actually
// bound into place
wallpaper.wallpaperComponent = wallpaper.nextWallpaperComponent;
- final WallpaperData fallback =
- new WallpaperData(wallpaper.userId, getWallpaperDir(wallpaper.userId),
- WALLPAPER_LOCK_ORIG, WALLPAPER_LOCK_CROP);
+ final WallpaperData fallback = new WallpaperData(wallpaper.userId, FLAG_LOCK);
ensureSaneWallpaperData(fallback);
bindWallpaperComponentLocked(mImageWallpaper, true, false, fallback, reply);
mWaitingForUnlock = true;
@@ -2914,8 +2802,7 @@
}
// We know a-priori that there is no lock-only wallpaper currently
- WallpaperData lockWP = new WallpaperData(userId, getWallpaperDir(userId),
- WALLPAPER_LOCK_ORIG, WALLPAPER_LOCK_CROP);
+ WallpaperData lockWP = new WallpaperData(userId, FLAG_LOCK);
lockWP.wallpaperId = sysWP.wallpaperId;
lockWP.cropHint.set(sysWP.cropHint);
lockWP.allowBackup = sysWP.allowBackup;
@@ -3588,16 +3475,14 @@
// it now.
if (wallpaper == null) {
if (which == FLAG_LOCK) {
- wallpaper = new WallpaperData(userId, getWallpaperDir(userId),
- WALLPAPER_LOCK_ORIG, WALLPAPER_LOCK_CROP);
+ wallpaper = new WallpaperData(userId, FLAG_LOCK);
mLockWallpaperMap.put(userId, wallpaper);
ensureSaneWallpaperData(wallpaper);
} else {
// rationality fallback: we're in bad shape, but establishing a known
// valid system+lock WallpaperData will keep us from dying.
Slog.wtf(TAG, "Didn't find wallpaper in non-lock case!");
- wallpaper = new WallpaperData(userId, getWallpaperDir(userId),
- WALLPAPER, WALLPAPER_CROP);
+ wallpaper = new WallpaperData(userId, FLAG_SYSTEM);
mWallpaperMap.put(userId, wallpaper);
ensureSaneWallpaperData(wallpaper);
}
@@ -3616,8 +3501,7 @@
// Do this once per boot
migrateFromOld();
- wallpaper = new WallpaperData(userId, getWallpaperDir(userId),
- WALLPAPER, WALLPAPER_CROP);
+ wallpaper = new WallpaperData(userId, FLAG_SYSTEM);
wallpaper.allowBackup = true;
mWallpaperMap.put(userId, wallpaper);
if (!wallpaper.cropExists()) {
@@ -3668,8 +3552,7 @@
// keyguard-specific wallpaper for this user
WallpaperData lockWallpaper = mLockWallpaperMap.get(userId);
if (lockWallpaper == null) {
- lockWallpaper = new WallpaperData(userId, getWallpaperDir(userId),
- WALLPAPER_LOCK_ORIG, WALLPAPER_LOCK_CROP);
+ lockWallpaper = new WallpaperData(userId, FLAG_LOCK);
mLockWallpaperMap.put(userId, lockWallpaper);
}
parseWallpaperAttributes(parser, lockWallpaper, false);
@@ -3720,8 +3603,7 @@
if (mFallbackWallpaper == null) {
if (DEBUG) Slog.d(TAG, "Initialize fallback wallpaper");
final int systemUserId = UserHandle.USER_SYSTEM;
- mFallbackWallpaper = new WallpaperData(systemUserId, getWallpaperDir(systemUserId),
- WALLPAPER, WALLPAPER_CROP);
+ mFallbackWallpaper = new WallpaperData(systemUserId, FLAG_SYSTEM);
mFallbackWallpaper.allowBackup = false;
mFallbackWallpaper.wallpaperId = makeWallpaperIdLocked();
bindWallpaperComponentLocked(mImageWallpaper, true, false, mFallbackWallpaper, null);
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperUtils.java b/services/core/java/com/android/server/wallpaper/WallpaperUtils.java
new file mode 100644
index 0000000..a9b8092
--- /dev/null
+++ b/services/core/java/com/android/server/wallpaper/WallpaperUtils.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 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.server.wallpaper;
+
+import android.os.Environment;
+
+import java.io.File;
+
+class WallpaperUtils {
+
+ static File getWallpaperDir(int userId) {
+ return Environment.getUserSystemDirectory(userId);
+ }
+}
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index a16e659..4428be7 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -1644,4 +1644,19 @@
}
return false;
}
+
+ @Override
+ public void enableTaskLocaleOverride(IBinder token) {
+ if (UserHandle.getAppId(Binder.getCallingUid()) != SYSTEM_UID) {
+ // Only allow system to align locale.
+ return;
+ }
+
+ synchronized (mGlobalLock) {
+ final ActivityRecord r = ActivityRecord.forTokenLocked(token);
+ if (r != null) {
+ r.getTask().mAlignActivityLocaleWithTask = true;
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 8410942..45ae3d8 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -298,6 +298,7 @@
import android.os.Debug;
import android.os.IBinder;
import android.os.IRemoteCallback;
+import android.os.LocaleList;
import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteException;
@@ -726,6 +727,7 @@
/**
* When set to true, the IME insets will be frozen until the next app becomes IME input target.
* @see InsetsPolicy#adjustVisibilityForIme
+ * @see ImeInsetsSourceProvider#updateClientVisibility
*/
boolean mImeInsetsFrozenUntilStartInput;
@@ -1575,7 +1577,6 @@
if (newParent != null) {
if (isState(RESUMED)) {
newParent.setResumedActivity(this, "onParentChanged");
- mImeInsetsFrozenUntilStartInput = false;
}
mLetterboxUiController.onActivityParentChanged(newParent);
}
@@ -7998,6 +7999,9 @@
}
super.resolveOverrideConfiguration(newParentConfiguration);
final Configuration resolvedConfig = getResolvedOverrideConfiguration();
+
+ applyLocaleOverrideIfNeeded(resolvedConfig);
+
if (isFixedRotationTransforming()) {
// The resolved configuration is applied with rotated display configuration. If this
// activity matches its parent (the following resolving procedures are no-op), then it
@@ -8870,13 +8874,6 @@
}
}
- @Override
- void onResize() {
- // Reset freezing IME insets flag when the activity resized.
- mImeInsetsFrozenUntilStartInput = false;
- super.onResize();
- }
-
private boolean applyAspectRatio(Rect outBounds, Rect containingAppBounds,
Rect containingBounds) {
return applyAspectRatio(outBounds, containingAppBounds, containingBounds,
@@ -10160,6 +10157,35 @@
}
}
+ private void applyLocaleOverrideIfNeeded(Configuration resolvedConfig) {
+ // We always align the locale for ActivityEmbedding apps. System apps or some apps which
+ // has set known cert apps can embed across different uid activity.
+ boolean shouldAlignLocale = isEmbedded()
+ || (task != null && task.mAlignActivityLocaleWithTask);
+ if (!shouldAlignLocale) {
+ return;
+ }
+
+ boolean differentPackage = task != null
+ && task.realActivity != null
+ && !task.realActivity.getPackageName().equals(packageName);
+ if (!differentPackage) {
+ return;
+ }
+
+ LocaleList locale;
+ final ActivityTaskManagerInternal.PackageConfig appConfig =
+ mAtmService.mPackageConfigPersister.findPackageConfiguration(
+ task.realActivity.getPackageName(), mUserId);
+ // if there is no app locale for the package, clear the target activity's locale.
+ if (appConfig == null || appConfig.mLocales == null || appConfig.mLocales.isEmpty()) {
+ locale = LocaleList.getEmptyLocaleList();
+ } else {
+ locale = appConfig.mLocales;
+ }
+ resolvedConfig.setLocales(locale);
+ }
+
/**
* Whether we should send fake focus when the activity is resumed. This is done because some
* game engines wait to get focus before drawing the content of the app.
diff --git a/services/core/java/com/android/server/wm/ActivitySecurityModelFeatureFlags.java b/services/core/java/com/android/server/wm/ActivitySecurityModelFeatureFlags.java
new file mode 100644
index 0000000..64af9dd
--- /dev/null
+++ b/services/core/java/com/android/server/wm/ActivitySecurityModelFeatureFlags.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2022 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.server.wm;
+
+import static android.provider.DeviceConfig.NAMESPACE_WINDOW_MANAGER;
+
+import static com.android.server.wm.ActivityStarter.ASM_RESTRICTIONS;
+
+import android.annotation.NonNull;
+import android.app.compat.CompatChanges;
+import android.content.pm.PackageManager;
+import android.provider.DeviceConfig;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.HashSet;
+import java.util.concurrent.Executor;
+
+/**
+ * Contains utility methods to query whether or not go/activity-security should be enabled
+ * asm_start_rules_enabled - Enable rule enforcement in ActivityStarter.java
+ * asm_start_rules_toasts_enabled - Show toasts when rules would block from ActivityStarter.java
+ * asm_start_rules_exception_list - Comma separated list of packages to exclude from the above
+ * 2 rules.
+ * TODO(b/258792202) Cleanup once ASM is ready to launch
+ */
+class ActivitySecurityModelFeatureFlags {
+ // TODO(b/230590090): Replace with public documentation once ready
+ static final String DOC_LINK = "go/android-asm";
+
+ private static final String NAMESPACE = NAMESPACE_WINDOW_MANAGER;
+ private static final String KEY_ASM_RESTRICTIONS_ENABLED = "asm_restrictions_enabled";
+ private static final String KEY_ASM_TOASTS_ENABLED = "asm_toasts_enabled";
+ private static final String KEY_ASM_EXEMPTED_PACKAGES = "asm_exempted_packages";
+ private static final int VALUE_DISABLE = 0;
+ private static final int VALUE_ENABLE_FOR_U = 1;
+ private static final int VALUE_ENABLE_FOR_ALL = 2;
+
+ private static final int DEFAULT_VALUE = VALUE_DISABLE;
+ private static final String DEFAULT_EXCEPTION_LIST = "";
+
+ private static int sAsmToastsEnabled;
+ private static int sAsmRestrictionsEnabled;
+ private static final HashSet<String> sExcludedPackageNames = new HashSet<>();
+ private static PackageManager sPm;
+
+ @GuardedBy("ActivityTaskManagerService.mGlobalLock")
+ static void initialize(@NonNull Executor executor, @NonNull PackageManager pm) {
+ updateFromDeviceConfig();
+ DeviceConfig.addOnPropertiesChangedListener(NAMESPACE, executor,
+ properties -> updateFromDeviceConfig());
+ sPm = pm;
+ }
+
+ @GuardedBy("ActivityTaskManagerService.mGlobalLock")
+ static boolean shouldShowToast(int uid) {
+ return flagEnabledForUid(sAsmToastsEnabled, uid);
+ }
+
+ @GuardedBy("ActivityTaskManagerService.mGlobalLock")
+ static boolean shouldBlockActivityStart(int uid) {
+ return flagEnabledForUid(sAsmRestrictionsEnabled, uid);
+ }
+
+ private static boolean flagEnabledForUid(int flag, int uid) {
+ boolean flagEnabled = flag == VALUE_ENABLE_FOR_ALL
+ || (flag == VALUE_ENABLE_FOR_U
+ && CompatChanges.isChangeEnabled(ASM_RESTRICTIONS, uid));
+
+ if (flagEnabled) {
+ String[] packageNames = sPm.getPackagesForUid(uid);
+ for (int i = 0; i < packageNames.length; i++) {
+ if (sExcludedPackageNames.contains(packageNames[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ private static void updateFromDeviceConfig() {
+ sAsmToastsEnabled = DeviceConfig.getInt(NAMESPACE, KEY_ASM_TOASTS_ENABLED,
+ DEFAULT_VALUE);
+ sAsmRestrictionsEnabled = DeviceConfig.getInt(NAMESPACE, KEY_ASM_RESTRICTIONS_ENABLED,
+ DEFAULT_VALUE);
+
+ String rawExceptionList = DeviceConfig.getString(NAMESPACE,
+ KEY_ASM_EXEMPTED_PACKAGES, DEFAULT_EXCEPTION_LIST);
+ sExcludedPackageNames.clear();
+ String[] packages = rawExceptionList.split(",");
+ for (String packageName : packages) {
+ String packageNameTrimmed = packageName.trim();
+ if (!packageNameTrimmed.isEmpty()) {
+ sExcludedPackageNames.add(packageNameTrimmed);
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 034f5c8..40432dc 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -56,10 +56,11 @@
import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
+import static com.android.server.wm.ActivityRecord.State.FINISHING;
import static com.android.server.wm.ActivityRecord.State.RESUMED;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
@@ -74,7 +75,12 @@
import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME;
import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
+import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_ALLOWLISTED_COMPONENT;
+import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_ALLOWLISTED_UID;
+import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_BAL_PERMISSION;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_DEFAULT;
+import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_PENDING_INTENT;
+import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_VISIBLE_WINDOW;
import static com.android.server.wm.BackgroundActivityStartController.BAL_BLOCK;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY;
@@ -119,6 +125,7 @@
import android.text.TextUtils;
import android.util.Pools.SynchronizedPool;
import android.util.Slog;
+import android.widget.Toast;
import android.window.RemoteTransition;
import com.android.internal.annotations.VisibleForTesting;
@@ -126,6 +133,7 @@
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.FrameworkStatsLog;
+import com.android.server.UiThread;
import com.android.server.am.PendingIntentRecord;
import com.android.server.pm.InstantAppResolver;
import com.android.server.power.ShutdownCheckPoints;
@@ -152,6 +160,7 @@
private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
+
private static final int INVALID_LAUNCH_MODE = -1;
/**
@@ -161,6 +170,13 @@
@EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
static final long ENABLE_PENDING_INTENT_BAL_OPTION = 192341120L;
+ /**
+ * Feature flag for go/activity-security rules
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ static final long ASM_RESTRICTIONS = 230590090L;
+
private final ActivityTaskManagerService mService;
private final RootWindowContainer mRootWindowContainer;
private final ActivityTaskSupervisor mSupervisor;
@@ -1851,65 +1867,134 @@
}
}
- // Log activity starts which violate one of the following rules of the
- // activity security model (ASM):
- // 1. Only the top activity on a task can start activities on that task
- // 2. Only the top activity on the top task can create new (top) tasks
- // We don't currently block, but these checks may later become blocks
- // TODO(b/236234252): Shift to BackgroundActivityStartController once
- // class is ready
- if (mSourceRecord != null) {
- int callerUid = mSourceRecord.getUid();
- ActivityRecord targetTopActivity =
- targetTask != null ? targetTask.getTopNonFinishingActivity() : null;
- boolean passesAsmChecks = newTask
- ? mService.mVisibleActivityProcessTracker.hasResumedActivity(callerUid)
- : targetTopActivity != null && targetTopActivity.getUid() == callerUid;
-
- if (!passesAsmChecks) {
- Slog.i(TAG, "Launching r: " + r
- + " from background: " + mSourceRecord
- + ". New task: " + newTask);
- boolean newOrEmptyTask = newTask || (targetTopActivity == null);
- int action = newTask
- ? FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__ACTIVITY_START_NEW_TASK
- : (mSourceRecord.getTask().equals(targetTask)
- ? FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__ACTIVITY_START_SAME_TASK
- : FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__ACTIVITY_START_DIFFERENT_TASK);
- FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED,
- /* caller_uid */
- callerUid,
- /* caller_activity_class_name */
- mSourceRecord.info.name,
- /* target_task_top_activity_uid */
- newOrEmptyTask ? -1 : targetTopActivity.getUid(),
- /* target_task_top_activity_class_name */
- newOrEmptyTask ? null : targetTopActivity.info.name,
- /* target_task_is_different */
- newTask || !mSourceRecord.getTask().equals(targetTask),
- /* target_activity_uid */
- r.getUid(),
- /* target_activity_class_name */
- r.info.name,
- /* target_intent_action */
- r.intent.getAction(),
- /* target_intent_flags */
- r.intent.getFlags(),
- /* action */
- action,
- /* version */
- 1,
- /* multi_window */
- targetTask != null && !targetTask.equals(mSourceRecord.getTask())
- && targetTask.isVisible()
- );
- }
+ if (!checkActivitySecurityModel(r, newTask, targetTask)) {
+ return START_ABORTED;
}
return START_SUCCESS;
}
/**
+ * TODO(b/263368846): Shift to BackgroundActivityStartController once class is ready
+ * Log activity starts which violate one of the following rules of the
+ * activity security model (ASM):
+ * See go/activity-security for rationale behind the rules.
+ * We don't currently block, but these checks may later become blocks
+ * 1. Within a task, only an activity matching a top UID of the task can start activities
+ * 2. Only activities within a foreground task, which match a top UID of the task, can
+ * create a new task or bring an existing one into the foreground
+ */
+ private boolean checkActivitySecurityModel(ActivityRecord r, boolean newTask, Task targetTask) {
+ // Intents with FLAG_ACTIVITY_NEW_TASK will always be considered as creating a new task
+ // even if the intent is delivered to an existing task.
+ boolean taskToFront = newTask
+ || (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == FLAG_ACTIVITY_NEW_TASK;
+
+ if (mSourceRecord != null) {
+ boolean passesAsmChecks = true;
+ Task sourceTask = mSourceRecord.getTask();
+
+ // Don't allow launches into a new task if the current task is not foreground.
+ if (taskToFront) {
+ passesAsmChecks = sourceTask != null && sourceTask.isVisible();
+ }
+
+ Task taskToCheck = taskToFront ? sourceTask : targetTask;
+ passesAsmChecks = passesAsmChecks && ActivityTaskSupervisor
+ .doesTopActivityMatchingUidExistForAsm(taskToCheck, mSourceRecord.getUid(),
+ mSourceRecord);
+
+ if (passesAsmChecks) {
+ return true;
+ }
+ }
+
+ // BAL exception only allowed for new tasks
+ if (taskToFront) {
+ if (mBalCode == BAL_ALLOW_ALLOWLISTED_COMPONENT
+ || mBalCode == BAL_ALLOW_BAL_PERMISSION
+ || mBalCode == BAL_ALLOW_PENDING_INTENT) {
+ return true;
+ }
+ }
+
+ // BAL Exception allowed in all cases
+ if (mBalCode == BAL_ALLOW_ALLOWLISTED_UID) {
+ return true;
+ }
+
+ // TODO(b/230590090): Revisit this - ideally we would not rely on visibility, but rather
+ // have an explicit api for activities to opt-out of ASM protection if they need to.
+ if (mBalCode == BAL_ALLOW_VISIBLE_WINDOW) {
+ return true;
+ }
+
+ // ASM rules have failed. Log why
+ ActivityRecord targetTopActivity = targetTask == null ? null
+ : targetTask.getActivity(ar ->
+ !ar.isState(FINISHING) && !ar.isAlwaysOnTop());
+
+ int action = newTask || mSourceRecord == null
+ ? FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__ACTIVITY_START_NEW_TASK
+ : (mSourceRecord.getTask().equals(targetTask)
+ ? FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__ACTIVITY_START_SAME_TASK
+ : FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__ACTIVITY_START_DIFFERENT_TASK);
+
+ FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED,
+ /* caller_uid */
+ mSourceRecord != null ? mSourceRecord.getUid() : -1,
+ /* caller_activity_class_name */
+ mSourceRecord != null ? mSourceRecord.info.name : null,
+ /* target_task_top_activity_uid */
+ targetTopActivity != null ? targetTopActivity.getUid() : -1,
+ /* target_task_top_activity_class_name */
+ targetTopActivity != null ? targetTopActivity.info.name : null,
+ /* target_task_is_different */
+ newTask || mSourceRecord == null || targetTask == null
+ || !targetTask.equals(mSourceRecord.getTask()),
+ /* target_activity_uid */
+ r.getUid(),
+ /* target_activity_class_name */
+ r.info.name,
+ /* target_intent_action */
+ r.intent.getAction(),
+ /* target_intent_flags */
+ mLaunchFlags,
+ /* action */
+ action,
+ /* version */
+ 1,
+ /* multi_window - we have our source not in the target task, but both are visible */
+ targetTask != null && mSourceRecord != null
+ && !targetTask.equals(mSourceRecord.getTask()) && targetTask.isVisible()
+ );
+
+ boolean shouldBlockActivityStart =
+ ActivitySecurityModelFeatureFlags.shouldBlockActivityStart(mCallingUid);
+
+ if (ActivitySecurityModelFeatureFlags.shouldShowToast(mCallingUid)) {
+ UiThread.getHandler().post(() -> Toast.makeText(mService.mContext,
+ (shouldBlockActivityStart
+ ? "Activity start blocked by "
+ : "Activity start would be blocked by ")
+ + ActivitySecurityModelFeatureFlags.DOC_LINK,
+ Toast.LENGTH_SHORT).show());
+ }
+
+
+ if (shouldBlockActivityStart) {
+ Slog.e(TAG, "Abort Launching r: " + r
+ + " as source: " + mSourceRecord
+ + "is in background. New task: " + newTask
+ + ". Top activity: " + targetTopActivity);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
* Returns whether embedding of {@code starting} is allowed.
*
* @param taskFragment the TaskFragment for embedding.
@@ -2830,7 +2915,7 @@
if (taskFragment.isOrganized()) {
mService.mWindowOrganizerController.sendTaskFragmentOperationFailure(
taskFragment.getTaskFragmentOrganizer(), mRequest.errorCallbackToken,
- taskFragment, HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT,
+ taskFragment, OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT,
new SecurityException(errMsg));
} else {
// If the taskFragment is not organized, just dump error message as warning logs.
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index fd6d606..9a8ef19 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -859,6 +859,8 @@
mRecentTasks.onSystemReadyLocked();
mTaskSupervisor.onSystemReady();
mActivityClientController.onSystemReady();
+ // TODO(b/258792202) Cleanup once ASM is ready to launch
+ ActivitySecurityModelFeatureFlags.initialize(mContext.getMainExecutor(), pm);
}
}
@@ -1495,7 +1497,7 @@
a.persistableMode = ActivityInfo.PERSIST_NEVER;
a.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
a.colorMode = ActivityInfo.COLOR_MODE_DEFAULT;
- a.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
+ a.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | ActivityInfo.FLAG_NO_HISTORY;
a.resizeMode = RESIZE_MODE_UNRESIZEABLE;
a.configChanges = 0xffffffff;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index b1bc52a..407ffd0 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -51,6 +51,7 @@
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
+import static com.android.server.wm.ActivityRecord.State.FINISHING;
import static com.android.server.wm.ActivityRecord.State.PAUSED;
import static com.android.server.wm.ActivityRecord.State.PAUSING;
import static com.android.server.wm.ActivityRecord.State.RESTARTING_PROCESS;
@@ -157,6 +158,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
+import java.util.function.Predicate;
// TODO: This class has become a dumping ground. Let's
// - Move things relating to the hierarchy to RootWindowContainer
@@ -1629,10 +1631,11 @@
// cleared the calling identify. If so, we infer we do not need further restrictions here.
// TODO(b/263368846) Move to live with the rest of the ASM logic.
if (callingUid != SYSTEM_UID) {
- ActivityRecord topActivity = task.getTopNonFinishingActivity();
- boolean passesAsmChecks = topActivity != null
- && topActivity.getUid() == callingUid;
+ boolean passesAsmChecks = doesTopActivityMatchingUidExistForAsm(task, callingUid,
+ null);
if (!passesAsmChecks) {
+ ActivityRecord topActivity = task.getActivity(ar ->
+ !ar.isState(FINISHING) && !ar.isAlwaysOnTop());
Slog.i(TAG, "Finishing task from background. t: " + task);
FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED,
/* caller_uid */
@@ -1677,6 +1680,57 @@
}
}
+ /**
+ * For the purpose of ASM, ‘Top UID” for a task is defined as an activity UID
+ * 1. Which is top of the stack in z-order
+ * a. Excluding any activities with the flag ‘isAlwaysOnTop’ and
+ * b. Excluding any activities which are `finishing`
+ * 2. Or top of an adjacent task fragment to (1)
+ *
+ * The 'sourceRecord' can be considered top even if it is 'finishing'
+ *
+ * TODO(b/263368846) Shift to BackgroundActivityStartController once class is ready
+ */
+ @Nullable
+ static boolean doesTopActivityMatchingUidExistForAsm(@Nullable Task task,
+ int uid, @Nullable ActivityRecord sourceRecord) {
+ // If the source is visible, consider it 'top'.
+ if (sourceRecord != null && sourceRecord.isVisible()) {
+ return true;
+ }
+
+ // Consider the source activity, whether or not it is finishing. Do not consider any other
+ // finishing activity.
+ Predicate<ActivityRecord> topOfStackPredicate = (ar) -> ar.equals(sourceRecord)
+ || (!ar.isState(FINISHING) && !ar.isAlwaysOnTop());
+
+ // Check top of stack (or the first task fragment for embedding).
+ ActivityRecord topActivity = task.getActivity(topOfStackPredicate);
+ if (topActivity == null) {
+ return false;
+ }
+
+ if (topActivity.getUid() == uid) {
+ return true;
+ }
+
+ // Even if the top activity is not a match, we may be in an embedded activity scenario with
+ // an adjacent task fragment. Get the second fragment.
+ TaskFragment taskFragment = topActivity.getTaskFragment();
+ if (taskFragment == null) {
+ return false;
+ }
+
+ TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment();
+ if (adjacentTaskFragment == null) {
+ return false;
+ }
+
+ // Check the second fragment.
+ topActivity = adjacentTaskFragment.getActivity(topOfStackPredicate);
+ return topActivity != null && topActivity.getUid() == uid;
+ }
+
void cleanUpRemovedTaskLocked(Task task, boolean killProcess, boolean removeFromRecents) {
if (removeFromRecents) {
mRecentTasks.remove(task);
diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java
index 6b5f068..7bd8c53 100644
--- a/services/core/java/com/android/server/wm/AppTaskImpl.java
+++ b/services/core/java/com/android/server/wm/AppTaskImpl.java
@@ -99,7 +99,7 @@
throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
}
return mService.getRecentTasks().createRecentTaskInfo(task,
- false /* stripExtras */);
+ false /* stripExtras */, true /* getTasksAllowed */);
} finally {
Binder.restoreCallingIdentity(origId);
}
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 74d52b2..d65c2f9 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -900,7 +900,7 @@
*
* TODO(b/213312721): Remove this predicate and its callers once ShellTransition is enabled.
*/
- private static boolean isTaskViewTask(WindowContainer wc) {
+ static boolean isTaskViewTask(WindowContainer wc) {
// We use Task#mRemoveWithTaskOrganizer to identify an embedded Task, but this is a hack and
// it is not guaranteed to work this logic in the future version.
return wc instanceof Task && ((Task) wc).mRemoveWithTaskOrganizer;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index e7a5ee7..eadb11e 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -4509,11 +4509,35 @@
mImeWindowsContainer.getParent().mSurfaceControl));
updateImeControlTarget(forceUpdateImeParent);
}
- // Unfreeze IME insets after the new target updated, in case updateAboveInsetsState may
- // deliver unrelated IME insets change to the non-IME requester.
- if (target != null) {
- target.unfreezeInsetsAfterStartInput();
+ }
+
+ /**
+ * Callback from {@link ImeInsetsSourceProvider#updateClientVisibility} for the system to
+ * judge whether or not to notify the IME insets provider to dispatch this reported IME client
+ * visibility state to the app clients when needed.
+ */
+ boolean onImeInsetsClientVisibilityUpdate() {
+ boolean[] changed = new boolean[1];
+
+ // Unlike the IME layering target or the control target can be updated during the layout
+ // change, the IME input target requires to be changed after gaining the input focus.
+ // In case unfreezing IME insets state may too early during IME focus switching, we unfreeze
+ // when activities going to be visible until the input target changed, or the
+ // activity was the current input target that has to unfreeze after updating the IME
+ // client visibility.
+ final ActivityRecord inputTargetActivity =
+ mImeInputTarget != null ? mImeInputTarget.getActivityRecord() : null;
+ final boolean targetChanged = mImeInputTarget != mLastImeInputTarget;
+ if (targetChanged || inputTargetActivity != null && inputTargetActivity.isVisibleRequested()
+ && inputTargetActivity.mImeInsetsFrozenUntilStartInput) {
+ forAllActivities(r -> {
+ if (r.mImeInsetsFrozenUntilStartInput && r.isVisibleRequested()) {
+ r.mImeInsetsFrozenUntilStartInput = false;
+ changed[0] = true;
+ }
+ });
}
+ return changed[0];
}
void updateImeControlTarget() {
diff --git a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
index ba0413d..c6037da 100644
--- a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
@@ -203,8 +203,11 @@
|| !shouldRefreshActivity(activity, newConfig, lastReportedConfig)) {
return;
}
- boolean cycleThroughStop = mWmService.mLetterboxConfiguration
- .isCameraCompatRefreshCycleThroughStopEnabled();
+ boolean cycleThroughStop =
+ mWmService.mLetterboxConfiguration
+ .isCameraCompatRefreshCycleThroughStopEnabled()
+ && !activity.mLetterboxUiController
+ .shouldRefreshActivityViaPauseForCameraCompat();
try {
activity.mLetterboxUiController.setIsRefreshAfterRotationRequested(true);
ProtoLog.v(WM_DEBUG_STATES,
@@ -255,7 +258,8 @@
Configuration lastReportedConfig) {
return newConfig.windowConfiguration.getDisplayRotation()
!= lastReportedConfig.windowConfiguration.getDisplayRotation()
- && isTreatmentEnabledForActivity(activity);
+ && isTreatmentEnabledForActivity(activity)
+ && activity.mLetterboxUiController.shouldRefreshActivityForCameraCompat();
}
/**
@@ -294,7 +298,8 @@
// handle dynamic changes so we shouldn't force rotate them.
&& activity.getRequestedOrientation() != SCREEN_ORIENTATION_NOSENSOR
&& activity.getRequestedOrientation() != SCREEN_ORIENTATION_LOCKED
- && mCameraIdPackageBiMap.containsPackageName(activity.packageName);
+ && mCameraIdPackageBiMap.containsPackageName(activity.packageName)
+ && activity.mLetterboxUiController.shouldForceRotateForCameraCompat();
}
private synchronized void notifyCameraOpened(
diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
index d54f77a..c3c727a 100644
--- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java
+++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
@@ -335,10 +335,6 @@
}
@Override
- public void unfreezeInsetsAfterStartInput() {
- }
-
- @Override
public InsetsControlTarget getImeControlTarget() {
return mWmService.getDefaultDisplayContentLocked().mRemoteInsetsControlTarget;
}
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 90d0f16..85938e3 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -140,10 +140,14 @@
@Override
protected boolean updateClientVisibility(InsetsControlTarget caller) {
+ if (caller != getControlTarget()) {
+ return false;
+ }
boolean changed = super.updateClientVisibility(caller);
if (changed && caller.isRequestedVisible(mSource.getType())) {
reportImeDrawnForOrganizer(caller);
}
+ changed |= mDisplayContent.onImeInsetsClientVisibilityUpdate();
return changed;
}
diff --git a/services/core/java/com/android/server/wm/InputTarget.java b/services/core/java/com/android/server/wm/InputTarget.java
index b5ab62b..653f5f5 100644
--- a/services/core/java/com/android/server/wm/InputTarget.java
+++ b/services/core/java/com/android/server/wm/InputTarget.java
@@ -16,8 +16,8 @@
package com.android.server.wm;
-import android.view.IWindow;
import android.util.proto.ProtoOutputStream;
+import android.view.IWindow;
/**
* Common interface between focusable objects.
@@ -58,7 +58,6 @@
boolean canScreenshotIme();
ActivityRecord getActivityRecord();
- void unfreezeInsetsAfterStartInput();
boolean isInputMethodClientFocus(int uid, int pid);
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 659f8d7..49eaea2 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -508,6 +508,9 @@
}
mClientVisible = clientVisible;
updateVisibility();
+ // The visibility change needs a traversal to apply.
+ mDisplayContent.setLayoutNeeded();
+ mDisplayContent.mWmService.mWindowPlacerLocked.requestTraversal();
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index 0c8a645..75ba214 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -17,12 +17,18 @@
package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.pm.ActivityInfo.screenOrientationToString;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__BOTTOM;
@@ -132,6 +138,15 @@
@Nullable
private Letterbox mLetterbox;
+ @Nullable
+ private final Boolean mBooleanPropertyCameraCompatAllowForceRotation;
+
+ @Nullable
+ private final Boolean mBooleanPropertyCameraCompatAllowRefresh;
+
+ @Nullable
+ private final Boolean mBooleanPropertyCameraCompatEnableRefreshViaPause;
+
// Whether activity "refresh" was requested but not finished in
// ActivityRecord#activityResumedLocked following the camera compat force rotation in
// DisplayRotationCompatPolicy.
@@ -154,8 +169,33 @@
readComponentProperty(packageManager, mActivityRecord.packageName,
mLetterboxConfiguration::isPolicyForIgnoringRequestedOrientationEnabled,
PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION);
+ mBooleanPropertyCameraCompatAllowForceRotation =
+ readComponentProperty(packageManager, mActivityRecord.packageName,
+ () -> mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
+ /* checkDeviceConfig */ true),
+ PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION);
+ mBooleanPropertyCameraCompatAllowRefresh =
+ readComponentProperty(packageManager, mActivityRecord.packageName,
+ () -> mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
+ /* checkDeviceConfig */ true),
+ PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH);
+ mBooleanPropertyCameraCompatEnableRefreshViaPause =
+ readComponentProperty(packageManager, mActivityRecord.packageName,
+ () -> mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
+ /* checkDeviceConfig */ true),
+ PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE);
}
+ /**
+ * Reads a {@link Boolean} component property fot a given {@code packageName} and a {@code
+ * propertyName}. Returns {@code null} if {@code gatingCondition} is {@code false} or if the
+ * property isn't specified for the package.
+ *
+ * <p>Return value is {@link Boolean} rather than {@code boolean} so we can know when the
+ * property is unset. Particularly, when this returns {@code null}, {@link
+ * #shouldEnableWithOverrideAndProperty} will check the value of override for the final
+ * decision.
+ */
@Nullable
private static Boolean readComponentProperty(PackageManager packageManager, String packageName,
BooleanSupplier gatingCondition, String propertyName) {
@@ -210,15 +250,11 @@
* </ul>
*/
boolean shouldIgnoreRequestedOrientation(@ScreenOrientation int requestedOrientation) {
- if (!mLetterboxConfiguration.isPolicyForIgnoringRequestedOrientationEnabled()) {
- return false;
- }
- if (Boolean.FALSE.equals(mBooleanPropertyIgnoreRequestedOrientation)) {
- return false;
- }
- if (!Boolean.TRUE.equals(mBooleanPropertyIgnoreRequestedOrientation)
- && !mActivityRecord.info.isChangeEnabled(
- OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION)) {
+ if (!shouldEnableWithOverrideAndProperty(
+ /* gatingCondition */ mLetterboxConfiguration
+ ::isPolicyForIgnoringRequestedOrientationEnabled,
+ OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION,
+ mBooleanPropertyIgnoreRequestedOrientation)) {
return false;
}
if (mIsRelauchingAfterRequestedOrientationChanged) {
@@ -262,6 +298,109 @@
mIsRefreshAfterRotationRequested = isRequested;
}
+ /**
+ * Whether activity is eligible for activity "refresh" after camera compat force rotation
+ * treatment. See {@link DisplayRotationCompatPolicy} for context.
+ *
+ * <p>This treatment is enabled when the following conditions are met:
+ * <ul>
+ * <li>Flag gating the camera compat treatment is enabled.
+ * <li>Activity isn't opted out by the device manufacturer with override or by the app
+ * developers with the component property.
+ * </ul>
+ */
+ boolean shouldRefreshActivityForCameraCompat() {
+ return shouldEnableWithOptOutOverrideAndProperty(
+ /* gatingCondition */ () -> mLetterboxConfiguration
+ .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true),
+ OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH,
+ mBooleanPropertyCameraCompatAllowRefresh);
+ }
+
+ /**
+ * Whether activity should be "refreshed" after the camera compat force rotation treatment
+ * using the "resumed -> paused -> resumed" cycle rather than the "resumed -> ... -> stopped
+ * -> ... -> resumed" cycle. See {@link DisplayRotationCompatPolicy} for context.
+ *
+ * <p>This treatment is enabled when the following conditions are met:
+ * <ul>
+ * <li>Flag gating the camera compat treatment is enabled.
+ * <li>Activity "refresh" via "resumed -> paused -> resumed" cycle isn't disabled with the
+ * component property by the app developers.
+ * <li>Activity "refresh" via "resumed -> paused -> resumed" cycle is enabled by the device
+ * manufacturer with override / by the app developers with the component property.
+ * </ul>
+ */
+ boolean shouldRefreshActivityViaPauseForCameraCompat() {
+ return shouldEnableWithOverrideAndProperty(
+ /* gatingCondition */ () -> mLetterboxConfiguration
+ .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true),
+ OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE,
+ mBooleanPropertyCameraCompatEnableRefreshViaPause);
+ }
+
+ /**
+ * Whether activity is eligible for camera compat force rotation treatment. See {@link
+ * DisplayRotationCompatPolicy} for context.
+ *
+ * <p>This treatment is enabled when the following conditions are met:
+ * <ul>
+ * <li>Flag gating the camera compat treatment is enabled.
+ * <li>Activity isn't opted out by the device manufacturer with override or by the app
+ * developers with the component property.
+ * </ul>
+ */
+ boolean shouldForceRotateForCameraCompat() {
+ return shouldEnableWithOptOutOverrideAndProperty(
+ /* gatingCondition */ () -> mLetterboxConfiguration
+ .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true),
+ OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION,
+ mBooleanPropertyCameraCompatAllowForceRotation);
+ }
+
+ /**
+ * Returns {@code true} when the following conditions are met:
+ * <ul>
+ * <li>{@code gatingCondition} isn't {@code false}
+ * <li>OEM didn't opt out with a {@code overrideChangeId} override
+ * <li>App developers didn't opt out with a component {@code property}
+ * </ul>
+ *
+ * <p>This is used for the treatments that are enabled based with the heuristic but can be
+ * disabled on per-app basis by OEMs or app developers.
+ */
+ private boolean shouldEnableWithOptOutOverrideAndProperty(BooleanSupplier gatingCondition,
+ long overrideChangeId, Boolean property) {
+ if (!gatingCondition.getAsBoolean()) {
+ return false;
+ }
+ return !Boolean.FALSE.equals(property)
+ && !mActivityRecord.info.isChangeEnabled(overrideChangeId);
+ }
+
+ /**
+ * Returns {@code true} when the following conditions are met:
+ * <ul>
+ * <li>{@code gatingCondition} isn't {@code false}
+ * <li>App developers didn't opt out with a component {@code property}
+ * <li>App developers opted in with a component {@code property} or an OEM opted in with a
+ * component {@code property}
+ * </ul>
+ *
+ * <p>This is used for the treatments that are enabled only on per-app basis.
+ */
+ private boolean shouldEnableWithOverrideAndProperty(BooleanSupplier gatingCondition,
+ long overrideChangeId, Boolean property) {
+ if (!gatingCondition.getAsBoolean()) {
+ return false;
+ }
+ if (Boolean.FALSE.equals(property)) {
+ return false;
+ }
+ return Boolean.TRUE.equals(property)
+ || mActivityRecord.info.isChangeEnabled(overrideChangeId);
+ }
+
boolean hasWallpaperBackgroundForLetterbox() {
return mShowWallpaperForLetterboxBackground;
}
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index 9e95918..4be1c83 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -976,7 +976,7 @@
continue;
}
- res.add(createRecentTaskInfo(task, true /* stripExtras */));
+ res.add(createRecentTaskInfo(task, true /* stripExtras */, getTasksAllowed));
}
return res;
}
@@ -1889,7 +1889,8 @@
/**
* Creates a new RecentTaskInfo from a Task.
*/
- ActivityManager.RecentTaskInfo createRecentTaskInfo(Task tr, boolean stripExtras) {
+ ActivityManager.RecentTaskInfo createRecentTaskInfo(Task tr, boolean stripExtras,
+ boolean getTasksAllowed) {
final ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
// If the recent Task is detached, we consider it will be re-attached to the default
// TaskDisplayArea because we currently only support recent overview in the default TDA.
@@ -1901,6 +1902,9 @@
rti.id = rti.isRunning ? rti.taskId : INVALID_TASK_ID;
rti.persistentId = rti.taskId;
rti.lastSnapshotData.set(tr.mLastTaskSnapshotData);
+ if (!getTasksAllowed) {
+ Task.trimIneffectiveInfo(tr, rti);
+ }
// Fill in organized child task info for the task created by organizer.
if (tr.mCreatedByOrganizer) {
diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java
index 614b405..1cc1a57 100644
--- a/services/core/java/com/android/server/wm/RunningTasks.java
+++ b/services/core/java/com/android/server/wm/RunningTasks.java
@@ -173,6 +173,10 @@
}
// Fill in some deprecated values
rti.id = rti.taskId;
+
+ if (!mAllowed) {
+ Task.trimIneffectiveInfo(task, rti);
+ }
return rti;
}
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 3b5b5a9..e253ce0 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -612,6 +612,8 @@
boolean mLastSurfaceShowing = true;
+ boolean mAlignActivityLocaleWithTask = false;
+
private Task(ActivityTaskManagerService atmService, int _taskId, Intent _intent,
Intent _affinityIntent, String _affinity, String _rootAffinity,
ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
@@ -3402,6 +3404,54 @@
info.isSleeping = shouldSleepActivities();
}
+ /**
+ * Removes the activity info if the activity belongs to a different uid, which is
+ * different from the app that hosts the task.
+ */
+ static void trimIneffectiveInfo(Task task, TaskInfo info) {
+ final ActivityRecord baseActivity = task.getActivity(r -> !r.finishing,
+ false /* traverseTopToBottom */);
+ final int baseActivityUid =
+ baseActivity != null ? baseActivity.getUid() : task.effectiveUid;
+
+ if (info.topActivityInfo != null
+ && task.effectiveUid != info.topActivityInfo.applicationInfo.uid) {
+ // Making a copy to prevent eliminating the info in the original ActivityRecord.
+ info.topActivityInfo = new ActivityInfo(info.topActivityInfo);
+ info.topActivityInfo.applicationInfo =
+ new ApplicationInfo(info.topActivityInfo.applicationInfo);
+
+ // Strip the sensitive info.
+ info.topActivity = new ComponentName("", "");
+ info.topActivityInfo.packageName = "";
+ info.topActivityInfo.taskAffinity = "";
+ info.topActivityInfo.processName = "";
+ info.topActivityInfo.name = "";
+ info.topActivityInfo.parentActivityName = "";
+ info.topActivityInfo.targetActivity = "";
+ info.topActivityInfo.splitName = "";
+ info.topActivityInfo.applicationInfo.className = "";
+ info.topActivityInfo.applicationInfo.credentialProtectedDataDir = "";
+ info.topActivityInfo.applicationInfo.dataDir = "";
+ info.topActivityInfo.applicationInfo.deviceProtectedDataDir = "";
+ info.topActivityInfo.applicationInfo.manageSpaceActivityName = "";
+ info.topActivityInfo.applicationInfo.nativeLibraryDir = "";
+ info.topActivityInfo.applicationInfo.nativeLibraryRootDir = "";
+ info.topActivityInfo.applicationInfo.processName = "";
+ info.topActivityInfo.applicationInfo.publicSourceDir = "";
+ info.topActivityInfo.applicationInfo.scanPublicSourceDir = "";
+ info.topActivityInfo.applicationInfo.scanSourceDir = "";
+ info.topActivityInfo.applicationInfo.sourceDir = "";
+ info.topActivityInfo.applicationInfo.taskAffinity = "";
+ info.topActivityInfo.applicationInfo.name = "";
+ info.topActivityInfo.applicationInfo.packageName = "";
+ }
+
+ if (task.effectiveUid != baseActivityUid) {
+ info.baseActivity = new ComponentName("", "");
+ }
+ }
+
@Nullable PictureInPictureParams getPictureInPictureParams() {
final Task topTask = getTopMostTask();
if (topTask == null) return null;
@@ -6215,6 +6265,11 @@
return this;
}
+ Builder setRemoveWithTaskOrganizer(boolean removeWithTaskOrganizer) {
+ mRemoveWithTaskOrganizer = removeWithTaskOrganizer;
+ return this;
+ }
+
private Builder setUserId(int userId) {
mUserId = userId;
return this;
@@ -6412,7 +6467,7 @@
mCallingPackage = mActivityInfo.packageName;
mResizeMode = mActivityInfo.resizeMode;
mSupportsPictureInPicture = mActivityInfo.supportsPictureInPicture();
- if (mActivityOptions != null) {
+ if (!mRemoveWithTaskOrganizer && mActivityOptions != null) {
mRemoveWithTaskOrganizer = mActivityOptions.getRemoveWithTaskOranizer();
}
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index 90a0dff..5f186a1 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -49,6 +49,7 @@
import android.window.ITaskFragmentOrganizer;
import android.window.ITaskFragmentOrganizerController;
import android.window.TaskFragmentInfo;
+import android.window.TaskFragmentOperation;
import android.window.TaskFragmentParentInfo;
import android.window.TaskFragmentTransaction;
import android.window.WindowContainerTransaction;
@@ -297,7 +298,7 @@
@NonNull
TaskFragmentTransaction.Change prepareTaskFragmentError(
@Nullable IBinder errorCallbackToken, @Nullable TaskFragment taskFragment,
- int opType, @NonNull Throwable exception) {
+ @TaskFragmentOperation.OperationType int opType, @NonNull Throwable exception) {
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER,
"Sending TaskFragment error exception=%s", exception.toString());
final TaskFragmentInfo info =
@@ -629,7 +630,7 @@
void onTaskFragmentError(@NonNull ITaskFragmentOrganizer organizer,
@Nullable IBinder errorCallbackToken, @Nullable TaskFragment taskFragment,
- int opType, @NonNull Throwable exception) {
+ @TaskFragmentOperation.OperationType int opType, @NonNull Throwable exception) {
if (taskFragment != null && taskFragment.mTaskFragmentVanishedSent) {
return;
}
@@ -803,6 +804,7 @@
// Set when the event is deferred due to the host task is invisible. The defer time will
// be the last active time of the host task.
private long mDeferTime;
+ @TaskFragmentOperation.OperationType
private int mOpType;
private PendingTaskFragmentEvent(@EventType int eventType,
@@ -812,7 +814,7 @@
@Nullable Throwable exception,
@Nullable ActivityRecord activity,
@Nullable Task task,
- int opType) {
+ @TaskFragmentOperation.OperationType int opType) {
mEventType = eventType;
mTaskFragmentOrg = taskFragmentOrg;
mTaskFragment = taskFragment;
@@ -853,6 +855,7 @@
private ActivityRecord mActivity;
@Nullable
private Task mTask;
+ @TaskFragmentOperation.OperationType
private int mOpType;
Builder(@EventType int eventType, @NonNull ITaskFragmentOrganizer taskFragmentOrg) {
@@ -885,7 +888,7 @@
return this;
}
- Builder setOpType(int opType) {
+ Builder setOpType(@TaskFragmentOperation.OperationType int opType) {
mOpType = opType;
return this;
}
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 274d7ff..8570db2 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -783,7 +783,8 @@
}
@Override
- public void createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie) {
+ public void createRootTask(int displayId, int windowingMode, @Nullable IBinder launchCookie,
+ boolean removeWithTaskOrganizer) {
enforceTaskPermission("createRootTask()");
final long origId = Binder.clearCallingIdentity();
try {
@@ -795,7 +796,7 @@
return;
}
- createRootTask(display, windowingMode, launchCookie);
+ createRootTask(display, windowingMode, launchCookie, removeWithTaskOrganizer);
}
} finally {
Binder.restoreCallingIdentity(origId);
@@ -804,6 +805,12 @@
@VisibleForTesting
Task createRootTask(DisplayContent display, int windowingMode, @Nullable IBinder launchCookie) {
+ return createRootTask(display, windowingMode, launchCookie,
+ false /* removeWithTaskOrganizer */);
+ }
+
+ Task createRootTask(DisplayContent display, int windowingMode, @Nullable IBinder launchCookie,
+ boolean removeWithTaskOrganizer) {
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Create root task displayId=%d winMode=%d",
display.mDisplayId, windowingMode);
// We want to defer the task appear signal until the task is fully created and attached to
@@ -816,6 +823,7 @@
.setDeferTaskAppear(true)
.setLaunchCookie(launchCookie)
.setParent(display.getDefaultTaskDisplayArea())
+ .setRemoveWithTaskOrganizer(removeWithTaskOrganizer)
.build();
task.setDeferTaskAppear(false /* deferTaskAppear */);
return task;
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 7f9e808..16541c1 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -370,7 +370,7 @@
boolean updateWallpaperOffset(WindowState wallpaperWin, boolean sync) {
// Size of the display the wallpaper is rendered on.
- final Rect lastWallpaperBounds = wallpaperWin.getLastReportedBounds();
+ final Rect lastWallpaperBounds = wallpaperWin.getParentFrame();
// Full size of the wallpaper (usually larger than bounds above to parallax scroll when
// swiping through Launcher pages).
final Rect wallpaperFrame = wallpaperWin.getFrame();
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 0ab4faf..63bb5c3 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -3237,11 +3237,11 @@
private Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
boolean isVoiceInteraction) {
- if (isOrganized()
+ if (AppTransitionController.isTaskViewTask(this) || (isOrganized()
// TODO(b/161711458): Clean-up when moved to shell.
&& getWindowingMode() != WINDOWING_MODE_FULLSCREEN
&& getWindowingMode() != WINDOWING_MODE_FREEFORM
- && getWindowingMode() != WINDOWING_MODE_MULTI_WINDOW) {
+ && getWindowingMode() != WINDOWING_MODE_MULTI_WINDOW)) {
return null;
}
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 7d15902..dd70fca 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -21,12 +21,19 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOW_CONFIG_BOUNDS;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_DELETE_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS;
import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS;
+import static android.window.TaskFragmentOperation.OP_TYPE_SET_COMPANION_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_UNKNOWN;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_ADD_TASK_FRAGMENT_OPERATION;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CLEAR_ADJACENT_ROOTS;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_FINISH_ACTIVITY;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_LAUNCH_TASK;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_PENDING_INTENT;
@@ -34,19 +41,12 @@
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REMOVE_TASK;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_CHILDREN;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_RESTORE_TRANSIENT_ORDER;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ALWAYS_ON_TOP;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_COMPANION_TASK_FRAGMENT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_REPARENT_LEAF_TASK_IF_RELAUNCH;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_TASK_FRAGMENT_OPERATION;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_SHORTCUT;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
@@ -119,6 +119,7 @@
private static final String TAG = "WindowOrganizerController";
+ private static final int TRANSACT_EFFECTS_NONE = 0;
/** Flag indicating that an applied transaction may have effected lifecycle */
private static final int TRANSACT_EFFECTS_CLIENT_CONFIG = 1;
private static final int TRANSACT_EFFECTS_LIFECYCLE = 1 << 1;
@@ -488,7 +489,7 @@
private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
@Nullable Transition transition, @NonNull CallerInfo caller,
@Nullable Transition finishTransition) {
- int effects = 0;
+ int effects = TRANSACT_EFFECTS_NONE;
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Apply window transaction, syncId=%d", syncId);
mService.deferWindowLayout();
mService.mTaskSupervisor.setDeferRootVisibilityUpdate(true /* deferUpdate */);
@@ -630,7 +631,7 @@
// masks here.
final int configMask = change.getConfigSetMask() & CONTROLLABLE_CONFIGS;
final int windowMask = change.getWindowSetMask() & CONTROLLABLE_WINDOW_CONFIGS;
- int effects = 0;
+ int effects = TRANSACT_EFFECTS_NONE;
final int windowingMode = change.getWindowingMode();
if (configMask != 0) {
@@ -795,7 +796,7 @@
@NonNull WindowContainerTransaction.Change c, @Nullable IBinder errorCallbackToken) {
if (taskFragment.isEmbeddedTaskFragmentInPip()) {
// No override from organizer for embedded TaskFragment in a PIP Task.
- return 0;
+ return TRANSACT_EFFECTS_NONE;
}
// When the TaskFragment is resized, we may want to create a change transition for it, for
@@ -861,197 +862,6 @@
effects |= clearAdjacentRootsHierarchyOp(hop);
break;
}
- case HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT: {
- final TaskFragmentCreationParams taskFragmentCreationOptions =
- hop.getTaskFragmentCreationOptions();
- createTaskFragment(taskFragmentCreationOptions, errorCallbackToken, caller,
- transition);
- break;
- }
- case HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT: {
- final WindowContainer wc = WindowContainer.fromBinder(hop.getContainer());
- if (wc == null || !wc.isAttached()) {
- Slog.e(TAG, "Attempt to operate on unknown or detached container: " + wc);
- break;
- }
- final TaskFragment taskFragment = wc.asTaskFragment();
- if (taskFragment == null || taskFragment.asTask() != null) {
- throw new IllegalArgumentException(
- "Can only delete organized TaskFragment, but not Task.");
- }
- if (isInLockTaskMode) {
- final ActivityRecord bottomActivity = taskFragment.getActivity(
- a -> !a.finishing, false /* traverseTopToBottom */);
- if (bottomActivity != null
- && mService.getLockTaskController().activityBlockedFromFinish(
- bottomActivity)) {
- Slog.w(TAG, "Skip removing TaskFragment due in lock task mode.");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken,
- taskFragment, type, new IllegalStateException(
- "Not allow to delete task fragment in lock task mode."));
- break;
- }
- }
- effects |= deleteTaskFragment(taskFragment, organizer, errorCallbackToken,
- transition);
- break;
- }
- case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT: {
- final IBinder fragmentToken = hop.getContainer();
- final TaskFragment tf = mLaunchTaskFragments.get(fragmentToken);
- if (tf == null) {
- final Throwable exception = new IllegalArgumentException(
- "Not allowed to operate with invalid fragment token");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf, type,
- exception);
- break;
- }
- if (tf.isEmbeddedTaskFragmentInPip()) {
- final Throwable exception = new IllegalArgumentException(
- "Not allowed to start activity in PIP TaskFragment");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf, type,
- exception);
- break;
- }
- final Intent activityIntent = hop.getActivityIntent();
- final Bundle activityOptions = hop.getLaunchOptions();
- final int result = mService.getActivityStartController()
- .startActivityInTaskFragment(tf, activityIntent, activityOptions,
- hop.getCallingActivity(), caller.mUid, caller.mPid,
- errorCallbackToken);
- if (!isStartResultSuccessful(result)) {
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf, type,
- convertStartFailureToThrowable(result, activityIntent));
- } else {
- effects |= TRANSACT_EFFECTS_LIFECYCLE;
- }
- break;
- }
- case HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT: {
- final IBinder fragmentToken = hop.getNewParent();
- final IBinder activityToken = hop.getContainer();
- ActivityRecord activity = ActivityRecord.forTokenLocked(activityToken);
- if (activity == null) {
- // The token may be a temporary token if the activity doesn't belong to
- // the organizer process.
- activity = mTaskFragmentOrganizerController
- .getReparentActivityFromTemporaryToken(organizer, activityToken);
- }
- final TaskFragment parent = mLaunchTaskFragments.get(fragmentToken);
- if (parent == null || activity == null) {
- final Throwable exception = new IllegalArgumentException(
- "Not allowed to operate with invalid fragment token or activity.");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, parent, type,
- exception);
- break;
- }
- if (parent.isEmbeddedTaskFragmentInPip()) {
- final Throwable exception = new IllegalArgumentException(
- "Not allowed to reparent activity to PIP TaskFragment");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, parent, type,
- exception);
- break;
- }
- if (parent.isAllowedToEmbedActivity(activity) != EMBEDDING_ALLOWED) {
- final Throwable exception = new SecurityException(
- "The task fragment is not allowed to embed the given activity.");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, parent, type,
- exception);
- break;
- }
- if (parent.getTask() != activity.getTask()) {
- final Throwable exception = new SecurityException("The reparented activity is"
- + " not in the same Task as the target TaskFragment.");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, parent, type,
- exception);
- break;
- }
-
- if (transition != null) {
- transition.collect(activity);
- if (activity.getParent() != null) {
- // Collect the current parent. Its visibility may change as a result of
- // this reparenting.
- transition.collect(activity.getParent());
- }
- transition.collect(parent);
- }
- activity.reparent(parent, POSITION_TOP);
- effects |= TRANSACT_EFFECTS_LIFECYCLE;
- break;
- }
- case HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS: {
- final IBinder fragmentToken = hop.getContainer();
- final IBinder adjacentFragmentToken = hop.getAdjacentRoot();
- final TaskFragment tf1 = mLaunchTaskFragments.get(fragmentToken);
- final TaskFragment tf2 = adjacentFragmentToken != null
- ? mLaunchTaskFragments.get(adjacentFragmentToken)
- : null;
- if (tf1 == null || (adjacentFragmentToken != null && tf2 == null)) {
- final Throwable exception = new IllegalArgumentException(
- "Not allowed to set adjacent on invalid fragment tokens");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf1, type,
- exception);
- break;
- }
- if (tf1.isEmbeddedTaskFragmentInPip()
- || (tf2 != null && tf2.isEmbeddedTaskFragmentInPip())) {
- final Throwable exception = new IllegalArgumentException(
- "Not allowed to set adjacent on TaskFragment in PIP Task");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf1, type,
- exception);
- break;
- }
- tf1.setAdjacentTaskFragment(tf2);
- effects |= TRANSACT_EFFECTS_LIFECYCLE;
-
- // Clear the focused app if the focused app is no longer visible after reset the
- // adjacent TaskFragments.
- if (tf2 == null && tf1.getDisplayContent().mFocusedApp != null
- && tf1.hasChild(tf1.getDisplayContent().mFocusedApp)
- && !tf1.shouldBeVisible(null /* starting */)) {
- tf1.getDisplayContent().setFocusedApp(null);
- }
-
- final Bundle bundle = hop.getLaunchOptions();
- final WindowContainerTransaction.TaskFragmentAdjacentParams adjacentParams =
- bundle != null ? new WindowContainerTransaction.TaskFragmentAdjacentParams(
- bundle) : null;
- if (adjacentParams == null) {
- break;
- }
-
- tf1.setDelayLastActivityRemoval(
- adjacentParams.shouldDelayPrimaryLastActivityRemoval());
- if (tf2 != null) {
- tf2.setDelayLastActivityRemoval(
- adjacentParams.shouldDelaySecondaryLastActivityRemoval());
- }
- break;
- }
- case HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT: {
- final TaskFragment tf = mLaunchTaskFragments.get(hop.getContainer());
- if (tf == null || !tf.isAttached()) {
- Slog.e(TAG, "Attempt to operate on detached container: " + tf);
- break;
- }
- final ActivityRecord curFocus = tf.getDisplayContent().mFocusedApp;
- if (curFocus != null && curFocus.getTaskFragment() == tf) {
- Slog.d(TAG, "The requested TaskFragment already has the focus.");
- break;
- }
- if (curFocus != null && curFocus.getTask() != tf.getTask()) {
- Slog.d(TAG, "The Task of the requested TaskFragment doesn't have focus.");
- break;
- }
- final ActivityRecord targetFocus = tf.getTopResumedActivity();
- if (targetFocus == null) {
- Slog.d(TAG, "There is no resumed activity in the requested TaskFragment.");
- break;
- }
- tf.getDisplayContent().setFocusedApp(targetFocus);
- break;
- }
case HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT: {
effects |= reparentChildrenTasksHierarchyOp(hop, transition, syncId,
isInLockTaskMode);
@@ -1126,24 +936,9 @@
effects |= sanitizeAndApplyHierarchyOp(wc, hop);
break;
}
- case HIERARCHY_OP_TYPE_SET_COMPANION_TASK_FRAGMENT: {
- final IBinder fragmentToken = hop.getContainer();
- final IBinder companionToken = hop.getCompanionContainer();
- final TaskFragment fragment = mLaunchTaskFragments.get(fragmentToken);
- final TaskFragment companion = companionToken != null ? mLaunchTaskFragments.get(
- companionToken) : null;
- if (fragment == null || !fragment.isAttached()) {
- final Throwable exception = new IllegalArgumentException(
- "Not allowed to set companion on invalid fragment tokens");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, fragment, type,
- exception);
- break;
- }
- fragment.setCompanionTaskFragment(companion);
- break;
- }
- case HIERARCHY_OP_TYPE_SET_TASK_FRAGMENT_OPERATION: {
- effects |= applyTaskFragmentOperation(hop, errorCallbackToken, organizer);
+ case HIERARCHY_OP_TYPE_ADD_TASK_FRAGMENT_OPERATION: {
+ effects |= applyTaskFragmentOperation(hop, transition, isInLockTaskMode, caller,
+ errorCallbackToken, organizer);
break;
}
default: {
@@ -1203,22 +998,6 @@
}
break;
}
- case HIERARCHY_OP_TYPE_REPARENT_CHILDREN: {
- final WindowContainer oldParent = WindowContainer.fromBinder(hop.getContainer());
- final WindowContainer newParent = hop.getNewParent() != null
- ? WindowContainer.fromBinder(hop.getNewParent())
- : null;
- if (oldParent == null || oldParent.asTaskFragment() == null
- || !oldParent.isAttached()) {
- Slog.e(TAG, "Attempt to operate on unknown or detached container: "
- + oldParent);
- break;
- }
- reparentTaskFragment(oldParent.asTaskFragment(), newParent, organizer,
- errorCallbackToken, transition);
- effects |= TRANSACT_EFFECTS_LIFECYCLE;
- break;
- }
case HIERARCHY_OP_TYPE_RESTORE_TRANSIENT_ORDER: {
if (finishTransition == null) break;
final WindowContainer container = WindowContainer.fromBinder(hop.getContainer());
@@ -1278,45 +1057,241 @@
return effects;
}
- /** Applies change set through {@link WindowContainerTransaction#setTaskFragmentOperation}. */
+ /**
+ * Applies change set through {@link WindowContainerTransaction#addTaskFragmentOperation}.
+ * @return an int to represent the transaction effects, such as {@link #TRANSACT_EFFECTS_NONE},
+ * {@link #TRANSACT_EFFECTS_LIFECYCLE} or {@link #TRANSACT_EFFECTS_CLIENT_CONFIG}.
+ */
private int applyTaskFragmentOperation(@NonNull WindowContainerTransaction.HierarchyOp hop,
+ @Nullable Transition transition, boolean isInLockTaskMode, @NonNull CallerInfo caller,
@Nullable IBinder errorCallbackToken, @Nullable ITaskFragmentOrganizer organizer) {
+ if (!validateTaskFragmentOperation(hop, errorCallbackToken, organizer)) {
+ return TRANSACT_EFFECTS_NONE;
+ }
final IBinder fragmentToken = hop.getContainer();
final TaskFragment taskFragment = mLaunchTaskFragments.get(fragmentToken);
final TaskFragmentOperation operation = hop.getTaskFragmentOperation();
- if (operation == null) {
- final Throwable exception = new IllegalArgumentException(
- "TaskFragmentOperation must be non-null");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
- HIERARCHY_OP_TYPE_SET_TASK_FRAGMENT_OPERATION, exception);
- return 0;
- }
final int opType = operation.getOpType();
- if (taskFragment == null || !taskFragment.isAttached()) {
- final Throwable exception = new IllegalArgumentException(
- "Not allowed to apply operation on invalid fragment tokens opType=" + opType);
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
- HIERARCHY_OP_TYPE_SET_TASK_FRAGMENT_OPERATION, exception);
- return 0;
- }
- int effect = 0;
+ int effects = TRANSACT_EFFECTS_NONE;
switch (opType) {
+ case OP_TYPE_CREATE_TASK_FRAGMENT: {
+ final TaskFragmentCreationParams taskFragmentCreationParams =
+ operation.getTaskFragmentCreationParams();
+ if (taskFragmentCreationParams == null) {
+ final Throwable exception = new IllegalArgumentException(
+ "TaskFragmentCreationParams must be non-null");
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
+ opType, exception);
+ break;
+ }
+ createTaskFragment(taskFragmentCreationParams, errorCallbackToken, caller,
+ transition);
+ break;
+ }
+ case OP_TYPE_DELETE_TASK_FRAGMENT: {
+ if (isInLockTaskMode) {
+ final ActivityRecord bottomActivity = taskFragment.getActivity(
+ a -> !a.finishing, false /* traverseTopToBottom */);
+ if (bottomActivity != null
+ && mService.getLockTaskController().activityBlockedFromFinish(
+ bottomActivity)) {
+ Slog.w(TAG, "Skip removing TaskFragment due in lock task mode.");
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken,
+ taskFragment, opType, new IllegalStateException(
+ "Not allow to delete task fragment in lock task mode."));
+ break;
+ }
+ }
+ effects |= deleteTaskFragment(taskFragment, transition);
+ break;
+ }
+ case OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT: {
+ final IBinder callerActivityToken = operation.getActivityToken();
+ final Intent activityIntent = operation.getActivityIntent();
+ final Bundle activityOptions = operation.getBundle();
+ final int result = mService.getActivityStartController()
+ .startActivityInTaskFragment(taskFragment, activityIntent, activityOptions,
+ callerActivityToken, caller.mUid, caller.mPid,
+ errorCallbackToken);
+ if (!isStartResultSuccessful(result)) {
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
+ opType, convertStartFailureToThrowable(result, activityIntent));
+ } else {
+ effects |= TRANSACT_EFFECTS_LIFECYCLE;
+ }
+ break;
+ }
+ case OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT: {
+ final IBinder activityToken = operation.getActivityToken();
+ ActivityRecord activity = ActivityRecord.forTokenLocked(activityToken);
+ if (activity == null) {
+ // The token may be a temporary token if the activity doesn't belong to
+ // the organizer process.
+ activity = mTaskFragmentOrganizerController
+ .getReparentActivityFromTemporaryToken(organizer, activityToken);
+ }
+ if (activity == null) {
+ final Throwable exception = new IllegalArgumentException(
+ "Not allowed to operate with invalid activity.");
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
+ opType, exception);
+ break;
+ }
+ if (taskFragment.isAllowedToEmbedActivity(activity) != EMBEDDING_ALLOWED) {
+ final Throwable exception = new SecurityException(
+ "The task fragment is not allowed to embed the given activity.");
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
+ opType, exception);
+ break;
+ }
+ if (taskFragment.getTask() != activity.getTask()) {
+ final Throwable exception = new SecurityException("The reparented activity is"
+ + " not in the same Task as the target TaskFragment.");
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
+ opType, exception);
+ break;
+ }
+ if (transition != null) {
+ transition.collect(activity);
+ if (activity.getParent() != null) {
+ // Collect the current parent. Its visibility may change as a result of
+ // this reparenting.
+ transition.collect(activity.getParent());
+ }
+ transition.collect(taskFragment);
+ }
+ activity.reparent(taskFragment, POSITION_TOP);
+ effects |= TRANSACT_EFFECTS_LIFECYCLE;
+ break;
+ }
+ case OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS: {
+ final IBinder secondaryFragmentToken = operation.getSecondaryFragmentToken();
+ final TaskFragment secondaryTaskFragment = secondaryFragmentToken != null
+ ? mLaunchTaskFragments.get(secondaryFragmentToken)
+ : null;
+ taskFragment.setAdjacentTaskFragment(secondaryTaskFragment);
+ effects |= TRANSACT_EFFECTS_LIFECYCLE;
+
+ // Clear the focused app if the focused app is no longer visible after reset the
+ // adjacent TaskFragments.
+ if (secondaryTaskFragment == null
+ && taskFragment.getDisplayContent().mFocusedApp != null
+ && taskFragment.hasChild(taskFragment.getDisplayContent().mFocusedApp)
+ && !taskFragment.shouldBeVisible(null /* starting */)) {
+ taskFragment.getDisplayContent().setFocusedApp(null);
+ }
+
+ final Bundle bundle = hop.getLaunchOptions();
+ final WindowContainerTransaction.TaskFragmentAdjacentParams adjacentParams =
+ bundle != null ? new WindowContainerTransaction.TaskFragmentAdjacentParams(
+ bundle) : null;
+ if (adjacentParams == null) {
+ break;
+ }
+
+ taskFragment.setDelayLastActivityRemoval(
+ adjacentParams.shouldDelayPrimaryLastActivityRemoval());
+ if (secondaryTaskFragment != null) {
+ secondaryTaskFragment.setDelayLastActivityRemoval(
+ adjacentParams.shouldDelaySecondaryLastActivityRemoval());
+ }
+ break;
+ }
+ case OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT: {
+ final ActivityRecord curFocus = taskFragment.getDisplayContent().mFocusedApp;
+ if (curFocus != null && curFocus.getTaskFragment() == taskFragment) {
+ Slog.d(TAG, "The requested TaskFragment already has the focus.");
+ break;
+ }
+ if (curFocus != null && curFocus.getTask() != taskFragment.getTask()) {
+ Slog.d(TAG, "The Task of the requested TaskFragment doesn't have focus.");
+ break;
+ }
+ final ActivityRecord targetFocus = taskFragment.getTopResumedActivity();
+ if (targetFocus == null) {
+ Slog.d(TAG, "There is no resumed activity in the requested TaskFragment.");
+ break;
+ }
+ taskFragment.getDisplayContent().setFocusedApp(targetFocus);
+ break;
+ }
+ case OP_TYPE_SET_COMPANION_TASK_FRAGMENT: {
+ final IBinder companionFragmentToken = operation.getSecondaryFragmentToken();
+ final TaskFragment companionTaskFragment = companionFragmentToken != null
+ ? mLaunchTaskFragments.get(companionFragmentToken)
+ : null;
+ taskFragment.setCompanionTaskFragment(companionTaskFragment);
+ break;
+ }
case OP_TYPE_SET_ANIMATION_PARAMS: {
final TaskFragmentAnimationParams animationParams = operation.getAnimationParams();
if (animationParams == null) {
final Throwable exception = new IllegalArgumentException(
"TaskFragmentAnimationParams must be non-null");
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
- HIERARCHY_OP_TYPE_SET_TASK_FRAGMENT_OPERATION, exception);
+ opType, exception);
break;
}
taskFragment.setAnimationParams(animationParams);
break;
}
- // TODO(b/263436063): move other TaskFragment related operation here.
}
- return effect;
+ return effects;
+ }
+
+ private boolean validateTaskFragmentOperation(
+ @NonNull WindowContainerTransaction.HierarchyOp hop,
+ @Nullable IBinder errorCallbackToken, @Nullable ITaskFragmentOrganizer organizer) {
+ final TaskFragmentOperation operation = hop.getTaskFragmentOperation();
+ final IBinder fragmentToken = hop.getContainer();
+ final TaskFragment taskFragment = mLaunchTaskFragments.get(fragmentToken);
+ if (operation == null) {
+ final Throwable exception = new IllegalArgumentException(
+ "TaskFragmentOperation must be non-null");
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
+ OP_TYPE_UNKNOWN, exception);
+ return false;
+ }
+ final int opType = operation.getOpType();
+ if (opType == OP_TYPE_CREATE_TASK_FRAGMENT) {
+ // No need to check TaskFragment.
+ return true;
+ }
+
+ if (!validateTaskFragment(taskFragment, opType, errorCallbackToken, organizer)) {
+ return false;
+ }
+
+ final IBinder secondaryFragmentToken = operation.getSecondaryFragmentToken();
+ return secondaryFragmentToken == null
+ || validateTaskFragment(mLaunchTaskFragments.get(secondaryFragmentToken), opType,
+ errorCallbackToken, organizer);
+ }
+
+ private boolean validateTaskFragment(@Nullable TaskFragment taskFragment,
+ @TaskFragmentOperation.OperationType int opType, @Nullable IBinder errorCallbackToken,
+ @Nullable ITaskFragmentOrganizer organizer) {
+ if (taskFragment == null || !taskFragment.isAttached()) {
+ // TaskFragment doesn't exist.
+ final Throwable exception = new IllegalArgumentException(
+ "Not allowed to apply operation on invalid fragment tokens opType=" + opType);
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
+ opType, exception);
+ return false;
+ }
+ if (taskFragment.isEmbeddedTaskFragmentInPip()
+ && (opType != OP_TYPE_DELETE_TASK_FRAGMENT
+ // When the Task enters PiP before the organizer removes the empty TaskFragment, we
+ // should allow it to delete the TaskFragment for cleanup.
+ || taskFragment.getTopNonFinishingActivity() != null)) {
+ final Throwable exception = new IllegalArgumentException(
+ "Not allowed to apply operation on PIP TaskFragment");
+ sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
+ opType, exception);
+ return false;
+ }
+ return true;
}
/** A helper method to send minimum dimension violation error to the client. */
@@ -1329,7 +1304,7 @@
+ taskFragment.getBounds() + " does not satisfy minimum dimensions:"
+ minDimensions + " " + reason);
sendTaskFragmentOperationFailure(taskFragment.getTaskFragmentOrganizer(),
- errorCallbackToken, taskFragment, -1 /* opType */, exception);
+ errorCallbackToken, taskFragment, OP_TYPE_UNKNOWN, exception);
}
/**
@@ -1366,7 +1341,7 @@
final DisplayContent dc = task.getDisplayContent();
if (dc == null) {
Slog.w(TAG, "Container is no longer attached: " + task);
- return 0;
+ return TRANSACT_EFFECTS_NONE;
}
final Task as = task;
@@ -1379,7 +1354,7 @@
: WindowContainer.fromBinder(hop.getNewParent());
if (newParent == null) {
Slog.e(TAG, "Can't resolve parent window from token");
- return 0;
+ return TRANSACT_EFFECTS_NONE;
}
if (task.getParent() != newParent) {
if (newParent.asTaskDisplayArea() != null) {
@@ -1390,14 +1365,14 @@
if (newParent.inPinnedWindowingMode()) {
Slog.w(TAG, "Can't support moving a task to another PIP window..."
+ " newParent=" + newParent + " task=" + task);
- return 0;
+ return TRANSACT_EFFECTS_NONE;
}
if (!task.supportsMultiWindowInDisplayArea(
newParent.asTask().getDisplayArea())) {
Slog.w(TAG, "Can't support task that doesn't support multi-window"
+ " mode in multi-window mode... newParent=" + newParent
+ " task=" + task);
- return 0;
+ return TRANSACT_EFFECTS_NONE;
}
}
task.reparent((Task) newParent,
@@ -1459,22 +1434,22 @@
if (currentParent == newParent) {
Slog.e(TAG, "reparentChildrenTasksHierarchyOp parent not changing: " + hop);
- return 0;
+ return TRANSACT_EFFECTS_NONE;
}
if (!currentParent.isAttached()) {
Slog.e(TAG, "reparentChildrenTasksHierarchyOp currentParent detached="
+ currentParent + " hop=" + hop);
- return 0;
+ return TRANSACT_EFFECTS_NONE;
}
if (!newParent.isAttached()) {
Slog.e(TAG, "reparentChildrenTasksHierarchyOp newParent detached="
+ newParent + " hop=" + hop);
- return 0;
+ return TRANSACT_EFFECTS_NONE;
}
if (newParent.inPinnedWindowingMode()) {
Slog.e(TAG, "reparentChildrenTasksHierarchyOp newParent in PIP="
+ newParent + " hop=" + hop);
- return 0;
+ return TRANSACT_EFFECTS_NONE;
}
final boolean newParentInMultiWindow = newParent.inMultiWindowMode();
@@ -1553,10 +1528,6 @@
throw new IllegalArgumentException("setAdjacentRootsHierarchyOp: Not created by"
+ " organizer root1=" + root1 + " root2=" + root2);
}
- if (root1.isEmbeddedTaskFragmentInPip() || root2.isEmbeddedTaskFragmentInPip()) {
- Slog.e(TAG, "Attempt to set adjacent TaskFragment in PIP Task");
- return 0;
- }
root1.setAdjacentTaskFragment(root2);
return TRANSACT_EFFECTS_LIFECYCLE;
}
@@ -1725,52 +1696,12 @@
final int type = hop.getType();
// Check for each type of the operations that are allowed for TaskFragmentOrganizer.
switch (type) {
- case HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT:
- enforceTaskFragmentOrganized(func,
- WindowContainer.fromBinder(hop.getContainer()), organizer);
- break;
- case HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS:
- enforceTaskFragmentOrganized(func,
- WindowContainer.fromBinder(hop.getContainer()), organizer);
- enforceTaskFragmentOrganized(func,
- WindowContainer.fromBinder(hop.getAdjacentRoot()),
- organizer);
- break;
- case HIERARCHY_OP_TYPE_CLEAR_ADJACENT_ROOTS:
- enforceTaskFragmentOrganized(func,
- WindowContainer.fromBinder(hop.getContainer()), organizer);
- break;
- case HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT:
- // We are allowing organizer to create TaskFragment. We will check the
- // ownerToken in #createTaskFragment, and trigger error callback if that is not
- // valid.
- break;
- case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT:
- case HIERARCHY_OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT:
- case HIERARCHY_OP_TYPE_SET_TASK_FRAGMENT_OPERATION:
+ case HIERARCHY_OP_TYPE_ADD_TASK_FRAGMENT_OPERATION:
enforceTaskFragmentOrganized(func, hop.getContainer(), organizer);
- break;
- case HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT:
- enforceTaskFragmentOrganized(func, hop.getNewParent(), organizer);
- break;
- case HIERARCHY_OP_TYPE_SET_COMPANION_TASK_FRAGMENT:
- enforceTaskFragmentOrganized(func, hop.getContainer(), organizer);
- if (hop.getCompanionContainer() != null) {
- enforceTaskFragmentOrganized(func, hop.getCompanionContainer(), organizer);
- }
- break;
- case HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS:
- enforceTaskFragmentOrganized(func, hop.getContainer(), organizer);
- if (hop.getAdjacentRoot() != null) {
- enforceTaskFragmentOrganized(func, hop.getAdjacentRoot(), organizer);
- }
- break;
- case HIERARCHY_OP_TYPE_REPARENT_CHILDREN:
- enforceTaskFragmentOrganized(func,
- WindowContainer.fromBinder(hop.getContainer()), organizer);
- if (hop.getNewParent() != null) {
+ if (hop.getTaskFragmentOperation() != null
+ && hop.getTaskFragmentOperation().getSecondaryFragmentToken() != null) {
enforceTaskFragmentOrganized(func,
- WindowContainer.fromBinder(hop.getNewParent()),
+ hop.getTaskFragmentOperation().getSecondaryFragmentToken(),
organizer);
}
break;
@@ -1917,21 +1848,21 @@
final Throwable exception =
new IllegalArgumentException("TaskFragment token must be unique");
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, null /* taskFragment */,
- HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT, exception);
+ OP_TYPE_CREATE_TASK_FRAGMENT, exception);
return;
}
if (ownerActivity == null || ownerActivity.getTask() == null) {
final Throwable exception =
new IllegalArgumentException("Not allowed to operate with invalid ownerToken");
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, null /* taskFragment */,
- HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT, exception);
+ OP_TYPE_CREATE_TASK_FRAGMENT, exception);
return;
}
if (!ownerActivity.isResizeable()) {
final IllegalArgumentException exception = new IllegalArgumentException("Not allowed"
+ " to operate with non-resizable owner Activity");
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, null /* taskFragment */,
- HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT, exception);
+ OP_TYPE_CREATE_TASK_FRAGMENT, exception);
return;
}
// The ownerActivity has to belong to the same app as the target Task.
@@ -1942,14 +1873,14 @@
new SecurityException("Not allowed to operate with the ownerToken while "
+ "the root activity of the target task belong to the different app");
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, null /* taskFragment */,
- HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT, exception);
+ OP_TYPE_CREATE_TASK_FRAGMENT, exception);
return;
}
if (ownerTask.inPinnedWindowingMode()) {
final Throwable exception = new IllegalArgumentException(
"Not allowed to create TaskFragment in PIP Task");
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, null /* taskFragment */,
- HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT, exception);
+ OP_TYPE_CREATE_TASK_FRAGMENT, exception);
return;
}
final TaskFragment taskFragment = new TaskFragment(mService,
@@ -1966,6 +1897,13 @@
creationParams.getPairedPrimaryFragmentToken());
final int pairedPosition = ownerTask.mChildren.indexOf(pairedPrimaryTaskFragment);
position = pairedPosition != -1 ? pairedPosition + 1 : POSITION_TOP;
+ } else if (creationParams.getPairedActivityToken() != null) {
+ // When there is a paired Activity, we want to place the new TaskFragment right above
+ // the paired Activity to make sure the Activity position is not changed after reparent.
+ final ActivityRecord pairedActivity = ActivityRecord.forTokenLocked(
+ creationParams.getPairedActivityToken());
+ final int pairedPosition = ownerTask.mChildren.indexOf(pairedActivity);
+ position = pairedPosition != -1 ? pairedPosition + 1 : POSITION_TOP;
} else {
position = POSITION_TOP;
}
@@ -1977,91 +1915,11 @@
if (transition != null) transition.collectExistenceChange(taskFragment);
}
- private void reparentTaskFragment(@NonNull TaskFragment oldParent,
- @Nullable WindowContainer<?> newParent, @Nullable ITaskFragmentOrganizer organizer,
- @Nullable IBinder errorCallbackToken, @Nullable Transition transition) {
- final TaskFragment newParentTF;
- if (newParent == null) {
- // Use the old parent's parent if the caller doesn't specify the new parent.
- newParentTF = oldParent.getTask();
- } else {
- newParentTF = newParent.asTaskFragment();
- }
- if (newParentTF == null) {
- final Throwable exception =
- new IllegalArgumentException("Not allowed to operate with invalid container");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, newParentTF,
- HIERARCHY_OP_TYPE_REPARENT_CHILDREN, exception);
- return;
- }
- if (newParentTF.getTaskFragmentOrganizer() != null) {
- // We are reparenting activities to a new embedded TaskFragment, this operation is only
- // allowed if the new parent is trusted by all reparent activities.
- final boolean isEmbeddingDisallowed = oldParent.forAllActivities(activity ->
- newParentTF.isAllowedToEmbedActivity(activity) != EMBEDDING_ALLOWED);
- if (isEmbeddingDisallowed) {
- final Throwable exception = new SecurityException(
- "The new parent is not allowed to embed the activities.");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, newParentTF,
- HIERARCHY_OP_TYPE_REPARENT_CHILDREN, exception);
- return;
- }
- }
- if (newParentTF.isEmbeddedTaskFragmentInPip() || oldParent.isEmbeddedTaskFragmentInPip()) {
- final Throwable exception = new SecurityException(
- "Not allow to reparent in TaskFragment in PIP Task.");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, newParentTF,
- HIERARCHY_OP_TYPE_REPARENT_CHILDREN, exception);
- return;
- }
- if (newParentTF.getTask() != oldParent.getTask()) {
- final Throwable exception = new SecurityException(
- "The new parent is not in the same Task as the old parent.");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, newParentTF,
- HIERARCHY_OP_TYPE_REPARENT_CHILDREN, exception);
- return;
- }
- if (transition != null) {
- // Collect the current parent. It's visibility may change as a result of this
- // reparenting.
- transition.collect(oldParent);
- transition.collect(newParentTF);
- }
- while (oldParent.hasChild()) {
- final WindowContainer child = oldParent.getChildAt(0);
- if (transition != null) {
- transition.collect(child);
- }
- child.reparent(newParentTF, POSITION_TOP);
- }
- }
-
private int deleteTaskFragment(@NonNull TaskFragment taskFragment,
- @Nullable ITaskFragmentOrganizer organizer, @Nullable IBinder errorCallbackToken,
@Nullable Transition transition) {
- final int index = mLaunchTaskFragments.indexOfValue(taskFragment);
- if (index < 0) {
- final Throwable exception =
- new IllegalArgumentException("Not allowed to operate with invalid "
- + "taskFragment");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
- HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT, exception);
- return 0;
- }
- if (taskFragment.isEmbeddedTaskFragmentInPip()
- // When the Task enters PiP before the organizer removes the empty TaskFragment, we
- // should allow it to do the cleanup.
- && taskFragment.getTopNonFinishingActivity() != null) {
- final Throwable exception = new IllegalArgumentException(
- "Not allowed to delete TaskFragment in PIP Task");
- sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
- HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT, exception);
- return 0;
- }
-
if (transition != null) transition.collectExistenceChange(taskFragment);
- mLaunchTaskFragments.removeAt(index);
+ mLaunchTaskFragments.remove(taskFragment.getFragmentToken());
taskFragment.remove(true /* withTransition */, "deleteTaskFragment");
return TRANSACT_EFFECTS_LIFECYCLE;
}
@@ -2086,8 +1944,8 @@
}
void sendTaskFragmentOperationFailure(@NonNull ITaskFragmentOrganizer organizer,
- @Nullable IBinder errorCallbackToken, @Nullable TaskFragment taskFragment, int opType,
- @NonNull Throwable exception) {
+ @Nullable IBinder errorCallbackToken, @Nullable TaskFragment taskFragment,
+ @TaskFragmentOperation.OperationType int opType, @NonNull Throwable exception) {
if (organizer == null) {
throw new IllegalArgumentException("Not allowed to operate with invalid organizer");
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 096f8f6..e08bacc 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3068,12 +3068,6 @@
return mLastReportedConfiguration.getMergedConfiguration();
}
- /** Returns the last window configuration bounds reported to the client. */
- Rect getLastReportedBounds() {
- final Rect bounds = getLastReportedConfiguration().windowConfiguration.getBounds();
- return !bounds.isEmpty() ? bounds : getBounds();
- }
-
void adjustStartingWindowFlags() {
if (mAttrs.type == TYPE_BASE_APPLICATION && mActivityRecord != null
&& mActivityRecord.mStartingWindow != null) {
@@ -4390,6 +4384,9 @@
pw.print("null");
}
+ if (mXOffset != 0 || mYOffset != 0) {
+ pw.println(prefix + "mXOffset=" + mXOffset + " mYOffset=" + mYOffset);
+ }
if (mHScale != 1 || mVScale != 1) {
pw.println(prefix + "mHScale=" + mHScale
+ " mVScale=" + mVScale);
@@ -5527,7 +5524,7 @@
mSurfacePosition);
if (mWallpaperScale != 1f) {
- final Rect bounds = getLastReportedBounds();
+ final Rect bounds = getParentFrame();
Matrix matrix = mTmpMatrix;
matrix.setTranslate(mXOffset, mYOffset);
matrix.postScale(mWallpaperScale, mWallpaperScale, bounds.exactCenterX(),
@@ -5640,6 +5637,14 @@
&& imeTarget.compareTo(this) <= 0;
return inTokenWithAndAboveImeTarget;
}
+
+ // The condition is for the system dialog not belonging to any Activity.
+ // (^FLAG_NOT_FOCUSABLE & FLAG_ALT_FOCUSABLE_IM) means the dialog is still focusable but
+ // should be placed above the IME window.
+ if ((mAttrs.flags & (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM))
+ == FLAG_ALT_FOCUSABLE_IM && isTrustedOverlay() && canAddInternalSystemWindow()) {
+ return true;
+ }
return false;
}
@@ -6262,13 +6267,6 @@
}
@Override
- public void unfreezeInsetsAfterStartInput() {
- if (mActivityRecord != null) {
- mActivityRecord.mImeInsetsFrozenUntilStartInput = false;
- }
- }
-
- @Override
public boolean isInputMethodClientFocus(int uid, int pid) {
return getDisplayContent().isInputMethodClientFocus(uid, pid);
}
diff --git a/services/core/jni/com_android_server_companion_virtual_InputController.cpp b/services/core/jni/com_android_server_companion_virtual_InputController.cpp
index b7a4fd1..4cb7a8f 100644
--- a/services/core/jni/com_android_server_companion_virtual_InputController.cpp
+++ b/services/core/jni/com_android_server_companion_virtual_InputController.cpp
@@ -81,7 +81,7 @@
static std::map<int, int> DPAD_KEY_CODE_MAPPING = {
{AKEYCODE_DPAD_DOWN, KEY_DOWN}, {AKEYCODE_DPAD_UP, KEY_UP},
{AKEYCODE_DPAD_LEFT, KEY_LEFT}, {AKEYCODE_DPAD_RIGHT, KEY_RIGHT},
- {AKEYCODE_DPAD_CENTER, KEY_SELECT},
+ {AKEYCODE_DPAD_CENTER, KEY_SELECT}, {AKEYCODE_BACK, KEY_BACK},
};
// Keycode mapping from https://source.android.com/devices/input/keyboard-devices
@@ -378,7 +378,7 @@
const std::map<int, int>& keyCodeMapping) {
auto keyCodeIterator = keyCodeMapping.find(androidKeyCode);
if (keyCodeIterator == keyCodeMapping.end()) {
- ALOGE("No supportive native keycode for androidKeyCode %d", androidKeyCode);
+ ALOGE("Unsupported native keycode for androidKeyCode %d", androidKeyCode);
return false;
}
auto actionIterator = KEY_ACTION_MAPPING.find(action);
@@ -512,4 +512,4 @@
methods, NELEM(methods));
}
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/services/credentials/java/com/android/server/credentials/ClearRequestSession.java b/services/credentials/java/com/android/server/credentials/ClearRequestSession.java
index 2141d51..595d03d 100644
--- a/services/credentials/java/com/android/server/credentials/ClearRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/ClearRequestSession.java
@@ -84,14 +84,12 @@
respondToClientWithResponseAndFinish();
}
- @Override
protected void onProviderResponseComplete(ComponentName componentName) {
if (!isAnyProviderPending()) {
onFinalResponseReceived(componentName, null);
}
}
- @Override
protected void onProviderTerminated(ComponentName componentName) {
if (!isAnyProviderPending()) {
processResponses();
@@ -138,6 +136,6 @@
}
}
// TODO: Replace with properly defined error type
- respondToClientWithErrorAndFinish("unknown", "All providers failed");
+ respondToClientWithErrorAndFinish("UNKNOWN", "All providers failed");
}
}
diff --git a/services/credentials/java/com/android/server/credentials/CreateRequestSession.java b/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
index 3091c0a..82c2358 100644
--- a/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
@@ -20,6 +20,7 @@
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
+import android.credentials.CreateCredentialException;
import android.credentials.CreateCredentialRequest;
import android.credentials.CreateCredentialResponse;
import android.credentials.CredentialManager;
@@ -86,20 +87,13 @@
}
@Override
- public void onProviderStatusChanged(ProviderSession.Status status,
- ComponentName componentName) {
- super.onProviderStatusChanged(status, componentName);
- }
-
- @Override
public void onFinalResponseReceived(ComponentName componentName,
@Nullable CreateCredentialResponse response) {
Log.i(TAG, "onFinalCredentialReceived from: " + componentName.flattenToString());
if (response != null) {
respondToClientWithResponseAndFinish(response);
} else {
- // TODO("Replace with properly defined error type)
- respondToClientWithErrorAndFinish("unknown_type",
+ respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_NO_CREDENTIAL,
"Invalid response");
}
}
@@ -113,7 +107,7 @@
@Override
public void onUiCancellation() {
// TODO("Replace with properly defined error type")
- respondToClientWithErrorAndFinish("user_cancelled",
+ respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_NO_CREDENTIAL,
"User cancelled the selector");
}
@@ -136,4 +130,22 @@
}
finishSession();
}
+
+ @Override
+ public void onProviderStatusChanged(ProviderSession.Status status,
+ ComponentName componentName) {
+ Log.i(TAG, "in onProviderStatusChanged with status: " + status);
+ // If all provider responses have been received, we can either need the UI,
+ // or we need to respond with error. The only other case is the entry being
+ // selected after the UI has been invoked which has a separate code path.
+ if (!isAnyProviderPending()) {
+ if (isUiInvocationNeeded()) {
+ Log.i(TAG, "in onProviderStatusChanged - isUiInvocationNeeded");
+ getProviderDataAndInitiateUi();
+ } else {
+ respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_NO_CREDENTIAL,
+ "No credentials available");
+ }
+ }
+ }
}
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
index 50ce1c3..aefd300 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
@@ -26,7 +26,9 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.credentials.ClearCredentialStateRequest;
+import android.credentials.CreateCredentialException;
import android.credentials.CreateCredentialRequest;
+import android.credentials.GetCredentialException;
import android.credentials.GetCredentialOption;
import android.credentials.GetCredentialRequest;
import android.credentials.IClearCredentialStateCallback;
@@ -50,6 +52,7 @@
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
+import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.server.infra.AbstractMasterSystemService;
@@ -73,6 +76,16 @@
private static final String TAG = "CredManSysService";
+ private final Context mContext;
+
+ /**
+ * Cache of system service list per user id.
+ */
+ @GuardedBy("mLock")
+ private final SparseArray<List<CredentialManagerServiceImpl>> mSystemServicesCacheList =
+ new SparseArray<>();
+
+
public CredentialManagerService(@NonNull Context context) {
super(
context,
@@ -80,6 +93,20 @@
context, Settings.Secure.CREDENTIAL_SERVICE, /* isMultipleMode= */ true),
null,
PACKAGE_UPDATE_POLICY_REFRESH_EAGER);
+ mContext = context;
+ }
+
+ @NonNull
+ @GuardedBy("mLock")
+ private List<CredentialManagerServiceImpl> constructSystemServiceListLocked(
+ int resolvedUserId) {
+ List<CredentialManagerServiceImpl> services = new ArrayList<>();
+ List<CredentialProviderInfo> credentialProviderInfos =
+ CredentialProviderInfo.getAvailableSystemServices(mContext, resolvedUserId);
+ credentialProviderInfos.forEach(info -> {
+ services.add(new CredentialManagerServiceImpl(this, mLock, resolvedUserId, info));
+ });
+ return services;
}
@Override
@@ -105,8 +132,10 @@
}
@Override // from AbstractMasterSystemService
+ @GuardedBy("mLock")
protected List<CredentialManagerServiceImpl> newServiceListLocked(
int resolvedUserId, boolean disabled, String[] serviceNames) {
+ getOrConstructSystemServiceListLock(resolvedUserId);
if (serviceNames == null || serviceNames.length == 0) {
Slog.i(TAG, "serviceNames sent in newServiceListLocked is null, or empty");
return new ArrayList<>();
@@ -155,13 +184,24 @@
// TODO("Iterate over system services and remove if needed")
}
+ @GuardedBy("mLock")
+ private List<CredentialManagerServiceImpl> getOrConstructSystemServiceListLock(
+ int resolvedUserId) {
+ List<CredentialManagerServiceImpl> services = mSystemServicesCacheList.get(resolvedUserId);
+ if (services == null || services.size() == 0) {
+ services = constructSystemServiceListLocked(resolvedUserId);
+ mSystemServicesCacheList.put(resolvedUserId, services);
+ }
+ return services;
+ }
+
private void runForUser(@NonNull final Consumer<CredentialManagerServiceImpl> c) {
final int userId = UserHandle.getCallingUserId();
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
final List<CredentialManagerServiceImpl> services =
- getServiceListForUserLocked(userId);
+ getAllCredentialProviderServicesLocked(userId);
for (CredentialManagerServiceImpl s : services) {
c.accept(s);
}
@@ -171,6 +211,19 @@
}
}
+ @GuardedBy("mLock")
+ private List<CredentialManagerServiceImpl> getAllCredentialProviderServicesLocked(
+ int userId) {
+ List<CredentialManagerServiceImpl> concatenatedServices = new ArrayList<>();
+ List<CredentialManagerServiceImpl> userConfigurableServices =
+ getServiceListForUserLocked(userId);
+ if (userConfigurableServices != null && !userConfigurableServices.isEmpty()) {
+ concatenatedServices.addAll(userConfigurableServices);
+ }
+ concatenatedServices.addAll(getOrConstructSystemServiceListLock(userId));
+ return concatenatedServices;
+ }
+
@SuppressWarnings("GuardedBy") // ErrorProne requires initiateProviderSessionForRequestLocked
// to be guarded by 'service.mLock', which is the same as mLock.
private List<ProviderSession> initiateProviderSessions(
@@ -235,8 +288,8 @@
if (providerSessions.isEmpty()) {
try {
- // TODO("Replace with properly defined error type")
- callback.onError("unknown_type", "No providers available to fulfill request.");
+ callback.onError(GetCredentialException.TYPE_NO_CREDENTIAL,
+ "No credentials available on this device.");
} catch (RemoteException e) {
Log.i(
TAG,
@@ -248,14 +301,10 @@
// Iterate over all provider sessions and invoke the request
providerSessions.forEach(
- providerGetSession -> {
- providerGetSession
- .getRemoteCredentialService()
- .onBeginGetCredential(
- (BeginGetCredentialRequest)
- providerGetSession.getProviderRequest(),
- /* callback= */ providerGetSession);
- });
+ providerGetSession -> providerGetSession
+ .getRemoteCredentialService().onBeginGetCredential(
+ (BeginGetCredentialRequest) providerGetSession.getProviderRequest(),
+ /*callback=*/providerGetSession));
return cancelTransport;
}
@@ -284,8 +333,8 @@
if (providerSessions.isEmpty()) {
try {
- // TODO("Replace with properly defined error type")
- callback.onError("unknown_type", "No providers available to fulfill request.");
+ callback.onError(CreateCredentialException.TYPE_NO_CREDENTIAL,
+ "No credentials available on this device.");
} catch (RemoteException e) {
Log.i(
TAG,
@@ -297,14 +346,12 @@
// Iterate over all provider sessions and invoke the request
providerSessions.forEach(
- providerCreateSession -> {
- providerCreateSession
- .getRemoteCredentialService()
- .onCreateCredential(
- (BeginCreateCredentialRequest)
- providerCreateSession.getProviderRequest(),
- /* callback= */ providerCreateSession);
- });
+ providerCreateSession -> providerCreateSession
+ .getRemoteCredentialService()
+ .onCreateCredential(
+ (BeginCreateCredentialRequest)
+ providerCreateSession.getProviderRequest(),
+ /* callback= */ providerCreateSession));
return cancelTransport;
}
@@ -402,7 +449,8 @@
if (providerSessions.isEmpty()) {
try {
// TODO("Replace with properly defined error type")
- callback.onError("unknown_type", "No providers available to fulfill request.");
+ callback.onError("UNKNOWN", "No crdentials available on this "
+ + "device");
} catch (RemoteException e) {
Log.i(
TAG,
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java b/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java
index 0fd1f19..546c48f 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerServiceImpl.java
@@ -58,7 +58,18 @@
return mInfo.getServiceInfo().getComponentName();
}
- @Override // from PerUserSystemService
+ CredentialManagerServiceImpl(
+ @NonNull CredentialManagerService master,
+ @NonNull Object lock, int userId, CredentialProviderInfo providerInfo) {
+ super(master, lock, userId);
+ Log.i(TAG, "in CredentialManagerServiceImpl constructed with system constructor: "
+ + providerInfo.isSystemProvider()
+ + " , " + providerInfo.getServiceInfo() == null ? "" :
+ providerInfo.getServiceInfo().getComponentName().flattenToString());
+ mInfo = providerInfo;
+ }
+
+ @Override // from PerUserSystemService when a new setting based service is to be created
@GuardedBy("mLock")
protected ServiceInfo newServiceInfoLocked(@NonNull ComponentName serviceComponent)
throws PackageManager.NameNotFoundException {
@@ -71,7 +82,9 @@
Log.i(TAG, "newServiceInfoLocked with null mInfo , "
+ serviceComponent.getPackageName());
}
- mInfo = new CredentialProviderInfo(getContext(), serviceComponent, mUserId);
+ mInfo = new CredentialProviderInfo(
+ getContext(), serviceComponent,
+ mUserId, /*isSystemProvider=*/false);
return mInfo.getServiceInfo();
}
diff --git a/services/credentials/java/com/android/server/credentials/GetRequestSession.java b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
index 06396e0..c7fa72c 100644
--- a/services/credentials/java/com/android/server/credentials/GetRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
@@ -19,6 +19,7 @@
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
+import android.credentials.GetCredentialException;
import android.credentials.GetCredentialRequest;
import android.credentials.GetCredentialResponse;
import android.credentials.IGetCredentialCallback;
@@ -80,12 +81,6 @@
}
}
- @Override // from provider session
- public void onProviderStatusChanged(ProviderSession.Status status,
- ComponentName componentName) {
- super.onProviderStatusChanged(status, componentName);
- }
-
@Override
public void onFinalResponseReceived(ComponentName componentName,
@Nullable GetCredentialResponse response) {
@@ -93,8 +88,7 @@
if (response != null) {
respondToClientWithResponseAndFinish(response);
} else {
- // TODO("Replace with no credentials/unknown type when ready)
- respondToClientWithErrorAndFinish("unknown_type",
+ respondToClientWithErrorAndFinish(GetCredentialException.TYPE_NO_CREDENTIAL,
"Invalid response from provider");
}
}
@@ -108,29 +102,46 @@
}
private void respondToClientWithResponseAndFinish(GetCredentialResponse response) {
- Log.i(TAG, "respondToClientWithResponseAndFinish");
try {
mClientCallback.onResponse(response);
} catch (RemoteException e) {
- e.printStackTrace();
+ Log.i(TAG, "Issue while responding to client with a response : " + e.getMessage());
}
finishSession();
}
private void respondToClientWithErrorAndFinish(String errorType, String errorMsg) {
- Log.i(TAG, "respondToClientWithErrorAndFinish");
try {
mClientCallback.onError(errorType, errorMsg);
} catch (RemoteException e) {
- e.printStackTrace();
+ Log.i(TAG, "Issue while responding to client with error : " + e.getMessage());
+
}
finishSession();
}
@Override
public void onUiCancellation() {
- // TODO("Replace with properly defined error type")
- respondToClientWithErrorAndFinish("user_canceled",
+ // TODO("Replace with user cancelled error type when ready")
+ respondToClientWithErrorAndFinish(GetCredentialException.TYPE_NO_CREDENTIAL,
"User cancelled the selector");
}
+
+ @Override
+ public void onProviderStatusChanged(ProviderSession.Status status,
+ ComponentName componentName) {
+ Log.i(TAG, "in onStatusChanged with status: " + status);
+ if (!isAnyProviderPending()) {
+ // If all provider responses have been received, we can either need the UI,
+ // or we need to respond with error. The only other case is the entry being
+ // selected after the UI has been invoked which has a separate code path.
+ if (isUiInvocationNeeded()) {
+ Log.i(TAG, "in onProviderStatusChanged - isUiInvocationNeeded");
+ getProviderDataAndInitiateUi();
+ } else {
+ respondToClientWithErrorAndFinish(GetCredentialException.TYPE_NO_CREDENTIAL,
+ "No credentials available");
+ }
+ }
+ }
}
diff --git a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
index 9163b8e..27eaa0b 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.content.Intent;
import android.credentials.CreateCredentialException;
+import android.credentials.CreateCredentialResponse;
import android.credentials.ui.CreateCredentialProviderData;
import android.credentials.ui.Entry;
import android.credentials.ui.ProviderPendingIntentResponse;
@@ -98,7 +99,7 @@
private ProviderCreateSession(
@NonNull Context context,
@NonNull CredentialProviderInfo info,
- @NonNull ProviderInternalCallback callbacks,
+ @NonNull ProviderInternalCallback<CreateCredentialResponse> callbacks,
@UserIdInt int userId,
@NonNull RemoteCredentialService remoteCredentialService,
@NonNull BeginCreateCredentialRequest beginCreateRequest,
@@ -180,9 +181,7 @@
onSaveEntrySelected(providerPendingIntentResponse);
} else {
Log.i(TAG, "Unexpected save entry key");
- // TODO("Replace with no credentials error type");
- invokeCallbackWithError("unknown_type",
- "Issue while retrieving credential");
+ invokeCallbackOnInternalInvalidState();
}
break;
case REMOTE_ENTRY_KEY:
@@ -190,9 +189,7 @@
onRemoteEntrySelected(providerPendingIntentResponse);
} else {
Log.i(TAG, "Unexpected remote entry key");
- // TODO("Replace with unknown/no credentials exception")
- invokeCallbackWithError("unknown_type",
- "Issue while retrieving credential");
+ invokeCallbackOnInternalInvalidState();
}
break;
default:
@@ -248,23 +245,16 @@
} else {
Log.i(TAG, "onSaveEntrySelected - no response or error found in pending "
+ "intent response");
- invokeCallbackWithError(
- // TODO("Replace with unknown/no credentials exception")
- "unknown",
- "Issue encountered while retrieving the credential");
+ invokeCallbackOnInternalInvalidState();
}
}
- private void invokeCallbackWithError(String errorType, @Nullable String message) {
- mCallbacks.onFinalErrorReceived(mComponentName, errorType, message);
- }
-
@Nullable
private CreateCredentialException maybeGetPendingIntentException(
ProviderPendingIntentResponse pendingIntentResponse) {
if (pendingIntentResponse == null) {
Log.i(TAG, "pendingIntentResponse is null");
- return null;
+ return new CreateCredentialException(CreateCredentialException.TYPE_NO_CREDENTIAL);
}
if (PendingIntentResultHandler.isValidResponse(pendingIntentResponse)) {
CreateCredentialException exception = PendingIntentResultHandler
@@ -276,8 +266,19 @@
} else {
Log.i(TAG, "Pending intent result code not Activity.RESULT_OK");
// TODO("Update with unknown exception when ready")
- return new CreateCredentialException("unknown");
+ return new CreateCredentialException(CreateCredentialException.TYPE_NO_CREDENTIAL);
}
return null;
}
+
+ /**
+ * When an invalid state occurs, e.g. entry mismatch or no response from provider,
+ * we send back a TYPE_NO_CREDENTIAL error as to the developer, it is the same as not
+ * getting any credentials back.
+ */
+ private void invokeCallbackOnInternalInvalidState() {
+ mCallbacks.onFinalErrorReceived(mComponentName,
+ CreateCredentialException.TYPE_NO_CREDENTIAL,
+ null);
+ }
}
diff --git a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
index 9846d83..de93af4 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
@@ -144,7 +144,7 @@
public ProviderGetSession(Context context,
CredentialProviderInfo info,
- ProviderInternalCallback callbacks,
+ ProviderInternalCallback<GetCredentialResponse> callbacks,
int userId, RemoteCredentialService remoteCredentialService,
BeginGetCredentialRequest beginGetRequest,
android.credentials.GetCredentialRequest completeGetRequest) {
@@ -195,9 +195,7 @@
CredentialEntry credentialEntry = mUiCredentialEntries.get(entryKey);
if (credentialEntry == null) {
Log.i(TAG, "Unexpected credential entry key");
- // TODO("Replace with no credentials/unknown exception")
- invokeCallbackWithError("unknown_type",
- "Issue while retrieving credential");
+ invokeCallbackOnInternalInvalidState();
return;
}
onCredentialEntrySelected(credentialEntry, providerPendingIntentResponse);
@@ -206,9 +204,7 @@
Action actionEntry = mUiActionsEntries.get(entryKey);
if (actionEntry == null) {
Log.i(TAG, "Unexpected action entry key");
- // TODO("Replace with no credentials/unknown exception")
- invokeCallbackWithError("unknown_type",
- "Issue while retrieving credential");
+ invokeCallbackOnInternalInvalidState();
return;
}
onActionEntrySelected(providerPendingIntentResponse);
@@ -218,9 +214,7 @@
onAuthenticationEntrySelected(providerPendingIntentResponse);
} else {
Log.i(TAG, "Unexpected authentication entry key");
- // TODO("Replace with no credentials/unknown exception")
- invokeCallbackWithError("unknown_type",
- "Issue while retrieving credential");
+ invokeCallbackOnInternalInvalidState();
}
break;
case REMOTE_ENTRY_KEY:
@@ -228,9 +222,7 @@
onRemoteEntrySelected(providerPendingIntentResponse);
} else {
Log.i(TAG, "Unexpected remote entry key");
- // TODO("Replace with no credentials/unknown exception")
- invokeCallbackWithError("unknown_type",
- "Issue while retrieving credential");
+ invokeCallbackOnInternalInvalidState();
}
break;
default:
@@ -238,11 +230,6 @@
}
}
- private void invokeCallbackWithError(String errorType, @Nullable String errorMessage) {
- // TODO: Determine what the error message should be
- mCallbacks.onFinalErrorReceived(mComponentName, errorType, errorMessage);
- }
-
@Override // Call from request session to data to be shown on the UI
@Nullable protected GetCredentialProviderData prepareUiData() throws IllegalArgumentException {
Log.i(TAG, "In prepareUiData");
@@ -288,7 +275,8 @@
String entryId = generateEntryId();
Entry authEntry = new Entry(
AUTHENTICATION_ACTION_ENTRY_KEY, entryId,
- authenticationAction.getSlice());
+ authenticationAction.getSlice(),
+ setUpFillInIntentForAuthentication());
mUiAuthenticationAction = new Pair<>(entryId, authenticationAction);
return authEntry;
}
@@ -324,6 +312,15 @@
return intent;
}
+ private Intent setUpFillInIntentForAuthentication() {
+ Intent intent = new Intent();
+ intent.putExtra(
+ CredentialProviderService
+ .EXTRA_BEGIN_GET_CREDENTIAL_REQUEST,
+ mProviderRequest);
+ return intent;
+ }
+
private List<Entry> prepareUiActionEntries(@Nullable List<Action> actions) {
List<Entry> actionEntries = new ArrayList<>();
for (Action action : actions) {
@@ -369,20 +366,15 @@
}
Log.i(TAG, "Pending intent response contains no credential, or error");
- // TODO("Replace with no credentials/unknown error when ready)
- invokeCallbackWithError("unknown_type",
- "Issue while retrieving credential");
+ invokeCallbackOnInternalInvalidState();
}
Log.i(TAG, "CredentialEntry does not have a credential or a pending intent result");
- // TODO("Replace with no credentials/unknown error when ready)
- invokeCallbackWithError("unknown_type",
- "Error encountered while retrieving the credential");
+ invokeCallbackOnInternalInvalidState();
}
private void onAuthenticationEntrySelected(
@Nullable ProviderPendingIntentResponse providerPendingIntentResponse) {
//TODO: Other provider intent statuses
- // Check if pending intent has an error
GetCredentialException exception = maybeGetPendingIntentException(
providerPendingIntentResponse);
if (exception != null) {
@@ -401,9 +393,7 @@
}
Log.i(TAG, "No error or respond found in pending intent response");
- // TODO("Replace with no credentials/unknown error when ready)
- invokeCallbackWithError("unknown type", "Issue"
- + " while retrieving credential");
+ invokeCallbackOnInternalInvalidState();
}
private void onActionEntrySelected(ProviderPendingIntentResponse
@@ -430,7 +420,7 @@
ProviderPendingIntentResponse pendingIntentResponse) {
if (pendingIntentResponse == null) {
Log.i(TAG, "pendingIntentResponse is null");
- return null;
+ return new GetCredentialException(GetCredentialException.TYPE_NO_CREDENTIAL);
}
if (PendingIntentResultHandler.isValidResponse(pendingIntentResponse)) {
GetCredentialException exception = PendingIntentResultHandler
@@ -441,9 +431,19 @@
}
} else {
Log.i(TAG, "Pending intent result code not Activity.RESULT_OK");
- // TODO("Update with unknown exception when ready")
- return new GetCredentialException("unknown");
+ return new GetCredentialException(GetCredentialException.TYPE_NO_CREDENTIAL);
}
return null;
}
+
+ /**
+ * When an invalid state occurs, e.g. entry mismatch or no response from provider,
+ * we send back a TYPE_NO_CREDENTIAL error as to the developer, it is the same as not
+ * getting any credentials back.
+ */
+ private void invokeCallbackOnInternalInvalidState() {
+ mCallbacks.onFinalErrorReceived(mComponentName,
+ GetCredentialException.TYPE_NO_CREDENTIAL,
+ null);
+ }
}
diff --git a/services/credentials/java/com/android/server/credentials/ProviderSession.java b/services/credentials/java/com/android/server/credentials/ProviderSession.java
index 93e816a..7036dfb 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderSession.java
@@ -191,6 +191,11 @@
return mProviderResponse != null || mProviderResponseSet;
}
+ protected void invokeCallbackWithError(String errorType, @Nullable String errorMessage) {
+ // TODO: Determine what the error message should be
+ mCallbacks.onFinalErrorReceived(mComponentName, errorType, errorMessage);
+ }
+
/** Update the response state stored with the provider session. */
@Nullable protected R getProviderResponse() {
return mProviderResponse;
diff --git a/services/credentials/java/com/android/server/credentials/RequestSession.java b/services/credentials/java/com/android/server/credentials/RequestSession.java
index f59a0ef..0c3c34e 100644
--- a/services/credentials/java/com/android/server/credentials/RequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/RequestSession.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.UserIdInt;
-import android.content.ComponentName;
import android.content.Context;
import android.credentials.ui.ProviderData;
import android.credentials.ui.UserSelectionDialogResult;
@@ -98,41 +97,6 @@
finishSession();
}
- protected void onProviderStatusChanged(ProviderSession.Status status,
- ComponentName componentName) {
- Log.i(TAG, "in onStatusChanged with status: " + status);
- if (ProviderSession.isTerminatingStatus(status)) {
- Log.i(TAG, "in onStatusChanged terminating status");
- onProviderTerminated(componentName);
- //TODO: Check if this was the provider we were waiting for and can invoke the UI now
- } else if (ProviderSession.isCompletionStatus(status)) {
- Log.i(TAG, "in onStatusChanged isCompletionStatus status");
- onProviderResponseComplete(componentName);
- } else if (ProviderSession.isUiInvokingStatus(status)) {
- Log.i(TAG, "in onStatusChanged isUiInvokingStatus status");
- onProviderResponseRequiresUi();
- }
- }
-
- protected void onProviderTerminated(ComponentName componentName) {
- //TODO: Implement
- }
-
- protected void onProviderResponseComplete(ComponentName componentName) {
- //TODO: Implement
- }
-
- protected void onProviderResponseRequiresUi() {
- Log.i(TAG, "in onProviderResponseComplete");
- // TODO: Determine whether UI has already been invoked, and deal accordingly
- if (!isAnyProviderPending()) {
- Log.i(TAG, "in onProviderResponseComplete - isResponseCompleteAcrossProviders");
- getProviderDataAndInitiateUi();
- } else {
- Log.i(TAG, "Can't invoke UI - waiting on some providers");
- }
- }
-
protected void finishSession() {
Log.i(TAG, "finishing session");
clearProviderSessions();
@@ -144,7 +108,7 @@
mProviders.clear();
}
- boolean isAnyProviderPending() {
+ protected boolean isAnyProviderPending() {
for (ProviderSession session : mProviders.values()) {
if (ProviderSession.isStatusWaitingForRemoteResponse(session.getStatus())) {
return true;
@@ -153,7 +117,22 @@
return false;
}
- private void getProviderDataAndInitiateUi() {
+ /**
+ * Returns true if at least one provider is ready for UI invocation, and no
+ * provider is pending a response.
+ */
+ boolean isUiInvocationNeeded() {
+ for (ProviderSession session : mProviders.values()) {
+ if (ProviderSession.isUiInvokingStatus(session.getStatus())) {
+ return true;
+ } else if (ProviderSession.isStatusWaitingForRemoteResponse(session.getStatus())) {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ void getProviderDataAndInitiateUi() {
Log.i(TAG, "In getProviderDataAndInitiateUi");
Log.i(TAG, "In getProviderDataAndInitiateUi providers size: " + mProviders.size());
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index cdb2e08..8be3df4 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -8742,21 +8742,6 @@
}
}
- private boolean isDeviceOwnerPackage(String packageName, int userId) {
- synchronized (getLockObject()) {
- return mOwners.hasDeviceOwner()
- && mOwners.getDeviceOwnerUserId() == userId
- && mOwners.getDeviceOwnerPackageName().equals(packageName);
- }
- }
-
- private boolean isProfileOwnerPackage(String packageName, int userId) {
- synchronized (getLockObject()) {
- return mOwners.hasProfileOwner(userId)
- && mOwners.getProfileOwnerPackage(userId).equals(packageName);
- }
- }
-
public boolean isProfileOwner(ComponentName who, int userId) {
final ComponentName profileOwner = mInjector.binderWithCleanCallingIdentity(() ->
getProfileOwnerAsUser(userId));
@@ -9315,7 +9300,7 @@
boolean hasProfileOwner = mOwners.hasProfileOwner(userId);
if (!hasProfileOwner) {
int managedUserId = getManagedUserId(userId);
- if (managedUserId == -1 && newState != STATE_USER_UNMANAGED) {
+ if (managedUserId < 0 && newState != STATE_USER_UNMANAGED) {
// No managed device, user or profile, so setting provisioning state makes
// no sense.
String error = "Not allowed to change provisioning state unless a "
@@ -12524,7 +12509,7 @@
/**
* @return the user ID of the managed user that is linked to the current user, if any.
- * Otherwise -1.
+ * Otherwise UserHandle.USER_NULL (-10000).
*/
public int getManagedUserId(@UserIdInt int callingUserId) {
if (VERBOSE_LOG) Slogf.v(LOG_TAG, "getManagedUserId: callingUserId=%d", callingUserId);
@@ -12537,7 +12522,26 @@
return ui.id;
}
if (VERBOSE_LOG) Slogf.v(LOG_TAG, "Managed user not found.");
- return -1;
+ return UserHandle.USER_NULL;
+ }
+
+ /**
+ * Returns the userId of the managed profile on the device.
+ * If none exists, return {@link UserHandle#USER_NULL}.
+ *
+ * We assume there is only one managed profile across all users
+ * on the device, which is true for now (HSUM or not) but could
+ * change in future.
+ */
+ private @UserIdInt int getManagedUserId() {
+ // On HSUM, there is only one main user and only the main user
+ // can have a managed profile (for now). On non-HSUM, only user 0
+ // can host the managed profile and user 0 is the main user.
+ // So in both cases, we could just get the main user and
+ // search for the profile user under it.
+ UserHandle mainUser = mUserManager.getMainUser();
+ if (mainUser == null) return UserHandle.USER_NULL;
+ return getManagedUserId(mainUser.getIdentifier());
}
@Override
@@ -16187,7 +16191,7 @@
return mOwners.getDeviceOwnerUserId();
} else {
return mInjector.binderWithCleanCallingIdentity(
- () -> getManagedUserId(UserHandle.USER_SYSTEM));
+ () -> getManagedUserId());
}
}
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 5b9460a..5c5442d 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -108,7 +108,6 @@
import com.android.server.am.ActivityManagerService;
import com.android.server.ambientcontext.AmbientContextManagerService;
import com.android.server.appbinding.AppBindingService;
-import com.android.server.art.ArtManagerLocal;
import com.android.server.art.ArtModuleServiceInitializer;
import com.android.server.art.DexUseManagerLocal;
import com.android.server.attention.AttentionManagerService;
@@ -132,8 +131,8 @@
import com.android.server.display.color.ColorDisplayService;
import com.android.server.dreams.DreamManagerService;
import com.android.server.emergency.EmergencyAffordanceService;
-import com.android.server.grammaticalinflection.GrammaticalInflectionService;
import com.android.server.gpu.GpuService;
+import com.android.server.grammaticalinflection.GrammaticalInflectionService;
import com.android.server.graphics.fonts.FontManagerService;
import com.android.server.hdmi.HdmiControlService;
import com.android.server.incident.IncidentCompanionService;
@@ -147,6 +146,7 @@
import com.android.server.media.MediaRouterService;
import com.android.server.media.metrics.MediaMetricsManagerService;
import com.android.server.media.projection.MediaProjectionManagerService;
+import com.android.server.net.NetworkManagementService;
import com.android.server.net.NetworkPolicyManagerService;
import com.android.server.net.watchlist.NetworkWatchlistService;
import com.android.server.notification.NotificationManagerService;
@@ -163,6 +163,7 @@
import com.android.server.pm.BackgroundInstallControlService;
import com.android.server.pm.CrossProfileAppsService;
import com.android.server.pm.DataLoaderManagerService;
+import com.android.server.pm.DexOptHelper;
import com.android.server.pm.DynamicCodeLoggingService;
import com.android.server.pm.Installer;
import com.android.server.pm.LauncherAppsService;
@@ -1250,7 +1251,7 @@
// DexUseManagerLocal needs to be loaded after PackageManagerLocal has been registered, but
// before PackageManagerService starts processing binder calls to notifyDexLoad.
LocalManagerRegistry.addManager(
- DexUseManagerLocal.class, DexUseManagerLocal.createInstance());
+ DexUseManagerLocal.class, DexUseManagerLocal.createInstance(mSystemContext));
t.traceEnd();
if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
@@ -2770,7 +2771,7 @@
t.traceEnd();
t.traceBegin("ArtManagerLocal");
- LocalManagerRegistry.addManager(ArtManagerLocal.class, new ArtManagerLocal(context));
+ DexOptHelper.initializeArtManagerLocal(context, mPackageManagerService);
t.traceEnd();
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_UWB)) {
diff --git a/services/permission/java/com/android/server/permission/access/collection/IndexedMap.kt b/services/permission/java/com/android/server/permission/access/collection/IndexedMap.kt
index f4e362c..998d206 100644
--- a/services/permission/java/com/android/server/permission/access/collection/IndexedMap.kt
+++ b/services/permission/java/com/android/server/permission/access/collection/IndexedMap.kt
@@ -148,6 +148,13 @@
return isChanged
}
+inline fun <K, V, R> IndexedMap<K, V>.mapIndexed(transform: (Int, K, V) -> R): IndexedList<R> =
+ IndexedList<R>().also { destination ->
+ forEachIndexed { index, key, value ->
+ transform(index, key, value).let { destination += it }
+ }
+ }
+
inline fun <K, V, R> IndexedMap<K, V>.mapNotNullIndexed(
transform: (Int, K, V) -> R?
): IndexedList<R> =
diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
index acd0a3c..903fad3 100644
--- a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
@@ -73,6 +73,7 @@
import com.android.server.pm.UserManagerService
import com.android.server.pm.parsing.pkg.AndroidPackageUtils
import com.android.server.pm.permission.LegacyPermission
+import com.android.server.pm.permission.Permission as LegacyPermission2
import com.android.server.pm.permission.LegacyPermissionSettings
import com.android.server.pm.permission.LegacyPermissionState
import com.android.server.pm.permission.PermissionManagerServiceInterface
@@ -1673,40 +1674,77 @@
context.getSystemService(PermissionControllerManager::class.java)!!.dump(fd, args)
}
- override fun getPermissionTEMP(
- permissionName: String
- ): com.android.server.pm.permission.Permission? {
- // TODO("Not yet implemented")
- return null
+ override fun getPermissionTEMP(permissionName: String): LegacyPermission2? {
+ val permission = service.getState {
+ with(policy) { getPermissions()[permissionName] }
+ } ?: return null
+
+ return LegacyPermission2(
+ permission.permissionInfo, permission.type, permission.isReconciled, permission.appId,
+ permission.gids, permission.areGidsPerUser
+ )
}
- override fun getLegacyPermissions(): List<LegacyPermission> {
- // TODO("Not yet implemented")
- return emptyList()
- }
+ override fun getLegacyPermissions(): List<LegacyPermission> =
+ service.getState {
+ with(policy) { getPermissions() }
+ }.mapIndexed { _, _, permission ->
+ LegacyPermission(
+ permission.permissionInfo, permission.type, permission.appId, permission.gids
+ )
+ }
override fun readLegacyPermissionsTEMP(legacyPermissionSettings: LegacyPermissionSettings) {
// Package settings has been read when this method is called.
service.initialize()
- // TODO("Not yet implemented")
}
override fun writeLegacyPermissionsTEMP(legacyPermissionSettings: LegacyPermissionSettings) {
- // TODO("Not yet implemented")
+ service.getState {
+ val permissions = with(policy) { getPermissions() }
+ legacyPermissionSettings.replacePermissions(toLegacyPermissions(permissions))
+ val permissionTrees = with(policy) { getPermissionTrees() }
+ legacyPermissionSettings.replacePermissionTrees(toLegacyPermissions(permissionTrees))
+ }
}
+ private fun toLegacyPermissions(
+ permissions: IndexedMap<String, Permission>
+ ): List<LegacyPermission> =
+ permissions.mapIndexed { _, _, permission ->
+ // We don't need to provide UID and GIDs, which are only retrieved when dumping.
+ LegacyPermission(
+ permission.permissionInfo, permission.type, 0, EmptyArray.INT
+ )
+ }
+
override fun getLegacyPermissionState(appId: Int): LegacyPermissionState {
- // TODO("Not yet implemented")
- return LegacyPermissionState()
+ val legacyState = LegacyPermissionState()
+ val userIds = userManagerService.userIdsIncludingPreCreated
+ service.getState {
+ val permissions = with(policy) { getPermissions() }
+ userIds.forEachIndexed { _, userId ->
+ val permissionFlags = with(policy) { getUidPermissionFlags(appId, userId) }
+ ?: return@forEachIndexed
+
+ permissionFlags.forEachIndexed permissionFlags@{ _, permissionName, flags ->
+ val permission = permissions[permissionName] ?: return@permissionFlags
+ val legacyPermissionState = LegacyPermissionState.PermissionState(
+ permissionName,
+ permission.isRuntime,
+ PermissionFlags.isPermissionGranted(flags),
+ PermissionFlags.toApiFlags(flags)
+ )
+ legacyState.putPermissionState(legacyPermissionState, userId)
+ }
+ }
+ }
+ return legacyState
}
- override fun readLegacyPermissionStateTEMP() {
- // TODO("Not yet implemented")
- }
+ override fun readLegacyPermissionStateTEMP() {}
- override fun writeLegacyPermissionStateTEMP() {
- // TODO("Not yet implemented")
- }
+ override fun writeLegacyPermissionStateTEMP() {}
override fun onSystemReady() {
// TODO STOPSHIP privappPermissionsViolationsfix check
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/AppsFilterImplTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/AppsFilterImplTest.java
index 5e5e7e3..7909ba4 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/AppsFilterImplTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/AppsFilterImplTest.java
@@ -283,7 +283,7 @@
assertFalse(
appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
- watcher.verifyNoChangeReported("shouldFilterAplication");
+ watcher.verifyNoChangeReported("shouldFilterApplication");
}
@Test
@@ -1024,7 +1024,10 @@
DUMMY_TARGET_APPID);
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
DUMMY_CALLING_APPID,
- withInstallSource(target.getPackageName(), null, null, INVALID_UID, null, false));
+ withInstallSource(target.getPackageName(), null /* originatingPackageName */,
+ null /* installerPackageName */, INVALID_UID,
+ null /* updateOwnerPackageName */, null /* installerAttributionTag */,
+ false /* isInitiatingPackageUninstalled */));
assertFalse(
appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
@@ -1043,7 +1046,10 @@
DUMMY_TARGET_APPID);
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
DUMMY_CALLING_APPID,
- withInstallSource(target.getPackageName(), null, null, INVALID_UID, null, true));
+ withInstallSource(target.getPackageName(), null /* originatingPackageName */,
+ null /* installerPackageName */, INVALID_UID,
+ null /* updateOwnerPackageName */, null /* installerAttributionTag */,
+ true /* isInitiatingPackageUninstalled */));
assertTrue(
appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
@@ -1066,14 +1072,16 @@
DUMMY_TARGET_APPID);
watcher.verifyChangeReported("add package");
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
- DUMMY_CALLING_APPID, withInstallSource(null, target.getPackageName(), null,
- INVALID_UID, null, false));
+ DUMMY_CALLING_APPID, withInstallSource(null /* initiatingPackageName */,
+ target.getPackageName(), null /* installerPackageName */, INVALID_UID,
+ null /* updateOwnerPackageName */, null /* installerAttributionTag */,
+ false /* isInitiatingPackageUninstalled */));
watcher.verifyChangeReported("add package");
assertTrue(
appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
- watcher.verifyNoChangeReported("shouldFilterAplication");
+ watcher.verifyNoChangeReported("shouldFilterApplication");
}
@Test
@@ -1092,14 +1100,46 @@
DUMMY_TARGET_APPID);
watcher.verifyChangeReported("add package");
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
- DUMMY_CALLING_APPID, withInstallSource(null, null, target.getPackageName(),
- DUMMY_TARGET_APPID, null, false));
+ DUMMY_CALLING_APPID, withInstallSource(null /* initiatingPackageName */,
+ null /* originatingPackageName */, target.getPackageName(),
+ DUMMY_TARGET_APPID, null /* updateOwnerPackageName */,
+ null /* installerAttributionTag */,
+ false /* isInitiatingPackageUninstalled */));
watcher.verifyChangeReported("add package");
assertFalse(
appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
- watcher.verifyNoChangeReported("shouldFilterAplication");
+ watcher.verifyNoChangeReported("shouldFilterApplication");
+ }
+
+ @Test
+ public void testUpdateOwner_DoesntFilter() throws Exception {
+ final AppsFilterImpl appsFilter =
+ new AppsFilterImpl(mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */
+ false, /* overlayProvider */ null, mMockHandler);
+ final WatchableTester watcher = new WatchableTester(appsFilter, "onChange");
+ watcher.register();
+ simulateAddBasicAndroid(appsFilter);
+ watcher.verifyChangeReported("addBasicAndroid");
+ appsFilter.onSystemReady(mPmInternal);
+ watcher.verifyChangeReported("systemReady");
+
+ PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
+ DUMMY_TARGET_APPID);
+ watcher.verifyChangeReported("add package");
+ PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package"),
+ DUMMY_CALLING_APPID, withInstallSource(null /* initiatingPackageName */,
+ null /* originatingPackageName */, null /* installerPackageName */,
+ INVALID_UID, target.getPackageName(),
+ null /* installerAttributionTag */,
+ false /* isInitiatingPackageUninstalled */));
+ watcher.verifyChangeReported("add package");
+
+ assertFalse(
+ appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
+ watcher.verifyNoChangeReported("shouldFilterApplication");
}
@Test
@@ -1128,7 +1168,7 @@
assertFalse(
appsFilter.shouldFilterApplication(mSnapshot, DUMMY_TARGET_APPID, target,
instrumentation, SYSTEM_USER));
- watcher.verifyNoChangeReported("shouldFilterAplication");
+ watcher.verifyNoChangeReported("shouldFilterApplication");
}
@Test
@@ -1679,10 +1719,12 @@
private WithSettingBuilder withInstallSource(String initiatingPackageName,
String originatingPackageName, String installerPackageName, int installerPackageUid,
- String installerAttributionTag, boolean isInitiatingPackageUninstalled) {
+ String updateOwnerPackageName, String installerAttributionTag,
+ boolean isInitiatingPackageUninstalled) {
final InstallSource installSource = InstallSource.create(initiatingPackageName,
originatingPackageName, installerPackageName, installerPackageUid,
- installerAttributionTag, /* isOrphaned= */ false, isInitiatingPackageUninstalled);
+ updateOwnerPackageName, installerAttributionTag, /* isOrphaned= */ false,
+ isInitiatingPackageUninstalled);
return setting -> setting.setInstallSource(installSource);
}
}
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.java
index 4da082e..98655c8 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.java
@@ -167,8 +167,8 @@
params.isMultiPackage = true;
}
InstallSource installSource = InstallSource.create("testInstallInitiator",
- "testInstallOriginator", "testInstaller", -1, "testAttributionTag",
- PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
+ "testInstallOriginator", "testInstaller", -1, "testUpdateOwner",
+ "testAttributionTag", PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
return new PackageInstallerSession(
/* callback */ null,
/* context */null,
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt
index 8e1ca3c..0b7020c7 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt
@@ -218,6 +218,7 @@
AndroidPackage::isAllowClearUserDataOnFailedRestore,
AndroidPackage::isAllowNativeHeapPointerTagging,
AndroidPackage::isAllowTaskReparenting,
+ AndroidPackage::isAllowUpdateOwnership,
AndroidPackage::isBackupInForeground,
AndroidPackage::isHardwareAccelerated,
AndroidPackage::isCantSaveState,
diff --git a/services/tests/RemoteProvisioningServiceTests/src/com/android/server/security/rkp/RemoteProvisioningRegistrationTest.java b/services/tests/RemoteProvisioningServiceTests/src/com/android/server/security/rkp/RemoteProvisioningRegistrationTest.java
index 470f2be..7b361d3 100644
--- a/services/tests/RemoteProvisioningServiceTests/src/com/android/server/security/rkp/RemoteProvisioningRegistrationTest.java
+++ b/services/tests/RemoteProvisioningServiceTests/src/com/android/server/security/rkp/RemoteProvisioningRegistrationTest.java
@@ -34,7 +34,9 @@
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
import android.os.OutcomeReceiver;
+import android.os.RemoteException;
import android.security.rkp.IGetKeyCallback;
+import android.security.rkp.IStoreUpgradedKeyCallback;
import android.security.rkp.service.RegistrationProxy;
import android.security.rkp.service.RemotelyProvisionedKey;
@@ -72,6 +74,12 @@
return answerVoid(answer);
}
+ // answerVoid wrapper for mocking storeUpgradeKeyAsync.
+ static Answer<Void> answerStoreUpgradedKeyAsync(
+ VoidAnswer4<byte[], byte[], Executor, OutcomeReceiver<Void, Exception>> answer) {
+ return answerVoid(answer);
+ }
+
// matcher helper, making it easier to match the different key types
private android.security.rkp.RemotelyProvisionedKey matches(
RemotelyProvisionedKey expectedKey) {
@@ -178,16 +186,63 @@
@Test
public void storeUpgradedKeySuccess() throws Exception {
- // TODO(b/262748535)
+ doAnswer(
+ answerStoreUpgradedKeyAsync((oldBlob, newBlob, executor, receiver) ->
+ executor.execute(() -> receiver.onResult(null))))
+ .when(mRegistrationProxy)
+ .storeUpgradedKeyAsync(any(), any(), any(), any());
+
+ IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
+ mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
+ verify(callback).onSuccess();
+ verifyNoMoreInteractions(callback);
}
@Test
public void storeUpgradedKeyFails() throws Exception {
- // TODO(b/262748535)
+ final String errorString = "this is a failure";
+ doAnswer(
+ answerStoreUpgradedKeyAsync((oldBlob, newBlob, executor, receiver) ->
+ executor.execute(() -> receiver.onError(new RemoteException(errorString)))))
+ .when(mRegistrationProxy)
+ .storeUpgradedKeyAsync(any(), any(), any(), any());
+
+ IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
+ mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
+ verify(callback).onError(errorString);
+ verifyNoMoreInteractions(callback);
}
@Test
- public void storeUpgradedCatchesExceptionFromProxy() throws Exception {
- // TODO(b/262748535)
+ public void storeUpgradedKeyHandlesException() throws Exception {
+ final String errorString = "all aboard the failboat, toot toot";
+ doThrow(new IllegalArgumentException(errorString))
+ .when(mRegistrationProxy)
+ .storeUpgradedKeyAsync(any(), any(), any(), any());
+
+ IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
+ mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
+ verify(callback).onError(errorString);
+ verifyNoMoreInteractions(callback);
}
+
+ @Test
+ public void storeUpgradedKeyDuplicateCallback() throws Exception {
+ IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
+
+ doAnswer(
+ answerStoreUpgradedKeyAsync((oldBlob, newBlob, executor, receiver) -> {
+ assertThrows(IllegalArgumentException.class,
+ () -> mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0],
+ callback));
+ executor.execute(() -> receiver.onResult(null));
+ }))
+ .when(mRegistrationProxy)
+ .storeUpgradedKeyAsync(any(), any(), any(), any());
+
+ mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
+ verify(callback).onSuccess();
+ verifyNoMoreInteractions(callback);
+ }
+
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
index 77127c5..92570aa 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
@@ -22,7 +22,6 @@
import static com.android.server.am.BroadcastProcessQueue.REASON_CONTAINS_MANIFEST;
import static com.android.server.am.BroadcastProcessQueue.REASON_CONTAINS_ORDERED;
import static com.android.server.am.BroadcastProcessQueue.REASON_CONTAINS_PRIORITIZED;
-import static com.android.server.am.BroadcastProcessQueue.REASON_CONTAINS_RESULT_TO;
import static com.android.server.am.BroadcastProcessQueue.insertIntoRunnableList;
import static com.android.server.am.BroadcastProcessQueue.removeFromRunnableList;
import static com.android.server.am.BroadcastQueueTest.CLASS_BLUE;
@@ -115,8 +114,29 @@
mConstants.DELAY_NORMAL_MILLIS = 10_000;
mConstants.DELAY_CACHED_MILLIS = 120_000;
+ final BroadcastSkipPolicy emptySkipPolicy = new BroadcastSkipPolicy(mAms) {
+ public boolean shouldSkip(BroadcastRecord r, Object o) {
+ // Ignored
+ return false;
+ }
+ public String shouldSkipMessage(BroadcastRecord r, Object o) {
+ // Ignored
+ return null;
+ }
+ public boolean disallowBackgroundStart(BroadcastRecord r) {
+ // Ignored
+ return false;
+ }
+ };
+ final BroadcastHistory emptyHistory = new BroadcastHistory(mConstants) {
+ public void addBroadcastToHistoryLocked(BroadcastRecord original) {
+ // Ignored
+ }
+ };
+
+
mImpl = new BroadcastQueueModernImpl(mAms, mHandlerThread.getThreadHandler(),
- mConstants, mConstants);
+ mConstants, mConstants, emptySkipPolicy, emptyHistory);
doReturn(1L).when(mQueue1).getRunnableAt();
doReturn(2L).when(mQueue2).getRunnableAt();
@@ -200,7 +220,8 @@
private void enqueueOrReplaceBroadcast(BroadcastProcessQueue queue,
BroadcastRecord record, int recordIndex, long enqueueTime) {
- queue.enqueueOrReplaceBroadcast(record, recordIndex, null /* replacedBroadcastConsumer */);
+ queue.enqueueOrReplaceBroadcast(record, recordIndex,
+ null /* replacedBroadcastConsumer */, false);
record.enqueueTime = enqueueTime;
}
@@ -330,7 +351,8 @@
final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
final BroadcastRecord airplaneRecord = makeBroadcastRecord(airplane,
List.of(makeMockRegisteredReceiver()));
- queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, null /* replacedBroadcastConsumer */);
+ queue.enqueueOrReplaceBroadcast(airplaneRecord, 0,
+ null /* replacedBroadcastConsumer */, false);
queue.setProcessCached(false);
final long notCachedRunnableAt = queue.getRunnableAt();
@@ -352,12 +374,14 @@
// enqueue a bg-priority broadcast then a fg-priority one
final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
final BroadcastRecord timezoneRecord = makeBroadcastRecord(timezone);
- queue.enqueueOrReplaceBroadcast(timezoneRecord, 0, null /* replacedBroadcastConsumer */);
+ queue.enqueueOrReplaceBroadcast(timezoneRecord, 0,
+ null /* replacedBroadcastConsumer */, false);
final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
airplane.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
final BroadcastRecord airplaneRecord = makeBroadcastRecord(airplane);
- queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, null /* replacedBroadcastConsumer */);
+ queue.enqueueOrReplaceBroadcast(airplaneRecord, 0,
+ null /* replacedBroadcastConsumer */, false);
// verify that:
// (a) the queue is immediately runnable by existence of a fg-priority broadcast
@@ -388,7 +412,8 @@
final BroadcastRecord airplaneRecord = makeBroadcastRecord(airplane, null,
List.of(withPriority(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 10),
withPriority(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 0)), true);
- queue.enqueueOrReplaceBroadcast(airplaneRecord, 1, null /* replacedBroadcastConsumer */);
+ queue.enqueueOrReplaceBroadcast(airplaneRecord, 1,
+ null /* replacedBroadcastConsumer */, false);
assertFalse(queue.isRunnable());
assertEquals(BroadcastProcessQueue.REASON_BLOCKED, queue.getRunnableAtReason());
@@ -411,7 +436,8 @@
final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
final BroadcastRecord airplaneRecord = makeBroadcastRecord(airplane,
List.of(makeMockRegisteredReceiver()));
- queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, null /* replacedBroadcastConsumer */);
+ queue.enqueueOrReplaceBroadcast(airplaneRecord, 0,
+ null /* replacedBroadcastConsumer */, false);
mConstants.MAX_PENDING_BROADCASTS = 128;
queue.invalidateRunnableAt();
@@ -437,11 +463,13 @@
new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED),
List.of(makeMockRegisteredReceiver()));
- queue.enqueueOrReplaceBroadcast(lazyRecord, 0, null /* replacedBroadcastConsumer */);
+ queue.enqueueOrReplaceBroadcast(lazyRecord, 0,
+ null /* replacedBroadcastConsumer */, false);
assertThat(queue.getRunnableAt()).isGreaterThan(lazyRecord.enqueueTime);
assertThat(queue.getRunnableAtReason()).isNotEqualTo(testRunnableAtReason);
- queue.enqueueOrReplaceBroadcast(testRecord, 0, null /* replacedBroadcastConsumer */);
+ queue.enqueueOrReplaceBroadcast(testRecord, 0,
+ null /* replacedBroadcastConsumer */, false);
assertThat(queue.getRunnableAt()).isAtMost(testRecord.enqueueTime);
assertThat(queue.getRunnableAtReason()).isEqualTo(testRunnableAtReason);
}
@@ -459,13 +487,6 @@
}
@Test
- public void testRunnableAt_Cached_ResultTo() {
- final IIntentReceiver resultTo = mock(IIntentReceiver.class);
- doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), null,
- List.of(makeMockRegisteredReceiver()), resultTo, false), REASON_CONTAINS_RESULT_TO);
- }
-
- @Test
public void testRunnableAt_Cached_Foreground() {
final Intent foregroundIntent = new Intent();
foregroundIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
@@ -511,25 +532,25 @@
queue.enqueueOrReplaceBroadcast(
makeBroadcastRecord(new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED)
.addFlags(Intent.FLAG_RECEIVER_OFFLOAD)), 0,
- null /* replacedBroadcastConsumer */);
+ null /* replacedBroadcastConsumer */, false);
queue.enqueueOrReplaceBroadcast(
makeBroadcastRecord(new Intent(Intent.ACTION_TIMEZONE_CHANGED)), 0,
- null /* replacedBroadcastConsumer */);
+ null /* replacedBroadcastConsumer */, false);
queue.enqueueOrReplaceBroadcast(
makeBroadcastRecord(new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)), 0,
- null /* replacedBroadcastConsumer */);
+ null /* replacedBroadcastConsumer */, false);
queue.enqueueOrReplaceBroadcast(
makeBroadcastRecord(new Intent(Intent.ACTION_ALARM_CHANGED)
.addFlags(Intent.FLAG_RECEIVER_OFFLOAD)), 0,
- null /* replacedBroadcastConsumer */);
+ null /* replacedBroadcastConsumer */, false);
queue.enqueueOrReplaceBroadcast(
makeBroadcastRecord(new Intent(Intent.ACTION_TIME_TICK)), 0,
- null /* replacedBroadcastConsumer */);
+ null /* replacedBroadcastConsumer */, false);
queue.enqueueOrReplaceBroadcast(
makeBroadcastRecord(new Intent(Intent.ACTION_LOCALE_CHANGED)
.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)), 0,
- null /* replacedBroadcastConsumer */);
+ null /* replacedBroadcastConsumer */, false);
queue.makeActiveNextPending();
assertEquals(Intent.ACTION_LOCKED_BOOT_COMPLETED, queue.getActive().intent.getAction());
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
index 8d9dda08..64be0f7 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
@@ -357,6 +357,11 @@
}
receiversToSkip.add(o);
}
+ public boolean disallowBackgroundStart(BroadcastRecord r) {
+ // Ignored
+ return false;
+ }
+
}
private class TestInjector extends Injector {
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
index f2cba40..2a790a1 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
@@ -80,6 +80,8 @@
@Mock
private DisplayBlanker mDisplayBlankerMock;
@Mock
+ private HighBrightnessModeMetadata mHighBrightnessModeMetadataMock;
+ @Mock
private LogicalDisplay mLogicalDisplayMock;
@Mock
private DisplayDevice mDisplayDeviceMock;
@@ -169,7 +171,7 @@
mContextSpy, mInjector, mDisplayPowerCallbacksMock, mHandler,
mSensorManagerMock, mDisplayBlankerMock, mLogicalDisplayMock,
mBrightnessTrackerMock, mBrightnessSettingMock, () -> {
- });
+ }, mHighBrightnessModeMetadataMock);
when(mDisplayPowerStateMock.getScreenState()).thenReturn(Display.STATE_ON);
// send a display power request
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
index 4f8cb88..d99ed78 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -84,6 +84,8 @@
@Mock
private DisplayDevice mDisplayDeviceMock;
@Mock
+ private HighBrightnessModeMetadata mHighBrightnessModeMetadataMock;
+ @Mock
private BrightnessTracker mBrightnessTrackerMock;
@Mock
private BrightnessSetting mBrightnessSettingMock;
@@ -151,7 +153,7 @@
mContextSpy, mInjector, mDisplayPowerCallbacksMock, mHandler,
mSensorManagerMock, mDisplayBlankerMock, mLogicalDisplayMock,
mBrightnessTrackerMock, mBrightnessSettingMock, () -> {
- });
+ }, mHighBrightnessModeMetadataMock);
when(mDisplayPowerStateMock.getScreenState()).thenReturn(Display.STATE_ON);
// send a display power request
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/JobConcurrencyManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/JobConcurrencyManagerTest.java
index 79fbc87..7e1a42b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/JobConcurrencyManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/JobConcurrencyManagerTest.java
@@ -213,7 +213,7 @@
mJobConcurrencyManager.prepareForAssignmentDeterminationLocked(
idle, preferredUidOnly, stoppable, assignmentInfo);
- assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, idle.size());
+ assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, idle.size());
assertEquals(0, preferredUidOnly.size());
assertEquals(0, stoppable.size());
assertEquals(0, assignmentInfo.minPreferredUidOnlyWaitingTimeMs);
@@ -222,7 +222,7 @@
@Test
public void testPrepareForAssignmentDetermination_onlyPendingJobs() {
- for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT; ++i) {
+ for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT; ++i) {
JobStatus job = createJob(mDefaultUserId * UserHandle.PER_USER_RANGE + i);
mPendingJobQueue.add(job);
}
@@ -235,7 +235,7 @@
mJobConcurrencyManager.prepareForAssignmentDeterminationLocked(
idle, preferredUidOnly, stoppable, assignmentInfo);
- assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, idle.size());
+ assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, idle.size());
assertEquals(0, preferredUidOnly.size());
assertEquals(0, stoppable.size());
assertEquals(0, assignmentInfo.minPreferredUidOnlyWaitingTimeMs);
@@ -244,7 +244,7 @@
@Test
public void testPrepareForAssignmentDetermination_onlyPreferredUidOnly() {
- for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT; ++i) {
+ for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT; ++i) {
JobStatus job = createJob(mDefaultUserId * UserHandle.PER_USER_RANGE + i);
mJobConcurrencyManager.addRunningJobForTesting(job);
}
@@ -262,7 +262,7 @@
idle, preferredUidOnly, stoppable, assignmentInfo);
assertEquals(0, idle.size());
- assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, preferredUidOnly.size());
+ assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, preferredUidOnly.size());
assertEquals(0, stoppable.size());
assertEquals(0, assignmentInfo.minPreferredUidOnlyWaitingTimeMs);
assertEquals(0, assignmentInfo.numRunningImmediacyPrivileged);
@@ -270,7 +270,7 @@
@Test
public void testPrepareForAssignmentDetermination_onlyStartedWithImmediacyPrivilege() {
- for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT; ++i) {
+ for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT; ++i) {
JobStatus job = createJob(mDefaultUserId * UserHandle.PER_USER_RANGE + i);
job.startedWithImmediacyPrivilege = true;
mJobConcurrencyManager.addRunningJobForTesting(job);
@@ -289,19 +289,19 @@
idle, preferredUidOnly, stoppable, assignmentInfo);
assertEquals(0, idle.size());
- assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT / 2, preferredUidOnly.size());
- assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT / 2, stoppable.size());
+ assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT / 2, preferredUidOnly.size());
+ assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT / 2, stoppable.size());
assertEquals(0, assignmentInfo.minPreferredUidOnlyWaitingTimeMs);
- assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT,
+ assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT,
assignmentInfo.numRunningImmediacyPrivileged);
}
@Test
public void testDetermineAssignments_allRegular() throws Exception {
- setConcurrencyConfig(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT,
- new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT));
+ setConcurrencyConfig(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT,
+ new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT));
final ArraySet<JobStatus> jobs = new ArraySet<>();
- for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT; ++i) {
+ for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT; ++i) {
final int uid = mDefaultUserId * UserHandle.PER_USER_RANGE + i;
final String sourcePkgName = "com.source.package." + UserHandle.getAppId(uid);
setPackageUid(sourcePkgName, uid);
@@ -322,7 +322,7 @@
.determineAssignmentsLocked(changed, idle, preferredUidOnly, stoppable,
assignmentInfo);
- assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, changed.size());
+ assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, changed.size());
for (int i = changed.size() - 1; i >= 0; --i) {
jobs.remove(changed.valueAt(i).newJob);
}
@@ -332,16 +332,16 @@
@Test
public void testDetermineAssignments_allPreferredUidOnly_shortTimeLeft() throws Exception {
mConfigBuilder.setBoolean(JobConcurrencyManager.KEY_ENABLE_MAX_WAIT_TIME_BYPASS, true);
- setConcurrencyConfig(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT,
- new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT));
- for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT * 2; ++i) {
+ setConcurrencyConfig(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT,
+ new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT));
+ for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT * 2; ++i) {
final int uid = mDefaultUserId * UserHandle.PER_USER_RANGE + i;
final String sourcePkgName = "com.source.package." + UserHandle.getAppId(uid);
setPackageUid(sourcePkgName, uid);
final JobStatus job = createJob(uid, sourcePkgName);
spyOn(job);
doReturn(i % 2 == 0).when(job).shouldTreatAsExpeditedJob();
- if (i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT) {
+ if (i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT) {
mJobConcurrencyManager.addRunningJobForTesting(job);
} else {
mPendingJobQueue.add(job);
@@ -366,30 +366,30 @@
mJobConcurrencyManager.prepareForAssignmentDeterminationLocked(
idle, preferredUidOnly, stoppable, assignmentInfo);
assertEquals(remainingTimeMs, assignmentInfo.minPreferredUidOnlyWaitingTimeMs);
- assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, preferredUidOnly.size());
+ assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, preferredUidOnly.size());
mJobConcurrencyManager
.determineAssignmentsLocked(changed, idle, preferredUidOnly, stoppable,
assignmentInfo);
- assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, preferredUidOnly.size());
+ assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, preferredUidOnly.size());
assertEquals(0, changed.size());
}
@Test
public void testDetermineAssignments_allPreferredUidOnly_mediumTimeLeft() throws Exception {
mConfigBuilder.setBoolean(JobConcurrencyManager.KEY_ENABLE_MAX_WAIT_TIME_BYPASS, true);
- setConcurrencyConfig(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT,
- new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT));
+ setConcurrencyConfig(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT,
+ new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT));
final ArraySet<JobStatus> jobs = new ArraySet<>();
- for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT * 2; ++i) {
+ for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT * 2; ++i) {
final int uid = mDefaultUserId * UserHandle.PER_USER_RANGE + i;
final String sourcePkgName = "com.source.package." + UserHandle.getAppId(uid);
setPackageUid(sourcePkgName, uid);
final JobStatus job = createJob(uid, sourcePkgName);
spyOn(job);
doReturn(i % 2 == 0).when(job).shouldTreatAsExpeditedJob();
- if (i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT) {
+ if (i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT) {
mJobConcurrencyManager.addRunningJobForTesting(job);
} else {
mPendingJobQueue.add(job);
@@ -417,17 +417,17 @@
mJobConcurrencyManager.prepareForAssignmentDeterminationLocked(
idle, preferredUidOnly, stoppable, assignmentInfo);
assertEquals(remainingTimeMs, assignmentInfo.minPreferredUidOnlyWaitingTimeMs);
- assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, preferredUidOnly.size());
+ assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, preferredUidOnly.size());
mJobConcurrencyManager
.determineAssignmentsLocked(changed, idle, preferredUidOnly, stoppable,
assignmentInfo);
- assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, preferredUidOnly.size());
+ assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, preferredUidOnly.size());
for (int i = changed.size() - 1; i >= 0; --i) {
jobs.remove(changed.valueAt(i).newJob);
}
- assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT - 1, jobs.size());
+ assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT - 1, jobs.size());
assertEquals(1, changed.size());
JobStatus assignedJob = changed.valueAt(0).newJob;
assertTrue(assignedJob.shouldTreatAsExpeditedJob());
@@ -436,17 +436,17 @@
@Test
public void testDetermineAssignments_allPreferredUidOnly_longTimeLeft() throws Exception {
mConfigBuilder.setBoolean(JobConcurrencyManager.KEY_ENABLE_MAX_WAIT_TIME_BYPASS, true);
- setConcurrencyConfig(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT,
- new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT));
+ setConcurrencyConfig(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT,
+ new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT));
final ArraySet<JobStatus> jobs = new ArraySet<>();
- for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT * 2; ++i) {
+ for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT * 2; ++i) {
final int uid = mDefaultUserId * UserHandle.PER_USER_RANGE + i;
final String sourcePkgName = "com.source.package." + UserHandle.getAppId(uid);
setPackageUid(sourcePkgName, uid);
final JobStatus job = createJob(uid, sourcePkgName);
spyOn(job);
doReturn(i % 2 == 0).when(job).shouldTreatAsExpeditedJob();
- if (i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT) {
+ if (i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT) {
mJobConcurrencyManager.addRunningJobForTesting(job);
} else {
mPendingJobQueue.add(job);
@@ -473,13 +473,13 @@
mJobConcurrencyManager.prepareForAssignmentDeterminationLocked(
idle, preferredUidOnly, stoppable, assignmentInfo);
assertEquals(remainingTimeMs, assignmentInfo.minPreferredUidOnlyWaitingTimeMs);
- assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, preferredUidOnly.size());
+ assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, preferredUidOnly.size());
mJobConcurrencyManager
.determineAssignmentsLocked(changed, idle, preferredUidOnly, stoppable,
assignmentInfo);
- assertEquals(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT, preferredUidOnly.size());
+ assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, preferredUidOnly.size());
// Depending on iteration order, we may create 1 or 2 contexts.
final long numAssignedJobs = changed.size();
assertTrue(numAssignedJobs > 0);
@@ -488,7 +488,7 @@
jobs.remove(changed.valueAt(i).newJob);
}
assertEquals(numAssignedJobs,
- JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT - jobs.size());
+ JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT - jobs.size());
JobStatus firstAssignedJob = changed.valueAt(0).newJob;
if (!firstAssignedJob.shouldTreatAsExpeditedJob()) {
assertEquals(2, numAssignedJobs);
@@ -538,14 +538,14 @@
assertFalse(mJobConcurrencyManager.isPkgConcurrencyLimitedLocked(topJob));
// Pending jobs shouldn't affect TOP job's status.
- for (int i = 1; i <= JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT; ++i) {
+ for (int i = 1; i <= JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT; ++i) {
final JobStatus job = createJob(mDefaultUserId * UserHandle.PER_USER_RANGE + i);
mPendingJobQueue.add(job);
}
assertFalse(mJobConcurrencyManager.isPkgConcurrencyLimitedLocked(topJob));
// Already running jobs shouldn't affect TOP job's status.
- for (int i = 1; i <= JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT; ++i) {
+ for (int i = 1; i <= JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT; ++i) {
final JobStatus job = createJob(mDefaultUserId * UserHandle.PER_USER_RANGE, i);
mJobConcurrencyManager.addRunningJobForTesting(job);
}
@@ -605,9 +605,9 @@
spyOn(testEj);
doReturn(true).when(testEj).shouldTreatAsExpeditedJob();
- setConcurrencyConfig(JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT);
+ setConcurrencyConfig(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT);
- for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT; ++i) {
+ for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT; ++i) {
final JobStatus job = createJob(mDefaultUserId * UserHandle.PER_USER_RANGE + i, i + 1);
mPendingJobQueue.add(job);
}
@@ -887,12 +887,14 @@
mConfigBuilder
.setInt(WorkTypeConfig.KEY_PREFIX_MAX_TOTAL + identifier, total);
for (TypeConfig config : typeConfigs) {
- mConfigBuilder.setInt(
- WorkTypeConfig.KEY_PREFIX_MAX + config.workTypeString + "_" + identifier,
- config.max);
- mConfigBuilder.setInt(
- WorkTypeConfig.KEY_PREFIX_MIN + config.workTypeString + "_" + identifier,
- config.min);
+ mConfigBuilder.setFloat(
+ WorkTypeConfig.KEY_PREFIX_MAX_RATIO + config.workTypeString + "_"
+ + identifier,
+ (float) config.max / total);
+ mConfigBuilder.setFloat(
+ WorkTypeConfig.KEY_PREFIX_MIN_RATIO + config.workTypeString + "_"
+ + identifier,
+ (float) config.min / total);
}
}
updateDeviceConfig();
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
index 9935a2f..06ba5dd 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
@@ -63,6 +63,7 @@
import com.android.server.compat.PlatformCompat
import com.android.server.extendedtestutils.wheneverStatic
import com.android.server.pm.dex.DexManager
+import com.android.server.pm.dex.DynamicCodeLogger
import com.android.server.pm.parsing.PackageParser2
import com.android.server.pm.parsing.pkg.PackageImpl
import com.android.server.pm.parsing.pkg.ParsedPackage
@@ -208,6 +209,7 @@
whenever(snapshot()) { appsFilterSnapshot }
}
val dexManager: DexManager = mock()
+ val dynamicCodeLogger: DynamicCodeLogger = mock()
val installer: Installer = mock()
val displayMetrics: DisplayMetrics = mock()
val domainVerificationManagerInternal: DomainVerificationManagerInternal = mock()
@@ -285,6 +287,7 @@
whenever(mocks.injector.crossProfileIntentFilterHelper)
.thenReturn(mocks.crossProfileIntentFilterHelper)
whenever(mocks.injector.dexManager).thenReturn(mocks.dexManager)
+ whenever(mocks.injector.dynamicCodeLogger).thenReturn(mocks.dynamicCodeLogger)
whenever(mocks.injector.systemConfig).thenReturn(mocks.systemConfig)
whenever(mocks.injector.apexManager).thenReturn(mocks.apexManager)
whenever(mocks.injector.scanningCachingPackageParser).thenReturn(mocks.packageParser)
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java
index cfd5279..d2547a3 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java
@@ -723,8 +723,8 @@
params.isStaged = true;
InstallSource installSource = InstallSource.create("testInstallInitiator",
- "testInstallOriginator", "testInstaller", 100, "testAttributionTag",
- PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
+ "testInstallOriginator", "testInstaller", 100, "testUpdateOwner",
+ "testAttributionTag", PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
PackageInstallerSession session = new PackageInstallerSession(
/* callback */ null,
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorSUSDTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorSUSDTest.java
index 88709e1..b9ba780 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorSUSDTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorSUSDTest.java
@@ -49,6 +49,7 @@
int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, FG,
DEFAULT_DISPLAY);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
+ expectUserCannotBeUnassignedFromDisplay(USER_ID, DEFAULT_DISPLAY);
expectUserIsVisible(USER_ID);
expectUserIsNotVisibleOnDisplay(USER_ID, INVALID_DISPLAY);
@@ -80,6 +81,7 @@
int result = mMediator.assignUserToDisplayOnStart(currentUserId, currentUserId, FG,
DEFAULT_DISPLAY);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
+ expectUserCannotBeUnassignedFromDisplay(currentUserId, DEFAULT_DISPLAY);
expectUserIsVisible(currentUserId);
expectUserIsNotVisibleOnDisplay(currentUserId, INVALID_DISPLAY);
@@ -110,6 +112,7 @@
int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID,
BG_VISIBLE, DEFAULT_DISPLAY);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
+ expectUserCannotBeUnassignedFromDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY);
expectUserIsVisible(PROFILE_USER_ID);
expectUserIsNotVisibleOnDisplay(PROFILE_USER_ID, INVALID_DISPLAY);
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java
index e4664d2..c59834b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java
@@ -165,12 +165,16 @@
expectNoDisplayAssignedToUser(USER_ID);
expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY);
+ assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID);
+
listener.verify();
}
@Test
public final void testStartVisibleBgUser_onDefaultDisplay() throws Exception {
visibleBgUserCannotBeStartedOnDefaultDisplayTest();
+
+ assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID);
}
protected final void visibleBgUserCannotBeStartedOnDefaultDisplayTest() throws Exception {
@@ -180,8 +184,8 @@
DEFAULT_DISPLAY);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE);
- expectUserIsNotVisibleAtAll(PROFILE_USER_ID);
- expectNoDisplayAssignedToUser(PROFILE_USER_ID);
+ expectUserIsNotVisibleAtAll(USER_ID);
+ expectNoDisplayAssignedToUser(USER_ID);
listener.verify();
}
@@ -194,8 +198,11 @@
SECONDARY_DISPLAY_ID);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE);
- expectUserIsNotVisibleAtAll(PROFILE_USER_ID);
- expectNoDisplayAssignedToUser(PROFILE_USER_ID);
+ expectUserIsNotVisibleAtAll(USER_ID);
+ expectNoDisplayAssignedToUser(USER_ID);
+
+ assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID);
+ assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, OTHER_SECONDARY_DISPLAY_ID);
listener.verify();
}
@@ -217,6 +224,9 @@
expectNoDisplayAssignedToUser(USER_SYSTEM);
expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, USER_ID);
+ assertUserCannotBeAssignedExtraDisplay(USER_SYSTEM, SECONDARY_DISPLAY_ID);
+ assertUserCannotBeAssignedExtraDisplay(USER_SYSTEM, OTHER_SECONDARY_DISPLAY_ID);
+
listener.verify();
}
@@ -256,6 +266,8 @@
expectNoDisplayAssignedToUser(PROFILE_USER_ID);
expectUserAssignedToDisplay(DEFAULT_DISPLAY, OTHER_USER_ID);
+ assertUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
+
listener.verify();
}
@@ -289,6 +301,8 @@
expectNoDisplayAssignedToUser(PROFILE_USER_ID);
expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY);
+ assertUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
+
listener.verify();
}
@@ -305,6 +319,10 @@
expectNoDisplayAssignedToUser(PROFILE_USER_ID);
expectInitialCurrentUserAssignedToDisplay(SECONDARY_DISPLAY_ID);
+ assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
+ assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID,
+ OTHER_SECONDARY_DISPLAY_ID);
+
listener.verify();
}
@@ -320,6 +338,10 @@
expectNoDisplayAssignedToUser(PROFILE_USER_ID);
expectInitialCurrentUserAssignedToDisplay(SECONDARY_DISPLAY_ID);
+ assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
+ assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID,
+ OTHER_SECONDARY_DISPLAY_ID);
+
listener.verify();
}
@@ -336,6 +358,9 @@
expectNoDisplayAssignedToUser(PROFILE_USER_ID);
expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY);
+ assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY);
+ assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
+
listener.verify();
}
@@ -351,6 +376,10 @@
expectNoDisplayAssignedToUser(PROFILE_USER_ID);
expectInitialCurrentUserAssignedToDisplay(SECONDARY_DISPLAY_ID);
+ assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
+ assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID,
+ OTHER_SECONDARY_DISPLAY_ID);
+
listener.verify();
}
@@ -481,6 +510,63 @@
.that(actualResult).isEqualTo(expectedResult);
}
+ protected void assertBgUserBecomesInvisibleOnStop(@UserIdInt int userId) {
+ Log.d(TAG, "Stopping user " + userId);
+ mMediator.unassignUserFromDisplayOnStop(userId);
+ expectUserIsNotVisibleAtAll(userId);
+ }
+
+ /**
+ * Assigns and unassigns the user to / from an extra display, asserting the visibility state in
+ * between.
+ *
+ * <p>It assumes the user was not visible in the display beforehand.
+ */
+ protected void assertUserCanBeAssignedExtraDisplay(@UserIdInt int userId, int displayId) {
+ assertUserCanBeAssignedExtraDisplay(userId, displayId, /* unassign= */ true);
+ }
+
+ protected void assertUserCanBeAssignedExtraDisplay(@UserIdInt int userId, int displayId,
+ boolean unassign) {
+
+ expectUserIsNotVisibleOnDisplay(userId, displayId);
+
+ Log.d(TAG, "Calling assignUserToExtraDisplay(" + userId + ", " + displayId + ")");
+ assertWithMessage("assignUserToExtraDisplay(%s, %s)", userId, displayId)
+ .that(mMediator.assignUserToExtraDisplay(userId, displayId))
+ .isTrue();
+ expectUserIsVisibleOnDisplay(userId, displayId);
+
+ if (unassign) {
+ Log.d(TAG, "Calling unassignUserFromExtraDisplay(" + userId + ", " + displayId + ")");
+ assertWithMessage("unassignUserFromExtraDisplay(%s, %s)", userId, displayId)
+ .that(mMediator.unassignUserFromExtraDisplay(userId, displayId))
+ .isTrue();
+ expectUserIsNotVisibleOnDisplay(userId, displayId);
+ }
+ }
+
+ /**
+ * Asserts that a user (already visible or not) cannot be assigned to an extra display (and
+ * hence won't be visible on that display).
+ */
+ protected void assertUserCannotBeAssignedExtraDisplay(@UserIdInt int userId, int displayId) {
+ expectWithMessage("assignUserToExtraDisplay(%s, %s)", userId, displayId)
+ .that(mMediator.assignUserToExtraDisplay(userId, displayId))
+ .isFalse();
+ expectUserIsNotVisibleOnDisplay(userId, displayId);
+ }
+
+ /**
+ * Asserts that an invisible user cannot be assigned to an extra display.
+ */
+ protected void assertInvisibleUserCannotBeAssignedExtraDisplay(@UserIdInt int userId,
+ int displayId) {
+ assertUserCannotBeAssignedExtraDisplay(userId, displayId);
+ expectNoDisplayAssignedToUser(userId);
+ expectInitialCurrentUserAssignedToDisplay(displayId);
+ }
+
protected void expectUserIsVisible(@UserIdInt int userId) {
expectWithMessage("isUserVisible(%s)", userId)
.that(mMediator.isUserVisible(userId))
@@ -534,6 +620,11 @@
.that(mMediator.getDisplayAssignedToUser(userId)).isEqualTo(INVALID_DISPLAY);
}
+ protected void expectUserCannotBeUnassignedFromDisplay(@UserIdInt int userId, int displayId) {
+ expectWithMessage("unassignUserFromExtraDisplay(%s, %s)", userId, displayId)
+ .that(mMediator.unassignUserFromExtraDisplay(userId, displayId)).isFalse();
+ }
+
protected void expectUserAssignedToDisplay(int displayId, @UserIdInt int userId) {
expectWithMessage("getUserAssignedToDisplay(%s)", displayId)
.that(mMediator.getUserAssignedToDisplay(displayId)).isEqualTo(userId);
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorVisibleBackgroundUserTestCase.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorVisibleBackgroundUserTestCase.java
index 66d7eb6..627553b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorVisibleBackgroundUserTestCase.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorVisibleBackgroundUserTestCase.java
@@ -52,6 +52,7 @@
int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, FG,
DEFAULT_DISPLAY);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
+ expectUserCannotBeUnassignedFromDisplay(USER_ID, DEFAULT_DISPLAY);
expectUserIsVisible(USER_ID);
expectUserIsVisibleOnDisplay(USER_ID, DEFAULT_DISPLAY);
@@ -64,7 +65,9 @@
expectUserAssignedToDisplay(INVALID_DISPLAY, USER_ID);
expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, USER_ID);
- expectDisplayAssignedToUser(USER_NULL, INVALID_DISPLAY);
+ expectNoDisplayAssignedToUser(USER_NULL);
+
+ assertUserCanBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID);
listener.verify();
}
@@ -83,6 +86,7 @@
int result = mMediator.assignUserToDisplayOnStart(currentUserId, currentUserId, FG,
DEFAULT_DISPLAY);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
+ expectUserCannotBeUnassignedFromDisplay(currentUserId, DEFAULT_DISPLAY);
expectUserIsVisible(currentUserId);
expectUserIsVisibleOnDisplay(currentUserId, DEFAULT_DISPLAY);
@@ -98,6 +102,8 @@
expectUserIsNotVisibleAtAll(previousCurrentUserId);
expectNoDisplayAssignedToUser(previousCurrentUserId);
+ assertUserCanBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID);
+
listener.verify();
}
@@ -113,6 +119,7 @@
int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID,
BG_VISIBLE, DEFAULT_DISPLAY);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
+ expectUserCannotBeUnassignedFromDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY);
expectUserIsVisible(PROFILE_USER_ID);
expectUserIsNotVisibleOnDisplay(PROFILE_USER_ID, INVALID_DISPLAY);
@@ -123,6 +130,8 @@
expectDisplayAssignedToUser(PROFILE_USER_ID, DEFAULT_DISPLAY);
expectUserAssignedToDisplay(DEFAULT_DISPLAY, PARENT_USER_ID);
+ assertUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
+
listener.verify();
}
@@ -134,6 +143,9 @@
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE);
+ assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, DEFAULT_DISPLAY);
+ assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID);
+
listener.verify();
}
@@ -148,6 +160,9 @@
expectUserIsNotVisibleAtAll(USER_ID);
+ assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, DEFAULT_DISPLAY);
+ assertInvisibleUserCannotBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID);
+
listener.verify();
}
@@ -159,6 +174,7 @@
int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, BG_VISIBLE,
SECONDARY_DISPLAY_ID);
assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
+ expectUserCannotBeUnassignedFromDisplay(USER_ID, SECONDARY_DISPLAY_ID);
expectUserIsVisible(USER_ID);
expectUserIsVisibleOnDisplay(USER_ID, SECONDARY_DISPLAY_ID);
@@ -169,7 +185,16 @@
expectDisplayAssignedToUser(USER_ID, SECONDARY_DISPLAY_ID);
expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, USER_ID);
- listener.verify();
+ assertUserCanBeAssignedExtraDisplay(USER_ID, OTHER_SECONDARY_DISPLAY_ID);
+
+ // Assign again, without unassigning (to make sure it becomes invisible on stop)
+ AsyncUserVisibilityListener listener2 = addListenerForEvents(onInvisible(USER_ID));
+ assertUserCanBeAssignedExtraDisplay(USER_ID, OTHER_SECONDARY_DISPLAY_ID,
+ /* unassign= */ false);
+
+ assertBgUserBecomesInvisibleOnStop(USER_ID);
+
+ listener2.verify();
}
@Test
@@ -203,6 +228,8 @@
expectNoDisplayAssignedToUser(USER_ID);
expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, OTHER_USER_ID);
+ assertUserCannotBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID);
+
listener.verify();
}
@@ -226,7 +253,18 @@
expectDisplayAssignedToUser(USER_ID, OTHER_SECONDARY_DISPLAY_ID);
expectUserAssignedToDisplay(OTHER_SECONDARY_DISPLAY_ID, USER_ID);
+ assertUserCanBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID);
+
listener.verify();
+
+ // Assign again, without unassigning (to make sure it becomes invisible on stop)
+ AsyncUserVisibilityListener listener2 = addListenerForEvents(onInvisible(USER_ID));
+ assertUserCanBeAssignedExtraDisplay(USER_ID, SECONDARY_DISPLAY_ID,
+ /* unassign= */ false);
+
+ assertBgUserBecomesInvisibleOnStop(USER_ID);
+
+ listener2.verify();
}
@Test
@@ -244,12 +282,14 @@
expectNoDisplayAssignedToUser(PROFILE_USER_ID);
expectUserAssignedToDisplay(OTHER_SECONDARY_DISPLAY_ID, PARENT_USER_ID);
+ assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
+
listener.verify();
}
+ // Conditions below are asserted on other tests, but they're explicitly checked in the 2
+ // tests below (which call this method) as well
private void currentUserVisibilityWhenNoDisplayIsAssignedTest(@UserIdInt int currentUserId) {
- // Conditions below are asserted on other tests, but they're explicitly checked in the 2
- // tests below as well
expectUserIsVisible(currentUserId);
expectUserIsVisibleOnDisplay(currentUserId, DEFAULT_DISPLAY);
expectUserIsNotVisibleOnDisplay(currentUserId, SECONDARY_DISPLAY_ID);
@@ -277,4 +317,13 @@
expectUserIsNotVisibleAtAll(INITIAL_CURRENT_USER_ID);
expectDisplayAssignedToUser(INITIAL_CURRENT_USER_ID, INVALID_DISPLAY);
}
+
+ @Test
+ public final void testAssignUserToExtraDisplay_invalidDisplays() throws Exception {
+ expectWithMessage("assignUserToExtraDisplay(%s, %s)", USER_ID, INVALID_DISPLAY)
+ .that(mMediator.assignUserToExtraDisplay(USER_ID, INVALID_DISPLAY)).isFalse();
+ // DEFAULT_DISPLAY is always assigned to the current user
+ expectWithMessage("assignUserToExtraDisplay(%s, %s)", USER_ID, DEFAULT_DISPLAY)
+ .that(mMediator.assignUserToExtraDisplay(USER_ID, DEFAULT_DISPLAY)).isFalse();
+ }
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/dex/DexManagerTests.java b/services/tests/mockingservicestests/src/com/android/server/pm/dex/DexManagerTests.java
index fb9cbb0..7dae235 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/dex/DexManagerTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/dex/DexManagerTests.java
@@ -85,6 +85,7 @@
private final Object mInstallLock = new Object();
+ private DynamicCodeLogger mDynamicCodeLogger;
private DexManager mDexManager;
private TestData mFooUser0;
@@ -158,8 +159,9 @@
.when(mockContext)
.getSystemService(PowerManager.class);
- mDexManager = new DexManager(mockContext, /*PackageDexOptimizer*/ null,
- mInstaller, mInstallLock, mPM);
+ mDynamicCodeLogger = new DynamicCodeLogger(mInstaller);
+ mDexManager = new DexManager(mockContext, /*PackageDexOptimizer*/ null, mInstaller,
+ mInstallLock, mDynamicCodeLogger, mPM);
// Foo and Bar are available to user0.
// Only Bar is available to user1;
@@ -452,6 +454,7 @@
notifyDexLoad(mBarUser1, mBarUser1.getSecondaryDexPaths(), mUser1);
mDexManager.notifyPackageDataDestroyed(mBarUser0.getPackageName(), mUser0);
+ mDynamicCodeLogger.notifyPackageDataDestroyed(mBarUser0.getPackageName(), mUser0);
// Data for user 1 should still be present
PackageUseInfo pui = getPackageUseInfo(mBarUser1);
@@ -474,6 +477,7 @@
notifyDexLoad(mBarUser0, mFooUser0.getBaseAndSplitDexPaths(), mUser0);
mDexManager.notifyPackageDataDestroyed(mFooUser0.getPackageName(), mUser0);
+ mDynamicCodeLogger.notifyPackageDataDestroyed(mFooUser0.getPackageName(), mUser0);
// Foo should still be around since it's used by other apps but with no
// secondary dex info.
@@ -491,6 +495,7 @@
notifyDexLoad(mFooUser0, fooSecondaries, mUser0);
mDexManager.notifyPackageDataDestroyed(mFooUser0.getPackageName(), mUser0);
+ mDynamicCodeLogger.notifyPackageDataDestroyed(mFooUser0.getPackageName(), mUser0);
// Foo should not be around since all its secondary dex info were deleted
// and it is not used by other apps.
@@ -505,6 +510,8 @@
notifyDexLoad(mBarUser1, mBarUser1.getSecondaryDexPaths(), mUser1);
mDexManager.notifyPackageDataDestroyed(mBarUser0.getPackageName(), UserHandle.USER_ALL);
+ mDynamicCodeLogger.notifyPackageDataDestroyed(
+ mBarUser0.getPackageName(), UserHandle.USER_ALL);
// Bar should not be around since it was removed for all users.
assertNoUseInfo(mBarUser0);
@@ -906,8 +913,7 @@
}
private PackageDynamicCode getPackageDynamicCodeInfo(TestData testData) {
- return mDexManager.getDynamicCodeLogger()
- .getPackageDynamicCodeInfo(testData.getPackageName());
+ return mDynamicCodeLogger.getPackageDynamicCodeInfo(testData.getPackageName());
}
private void assertNoUseInfo(TestData testData) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
index 7fd1ddb..bcba4a1 100644
--- a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
@@ -29,7 +29,6 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.wallpaper.WallpaperManagerService.WALLPAPER;
-import static com.android.server.wallpaper.WallpaperManagerService.WALLPAPER_CROP;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.assertEquals;
@@ -76,12 +75,12 @@
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.dx.mockito.inline.extended.StaticMockitoSession;
import com.android.internal.R;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
import com.android.server.LocalServices;
-import com.android.server.wallpaper.WallpaperManagerService.WallpaperData;
import com.android.server.wm.WindowManagerInternal;
import org.hamcrest.CoreMatchers;
@@ -114,6 +113,8 @@
@FlakyTest(bugId = 129797242)
@RunWith(AndroidJUnit4.class)
public class WallpaperManagerServiceTests {
+
+ private static final String TAG = "WallpaperManagerServiceTests";
private static final int DISPLAY_SIZE_DIMENSION = 100;
private static StaticMockitoSession sMockitoSession;
@@ -138,6 +139,7 @@
public static void setUpClass() {
sMockitoSession = mockitoSession()
.strictness(Strictness.LENIENT)
+ .spyStatic(WallpaperUtils.class)
.spyStatic(LocalServices.class)
.spyStatic(WallpaperManager.class)
.startMocking();
@@ -193,6 +195,11 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
+ ExtendedMockito.doAnswer(invocation -> {
+ int userId = (invocation.getArgument(0));
+ return getWallpaperTestDir(userId);
+ }).when(() -> WallpaperUtils.getWallpaperDir(anyInt()));
+
sContext.addMockSystemService(DisplayManager.class, mDisplayManager);
final Display mockDisplay = mock(Display.class);
@@ -217,27 +224,25 @@
mService = null;
}
+ private File getWallpaperTestDir(int userId) {
+ File tempDir = mTempDirs.get(userId);
+ if (tempDir == null) {
+ try {
+ tempDir = mFolder.newFolder(String.valueOf(userId));
+ mTempDirs.append(userId, tempDir);
+ } catch (IOException e) {
+ Log.e(TAG, "getWallpaperTestDir failed at userId= " + userId);
+ }
+ }
+ return tempDir;
+ }
+
protected class TestWallpaperManagerService extends WallpaperManagerService {
- private static final String TAG = "TestWallpaperManagerService";
TestWallpaperManagerService(Context context) {
super(context);
}
- @Override
- File getWallpaperDir(int userId) {
- File tempDir = mTempDirs.get(userId);
- if (tempDir == null) {
- try {
- tempDir = mFolder.newFolder(String.valueOf(userId));
- mTempDirs.append(userId, tempDir);
- } catch (IOException e) {
- Log.e(TAG, "getWallpaperDir failed at userId= " + userId);
- }
- }
- return tempDir;
- }
-
// Always return true for test
@Override
public boolean isWallpaperSupported(String callingPackage) {
@@ -403,8 +408,7 @@
@Test
public void testWallpaperManagerCallbackInRightOrder() throws RemoteException {
- WallpaperData wallpaper = new WallpaperData(
- USER_SYSTEM, mService.getWallpaperDir(USER_SYSTEM), WALLPAPER, WALLPAPER_CROP);
+ WallpaperData wallpaper = new WallpaperData(USER_SYSTEM, FLAG_SYSTEM);
wallpaper.primaryColors = new WallpaperColors(Color.valueOf(Color.RED),
Color.valueOf(Color.BLUE), null);
diff --git a/services/tests/servicestests/res/xml/usertypes_test_profile.xml b/services/tests/servicestests/res/xml/usertypes_test_profile.xml
index f3ad6d8..450cc40 100644
--- a/services/tests/servicestests/res/xml/usertypes_test_profile.xml
+++ b/services/tests/servicestests/res/xml/usertypes_test_profile.xml
@@ -35,6 +35,7 @@
startWithParent='false'
useParentsContacts='false'
crossProfileIntentFilterAccessControl='20'
+ crossProfileIntentResolutionStrategy='0'
/>
</profile-type>
<profile-type name='custom.test.1' max-allowed-per-parent='14' />
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index d056348..448ffe5 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -55,6 +55,7 @@
import android.hardware.display.DisplayManagerGlobal;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.LocaleList;
import android.os.UserHandle;
import android.provider.Settings;
import android.testing.TestableContext;
@@ -106,7 +107,8 @@
private static final String INTENT_ACTION = "TESTACTION";
private static final String DESCRIPTION = "description";
private static final PendingIntent TEST_PENDING_INTENT = PendingIntent.getBroadcast(
- ApplicationProvider.getApplicationContext(), 0, new Intent(INTENT_ACTION),
+ ApplicationProvider.getApplicationContext(), 0, new Intent(INTENT_ACTION)
+ .setPackage(ApplicationProvider.getApplicationContext().getPackageName()),
PendingIntent.FLAG_MUTABLE_UNAUDITED);
private static final RemoteAction TEST_ACTION = new RemoteAction(
Icon.createWithContentUri("content://test"),
@@ -487,7 +489,7 @@
final int userid = 10;
final int windowId = 100;
final AccessibilityWindowAttributes attributes = new AccessibilityWindowAttributes(
- new WindowManager.LayoutParams());
+ new WindowManager.LayoutParams(), LocaleList.getEmptyLocaleList());
mA11yms.setAccessibilityWindowAttributes(displayId, windowId, userid, attributes);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
index 7b7e1e0..2dfabd0 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
@@ -43,6 +43,7 @@
import android.graphics.Region;
import android.os.IBinder;
+import android.os.LocaleList;
import android.os.RemoteException;
import android.os.UserHandle;
import android.text.TextUtils;
@@ -909,7 +910,7 @@
final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
layoutParams.accessibilityTitle = "accessibility window title";
final AccessibilityWindowAttributes attributes = new AccessibilityWindowAttributes(
- layoutParams);
+ layoutParams, new LocaleList());
mA11yWindowManager.setAccessibilityWindowAttributes(Display.DEFAULT_DISPLAY, windowId,
USER_SYSTEM_ID, attributes);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java
index bbcf77b..13d93cb 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java
@@ -76,14 +76,18 @@
private static final String DESCRIPTION1 = "description1";
private static final String DESCRIPTION2 = "description2";
private static final PendingIntent TEST_PENDING_INTENT_1 = PendingIntent.getBroadcast(
- InstrumentationRegistry.getTargetContext(), 0, new Intent(INTENT_ACTION1), PendingIntent.FLAG_MUTABLE_UNAUDITED);
+ InstrumentationRegistry.getTargetContext(), 0, new Intent(INTENT_ACTION1)
+ .setPackage(InstrumentationRegistry.getTargetContext().getPackageName()),
+ PendingIntent.FLAG_MUTABLE_UNAUDITED);
private static final RemoteAction NEW_TEST_ACTION_1 = new RemoteAction(
Icon.createWithContentUri("content://test"),
LABEL_1,
DESCRIPTION1,
TEST_PENDING_INTENT_1);
private static final PendingIntent TEST_PENDING_INTENT_2 = PendingIntent.getBroadcast(
- InstrumentationRegistry.getTargetContext(), 0, new Intent(INTENT_ACTION2), PendingIntent.FLAG_MUTABLE_UNAUDITED);
+ InstrumentationRegistry.getTargetContext(), 0, new Intent(INTENT_ACTION2)
+ .setPackage(InstrumentationRegistry.getTargetContext().getPackageName()),
+ PendingIntent.FLAG_MUTABLE_UNAUDITED);
private static final RemoteAction NEW_TEST_ACTION_2 = new RemoteAction(
Icon.createWithContentUri("content://test"),
LABEL_2,
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
index eac8671..2a80ce0 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
@@ -26,13 +26,13 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -40,26 +40,33 @@
import static org.mockito.Mockito.when;
import android.accessibilityservice.MagnificationConfig;
+import android.animation.ValueAnimator;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Region;
+import android.hardware.display.DisplayManagerInternal;
+import android.os.Looper;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import android.test.mock.MockContentResolver;
import android.testing.DexmakerShareClassLoaderRule;
import android.view.Display;
+import android.view.DisplayInfo;
import android.view.accessibility.IRemoteMagnificationAnimationCallback;
import android.view.accessibility.MagnificationAnimationCallback;
+import androidx.annotation.NonNull;
+import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.server.LocalServices;
import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.accessibility.AccessibilityTraceManager;
+import com.android.server.accessibility.test.MessageCapturingHandler;
import com.android.server.wm.WindowManagerInternal;
import org.junit.After;
@@ -70,7 +77,6 @@
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
-import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.stubbing.Answer;
@@ -82,6 +88,8 @@
private static final int TEST_DISPLAY = Display.DEFAULT_DISPLAY;
private static final int TEST_SERVICE_ID = 1;
+ private static final Region INITIAL_SCREEN_MAGNIFICATION_REGION =
+ new Region(0, 0, 500, 600);
private static final Rect TEST_RECT = new Rect(0, 50, 100, 51);
private static final float MAGNIFIED_CENTER_X = 100;
private static final float MAGNIFIED_CENTER_Y = 200;
@@ -101,9 +109,20 @@
@Mock
private Context mContext;
@Mock
- PackageManager mPackageManager;
+ private PackageManager mPackageManager;
+
@Mock
+ private FullScreenMagnificationController.ControllerContext mControllerCtx;
+ @Mock
+ private ValueAnimator mValueAnimator;
+ @Mock
+ private MessageCapturingHandler mMessageCapturingHandler;
+
private FullScreenMagnificationController mScreenMagnificationController;
+ private final FullScreenMagnificationCtrInfoChangedCallbackDelegate
+ mScreenMagnificationInfoChangedCallbackDelegate =
+ new FullScreenMagnificationCtrInfoChangedCallbackDelegate();
+
private MagnificationScaleProvider mScaleProvider;
@Captor
private ArgumentCaptor<MagnificationAnimationCallback> mCallbackArgumentCaptor;
@@ -112,13 +131,17 @@
private WindowMagnificationManager mWindowMagnificationManager;
private MockContentResolver mMockResolver;
private MagnificationController mMagnificationController;
- private final WindowMagnificationMgrCallbackDelegate mCallbackDelegate =
+ private final WindowMagnificationMgrCallbackDelegate
+ mWindowMagnificationCallbackDelegate =
new WindowMagnificationMgrCallbackDelegate();
@Mock
- private WindowManagerInternal mMockWindowManagerInternal;
+ private WindowManagerInternal mWindowManagerInternal;
@Mock
- private WindowManagerInternal.AccessibilityControllerInternal mMockA11yController;
+ private WindowManagerInternal.AccessibilityControllerInternal mA11yController;
+
+ @Mock
+ private DisplayManagerInternal mDisplayManagerInternal;
// To mock package-private class
@Rule
@@ -132,31 +155,60 @@
final Object globalLock = new Object();
LocalServices.removeServiceForTest(WindowManagerInternal.class);
- LocalServices.addService(WindowManagerInternal.class, mMockWindowManagerInternal);
- when(mMockWindowManagerInternal.getAccessibilityController()).thenReturn(
- mMockA11yController);
+ LocalServices.addService(WindowManagerInternal.class, mWindowManagerInternal);
+ when(mWindowManagerInternal.getAccessibilityController()).thenReturn(
+ mA11yController);
+ when(mWindowManagerInternal.setMagnificationCallbacks(eq(TEST_DISPLAY), any()))
+ .thenReturn(true);
+ doAnswer((Answer<Void>) invocationOnMock -> {
+ Object[] args = invocationOnMock.getArguments();
+ Region regionArg = (Region) args[1];
+ regionArg.set(INITIAL_SCREEN_MAGNIFICATION_REGION);
+ return null;
+ }).when(mWindowManagerInternal).getMagnificationRegion(anyInt(), any(Region.class));
mMockResolver = new MockContentResolver();
mMockResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+ Looper looper = InstrumentationRegistry.getContext().getMainLooper();
+ // Pretending ID of the Thread associated with looper as main thread ID in controller
+ when(mContext.getMainLooper()).thenReturn(looper);
when(mContext.getContentResolver()).thenReturn(mMockResolver);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
Settings.Secure.putFloatForUser(mMockResolver,
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, DEFAULT_SCALE,
CURRENT_USER_ID);
mScaleProvider = spy(new MagnificationScaleProvider(mContext));
- mWindowMagnificationManager = Mockito.spy(
- new WindowMagnificationManager(mContext, globalLock,
- mCallbackDelegate, mTraceManager, mScaleProvider));
+
+ when(mControllerCtx.getContext()).thenReturn(mContext);
+ when(mControllerCtx.getTraceManager()).thenReturn(mTraceManager);
+ when(mControllerCtx.getWindowManager()).thenReturn(mWindowManagerInternal);
+ when(mControllerCtx.getHandler()).thenReturn(mMessageCapturingHandler);
+ when(mControllerCtx.getAnimationDuration()).thenReturn(1000L);
+ when(mControllerCtx.newValueAnimator()).thenReturn(mValueAnimator);
+
+ final DisplayInfo displayInfo = new DisplayInfo();
+ displayInfo.logicalDensityDpi = 300;
+ doReturn(displayInfo).when(mDisplayManagerInternal).getDisplayInfo(anyInt());
+ LocalServices.removeServiceForTest(DisplayManagerInternal.class);
+ LocalServices.addService(DisplayManagerInternal.class, mDisplayManagerInternal);
+
+ mScreenMagnificationController = spy(new FullScreenMagnificationController(
+ mControllerCtx, new Object(),
+ mScreenMagnificationInfoChangedCallbackDelegate, mScaleProvider));
+ mScreenMagnificationController.register(TEST_DISPLAY);
+
+ mWindowMagnificationManager = spy(new WindowMagnificationManager(mContext, globalLock,
+ mWindowMagnificationCallbackDelegate, mTraceManager, mScaleProvider));
mMockConnection = new MockWindowMagnificationConnection(true);
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+
mMagnificationController = new MagnificationController(mService, globalLock, mContext,
mScreenMagnificationController, mWindowMagnificationManager, mScaleProvider);
- new FullScreenMagnificationControllerStubber(mScreenMagnificationController,
- mMagnificationController);
-
mMagnificationController.setMagnificationCapabilities(
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
- mCallbackDelegate.setDelegate(mMagnificationController);
+
+ mScreenMagnificationInfoChangedCallbackDelegate.setDelegate(mMagnificationController);
+ mWindowMagnificationCallbackDelegate.setDelegate(mMagnificationController);
}
@After
@@ -213,8 +265,8 @@
verify(mTransitionCallBack).onResult(TEST_DISPLAY, false);
final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass(
MagnificationConfig.class);
- // The first time is for notifying full-screen enabled and the second time is for notifying
- // the target mode transitions failed.
+ // The first time is for notifying full-screen enabled.
+ // The second time is for notifying the target mode transitions failed.
verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class),
configCaptor.capture());
final MagnificationConfig actualConfig = configCaptor.getValue();
@@ -252,9 +304,9 @@
MODE_WINDOW,
mTransitionCallBack);
- // The first time is triggered when window mode is activated, the second time is triggered
- // when activating the window mode again. The third time is triggered when the transition is
- // completed.
+ // The first time is triggered when window mode is activated.
+ // The second time is triggered when activating the window mode again.
+ // The third time is triggered when the transition is completed.
verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_WINDOW));
}
@@ -279,8 +331,7 @@
@Test
public void transitionToFullScreen_centerNotInTheBounds_magnifyBoundsCenter()
throws RemoteException {
- final Rect magnificationBounds =
- FullScreenMagnificationControllerStubber.MAGNIFICATION_REGION.getBounds();
+ final Rect magnificationBounds = INITIAL_SCREEN_MAGNIFICATION_REGION.getBounds();
final PointF magnifiedCenter = new PointF(magnificationBounds.right + 100,
magnificationBounds.bottom + 100);
setMagnificationEnabled(MODE_WINDOW, magnifiedCenter.x, magnifiedCenter.y);
@@ -436,17 +487,19 @@
public void magnifyThroughExternalRequest_showMagnificationButton() {
mScreenMagnificationController.setScaleAndCenter(TEST_DISPLAY, DEFAULT_SCALE,
MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y, false, TEST_SERVICE_ID);
- mMagnificationController.onRequestMagnificationSpec(TEST_DISPLAY, TEST_SERVICE_ID);
- verify(mWindowMagnificationManager).showMagnificationButton(eq(TEST_DISPLAY),
+ // The first time is trigger when fullscreen mode is activated.
+ // The second time is triggered when magnification spec is changed.
+ verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_FULLSCREEN));
}
@Test
- public void setScaleOneThroughExternalRequest_removeMagnificationButton() {
+ public void setScaleOneThroughExternalRequest_fullScreenEnabled_removeMagnificationButton()
+ throws RemoteException {
+ setMagnificationEnabled(MODE_FULLSCREEN);
mScreenMagnificationController.setScaleAndCenter(TEST_DISPLAY, 1.0f,
MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y, false, TEST_SERVICE_ID);
- mMagnificationController.onRequestMagnificationSpec(TEST_DISPLAY, TEST_SERVICE_ID);
verify(mWindowMagnificationManager).removeMagnificationButton(eq(TEST_DISPLAY));
}
@@ -490,12 +543,12 @@
config.getScale(), config.getCenterX(), config.getCenterY(),
true, TEST_SERVICE_ID);
- // The first time is triggered when setting magnification enabled. And the second time is
- // triggered when calling setScaleAndCenter.
+ // The notify method is triggered when setting magnification enabled.
+ // The setScaleAndCenter call should not trigger notify method due to same scale and center.
final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass(
MagnificationConfig.class);
- verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY),
- eq(FullScreenMagnificationControllerStubber.MAGNIFICATION_REGION),
+ verify(mService).notifyMagnificationChanged(eq(TEST_DISPLAY),
+ eq(INITIAL_SCREEN_MAGNIFICATION_REGION),
configCaptor.capture());
final MagnificationConfig actualConfig = configCaptor.getValue();
assertEquals(config.getCenterX(), actualConfig.getCenterX(), 0);
@@ -514,8 +567,8 @@
final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass(
MagnificationConfig.class);
- // The first time is for notifying window enabled and the second time is for notifying
- // the target mode transitions.
+ // The first time is for notifying window enabled.
+ // The second time is for notifying the target mode transitions.
verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class),
configCaptor.capture());
final MagnificationConfig actualConfig = configCaptor.getValue();
@@ -534,8 +587,8 @@
final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass(
MagnificationConfig.class);
- // The first time is for notifying window enabled and the second time is for notifying
- // the target mode transitions.
+ // The first time is for notifying window enabled.
+ // The second time is for notifying the target mode transitions.
verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class),
configCaptor.capture());
final MagnificationConfig actualConfig = configCaptor.getValue();
@@ -558,8 +611,8 @@
final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass(
MagnificationConfig.class);
- // The first time is for notifying full-screen enabled and the second time is for notifying
- // the target mode transitions.
+ // The first time is for notifying full-screen enabled.
+ // The second time is for notifying the target mode transitions.
verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class),
configCaptor.capture());
final MagnificationConfig actualConfig = configCaptor.getValue();
@@ -578,8 +631,8 @@
final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass(
MagnificationConfig.class);
- // The first time is for notifying full-screen enabled and the second time is for notifying
- // the target mode transitions.
+ // The first time is for notifying full-screen enabled.
+ // The second time is for notifying the target mode transitions.
verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class),
configCaptor.capture());
final MagnificationConfig actualConfig = configCaptor.getValue();
@@ -597,6 +650,7 @@
mMagnificationController.onAccessibilityActionPerformed(TEST_DISPLAY);
// The first time is triggered when window mode is activated.
+ // The second time is triggered when accessibility action performed.
verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_WINDOW));
}
@@ -611,6 +665,7 @@
mMagnificationController.onAccessibilityActionPerformed(TEST_DISPLAY);
// The first time is triggered when window mode is activated.
+ // The second time is triggered when accessibility action performed.
verify(mWindowMagnificationManager, times(2)).removeMagnificationButton(eq(TEST_DISPLAY));
}
@@ -767,7 +822,10 @@
mMagnificationController.onTouchInteractionStart(TEST_DISPLAY, MODE_FULLSCREEN);
- verify(mWindowMagnificationManager).showMagnificationButton(eq(TEST_DISPLAY),
+ // The first time is triggered when fullscreen mode is activated.
+ // The second time is triggered when magnification spec is changed.
+ // The third time is triggered when user interaction changed.
+ verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_FULLSCREEN));
}
@@ -778,7 +836,10 @@
mMagnificationController.onTouchInteractionEnd(TEST_DISPLAY, MODE_FULLSCREEN);
- verify(mWindowMagnificationManager).showMagnificationButton(eq(TEST_DISPLAY),
+ // The first time is triggered when fullscreen mode is activated.
+ // The second time is triggered when magnification spec is changed.
+ // The third time is triggered when user interaction changed.
+ verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_FULLSCREEN));
}
@@ -790,6 +851,7 @@
mMagnificationController.onTouchInteractionStart(TEST_DISPLAY, MODE_WINDOW);
// The first time is triggered when the window mode is activated.
+ // The second time is triggered when user interaction changed.
verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_WINDOW));
}
@@ -802,6 +864,7 @@
mMagnificationController.onTouchInteractionEnd(TEST_DISPLAY, MODE_WINDOW);
// The first time is triggered when the window mode is activated.
+ // The second time is triggered when user interaction changed.
verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_WINDOW));
}
@@ -849,7 +912,10 @@
mMagnificationController.onFullScreenMagnificationActivationState(TEST_DISPLAY, true);
- verify(mWindowMagnificationManager).showMagnificationButton(eq(TEST_DISPLAY),
+ // The first time is triggered when fullscreen mode is activated.
+ // The second time is triggered when magnification spec is changed.
+ // The third time is triggered when fullscreen mode activation state is updated.
+ verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_FULLSCREEN));
}
@@ -867,11 +933,7 @@
public void onFullScreenDeactivated_fullScreenEnabled_removeMagnificationButton()
throws RemoteException {
setMagnificationEnabled(MODE_FULLSCREEN);
- mScreenMagnificationController.setScaleAndCenter(TEST_DISPLAY,
- /* scale= */ 1, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y,
- true, TEST_SERVICE_ID);
-
- mMagnificationController.onFullScreenMagnificationActivationState(TEST_DISPLAY, false);
+ mScreenMagnificationController.reset(TEST_DISPLAY, /* animate= */ true);
verify(mWindowMagnificationManager).removeMagnificationButton(eq(TEST_DISPLAY));
}
@@ -885,7 +947,10 @@
MODE_FULLSCREEN, mTransitionCallBack);
mMockConnection.invokeCallbacks();
- verify(mWindowMagnificationManager).showMagnificationButton(eq(TEST_DISPLAY),
+ // The first time is triggered when fullscreen mode is activated.
+ // The second time is triggered when magnification spec is changed.
+ // The third time is triggered when the disable-magnification callback is triggered.
+ verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_FULLSCREEN));
}
@@ -902,8 +967,8 @@
mCallbackArgumentCaptor.getValue().onResult(true);
mMockConnection.invokeCallbacks();
- // The first time is triggered when window mode is activated, the second time is triggered
- // when the disable-magnification callback is triggered.
+ // The first time is triggered when window mode is activated.
+ // The second time is triggered when the disable-magnification callback is triggered.
verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_WINDOW));
}
@@ -1023,8 +1088,7 @@
.UiChangesForAccessibilityCallbacks> captor = ArgumentCaptor.forClass(
WindowManagerInternal.AccessibilityControllerInternal
.UiChangesForAccessibilityCallbacks.class);
- verify(mMockWindowManagerInternal.getAccessibilityController())
- .setUiChangesForAccessibilityCallbacks(captor.capture());
+ verify(mA11yController).setUiChangesForAccessibilityCallbacks(captor.capture());
return captor.getValue();
}
@@ -1072,95 +1136,42 @@
}
}
- /**
- * Stubs public methods to simulate the real behaviours.
- */
- private static class FullScreenMagnificationControllerStubber {
- private static final Region MAGNIFICATION_REGION = new Region(0, 0, 500, 600);
- private final FullScreenMagnificationController mScreenMagnificationController;
- private final FullScreenMagnificationController.MagnificationInfoChangedCallback
- mMagnificationChangedCallback;
- private boolean mIsMagnifying = false;
- private float mScale = 1.0f;
- private float mCenterX = MAGNIFICATION_REGION.getBounds().exactCenterX();
- private float mCenterY = MAGNIFICATION_REGION.getBounds().exactCenterY();
- private int mServiceId = -1;
+ private static class FullScreenMagnificationCtrInfoChangedCallbackDelegate implements
+ FullScreenMagnificationController.MagnificationInfoChangedCallback {
+ private FullScreenMagnificationController.MagnificationInfoChangedCallback mCallback;
- FullScreenMagnificationControllerStubber(
- FullScreenMagnificationController screenMagnificationController,
+ public void setDelegate(
FullScreenMagnificationController.MagnificationInfoChangedCallback callback) {
- mScreenMagnificationController = screenMagnificationController;
- mMagnificationChangedCallback = callback;
- stubMethods();
+ mCallback = callback;
}
- private void stubMethods() {
- doAnswer(invocation -> mIsMagnifying).when(mScreenMagnificationController).isMagnifying(
- TEST_DISPLAY);
- doAnswer(invocation -> mIsMagnifying).when(
- mScreenMagnificationController).isForceShowMagnifiableBounds(TEST_DISPLAY);
- doAnswer(invocation -> mScale).when(mScreenMagnificationController).getPersistedScale(
- TEST_DISPLAY);
- doAnswer(invocation -> mScale).when(mScreenMagnificationController).getScale(
- TEST_DISPLAY);
- doAnswer(invocation -> mCenterX).when(mScreenMagnificationController).getCenterX(
- TEST_DISPLAY);
- doAnswer(invocation -> mCenterY).when(mScreenMagnificationController).getCenterY(
- TEST_DISPLAY);
- doAnswer(invocation -> mServiceId).when(
- mScreenMagnificationController).getIdOfLastServiceToMagnify(TEST_DISPLAY);
-
- doAnswer(invocation -> {
- final Region outRegion = invocation.getArgument(1);
- outRegion.set(MAGNIFICATION_REGION);
- return null;
- }).when(mScreenMagnificationController).getMagnificationRegion(anyInt(),
- any(Region.class));
-
- Answer setScaleAndCenterStubAnswer = invocation -> {
- final float scale = invocation.getArgument(1);
- mScale = Float.isNaN(scale) ? mScale : scale;
- mIsMagnifying = mScale > 1.0f;
- if (mIsMagnifying) {
- mCenterX = invocation.getArgument(2);
- mCenterY = invocation.getArgument(3);
- mServiceId = invocation.getArgument(5);
- } else {
- reset();
- }
-
- final MagnificationConfig config = new MagnificationConfig.Builder().setMode(
- MODE_FULLSCREEN).setScale(mScale).setCenterX(mCenterX).setCenterY(
- mCenterY).build();
- mMagnificationChangedCallback.onFullScreenMagnificationChanged(TEST_DISPLAY,
- FullScreenMagnificationControllerStubber.MAGNIFICATION_REGION,
- config);
- return true;
- };
- doAnswer(setScaleAndCenterStubAnswer).when(
- mScreenMagnificationController).setScaleAndCenter(eq(TEST_DISPLAY),
- anyFloat(), anyFloat(), anyFloat(), any(), anyInt());
-
- doAnswer(setScaleAndCenterStubAnswer).when(
- mScreenMagnificationController).setScaleAndCenter(eq(TEST_DISPLAY),
- anyFloat(), anyFloat(), anyFloat(), anyBoolean(), anyInt());
-
- Answer resetStubAnswer = invocation -> {
- reset();
- return true;
- };
- doAnswer(resetStubAnswer).when(mScreenMagnificationController).reset(eq(TEST_DISPLAY),
- any(MagnificationAnimationCallback.class));
- doAnswer(resetStubAnswer).when(mScreenMagnificationController).reset(eq(TEST_DISPLAY),
- anyBoolean());
+ @Override
+ public void onRequestMagnificationSpec(int displayId, int serviceId) {
+ if (mCallback != null) {
+ mCallback.onRequestMagnificationSpec(displayId, serviceId);
+ }
}
- private void reset() {
- mScale = 1.0f;
- mIsMagnifying = false;
- mServiceId = -1;
- mCenterX = MAGNIFICATION_REGION.getBounds().exactCenterX();
- mCenterY = MAGNIFICATION_REGION.getBounds().exactCenterY();
+ @Override
+ public void onFullScreenMagnificationActivationState(int displayId, boolean activated) {
+ if (mCallback != null) {
+ mCallback.onFullScreenMagnificationActivationState(displayId, activated);
+ }
+ }
+
+ @Override
+ public void onImeWindowVisibilityChanged(int displayId, boolean shown) {
+ if (mCallback != null) {
+ mCallback.onImeWindowVisibilityChanged(displayId, shown);
+ }
+ }
+
+ @Override
+ public void onFullScreenMagnificationChanged(int displayId, @NonNull Region region,
+ @NonNull MagnificationConfig config) {
+ if (mCallback != null) {
+ mCallback.onFullScreenMagnificationChanged(displayId, region, config);
+ }
}
}
}
diff --git a/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java b/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
index 574aaf0..5f55f09 100644
--- a/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
@@ -97,6 +97,8 @@
mContentResolver = new MockContentResolver(mContext);
mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
when(mContext.getContentResolver()).thenReturn(mContentResolver);
+ when(mContext.getCacheDir()).thenReturn(originalContext.getCacheDir());
+ when(mContext.getAttributionSource()).thenReturn(originalContext.getAttributionSource());
when(mContext.getResources()).thenReturn(mResources);
// To prevent NullPointerException at the constructor of ActivityManagerConstants.
when(mResources.getStringArray(anyInt())).thenReturn(new String[0]);
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
index 759b049..eb99e30 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
@@ -369,6 +369,21 @@
}
@Test
+ public void isDeviceIdValid_defaultDeviceId_returnsFalse() {
+ assertThat(mVdm.isValidVirtualDeviceId(DEVICE_ID_DEFAULT)).isFalse();
+ }
+
+ @Test
+ public void isDeviceIdValid_validVirtualDeviceId_returnsTrue() {
+ assertThat(mVdm.isValidVirtualDeviceId(mDeviceImpl.getDeviceId())).isTrue();
+ }
+
+ @Test
+ public void isDeviceIdValid_nonExistentDeviceId_returnsFalse() {
+ assertThat(mVdm.isValidVirtualDeviceId(mDeviceImpl.getDeviceId() + 1)).isFalse();
+ }
+
+ @Test
public void getDevicePolicy_invalidDeviceId_returnsDefault() {
assertThat(mVdm.getDevicePolicy(DEVICE_ID_INVALID, POLICY_TYPE_SENSORS))
.isEqualTo(DEVICE_POLICY_DEFAULT);
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
index 2a6a979..4163f33 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
@@ -219,8 +219,10 @@
// Add the system user with a fake profile group already set up (this can happen in the real
// world if a managed profile is added and then removed).
- systemUserDataDir = addUser(UserHandle.USER_SYSTEM, UserInfo.FLAG_PRIMARY,
+ systemUserDataDir = addUser(UserHandle.USER_SYSTEM,
+ UserInfo.FLAG_PRIMARY | UserInfo.FLAG_MAIN,
UserManager.USER_TYPE_FULL_SYSTEM, UserHandle.USER_SYSTEM);
+ when(userManager.getMainUser()).thenReturn(UserHandle.SYSTEM);
// System user is always running.
setUserRunning(UserHandle.USER_SYSTEM, true);
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index f676a3f..2d252cb 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -39,6 +39,8 @@
import android.app.PropertyInvalidatedCache;
import android.companion.virtual.IVirtualDevice;
+import android.companion.virtual.IVirtualDeviceManager;
+import android.companion.virtual.VirtualDeviceManager;
import android.compat.testing.PlatformCompatChangeRule;
import android.content.Context;
import android.content.ContextWrapper;
@@ -173,6 +175,7 @@
private final DisplayManagerService.Injector mBasicInjector = new BasicInjector();
+ @Mock IVirtualDeviceManager mIVirtualDeviceManager;
@Mock InputManagerInternal mMockInputManagerInternal;
@Mock VirtualDeviceManagerInternal mMockVirtualDeviceManagerInternal;
@Mock IVirtualDisplayCallback.Stub mMockAppToken;
@@ -202,6 +205,8 @@
mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
+ VirtualDeviceManager vdm = new VirtualDeviceManager(mIVirtualDeviceManager, mContext);
+ when(mContext.getSystemService(VirtualDeviceManager.class)).thenReturn(vdm);
// Disable binder caches in this process.
PropertyInvalidatedCache.disableForTestMode();
setUpDisplay();
@@ -727,10 +732,8 @@
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
IVirtualDevice virtualDevice = mock(IVirtualDevice.class);
- when(mMockVirtualDeviceManagerInternal.isValidVirtualDevice(virtualDevice))
- .thenReturn(true);
when(virtualDevice.getDeviceId()).thenReturn(1);
-
+ when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true);
// Create a first virtual display. A display group should be created for this display on the
// virtual device.
final VirtualDisplayConfig.Builder builder1 =
@@ -780,9 +783,8 @@
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
IVirtualDevice virtualDevice = mock(IVirtualDevice.class);
- when(mMockVirtualDeviceManagerInternal.isValidVirtualDevice(virtualDevice))
- .thenReturn(true);
when(virtualDevice.getDeviceId()).thenReturn(1);
+ when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true);
// Create a first virtual display. A display group should be created for this display on the
// virtual device.
@@ -806,6 +808,8 @@
.setFlags(VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP)
.setUniqueId("uniqueId --- own display group");
+ when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true);
+
int displayId2 =
localService.createVirtualDisplay(
builder2.build(),
@@ -832,9 +836,8 @@
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
IVirtualDevice virtualDevice = mock(IVirtualDevice.class);
- when(mMockVirtualDeviceManagerInternal.isValidVirtualDevice(virtualDevice))
- .thenReturn(true);
when(virtualDevice.getDeviceId()).thenReturn(1);
+ when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true);
// Allow an ALWAYS_UNLOCKED display to be created.
when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY))
@@ -1062,7 +1065,7 @@
* a virtual device, even if ADD_TRUSTED_DISPLAY is not granted.
*/
@Test
- public void testOwnDisplayGroup_allowCreationWithVirtualDevice() {
+ public void testOwnDisplayGroup_allowCreationWithVirtualDevice() throws Exception {
DisplayManagerService displayManager =
new DisplayManagerService(mContext, mBasicInjector);
DisplayManagerInternal localService = displayManager.new LocalService();
@@ -1081,8 +1084,8 @@
builder.setUniqueId("uniqueId --- OWN_DISPLAY_GROUP");
IVirtualDevice virtualDevice = mock(IVirtualDevice.class);
- when(mMockVirtualDeviceManagerInternal.isValidVirtualDevice(virtualDevice))
- .thenReturn(true);
+ when(virtualDevice.getDeviceId()).thenReturn(1);
+ when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true);
int displayId = localService.createVirtualDisplay(builder.build(),
mMockAppToken /* callback */, virtualDevice /* virtualDeviceToken */,
diff --git a/services/tests/servicestests/src/com/android/server/display/HbmEventTest.java b/services/tests/servicestests/src/com/android/server/display/HbmEventTest.java
new file mode 100644
index 0000000..24fc348
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/HbmEventTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 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.server.display;
+
+import static org.junit.Assert.assertEquals;
+
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class HbmEventTest {
+ private long mStartTimeMillis;
+ private long mEndTimeMillis;
+ private HbmEvent mHbmEvent;
+
+ @Before
+ public void setUp() {
+ mStartTimeMillis = 10;
+ mEndTimeMillis = 20;
+ mHbmEvent = new HbmEvent(mStartTimeMillis, mEndTimeMillis);
+ }
+
+ @Test
+ public void getCorrectValues() {
+ assertEquals(mHbmEvent.getStartTimeMillis(), mStartTimeMillis);
+ assertEquals(mHbmEvent.getEndTimeMillis(), mEndTimeMillis);
+ }
+
+ @Test
+ public void toStringGeneratesExpectedString() {
+ String actualString = mHbmEvent.toString();
+ String expectedString = "HbmEvent: {startTimeMillis:" + mStartTimeMillis
+ + ", endTimeMillis: " + mEndTimeMillis + "}, total: "
+ + ((mEndTimeMillis - mStartTimeMillis) / 1000) + "]";
+ assertEquals(actualString, expectedString);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java b/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java
index a1e5ce7..2655c3f 100644
--- a/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java
@@ -96,6 +96,7 @@
private Binder mDisplayToken;
private String mDisplayUniqueId;
private Context mContextSpy;
+ private HighBrightnessModeMetadata mHighBrightnessModeMetadata;
@Rule
public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
@@ -118,6 +119,7 @@
mTestLooper = new TestLooper(mClock::now);
mDisplayToken = null;
mDisplayUniqueId = "unique_id";
+
mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContextSpy);
when(mContextSpy.getContentResolver()).thenReturn(resolver);
@@ -134,7 +136,8 @@
initHandler(null);
final HighBrightnessModeController hbmc = new HighBrightnessModeController(
mInjectorMock, mHandler, DISPLAY_WIDTH, DISPLAY_HEIGHT, mDisplayToken,
- mDisplayUniqueId, DEFAULT_MIN, DEFAULT_MAX, null, null, () -> {}, mContextSpy);
+ mDisplayUniqueId, DEFAULT_MIN, DEFAULT_MAX, null, null, () -> {},
+ null, mContextSpy);
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_OFF);
assertEquals(hbmc.getTransitionPoint(), HBM_TRANSITION_POINT_INVALID, 0.0f);
}
@@ -144,7 +147,8 @@
initHandler(null);
final HighBrightnessModeController hbmc = new HighBrightnessModeController(
mInjectorMock, mHandler, DISPLAY_WIDTH, DISPLAY_HEIGHT, mDisplayToken,
- mDisplayUniqueId, DEFAULT_MIN, DEFAULT_MAX, null, null, () -> {}, mContextSpy);
+ mDisplayUniqueId, DEFAULT_MIN, DEFAULT_MAX, null, null, () -> {},
+ null, mContextSpy);
hbmc.setAutoBrightnessEnabled(AUTO_BRIGHTNESS_ENABLED);
hbmc.onAmbientLuxChange(MINIMUM_LUX - 1); // below allowed range
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_OFF);
@@ -699,9 +703,12 @@
// Creates instance with standard initialization values.
private HighBrightnessModeController createDefaultHbm(OffsettableClock clock) {
initHandler(clock);
+ if (mHighBrightnessModeMetadata == null) {
+ mHighBrightnessModeMetadata = new HighBrightnessModeMetadata();
+ }
return new HighBrightnessModeController(mInjectorMock, mHandler, DISPLAY_WIDTH,
DISPLAY_HEIGHT, mDisplayToken, mDisplayUniqueId, DEFAULT_MIN, DEFAULT_MAX,
- DEFAULT_HBM_DATA, null, () -> {}, mContextSpy);
+ DEFAULT_HBM_DATA, null, () -> {}, mHighBrightnessModeMetadata, mContextSpy);
}
private void initHandler(OffsettableClock clock) {
diff --git a/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeMetadataTest.java b/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeMetadataTest.java
new file mode 100644
index 0000000..ede54e0
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeMetadataTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 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.server.display;
+
+import static org.junit.Assert.assertEquals;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class HighBrightnessModeMetadataTest {
+ private HighBrightnessModeMetadata mHighBrightnessModeMetadata;
+
+ private long mRunningStartTimeMillis = -1;
+
+ @Before
+ public void setUp() {
+ mHighBrightnessModeMetadata = new HighBrightnessModeMetadata();
+ }
+
+ @Test
+ public void checkDefaultValues() {
+ assertEquals(mHighBrightnessModeMetadata.getRunningStartTimeMillis(),
+ mRunningStartTimeMillis);
+ assertEquals(mHighBrightnessModeMetadata.getHbmEventQueue().size(), 0);
+ }
+
+ @Test
+ public void checkSetValues() {
+ mRunningStartTimeMillis = 10;
+ mHighBrightnessModeMetadata.setRunningStartTimeMillis(mRunningStartTimeMillis);
+ assertEquals(mHighBrightnessModeMetadata.getRunningStartTimeMillis(),
+ mRunningStartTimeMillis);
+ HbmEvent expectedHbmEvent = new HbmEvent(10, 20);
+ mHighBrightnessModeMetadata.addHbmEvent(expectedHbmEvent);
+ HbmEvent actualHbmEvent = mHighBrightnessModeMetadata.getHbmEventQueue().peekFirst();
+ assertEquals(expectedHbmEvent.toString(), actualHbmEvent.toString());
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategyTest.java b/services/tests/servicestests/src/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategyTest.java
index 4a32796..b92aa9c 100644
--- a/services/tests/servicestests/src/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategyTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategyTest.java
@@ -59,8 +59,6 @@
DisplayBrightnessState updatedDisplayBrightnessState =
mTemporaryBrightnessStrategy.updateBrightness(displayPowerRequest);
assertEquals(updatedDisplayBrightnessState, expectedDisplayBrightnessState);
- assertEquals(mTemporaryBrightnessStrategy.getTemporaryScreenBrightness(),
- Float.NaN, 0.0f);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
index 112db76..ad1ecf1 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
@@ -88,6 +88,7 @@
Looper looper = mTestLooper.getLooper();
mHdmiControlService.setIoLooper(looper);
mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(mContextSpy));
+ mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
mNativeWrapper = new FakeNativeWrapper();
HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
this.mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
index e4eecc6..3df0449 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
@@ -105,6 +105,7 @@
Looper looper = mTestLooper.getLooper();
hdmiControlService.setIoLooper(looper);
hdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(mContextSpy));
+ hdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
mNativeWrapper = new FakeNativeWrapper();
HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
hdmiControlService, mNativeWrapper, hdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
index 2cb46da..61ab99b 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
@@ -101,6 +101,7 @@
Looper looper = mTestLooper.getLooper();
hdmiControlService.setIoLooper(looper);
hdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(mContextSpy));
+ hdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
mNativeWrapper = new FakeNativeWrapper();
HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
hdmiControlService, mNativeWrapper, hdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeControlTest.java b/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeControlTest.java
index 8ff87e3..93b151e 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeControlTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeControlTest.java
@@ -154,6 +154,7 @@
HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE,
HdmiControlManager.VOLUME_CONTROL_DISABLED);
mHdmiControlService.setHdmiCecConfig(mHdmiCecConfig);
+ mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
mNativeWrapper = new FakeNativeWrapper();
mNativeWrapper.setPhysicalAddress(getPhysicalAddress());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java
index 3a57db9..c4c5c2a 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java
@@ -104,6 +104,7 @@
Looper looper = mTestLooper.getLooper();
mHdmiControlService.setIoLooper(looper);
mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(mContextSpy));
+ mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
mNativeWrapper = new FakeNativeWrapper();
HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
this.mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java
index 6a899e8..b571f43 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java
@@ -120,6 +120,7 @@
mHdmiControlService.setIoLooper(mMyLooper);
mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context));
+ mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
mNativeWrapper = new FakeNativeWrapper();
mHdmiCecController = HdmiCecController.createWithNativeWrapper(
mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java
index 0419768..4d8d25a 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java
@@ -129,6 +129,7 @@
mHdmiControlService.setIoLooper(mMyLooper);
mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context));
+ mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
mNativeWrapper = new FakeNativeWrapper();
mHdmiCecController = HdmiCecController.createWithNativeWrapper(
mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/FakeDeviceConfigWrapper.java b/services/tests/servicestests/src/com/android/server/hdmi/FakeDeviceConfigWrapper.java
new file mode 100644
index 0000000..8780329
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/FakeDeviceConfigWrapper.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 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.server.hdmi;
+
+import android.provider.DeviceConfig;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Fake class which stubs DeviceConfigWrapper (useful for testing).
+ */
+public class FakeDeviceConfigWrapper extends DeviceConfigWrapper {
+
+ // Set all boolean flags to true such that all unit tests are running with enabled features.
+ @Override
+ boolean getBoolean(String name, boolean defaultValue) {
+ return true;
+ }
+
+ @Override
+ void addOnPropertiesChangedListener(Executor mainExecutor,
+ DeviceConfig.OnPropertiesChangedListener onPropertiesChangedListener) {
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java
index d2fe6da..f27587e 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java
@@ -114,6 +114,7 @@
mHdmiCecNetwork = new HdmiCecNetwork(mHdmiControlServiceSpy,
mHdmiCecController, mHdmiMhlControllerStub);
mHdmiControlServiceSpy.setHdmiCecNetwork(mHdmiCecNetwork);
+ mHdmiControlServiceSpy.setDeviceConfig(new FakeDeviceConfigWrapper());
HdmiPortInfo[] hdmiPortInfos = new HdmiPortInfo[1];
hdmiPortInfos[0] =
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java
index 367f41d..a7232fe 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java
@@ -108,6 +108,7 @@
doAnswer(__ -> mCecVersion).when(mHdmiControlServiceSpy).getCecVersion();
doNothing().when(mHdmiControlServiceSpy)
.writeStringSystemProperty(anyString(), anyString());
+ mHdmiControlServiceSpy.setDeviceConfig(new FakeDeviceConfigWrapper());
mNativeWrapper = new FakeNativeWrapper();
mHdmiCecController = HdmiCecController.createWithNativeWrapper(
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
index de2c218..90acc99 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
@@ -175,6 +175,7 @@
HdmiControlManager.VOLUME_CONTROL_ENABLED);
mMyLooper = mTestLooper.getLooper();
mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context));
+ mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
mHdmiCecLocalDeviceAudioSystem = new HdmiCecLocalDeviceAudioSystem(mHdmiControlService);
mHdmiCecLocalDevicePlayback = new HdmiCecLocalDevicePlayback(mHdmiControlService) {
@Override
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index 3ed8983..dfab207 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -141,6 +141,7 @@
};
mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context));
+ mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
mHdmiControlService.setIoLooper(mMyLooper);
mNativeWrapper = new FakeNativeWrapper();
mHdmiCecController = HdmiCecController.createWithNativeWrapper(
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
index b30118c..3796ce9 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
@@ -179,6 +179,7 @@
};
mHdmiControlService.setIoLooper(mTestLooper.getLooper());
mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context));
+ mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
mNativeWrapper = new FakeNativeWrapper();
mHdmiCecController = HdmiCecController.createWithNativeWrapper(
mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
index 5dd29fd..233fd6e 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -180,6 +180,7 @@
mHdmiControlService.setIoLooper(mMyLooper);
mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context));
+ mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
mNativeWrapper = new FakeNativeWrapper();
mHdmiCecController = HdmiCecController.createWithNativeWrapper(
mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java
index 4e5336e..8e5bb13 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java
@@ -91,6 +91,7 @@
mHdmiControlService.setIoLooper(myLooper);
mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(contextSpy));
+ mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
mNativeWrapper = new FakeNativeWrapper();
HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
index aa49a62..6c77405 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
@@ -119,6 +119,7 @@
mHdmiControlServiceSpy.setIoLooper(mMyLooper);
mHdmiControlServiceSpy.setHdmiCecConfig(hdmiCecConfig);
+ mHdmiControlServiceSpy.setDeviceConfig(new FakeDeviceConfigWrapper());
mHdmiControlServiceSpy.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
mNativeWrapper = new FakeNativeWrapper();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiEarcLocalDeviceTxTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiEarcLocalDeviceTxTest.java
index bf44e09..c79e219 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiEarcLocalDeviceTxTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiEarcLocalDeviceTxTest.java
@@ -121,6 +121,7 @@
mHdmiControlService.setIoLooper(mMyLooper);
mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context));
+ mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
mNativeWrapper = new FakeNativeWrapper();
mHdmiCecController = HdmiCecController.createWithNativeWrapper(
mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java
index 9b8cedf..b0e8ca7 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java
@@ -120,6 +120,7 @@
mNativeWrapper = new FakeNativeWrapper();
HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
this.mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
+ mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
mHdmiControlService.setCecController(hdmiCecController);
mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
mHdmiControlService.initService();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java
index f72ac71..a623841 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java
@@ -93,6 +93,7 @@
Looper looper = mTestLooper.getLooper();
mHdmiControlService.setIoLooper(looper);
mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(mContextSpy));
+ mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
mNativeWrapper = new FakeNativeWrapper();
HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
this.mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java
index f719ca1..1c19341 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java
@@ -116,6 +116,7 @@
mHdmiControlService.setIoLooper(mMyLooper);
mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context));
+ mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
mNativeWrapper = new FakeNativeWrapper();
mHdmiCecController = HdmiCecController.createWithNativeWrapper(
mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java
index be62df8..4e8cf4a 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java
@@ -175,6 +175,7 @@
mNativeWrapper = new FakeNativeWrapper();
mHdmiCecController = HdmiCecController.createWithNativeWrapper(
mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
+ mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
mHdmiControlService.setCecController(mHdmiCecController);
mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
HdmiPortInfo[] hdmiPortInfos = new HdmiPortInfo[1];
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryActionTest.java
index e3c8939..cac7815 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryActionTest.java
@@ -89,6 +89,7 @@
mLooper = mTestLooper.getLooper();
mHdmiControlServiceSpy.setIoLooper(mLooper);
mHdmiControlServiceSpy.setHdmiCecConfig(new FakeHdmiCecConfig(mContextSpy));
+ mHdmiControlServiceSpy.setDeviceConfig(new FakeDeviceConfigWrapper());
mNativeWrapper = new FakeNativeWrapper();
mNativeWrapper.setPhysicalAddress(mPhysicalAddress);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java
index e7557fe..70f9e5c 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java
@@ -97,6 +97,7 @@
mNativeWrapper = new FakeNativeWrapper();
HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
+ mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
mHdmiControlService.setCecController(hdmiCecController);
mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
HdmiPortInfo[] hdmiPortInfos = new HdmiPortInfo[2];
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
index c2f706a..b13ef4f 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
@@ -168,6 +168,7 @@
Looper looper = mTestLooper.getLooper();
hdmiControlService.setIoLooper(looper);
hdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context));
+ hdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper());
HdmiCecController.NativeWrapper nativeWrapper = new FakeNativeWrapper();
HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
hdmiControlService, nativeWrapper, hdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/input/BatteryControllerTests.kt b/services/tests/servicestests/src/com/android/server/input/BatteryControllerTests.kt
index ecd9d89..3ce747f 100644
--- a/services/tests/servicestests/src/com/android/server/input/BatteryControllerTests.kt
+++ b/services/tests/servicestests/src/com/android/server/input/BatteryControllerTests.kt
@@ -16,7 +16,9 @@
package com.android.server.input
+import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothManager
import android.content.Context
import android.content.ContextWrapper
import android.hardware.BatteryState.STATUS_CHARGING
@@ -246,6 +248,11 @@
notifyDeviceChanged(deviceId, hasBattery, supportsUsi)
}
+ private fun createBluetoothDevice(address: String): BluetoothDevice {
+ return context.getSystemService(BluetoothManager::class.java)!!
+ .adapter.getRemoteDevice(address)
+ }
+
@After
fun tearDown() {
InputManager.clearInstance()
@@ -656,29 +663,31 @@
addInputDevice(SECOND_BT_DEVICE_ID)
testLooper.dispatchNext()
- // Ensure that a BT battery listener is not added when there are no monitored BT devices.
- verify(bluetoothBatteryManager, never()).addListener(any())
+ // Listen to a non-Bluetooth device and ensure that the BT battery listener is not added
+ // when there are no monitored BT devices.
+ val listener = createMockListener()
+ batteryController.registerBatteryListener(DEVICE_ID, listener, PID)
+ verify(bluetoothBatteryManager, never()).addBatteryListener(any())
val bluetoothListener = ArgumentCaptor.forClass(BluetoothBatteryListener::class.java)
- val listener = createMockListener()
// The BT battery listener is added when the first BT input device is monitored.
batteryController.registerBatteryListener(BT_DEVICE_ID, listener, PID)
- verify(bluetoothBatteryManager).addListener(bluetoothListener.capture())
+ verify(bluetoothBatteryManager).addBatteryListener(bluetoothListener.capture())
// The BT listener is only added once for all BT devices.
batteryController.registerBatteryListener(SECOND_BT_DEVICE_ID, listener, PID)
- verify(bluetoothBatteryManager, times(1)).addListener(any())
+ verify(bluetoothBatteryManager, times(1)).addBatteryListener(any())
// The BT listener is only removed when there are no monitored BT devices.
batteryController.unregisterBatteryListener(BT_DEVICE_ID, listener, PID)
- verify(bluetoothBatteryManager, never()).removeListener(any())
+ verify(bluetoothBatteryManager, never()).removeBatteryListener(any())
`when`(iInputManager.getInputDeviceBluetoothAddress(SECOND_BT_DEVICE_ID))
.thenReturn(null)
notifyDeviceChanged(SECOND_BT_DEVICE_ID)
testLooper.dispatchNext()
- verify(bluetoothBatteryManager).removeListener(bluetoothListener.value)
+ verify(bluetoothBatteryManager).removeBatteryListener(bluetoothListener.value)
}
@Test
@@ -690,15 +699,14 @@
val bluetoothListener = ArgumentCaptor.forClass(BluetoothBatteryListener::class.java)
val listener = createMockListener()
batteryController.registerBatteryListener(BT_DEVICE_ID, listener, PID)
- verify(bluetoothBatteryManager).addListener(bluetoothListener.capture())
+ verify(bluetoothBatteryManager).addBatteryListener(bluetoothListener.capture())
listener.verifyNotified(BT_DEVICE_ID, capacity = 0.21f)
// When the state has not changed, the listener is not notified again.
- bluetoothListener.value!!.onBluetoothBatteryChanged(TIMESTAMP, "AA:BB:CC:DD:EE:FF")
+ bluetoothListener.value!!.onBluetoothBatteryChanged(TIMESTAMP, "AA:BB:CC:DD:EE:FF", 21)
listener.verifyNotified(BT_DEVICE_ID, mode = times(1), capacity = 0.21f)
- `when`(bluetoothBatteryManager.getBatteryLevel(eq("AA:BB:CC:DD:EE:FF"))).thenReturn(25)
- bluetoothListener.value!!.onBluetoothBatteryChanged(TIMESTAMP, "AA:BB:CC:DD:EE:FF")
+ bluetoothListener.value!!.onBluetoothBatteryChanged(TIMESTAMP, "AA:BB:CC:DD:EE:FF", 25)
listener.verifyNotified(BT_DEVICE_ID, capacity = 0.25f)
}
@@ -717,7 +725,7 @@
// When the device is first monitored and both native and BT battery is available,
// the latter is used.
batteryController.registerBatteryListener(BT_DEVICE_ID, listener, PID)
- verify(bluetoothBatteryManager).addListener(bluetoothListener.capture())
+ verify(bluetoothBatteryManager).addBatteryListener(bluetoothListener.capture())
verify(uEventManager).addListener(uEventListener.capture(), any())
listener.verifyNotified(BT_DEVICE_ID, capacity = 0.21f)
assertThat("battery state matches", batteryController.getBatteryState(BT_DEVICE_ID),
@@ -744,25 +752,144 @@
val uEventListener = ArgumentCaptor.forClass(UEventBatteryListener::class.java)
batteryController.registerBatteryListener(BT_DEVICE_ID, listener, PID)
- verify(bluetoothBatteryManager).addListener(bluetoothListener.capture())
+ verify(bluetoothBatteryManager).addBatteryListener(bluetoothListener.capture())
verify(uEventManager).addListener(uEventListener.capture(), any())
listener.verifyNotified(BT_DEVICE_ID, capacity = 0.21f)
// Fall back to the native state when BT is off.
- `when`(bluetoothBatteryManager.getBatteryLevel(eq("AA:BB:CC:DD:EE:FF")))
- .thenReturn(BluetoothDevice.BATTERY_LEVEL_BLUETOOTH_OFF)
- bluetoothListener.value!!.onBluetoothBatteryChanged(TIMESTAMP, "AA:BB:CC:DD:EE:FF")
+ bluetoothListener.value!!.onBluetoothBatteryChanged(TIMESTAMP, "AA:BB:CC:DD:EE:FF",
+ BluetoothDevice.BATTERY_LEVEL_BLUETOOTH_OFF)
listener.verifyNotified(BT_DEVICE_ID, capacity = 0.98f)
- `when`(bluetoothBatteryManager.getBatteryLevel(eq("AA:BB:CC:DD:EE:FF"))).thenReturn(22)
- bluetoothListener.value!!.onBluetoothBatteryChanged(TIMESTAMP, "AA:BB:CC:DD:EE:FF")
- verify(bluetoothBatteryManager).addListener(bluetoothListener.capture())
+ bluetoothListener.value!!.onBluetoothBatteryChanged(TIMESTAMP, "AA:BB:CC:DD:EE:FF", 22)
+ verify(bluetoothBatteryManager).addBatteryListener(bluetoothListener.capture())
listener.verifyNotified(BT_DEVICE_ID, capacity = 0.22f)
// Fall back to the native state when BT battery is unknown.
- `when`(bluetoothBatteryManager.getBatteryLevel(eq("AA:BB:CC:DD:EE:FF")))
- .thenReturn(BluetoothDevice.BATTERY_LEVEL_UNKNOWN)
- bluetoothListener.value!!.onBluetoothBatteryChanged(TIMESTAMP, "AA:BB:CC:DD:EE:FF")
+ bluetoothListener.value!!.onBluetoothBatteryChanged(TIMESTAMP, "AA:BB:CC:DD:EE:FF",
+ BluetoothDevice.BATTERY_LEVEL_UNKNOWN)
listener.verifyNotified(BT_DEVICE_ID, mode = times(2), capacity = 0.98f)
}
+
+ @Test
+ fun testRegisterBluetoothMetadataListenerForMonitoredBluetoothDevices() {
+ `when`(iInputManager.getInputDeviceBluetoothAddress(BT_DEVICE_ID))
+ .thenReturn("AA:BB:CC:DD:EE:FF")
+ `when`(iInputManager.getInputDeviceBluetoothAddress(SECOND_BT_DEVICE_ID))
+ .thenReturn("11:22:33:44:55:66")
+ addInputDevice(BT_DEVICE_ID)
+ testLooper.dispatchNext()
+ addInputDevice(SECOND_BT_DEVICE_ID)
+ testLooper.dispatchNext()
+
+ // Listen to a non-Bluetooth device and ensure that the metadata listener is not added when
+ // there are no monitored BT devices.
+ val listener = createMockListener()
+ batteryController.registerBatteryListener(DEVICE_ID, listener, PID)
+ verify(bluetoothBatteryManager, never()).addMetadataListener(any(), any())
+
+ val metadataListener1 = ArgumentCaptor.forClass(
+ BluetoothAdapter.OnMetadataChangedListener::class.java)
+ val metadataListener2 = ArgumentCaptor.forClass(
+ BluetoothAdapter.OnMetadataChangedListener::class.java)
+
+ // The metadata listener is added when the first BT input device is monitored.
+ batteryController.registerBatteryListener(BT_DEVICE_ID, listener, PID)
+ verify(bluetoothBatteryManager)
+ .addMetadataListener(eq("AA:BB:CC:DD:EE:FF"), metadataListener1.capture())
+
+ // There is one metadata listener added for each BT device.
+ batteryController.registerBatteryListener(SECOND_BT_DEVICE_ID, listener, PID)
+ verify(bluetoothBatteryManager)
+ .addMetadataListener(eq("11:22:33:44:55:66"), metadataListener2.capture())
+
+ // The metadata listener is removed when the device is no longer monitored.
+ batteryController.unregisterBatteryListener(BT_DEVICE_ID, listener, PID)
+ verify(bluetoothBatteryManager)
+ .removeMetadataListener("AA:BB:CC:DD:EE:FF", metadataListener1.value)
+
+ `when`(iInputManager.getInputDeviceBluetoothAddress(SECOND_BT_DEVICE_ID))
+ .thenReturn(null)
+ notifyDeviceChanged(SECOND_BT_DEVICE_ID)
+ testLooper.dispatchNext()
+ verify(bluetoothBatteryManager)
+ .removeMetadataListener("11:22:33:44:55:66", metadataListener2.value)
+ }
+
+ @Test
+ fun testNotifiesBluetoothMetadataBatteryChanges() {
+ `when`(iInputManager.getInputDeviceBluetoothAddress(BT_DEVICE_ID))
+ .thenReturn("AA:BB:CC:DD:EE:FF")
+ `when`(bluetoothBatteryManager.getMetadata("AA:BB:CC:DD:EE:FF",
+ BluetoothDevice.METADATA_MAIN_BATTERY))
+ .thenReturn("21".toByteArray())
+ addInputDevice(BT_DEVICE_ID)
+ val metadataListener = ArgumentCaptor.forClass(
+ BluetoothAdapter.OnMetadataChangedListener::class.java)
+ val listener = createMockListener()
+ val bluetoothDevice = createBluetoothDevice("AA:BB:CC:DD:EE:FF")
+ batteryController.registerBatteryListener(BT_DEVICE_ID, listener, PID)
+ verify(bluetoothBatteryManager)
+ .addMetadataListener(eq("AA:BB:CC:DD:EE:FF"), metadataListener.capture())
+ listener.verifyNotified(BT_DEVICE_ID, capacity = 0.21f, status = STATUS_UNKNOWN)
+
+ // When the state has not changed, the listener is not notified again.
+ metadataListener.value!!.onMetadataChanged(
+ bluetoothDevice, BluetoothDevice.METADATA_MAIN_BATTERY, "21".toByteArray())
+ listener.verifyNotified(BT_DEVICE_ID, mode = times(1), capacity = 0.21f)
+
+ metadataListener.value!!.onMetadataChanged(
+ bluetoothDevice, BluetoothDevice.METADATA_MAIN_BATTERY, "25".toByteArray())
+ listener.verifyNotified(BT_DEVICE_ID, capacity = 0.25f, status = STATUS_UNKNOWN)
+
+ metadataListener.value!!.onMetadataChanged(
+ bluetoothDevice, BluetoothDevice.METADATA_MAIN_CHARGING, "true".toByteArray())
+ listener.verifyNotified(BT_DEVICE_ID, capacity = 0.25f, status = STATUS_CHARGING)
+
+ metadataListener.value!!.onMetadataChanged(
+ bluetoothDevice, BluetoothDevice.METADATA_MAIN_CHARGING, "false".toByteArray())
+ listener.verifyNotified(BT_DEVICE_ID, capacity = 0.25f, status = STATUS_DISCHARGING)
+
+ metadataListener.value!!.onMetadataChanged(
+ bluetoothDevice, BluetoothDevice.METADATA_MAIN_CHARGING, null)
+ listener.verifyNotified(BT_DEVICE_ID, mode = times(2), capacity = 0.25f,
+ status = STATUS_UNKNOWN)
+ }
+
+ @Test
+ fun testBluetoothMetadataBatteryIsPrioritized() {
+ `when`(iInputManager.getInputDeviceBluetoothAddress(BT_DEVICE_ID))
+ .thenReturn("AA:BB:CC:DD:EE:FF")
+ `when`(bluetoothBatteryManager.getBatteryLevel(eq("AA:BB:CC:DD:EE:FF"))).thenReturn(21)
+ `when`(bluetoothBatteryManager.getMetadata("AA:BB:CC:DD:EE:FF",
+ BluetoothDevice.METADATA_MAIN_BATTERY))
+ .thenReturn("22".toByteArray())
+ addInputDevice(BT_DEVICE_ID)
+ val bluetoothListener = ArgumentCaptor.forClass(BluetoothBatteryListener::class.java)
+ val metadataListener = ArgumentCaptor.forClass(
+ BluetoothAdapter.OnMetadataChangedListener::class.java)
+ val listener = createMockListener()
+ val bluetoothDevice = createBluetoothDevice("AA:BB:CC:DD:EE:FF")
+ batteryController.registerBatteryListener(BT_DEVICE_ID, listener, PID)
+
+ verify(bluetoothBatteryManager).addBatteryListener(bluetoothListener.capture())
+ verify(bluetoothBatteryManager)
+ .addMetadataListener(eq("AA:BB:CC:DD:EE:FF"), metadataListener.capture())
+ listener.verifyNotified(BT_DEVICE_ID, capacity = 0.22f)
+
+ // A change in the Bluetooth battery level has no effect while there is a valid battery
+ // level obtained through the metadata.
+ bluetoothListener.value!!.onBluetoothBatteryChanged(TIMESTAMP, "AA:BB:CC:DD:EE:FF", 23)
+ listener.verifyNotified(BT_DEVICE_ID, mode = never(), capacity = 0.23f)
+
+ metadataListener.value!!.onMetadataChanged(
+ bluetoothDevice, BluetoothDevice.METADATA_MAIN_BATTERY, "24".toByteArray())
+ listener.verifyNotified(BT_DEVICE_ID, capacity = 0.24f)
+
+ // When the battery level from the metadata is no longer valid, we fall back to using the
+ // Bluetooth battery level.
+ metadataListener.value!!.onMetadataChanged(
+ bluetoothDevice, BluetoothDevice.METADATA_MAIN_BATTERY, null)
+ listener.verifyNotified(BT_DEVICE_ID, capacity = 0.23f)
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/job/BiasSchedulingTest.java b/services/tests/servicestests/src/com/android/server/job/BiasSchedulingTest.java
index e886e7d..56d01b0 100644
--- a/services/tests/servicestests/src/com/android/server/job/BiasSchedulingTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/BiasSchedulingTest.java
@@ -57,14 +57,14 @@
}
public void testLowerBiasJobPreempted() throws Exception {
- for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT; ++i) {
+ for (int i = 0; i < JobConcurrencyManager.MAX_CONCURRENCY_LIMIT; ++i) {
JobInfo job = new JobInfo.Builder(100 + i, sJobServiceComponent)
.setBias(LOW_BIAS)
.setOverrideDeadline(0)
.build();
mJobScheduler.schedule(job);
}
- final int higherBiasJobId = 100 + JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT;
+ final int higherBiasJobId = 100 + JobConcurrencyManager.MAX_CONCURRENCY_LIMIT;
JobInfo jobHigher = new JobInfo.Builder(higherBiasJobId, sJobServiceComponent)
.setBias(HIGH_BIAS)
.setMinimumLatency(2000)
@@ -88,14 +88,14 @@
}
public void testHigherBiasJobNotPreempted() throws Exception {
- for (int i = 0; i < JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT; ++i) {
+ for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT; ++i) {
JobInfo job = new JobInfo.Builder(100 + i, sJobServiceComponent)
.setBias(HIGH_BIAS)
.setOverrideDeadline(0)
.build();
mJobScheduler.schedule(job);
}
- final int lowerBiasJobId = 100 + JobConcurrencyManager.STANDARD_CONCURRENCY_LIMIT;
+ final int lowerBiasJobId = 100 + JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT;
JobInfo jobLower = new JobInfo.Builder(lowerBiasJobId, sJobServiceComponent)
.setBias(LOW_BIAS)
.setMinimumLatency(2000)
diff --git a/services/tests/servicestests/src/com/android/server/job/WorkCountTrackerTest.java b/services/tests/servicestests/src/com/android/server/job/WorkCountTrackerTest.java
index dd9ae65..0fd6a9e 100644
--- a/services/tests/servicestests/src/com/android/server/job/WorkCountTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/WorkCountTrackerTest.java
@@ -16,6 +16,7 @@
package com.android.server.job;
+import static com.android.server.job.JobConcurrencyManager.MAX_CONCURRENCY_LIMIT;
import static com.android.server.job.JobConcurrencyManager.NUM_WORK_TYPES;
import static com.android.server.job.JobConcurrencyManager.WORK_TYPE_BG;
import static com.android.server.job.JobConcurrencyManager.WORK_TYPE_BGUSER;
@@ -191,10 +192,10 @@
}
private void recount(Jobs jobs, int totalMax,
- @NonNull List<Pair<Integer, Integer>> minLimits,
- @NonNull List<Pair<Integer, Integer>> maxLimits) {
+ @NonNull List<Pair<Integer, Float>> minLimitRatios,
+ @NonNull List<Pair<Integer, Float>> maxLimitRatios) {
mWorkCountTracker.setConfig(new JobConcurrencyManager.WorkTypeConfig(
- "test", totalMax, minLimits, maxLimits));
+ "test", MAX_CONCURRENCY_LIMIT, totalMax, minLimitRatios, maxLimitRatios));
mWorkCountTracker.resetCounts();
for (int i = 0; i < jobs.running.size(); ++i) {
@@ -259,18 +260,18 @@
* Used by the following testRandom* tests.
*/
private void checkRandom(Jobs jobs, int numTests, int totalMax,
- @NonNull List<Pair<Integer, Integer>> minLimits,
- @NonNull List<Pair<Integer, Integer>> maxLimits,
+ @NonNull List<Pair<Integer, Float>> minLimitRatios,
+ @NonNull List<Pair<Integer, Float>> maxLimitRatios,
double probStart, double[] typeCdf, double[] numTypesCdf, double probStop) {
int minExpected = 0;
- for (Pair<Integer, Integer> minLimit : minLimits) {
- minExpected = Math.min(minLimit.second, minExpected);
+ for (Pair<Integer, Float> minLimit : minLimitRatios) {
+ minExpected = Math.min((int) (minLimit.second * MAX_CONCURRENCY_LIMIT), minExpected);
}
for (int i = 0; i < numTests; i++) {
jobs.maybeFinishJobs(probStop);
jobs.maybeEnqueueJobs(probStart, typeCdf, numTypesCdf);
- recount(jobs, totalMax, minLimits, maxLimits);
+ recount(jobs, totalMax, minLimitRatios, maxLimitRatios);
final int numPending = jobs.pendingMultiTypes.size();
startPendingJobs(jobs);
@@ -284,9 +285,11 @@
}
assertThat(totalRunning).isAtMost(totalMax);
assertThat(totalRunning).isAtLeast(Math.min(minExpected, numPending));
- for (Pair<Integer, Integer> maxLimit : maxLimits) {
- assertWithMessage("Work type " + maxLimit.first + " is running too many jobs")
- .that(jobs.running.get(maxLimit.first)).isAtMost(maxLimit.second);
+ for (Pair<Integer, Float> maxLimitRatio : maxLimitRatios) {
+ final int workType = maxLimitRatio.first;
+ final int maxLimit = (int) (maxLimitRatio.second * MAX_CONCURRENCY_LIMIT);
+ assertWithMessage("Work type " + workType + " is running too many jobs")
+ .that(jobs.running.get(workType)).isAtMost(maxLimit);
}
}
}
@@ -302,12 +305,14 @@
final int numTests = 5000;
final int totalMax = 6;
- final List<Pair<Integer, Integer>> maxLimits = List.of(Pair.create(WORK_TYPE_BG, 4));
- final List<Pair<Integer, Integer>> minLimits = List.of(Pair.create(WORK_TYPE_BG, 2));
+ final List<Pair<Integer, Float>> minLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3));
+ final List<Pair<Integer, Float>> maxLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3));
final double probStop = 0.1;
final double probStart = 0.1;
- checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
+ checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
EQUAL_PROBABILITY_CDF, EQUAL_PROBABILITY_CDF, probStop);
}
@@ -317,15 +322,15 @@
final int numTests = 5000;
final int totalMax = 2;
- final List<Pair<Integer, Integer>> maxLimits =
- List.of(Pair.create(WORK_TYPE_BG, 2), Pair.create(WORK_TYPE_BGUSER, 1));
- final List<Pair<Integer, Integer>> minLimits = List.of();
+ final List<Pair<Integer, Float>> minLimitRatios = List.of();
+ final List<Pair<Integer, Float>> maxLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, .5f));
final double probStop = 0.5;
final double[] cdf = buildWorkTypeCdf(0.5, 0, 0, 0.5, 0, 0);
final double[] numTypesCdf = buildCdf(.5, .3, .15, .05);
final double probStart = 0.5;
- checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
+ checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
cdf, numTypesCdf, probStop);
}
@@ -335,15 +340,15 @@
final int numTests = 5000;
final int totalMax = 2;
- final List<Pair<Integer, Integer>> maxLimits =
- List.of(Pair.create(WORK_TYPE_BG, 2), Pair.create(WORK_TYPE_BGUSER, 1));
- final List<Pair<Integer, Integer>> minLimits = List.of(Pair.create(WORK_TYPE_BG, 2));
+ final List<Pair<Integer, Float>> minLimitRatios = List.of(Pair.create(WORK_TYPE_BG, .99f));
+ final List<Pair<Integer, Float>> maxLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, .5f));
final double probStop = 0.5;
final double[] cdf = buildWorkTypeCdf(1.0 / 3, 0, 0, 1.0 / 3, 0, 1.0 / 3);
final double[] numTypesCdf = buildCdf(.75, .2, .05);
final double probStart = 0.5;
- checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
+ checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
cdf, numTypesCdf, probStop);
}
@@ -353,15 +358,15 @@
final int numTests = 5000;
final int totalMax = 10;
- final List<Pair<Integer, Integer>> maxLimits =
- List.of(Pair.create(WORK_TYPE_BG, 2), Pair.create(WORK_TYPE_BGUSER, 1));
- final List<Pair<Integer, Integer>> minLimits = List.of();
+ final List<Pair<Integer, Float>> minLimitRatios = List.of();
+ final List<Pair<Integer, Float>> maxLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, .2f), Pair.create(WORK_TYPE_BGUSER, .1f));
final double probStop = 0.5;
final double[] cdf = buildWorkTypeCdf(1.0 / 3, 0, 0, 1.0 / 3, 0, 1.0 / 3);
final double[] numTypesCdf = buildCdf(.05, .95);
final double probStart = 0.5;
- checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
+ checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
cdf, numTypesCdf, probStop);
}
@@ -371,15 +376,17 @@
final int numTests = 5000;
final int totalMax = 6;
- final List<Pair<Integer, Integer>> maxLimits =
- List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2));
- final List<Pair<Integer, Integer>> minLimits = List.of(Pair.create(WORK_TYPE_BG, 2));
+ final List<Pair<Integer, Float>> minLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3));
+ final List<Pair<Integer, Float>> maxLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER, 2.0f / 3));
final double probStop = 0.5;
final double[] cdf = buildWorkTypeCdf(0.1, 0, 0, 0.8, 0.02, .08);
final double[] numTypesCdf = buildCdf(.5, .3, .15, .05);
final double probStart = 0.5;
- checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
+ checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
cdf, numTypesCdf, probStop);
}
@@ -389,15 +396,17 @@
final int numTests = 5000;
final int totalMax = 6;
- final List<Pair<Integer, Integer>> maxLimits =
- List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2));
- final List<Pair<Integer, Integer>> minLimits = List.of(Pair.create(WORK_TYPE_BG, 2));
+ final List<Pair<Integer, Float>> minLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3));
+ final List<Pair<Integer, Float>> maxLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 3));
final double probStop = 0.5;
final double[] cdf = buildWorkTypeCdf(0.85, 0.05, 0, 0.1, 0, 0);
final double[] numTypesCdf = buildCdf(1);
final double probStart = 0.5;
- checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
+ checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
cdf, numTypesCdf, probStop);
}
@@ -407,15 +416,17 @@
final int numTests = 5000;
final int totalMax = 6;
- final List<Pair<Integer, Integer>> maxLimits =
- List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2));
- final List<Pair<Integer, Integer>> minLimits = List.of(Pair.create(WORK_TYPE_BG, 2));
+ final List<Pair<Integer, Float>> minLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3));
+ final List<Pair<Integer, Float>> maxLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 3));
final double probStop = 0.4;
final double[] cdf = buildWorkTypeCdf(0.1, 0, 0, 0.1, 0.05, .75);
final double[] numTypesCdf = buildCdf(0.5, 0.5);
final double probStart = 0.5;
- checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
+ checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
cdf, numTypesCdf, probStop);
}
@@ -425,16 +436,18 @@
final int numTests = 5000;
final int totalMax = 6;
- final List<Pair<Integer, Integer>> maxLimits =
- List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2));
- final List<Pair<Integer, Integer>> minLimits =
- List.of(Pair.create(WORK_TYPE_BG, 2), Pair.create(WORK_TYPE_BGUSER, 1));
+ final List<Pair<Integer, Float>> minLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 6));
+ final List<Pair<Integer, Float>> maxLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 3));
final double probStop = 0.4;
final double[] cdf = buildWorkTypeCdf(0.8, 0.1, 0, 0.05, 0, 0.05);
final double[] numTypesCdf = buildCdf(1);
final double probStart = 0.5;
- checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
+ checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
cdf, numTypesCdf, probStop);
}
@@ -444,16 +457,18 @@
final int numTests = 5000;
final int totalMax = 6;
- final List<Pair<Integer, Integer>> maxLimits =
- List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2));
- final List<Pair<Integer, Integer>> minLimits =
- List.of(Pair.create(WORK_TYPE_BG, 2), Pair.create(WORK_TYPE_BGUSER, 1));
+ final List<Pair<Integer, Float>> minLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 6));
+ final List<Pair<Integer, Float>> maxLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 3));
final double probStop = 0.5;
final double[] cdf = buildWorkTypeCdf(0, 0, 0, 0.5, 0, 0.5);
final double[] numTypesCdf = buildCdf(1);
final double probStart = 0.5;
- checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
+ checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
cdf, numTypesCdf, probStop);
}
@@ -463,16 +478,18 @@
final int numTests = 5000;
final int totalMax = 6;
- final List<Pair<Integer, Integer>> maxLimits =
- List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2));
- final List<Pair<Integer, Integer>> minLimits =
- List.of(Pair.create(WORK_TYPE_BG, 2), Pair.create(WORK_TYPE_BGUSER, 1));
+ final List<Pair<Integer, Float>> minLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 6));
+ final List<Pair<Integer, Float>> maxLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 3));
final double probStop = 0.5;
final double[] cdf = buildWorkTypeCdf(0, 0, 0, 0.1, 0, 0.9);
final double[] numTypesCdf = buildCdf(0.9, 0.1);
final double probStart = 0.5;
- checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
+ checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
cdf, numTypesCdf, probStop);
}
@@ -482,16 +499,18 @@
final int numTests = 5000;
final int totalMax = 6;
- final List<Pair<Integer, Integer>> maxLimits =
- List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2));
- final List<Pair<Integer, Integer>> minLimits =
- List.of(Pair.create(WORK_TYPE_BG, 2), Pair.create(WORK_TYPE_BGUSER, 1));
+ final List<Pair<Integer, Float>> minLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 6));
+ final List<Pair<Integer, Float>> maxLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 3));
final double probStop = 0.5;
final double[] cdf = buildWorkTypeCdf(0, 0, 0, 0.9, 0, 0.1);
final double[] numTypesCdf = buildCdf(1);
final double probStart = 0.5;
- checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
+ checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
cdf, numTypesCdf, probStop);
}
@@ -501,15 +520,16 @@
final int numTests = 5000;
final int totalMax = 6;
- final List<Pair<Integer, Integer>> maxLimits = List.of(Pair.create(WORK_TYPE_BG, 4));
- final List<Pair<Integer, Integer>> minLimits =
- List.of(Pair.create(WORK_TYPE_EJ, 2), Pair.create(WORK_TYPE_BG, 2));
+ final List<Pair<Integer, Float>> minLimitRatios =
+ List.of(Pair.create(WORK_TYPE_EJ, 1.0f / 3), Pair.create(WORK_TYPE_BG, 1.0f / 3));
+ final List<Pair<Integer, Float>> maxLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3));
final double probStop = 0.4;
final double[] cdf = buildWorkTypeCdf(0.5, 0, 0.5, 0, 0, 0);
final double[] numTypesCdf = buildCdf(0.1, 0.7, 0.2);
final double probStart = 0.5;
- checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
+ checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
cdf, numTypesCdf, probStop);
}
@@ -522,16 +542,16 @@
final int numTests = 5000;
final int totalMax = 13;
- final List<Pair<Integer, Integer>> maxLimits = List.of(
- Pair.create(WORK_TYPE_EJ, 5), Pair.create(WORK_TYPE_BG, 4),
- Pair.create(WORK_TYPE_BGUSER, 3));
- final List<Pair<Integer, Integer>> minLimits =
- List.of(Pair.create(WORK_TYPE_EJ, 2), Pair.create(WORK_TYPE_BG, 1));
+ final List<Pair<Integer, Float>> minLimitRatios =
+ List.of(Pair.create(WORK_TYPE_EJ, 2.0f / 13), Pair.create(WORK_TYPE_BG, 1.0f / 13));
+ final List<Pair<Integer, Float>> maxLimitRatios = List.of(
+ Pair.create(WORK_TYPE_EJ, 5.0f / 13), Pair.create(WORK_TYPE_BG, 4.0f / 13),
+ Pair.create(WORK_TYPE_BGUSER, 3.0f / 13));
final double probStop = 0.13;
final double[] numTypesCdf = buildCdf(0, 0.05, 0.1, 0.7, 0.1, 0.05);
final double probStart = 0.87;
- checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
+ checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
EQUAL_PROBABILITY_CDF, numTypesCdf, probStop);
}
@@ -541,15 +561,16 @@
final int numTests = 5000;
final int totalMax = 6;
- final List<Pair<Integer, Integer>> maxLimits =
- List.of(Pair.create(WORK_TYPE_EJ, 5), Pair.create(WORK_TYPE_BG, 4));
- final List<Pair<Integer, Integer>> minLimits = List.of(Pair.create(WORK_TYPE_BG, 2));
+ final List<Pair<Integer, Float>> minLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3));
+ final List<Pair<Integer, Float>> maxLimitRatios =
+ List.of(Pair.create(WORK_TYPE_EJ, 5.0f / 6), Pair.create(WORK_TYPE_BG, 2.0f / 3));
final double probStop = 0.4;
final double[] cdf = buildWorkTypeCdf(.1, 0, 0.5, 0.35, 0, 0.05);
final double[] numTypesCdf = buildCdf(1);
final double probStart = 0.5;
- checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
+ checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
cdf, numTypesCdf, probStop);
}
@@ -559,17 +580,17 @@
final int numTests = 5000;
final int totalMax = 6;
- final List<Pair<Integer, Integer>> maxLimits =
- List.of(Pair.create(WORK_TYPE_EJ, 5), Pair.create(WORK_TYPE_BG, 4),
- Pair.create(WORK_TYPE_BGUSER, 1));
- final List<Pair<Integer, Integer>> minLimits =
- List.of(Pair.create(WORK_TYPE_EJ, 3), Pair.create(WORK_TYPE_BG, 2));
+ final List<Pair<Integer, Float>> minLimitRatios =
+ List.of(Pair.create(WORK_TYPE_EJ, .5f), Pair.create(WORK_TYPE_BG, 1.0f / 3));
+ final List<Pair<Integer, Float>> maxLimitRatios =
+ List.of(Pair.create(WORK_TYPE_EJ, 5.0f / 6), Pair.create(WORK_TYPE_BG, 2.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 6));
final double probStop = 0.4;
final double[] cdf = buildWorkTypeCdf(0.01, 0.09, 0.4, 0.1, 0, 0.4);
final double[] numTypesCdf = buildCdf(0.7, 0.3);
final double probStart = 0.5;
- checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
+ checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
cdf, numTypesCdf, probStop);
}
@@ -579,25 +600,25 @@
final int numTests = 5000;
final int totalMax = 7;
- final List<Pair<Integer, Integer>> maxLimits =
- List.of(Pair.create(WORK_TYPE_EJ, 5), Pair.create(WORK_TYPE_BG, 4),
- Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1),
- Pair.create(WORK_TYPE_BGUSER, 1));
- final List<Pair<Integer, Integer>> minLimits =
- List.of(Pair.create(WORK_TYPE_EJ, 3), Pair.create(WORK_TYPE_BG, 2));
+ final List<Pair<Integer, Float>> minLimitRatios =
+ List.of(Pair.create(WORK_TYPE_EJ, 3.0f / 7), Pair.create(WORK_TYPE_BG, 2.0f / 7));
+ final List<Pair<Integer, Float>> maxLimitRatios =
+ List.of(Pair.create(WORK_TYPE_EJ, 5.0f / 7), Pair.create(WORK_TYPE_BG, 4.0f / 7),
+ Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 1.0f / 7),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 7));
final double probStop = 0.4;
final double[] cdf = buildWorkTypeCdf(0.01, 0.09, 0.25, 0.05, 0.3, 0.3);
final double[] numTypesCdf = buildCdf(0.7, 0.3);
final double probStart = 0.5;
- checkRandom(jobs, numTests, totalMax, minLimits, maxLimits, probStart,
+ checkRandom(jobs, numTests, totalMax, minLimitRatios, maxLimitRatios, probStart,
cdf, numTypesCdf, probStop);
}
/** Used by the following tests */
private void checkSimple(int totalMax,
- @NonNull List<Pair<Integer, Integer>> minLimits,
- @NonNull List<Pair<Integer, Integer>> maxLimits,
+ @NonNull List<Pair<Integer, Float>> minLimitRatios,
+ @NonNull List<Pair<Integer, Float>> maxLimitRatios,
@NonNull List<Pair<Integer, Integer>> running,
@NonNull List<Pair<Integer, Integer>> pending,
@NonNull List<Pair<Integer, Integer>> resultRunning,
@@ -610,17 +631,19 @@
jobs.addPending(pend.first, pend.second);
}
- recount(jobs, totalMax, minLimits, maxLimits);
+ recount(jobs, totalMax, minLimitRatios, maxLimitRatios);
startPendingJobs(jobs);
for (Pair<Integer, Integer> run : resultRunning) {
assertWithMessage(
- "Incorrect running result for work type " + workTypeToString(run.first))
+ "Incorrect running result for work type " + workTypeToString(run.first)
+ + " wanted " + run.second + ", got " + jobs.running.get(run.first))
.that(jobs.running.get(run.first)).isEqualTo(run.second);
}
for (Pair<Integer, Integer> pend : resultPending) {
assertWithMessage(
- "Incorrect pending result for work type " + workTypeToString(pend.first))
+ "Incorrect pending result for work type " + workTypeToString(pend.first)
+ + " wanted " + pend.second + ", got " + jobs.pending.get(pend.first))
.that(jobs.pending.get(pend.first)).isEqualTo(pend.second);
}
}
@@ -628,16 +651,18 @@
@Test
public void testBasic() {
checkSimple(6,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3)),
+ /* max */List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 3)),
/* run */ List.of(),
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 1)),
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 1)),
/* resPen */ List.of());
checkSimple(6,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 3)),
/* run */ List.of(),
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10)),
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 6)),
@@ -645,39 +670,40 @@
// When there are BG jobs pending, 2 (min-BG) jobs should run.
checkSimple(6,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 3)),
/* run */ List.of(),
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 1)),
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 5), Pair.create(WORK_TYPE_BG, 1)),
/* resPen */ List.of(Pair.create(WORK_TYPE_TOP, 5)));
checkSimple(6,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 4)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3)),
/* run */ List.of(),
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 3)),
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_BG, 2)),
/* resPen */ List.of(Pair.create(WORK_TYPE_TOP, 6), Pair.create(WORK_TYPE_BG, 1)));
checkSimple(8,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 6)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, .25f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, .75f)),
/* run */ List.of(),
/* pen */ List.of(Pair.create(WORK_TYPE_BG, 49)),
/* resRun */ List.of(Pair.create(WORK_TYPE_BG, 6)),
/* resPen */ List.of(Pair.create(WORK_TYPE_BG, 43)));
checkSimple(8,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 6)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, .25f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, .75f)),
/* run */ List.of(Pair.create(WORK_TYPE_TOP, 2), Pair.create(WORK_TYPE_BG, 4)),
/* pen */ List.of(Pair.create(WORK_TYPE_BG, 49)),
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 2), Pair.create(WORK_TYPE_BG, 6)),
/* resPen */ List.of(Pair.create(WORK_TYPE_BG, 47)));
checkSimple(8,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 6)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, .25f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, .75f)),
/* run */ List.of(Pair.create(WORK_TYPE_TOP, 2), Pair.create(WORK_TYPE_BG, 4)),
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 49), Pair.create(WORK_TYPE_BG, 49)),
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_BG, 4)),
@@ -686,48 +712,52 @@
checkSimple(8,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
- /* max */ List.of(Pair.create(WORK_TYPE_TOP, 6), Pair.create(WORK_TYPE_BG, 6)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, .25f)),
+ /* max */
+ List.of(Pair.create(WORK_TYPE_TOP, .75f), Pair.create(WORK_TYPE_BG, .75f)),
/* run */ List.of(Pair.create(WORK_TYPE_TOP, 2), Pair.create(WORK_TYPE_BG, 4)),
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 49)),
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_BG, 4)),
/* resPen */ List.of(Pair.create(WORK_TYPE_TOP, 8), Pair.create(WORK_TYPE_BG, 49)));
checkSimple(8,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
- /* max */ List.of(Pair.create(WORK_TYPE_TOP, 6), Pair.create(WORK_TYPE_BG, 6)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, .25f)),
+ /* max */ List.of(
+ Pair.create(WORK_TYPE_TOP, .75f), Pair.create(WORK_TYPE_BG, .75f)),
/* run */ List.of(Pair.create(WORK_TYPE_TOP, 2), Pair.create(WORK_TYPE_BG, 1)),
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 49)),
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 6), Pair.create(WORK_TYPE_BG, 2)),
/* resPen */ List.of(Pair.create(WORK_TYPE_TOP, 6), Pair.create(WORK_TYPE_BG, 48)));
checkSimple(8,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 1)),
- /* max */ List.of(Pair.create(WORK_TYPE_TOP, 6), Pair.create(WORK_TYPE_BG, 2)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 8)),
+ /* max */ List.of(
+ Pair.create(WORK_TYPE_TOP, .75f), Pair.create(WORK_TYPE_BG, .25f)),
/* run */ List.of(Pair.create(WORK_TYPE_BG, 6)),
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 49)),
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 2), Pair.create(WORK_TYPE_BG, 6)),
/* resPen */ List.of(Pair.create(WORK_TYPE_TOP, 8), Pair.create(WORK_TYPE_BG, 49)));
checkSimple(8,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 1)),
- /* max */ List.of(Pair.create(WORK_TYPE_TOP, 6), Pair.create(WORK_TYPE_BG, 2)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 8)),
+ /* max */
+ List.of(Pair.create(WORK_TYPE_TOP, .75f), Pair.create(WORK_TYPE_BG, .25f)),
/* run */ List.of(Pair.create(WORK_TYPE_BG, 6)),
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 49)),
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 2), Pair.create(WORK_TYPE_BG, 6)),
/* resPen */ List.of(Pair.create(WORK_TYPE_TOP, 8), Pair.create(WORK_TYPE_BG, 49)));
checkSimple(6,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 4)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3)),
/* run */ List.of(Pair.create(WORK_TYPE_TOP, 6)),
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 3)),
/* resRun */ List.of(Pair.create(WORK_TYPE_TOP, 6)),
/* resPen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 3)));
checkSimple(8,
- /* min */ List.of(Pair.create(WORK_TYPE_EJ, 2), Pair.create(WORK_TYPE_BG, 2)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 4)),
+ /* min */ List.of(Pair.create(WORK_TYPE_EJ, .25f), Pair.create(WORK_TYPE_BG, .25f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, .75f)),
/* run */ List.of(Pair.create(WORK_TYPE_TOP, 6)),
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_EJ, 5),
Pair.create(WORK_TYPE_BG, 3)),
@@ -740,15 +770,16 @@
// shouldn't start new ones.
checkSimple(5,
/* min */ List.of(),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 1)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, .2f)),
/* run */ List.of(Pair.create(WORK_TYPE_BG, 6)),
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 3)),
/* resRun */ List.of(Pair.create(WORK_TYPE_BG, 6)),
/* resPen */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 3)));
checkSimple(6,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 3)),
/* run */ List.of(Pair.create(WORK_TYPE_BG, 2)),
/* pen */ List.of(Pair.create(WORK_TYPE_TOP, 10),
Pair.create(WORK_TYPE_BG, 3),
@@ -759,8 +790,9 @@
Pair.create(WORK_TYPE_BGUSER, 3)));
checkSimple(6,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 3)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3)),
+ /* max */ List.of(
+ Pair.create(WORK_TYPE_BG, 2.0f / 3), Pair.create(WORK_TYPE_BGUSER, .5f)),
/* run */ List.of(Pair.create(WORK_TYPE_BG, 2)),
/* pen */ List.of(Pair.create(WORK_TYPE_BG, 3), Pair.create(WORK_TYPE_BGUSER, 3)),
/* resRun */ List.of(
@@ -769,8 +801,9 @@
Pair.create(WORK_TYPE_BG, 1), Pair.create(WORK_TYPE_BGUSER, 1)));
checkSimple(6,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 2)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 1)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, 1.0f / 3)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, 2.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 6)),
/* run */ List.of(Pair.create(WORK_TYPE_BG, 2)),
/* pen */ List.of(Pair.create(WORK_TYPE_BG, 3), Pair.create(WORK_TYPE_BGUSER, 3)),
/* resRun */ List.of(
@@ -778,12 +811,13 @@
/* resPen */ List.of(
Pair.create(WORK_TYPE_BG, 1), Pair.create(WORK_TYPE_BGUSER, 2)));
- Log.d(TAG, "START***#*#*#*#*#*#**#*");
// Test multi-types
checkSimple(6,
- /* min */ List.of(Pair.create(WORK_TYPE_EJ, 2), Pair.create(WORK_TYPE_BG, 2)),
+ /* min */
+ List.of(Pair.create(WORK_TYPE_EJ, 1.0f / 3), Pair.create(WORK_TYPE_BG, 1.0f / 3)),
/* max */ List.of(
- Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 1)),
+ Pair.create(WORK_TYPE_BG, 2.0f / 3),
+ Pair.create(WORK_TYPE_BGUSER, 1.0f / 6)),
/* run */ List.of(),
/* pen */ List.of(
// 2 of these as TOP, 1 as EJ
@@ -809,10 +843,12 @@
jobs.addPending(WORK_TYPE_BG, 10);
final int totalMax = 6;
- final List<Pair<Integer, Integer>> minLimits = List.of(Pair.create(WORK_TYPE_BG, 1));
- final List<Pair<Integer, Integer>> maxLimits = List.of(Pair.create(WORK_TYPE_BG, 5));
+ final List<Pair<Integer, Float>> minLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 1.0f / totalMax));
+ final List<Pair<Integer, Float>> maxLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 5.0f / totalMax));
- recount(jobs, totalMax, minLimits, maxLimits);
+ recount(jobs, totalMax, minLimitRatios, maxLimitRatios);
startPendingJobs(jobs);
@@ -887,11 +923,12 @@
jobs.addPending(WORK_TYPE_BG, 10); // c
final int totalMax = 8;
- final List<Pair<Integer, Integer>> minLimits =
- List.of(Pair.create(WORK_TYPE_EJ, 1), Pair.create(WORK_TYPE_BG, 1));
- final List<Pair<Integer, Integer>> maxLimits = List.of(Pair.create(WORK_TYPE_BG, 5));
+ final List<Pair<Integer, Float>> minLimitRatios =
+ List.of(Pair.create(WORK_TYPE_EJ, 1.0f / 8), Pair.create(WORK_TYPE_BG, 1.0f / 8));
+ final List<Pair<Integer, Float>> maxLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 5.0f / 8));
- recount(jobs, totalMax, minLimits, maxLimits);
+ recount(jobs, totalMax, minLimitRatios, maxLimitRatios);
assertThat(jobs.pending.get(WORK_TYPE_TOP)).isEqualTo(11);
assertThat(jobs.pending.get(WORK_TYPE_EJ)).isEqualTo(5);
@@ -966,11 +1003,12 @@
}
final int totalMax = 8;
- final List<Pair<Integer, Integer>> minLimits =
- List.of(Pair.create(WORK_TYPE_EJ, 1), Pair.create(WORK_TYPE_BG, 1));
- final List<Pair<Integer, Integer>> maxLimits = List.of(Pair.create(WORK_TYPE_BG, 5));
+ final List<Pair<Integer, Float>> minLimitRatios =
+ List.of(Pair.create(WORK_TYPE_EJ, 1.0f / 8), Pair.create(WORK_TYPE_BG, 1.0f / 8));
+ final List<Pair<Integer, Float>> maxLimitRatios =
+ List.of(Pair.create(WORK_TYPE_BG, 5.0f / 8));
- recount(jobs, totalMax, minLimits, maxLimits);
+ recount(jobs, totalMax, minLimitRatios, maxLimitRatios);
assertThat(jobs.pending.get(WORK_TYPE_TOP)).isEqualTo(11);
assertThat(jobs.pending.get(WORK_TYPE_EJ)).isEqualTo(10);
diff --git a/services/tests/servicestests/src/com/android/server/job/WorkTypeConfigTest.java b/services/tests/servicestests/src/com/android/server/job/WorkTypeConfigTest.java
index 21d2784..bd5a063 100644
--- a/services/tests/servicestests/src/com/android/server/job/WorkTypeConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/WorkTypeConfigTest.java
@@ -45,23 +45,26 @@
@SmallTest
public class WorkTypeConfigTest {
private static final String KEY_MAX_TOTAL = "concurrency_max_total_test";
- private static final String KEY_MAX_TOP = "concurrency_max_top_test";
- private static final String KEY_MAX_FGS = "concurrency_max_fgs_test";
- private static final String KEY_MAX_EJ = "concurrency_max_ej_test";
- private static final String KEY_MAX_BG = "concurrency_max_bg_test";
- private static final String KEY_MAX_BGUSER_IMPORTANT = "concurrency_max_bguser_important_test";
- private static final String KEY_MAX_BGUSER = "concurrency_max_bguser_test";
- private static final String KEY_MIN_TOP = "concurrency_min_top_test";
- private static final String KEY_MIN_FGS = "concurrency_min_fgs_test";
- private static final String KEY_MIN_EJ = "concurrency_min_ej_test";
- private static final String KEY_MIN_BG = "concurrency_min_bg_test";
- private static final String KEY_MIN_BGUSER_IMPORTANT = "concurrency_min_bguser_important_test";
- private static final String KEY_MIN_BGUSER = "concurrency_min_bguser_test";
+ private static final String KEY_MAX_RATIO_TOP = "concurrency_max_ratio_top_test";
+ private static final String KEY_MAX_RATIO_FGS = "concurrency_max_ratio_fgs_test";
+ private static final String KEY_MAX_RATIO_EJ = "concurrency_max_ratio_ej_test";
+ private static final String KEY_MAX_RATIO_BG = "concurrency_max_ratio_bg_test";
+ private static final String KEY_MAX_RATIO_BGUSER_IMPORTANT =
+ "concurrency_max_ratio_bguser_important_test";
+ private static final String KEY_MAX_RATIO_BGUSER = "concurrency_max_ratio_bguser_test";
+ private static final String KEY_MIN_RATIO_TOP = "concurrency_min_ratio_top_test";
+ private static final String KEY_MIN_RATIO_FGS = "concurrency_min_ratio_fgs_test";
+ private static final String KEY_MIN_RATIO_EJ = "concurrency_min_ratio_ej_test";
+ private static final String KEY_MIN_RATIO_BG = "concurrency_min_ratio_bg_test";
+ private static final String KEY_MIN_RATIO_BGUSER_IMPORTANT =
+ "concurrency_min_ratio_bguser_important_test";
+ private static final String KEY_MIN_RATIO_BGUSER = "concurrency_min_ratio_bguser_test";
private void check(@Nullable DeviceConfig.Properties config,
+ int defaultLimit,
int defaultTotal,
- @NonNull List<Pair<Integer, Integer>> defaultMin,
- @NonNull List<Pair<Integer, Integer>> defaultMax,
+ @NonNull List<Pair<Integer, Float>> defaultMinRatios,
+ @NonNull List<Pair<Integer, Float>> defaultMaxRatios,
boolean expectedValid, int expectedTotal,
@NonNull List<Pair<Integer, Integer>> expectedMinLimits,
@NonNull List<Pair<Integer, Integer>> expectedMaxLimits) throws Exception {
@@ -69,7 +72,7 @@
final WorkTypeConfig counts;
try {
counts = new WorkTypeConfig("test",
- defaultTotal, defaultMin, defaultMax);
+ defaultLimit, defaultTotal, defaultMinRatios, defaultMaxRatios);
if (!expectedValid) {
fail("Invalid config successfully created");
return;
@@ -84,7 +87,7 @@
}
if (config != null) {
- counts.update(config);
+ counts.update(config, defaultLimit);
}
assertEquals(expectedTotal, counts.getMaxTotal());
@@ -101,7 +104,7 @@
@Test
public void test() throws Exception {
// Tests with various combinations.
- check(null, /*default*/ 13,
+ check(null, /* limit */ 16, /*default*/ 13,
/* min */ List.of(),
/* max */ List.of(),
/*expected*/ true, 13,
@@ -109,111 +112,141 @@
Pair.create(WORK_TYPE_BG, 0), Pair.create(WORK_TYPE_BGUSER, 0)),
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 13), Pair.create(WORK_TYPE_EJ, 13),
Pair.create(WORK_TYPE_BG, 13), Pair.create(WORK_TYPE_BGUSER, 13)));
- check(null, /*default*/ 5,
- /* min */ List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_BG, 0)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 1)),
+ check(null, /* limit */ 16, /*default*/ 5,
+ /* min */ List.of(Pair.create(WORK_TYPE_TOP, .8f), Pair.create(WORK_TYPE_BG, 0f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, .2f)),
/*expected*/ true, 5,
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_BG, 0)),
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 5), Pair.create(WORK_TYPE_BG, 1)));
- check(null, /*default*/ 5,
- /* min */ List.of(Pair.create(WORK_TYPE_TOP, 5),
- Pair.create(WORK_TYPE_BG, 0), Pair.create(WORK_TYPE_BGUSER, 0)),
+ check(null, /* limit */ 16, /*default*/ 5,
+ /* min */ List.of(Pair.create(WORK_TYPE_TOP, 1f),
+ Pair.create(WORK_TYPE_BG, 0f), Pair.create(WORK_TYPE_BGUSER, 0f)),
/* max */ List.of(
- Pair.create(WORK_TYPE_BG, 0), Pair.create(WORK_TYPE_BGUSER, 1)),
- /*expected*/ true, 5,
+ Pair.create(WORK_TYPE_BG, 0f), Pair.create(WORK_TYPE_BGUSER, .2f)),
+ /*expected*/ false, 5,
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 5),
Pair.create(WORK_TYPE_BG, 0), Pair.create(WORK_TYPE_BGUSER, 0)),
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 5),
Pair.create(WORK_TYPE_BG, 1), Pair.create(WORK_TYPE_BGUSER, 1)));
- check(null, /*default*/ 0,
- /* min */ List.of(Pair.create(WORK_TYPE_TOP, 5), Pair.create(WORK_TYPE_BG, 0)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 0)),
- /*expected*/ false, 1,
- /* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 0)),
- /* max */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 1)));
- check(null, /*default*/ -1,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, -1)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, -1)),
- /*expected*/ false, 1,
- /* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 0)),
- /* max */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 1)));
- check(null, /*default*/ 5,
- /* min */ List.of(
- Pair.create(WORK_TYPE_BG, 5), Pair.create(WORK_TYPE_BGUSER, 0)),
+ check(null, /* limit */ 16, /*default*/ 5,
+ /* min */ List.of(Pair.create(WORK_TYPE_TOP, .99f),
+ Pair.create(WORK_TYPE_BG, 0f), Pair.create(WORK_TYPE_BGUSER, 0f)),
/* max */ List.of(
- Pair.create(WORK_TYPE_BG, 5), Pair.create(WORK_TYPE_BGUSER, 5)),
+ Pair.create(WORK_TYPE_BG, .01f), Pair.create(WORK_TYPE_BGUSER, .2f)),
+ /*expected*/ true, 5,
+ /* min */ List.of(Pair.create(WORK_TYPE_TOP, 4),
+ Pair.create(WORK_TYPE_BG, 0), Pair.create(WORK_TYPE_BGUSER, 0)),
+ /* max */ List.of(Pair.create(WORK_TYPE_TOP, 5),
+ Pair.create(WORK_TYPE_BG, 1), Pair.create(WORK_TYPE_BGUSER, 1)));
+ check(null, /* limit */ 16, /*default*/ 0,
+ /* min */ List.of(Pair.create(WORK_TYPE_TOP, 1f), Pair.create(WORK_TYPE_BG, 0f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, 0f)),
+ /*expected*/ false, 1,
+ /* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 0)),
+ /* max */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 1)));
+ check(null, /* limit */ 16, /*default*/ -1,
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, -1f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, -1f)),
+ /*expected*/ false, 1,
+ /* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 0)),
+ /* max */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 1)));
+ check(null, /* limit */ 16, /*default*/ 5,
+ /* min */ List.of(
+ Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, 0f)),
+ /* max */ List.of(
+ Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, 1f)),
+ /*expected*/ false, 5,
+ /* min */ List.of(Pair.create(WORK_TYPE_TOP, 1),
+ Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 0)),
+ /* max */ List.of(Pair.create(WORK_TYPE_TOP, 5),
+ Pair.create(WORK_TYPE_BG, 5), Pair.create(WORK_TYPE_BGUSER, 5)));
+ check(null, /* limit */ 16, /*default*/ 5,
+ /* min */ List.of(
+ Pair.create(WORK_TYPE_BG, .99f), Pair.create(WORK_TYPE_BGUSER, 0f)),
+ /* max */ List.of(
+ Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, 1f)),
/*expected*/ true, 5,
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1),
Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 0)),
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 5),
Pair.create(WORK_TYPE_BG, 5), Pair.create(WORK_TYPE_BGUSER, 5)));
- check(null, /*default*/ 6,
- /* min */ List.of(Pair.create(WORK_TYPE_TOP, 1),
- Pair.create(WORK_TYPE_BG, 6), Pair.create(WORK_TYPE_BGUSER, 2)),
+ check(null, /* limit */ 16, /*default*/ 6,
+ /* min */ List.of(Pair.create(WORK_TYPE_TOP, 1.0f / 6),
+ Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, 1.0f / 3)),
/* max */ List.of(
- Pair.create(WORK_TYPE_BG, 5), Pair.create(WORK_TYPE_BGUSER, 1)),
+ Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, 1.0f / 6)),
/*expected*/ false, 6,
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1),
Pair.create(WORK_TYPE_BG, 5), Pair.create(WORK_TYPE_BGUSER, 0)),
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 6),
Pair.create(WORK_TYPE_BG, 5), Pair.create(WORK_TYPE_BGUSER, 1)));
- check(null, /*default*/ 4,
+ check(null, /* limit */ 16, /*default*/ 4,
/* min */ List.of(
- Pair.create(WORK_TYPE_BG, 6), Pair.create(WORK_TYPE_BGUSER, 6)),
+ Pair.create(WORK_TYPE_BG, 1.5f), Pair.create(WORK_TYPE_BGUSER, 1.5f)),
/* max */ List.of(
- Pair.create(WORK_TYPE_BG, 5), Pair.create(WORK_TYPE_BGUSER, 5)),
+ Pair.create(WORK_TYPE_BG, 1.25f), Pair.create(WORK_TYPE_BGUSER, 1.25f)),
/*expected*/ false, 4,
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1),
Pair.create(WORK_TYPE_BG, 3), Pair.create(WORK_TYPE_BGUSER, 0)),
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 4),
Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 4)));
- check(null, /*default*/ 5,
- /* min */ List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_BG, 1)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 1)),
+ check(null, /* limit */ 16, /*default*/ 5,
+ /* min */ List.of(Pair.create(WORK_TYPE_TOP, .8f), Pair.create(WORK_TYPE_BG, .2f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, .2f)),
/*expected*/ true, 5,
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_BG, 1)),
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 5), Pair.create(WORK_TYPE_BG, 1)));
- check(null, /*default*/ 10,
- /* min */ List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_EJ, 3),
- Pair.create(WORK_TYPE_BG, 1)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 1)),
+ check(null, /* limit */ 16, /*default*/ 10,
+ /* min */ List.of(Pair.create(WORK_TYPE_TOP, .4f), Pair.create(WORK_TYPE_EJ, .3f),
+ Pair.create(WORK_TYPE_BG, .1f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, .1f)),
/*expected*/ true, 10,
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 4), Pair.create(WORK_TYPE_EJ, 3),
Pair.create(WORK_TYPE_BG, 1)),
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 10), Pair.create(WORK_TYPE_BG, 1)));
- check(null, /*default*/ 10,
- /* min */ List.of(Pair.create(WORK_TYPE_TOP, 3), Pair.create(WORK_TYPE_FGS, 2),
- Pair.create(WORK_TYPE_EJ, 1), Pair.create(WORK_TYPE_BG, 1)),
- /* max */ List.of(Pair.create(WORK_TYPE_FGS, 3)),
+ check(null, /* limit */ 16, /*default*/ 10,
+ /* min */ List.of(Pair.create(WORK_TYPE_TOP, .3f), Pair.create(WORK_TYPE_FGS, .2f),
+ Pair.create(WORK_TYPE_EJ, .1f), Pair.create(WORK_TYPE_BG, .1f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_FGS, .3f)),
/*expected*/ true, 10,
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 3), Pair.create(WORK_TYPE_FGS, 2),
Pair.create(WORK_TYPE_EJ, 1), Pair.create(WORK_TYPE_BG, 1)),
/* max */ List.of(Pair.create(WORK_TYPE_FGS, 3)));
- check(null, /*default*/ 15,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 15)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 15)),
+ check(null, /* limit */ 16, /*default*/ 15,
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, .95f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, 1f)),
/*expected*/ true, 15,
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 14)),
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 15), Pair.create(WORK_TYPE_BG, 15)));
- check(null, /*default*/ 16,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 16)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 16)),
+ check(null, /* limit */ 16, /*default*/ 16,
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, .99f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, 1f)),
/*expected*/ true, 16,
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 15)),
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 16), Pair.create(WORK_TYPE_BG, 16)));
- check(null, /*default*/ 20,
+ check(null, /* limit */ 16, /*default*/ 20,
/* min */ List.of(
- Pair.create(WORK_TYPE_BG, 20), Pair.create(WORK_TYPE_BGUSER, 10)),
+ Pair.create(WORK_TYPE_BG, .99f), Pair.create(WORK_TYPE_BGUSER, .5f)),
/* max */ List.of(
- Pair.create(WORK_TYPE_BG, 20), Pair.create(WORK_TYPE_BGUSER, 20)),
+ Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, 1f)),
/*expected*/ false, 16,
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1),
Pair.create(WORK_TYPE_BG, 15), Pair.create(WORK_TYPE_BGUSER, 0)),
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 16),
Pair.create(WORK_TYPE_BG, 16), Pair.create(WORK_TYPE_BGUSER, 16)));
- check(null, /*default*/ 20,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 16)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 16)),
+ check(null, /* limit */ 76, /*default*/ 80,
+ /* min */ List.of(
+ Pair.create(WORK_TYPE_BG, .98f), Pair.create(WORK_TYPE_BGUSER, .9f)),
+ /* max */ List.of(
+ Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, 1f)),
+ /*expected*/ false, 64,
+ /* min */ List.of(Pair.create(WORK_TYPE_TOP, 1),
+ Pair.create(WORK_TYPE_BG, 63), Pair.create(WORK_TYPE_BGUSER, 0)),
+ /* max */ List.of(Pair.create(WORK_TYPE_TOP, 64),
+ Pair.create(WORK_TYPE_BG, 64), Pair.create(WORK_TYPE_BGUSER, 64)));
+ check(null, /* limit */ 16, /*default*/ 20,
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, .99f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, 1f)),
/*expected*/ true, 16,
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 15)),
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 16), Pair.create(WORK_TYPE_BG, 16)));
@@ -221,94 +254,101 @@
// Test for overriding with a setting string.
check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
.setInt(KEY_MAX_TOTAL, 5)
- .setInt(KEY_MAX_BG, 4)
- .setInt(KEY_MIN_BG, 3)
+ .setFloat(KEY_MAX_RATIO_BG, .8f)
+ .setFloat(KEY_MIN_RATIO_BG, .6f)
.build(),
+ /* limit */ 16,
/*default*/ 9,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 9)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, .99f)),
/* max */ List.of(
- Pair.create(WORK_TYPE_BG, 9), Pair.create(WORK_TYPE_BGUSER, 2)),
+ Pair.create(WORK_TYPE_BG, 1f), Pair.create(WORK_TYPE_BGUSER, .4f)),
/*expected*/ true, 5,
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 3)),
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 5),
Pair.create(WORK_TYPE_BG, 4), Pair.create(WORK_TYPE_BGUSER, 2)));
check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
.setInt(KEY_MAX_TOTAL, 5).build(),
+ /* limit */ 16,
/*default*/ 9,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 9)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 9)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, .99f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, 1f)),
/*expected*/ true, 5,
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 4)),
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 5), Pair.create(WORK_TYPE_BG, 5)));
check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
- .setInt(KEY_MAX_BG, 4).build(),
+ .setFloat(KEY_MAX_RATIO_BG, 4.0f / 9).build(),
+ /* limit */ 16,
/*default*/ 9,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 9)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 9)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, .99f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, 1f)),
/*expected*/ true, 9,
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 4)),
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 9), Pair.create(WORK_TYPE_BG, 4)));
check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
- .setInt(KEY_MIN_BG, 3).build(),
+ .setFloat(KEY_MIN_RATIO_BG, 1.0f / 3).build(),
+ /* limit */ 16,
/*default*/ 9,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 9)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 9)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, .99f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, 1f)),
/*expected*/ true, 9,
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 3)),
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 9), Pair.create(WORK_TYPE_BG, 9)));
check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
.setInt(KEY_MAX_TOTAL, 20)
- .setInt(KEY_MAX_EJ, 5)
- .setInt(KEY_MIN_EJ, 2)
- .setInt(KEY_MAX_BG, 16)
- .setInt(KEY_MIN_BG, 8)
+ .setFloat(KEY_MAX_RATIO_EJ, .25f)
+ .setFloat(KEY_MIN_RATIO_EJ, .1f)
+ .setFloat(KEY_MAX_RATIO_BG, .8f)
+ .setFloat(KEY_MIN_RATIO_BG, .4f)
.build(),
+ /* limit */ 16,
/*default*/ 9,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 9)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 9)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, .99f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, 1f)),
/*expected*/ true, 16,
- /* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_EJ, 2),
- Pair.create(WORK_TYPE_BG, 8)),
+ /* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_EJ, 1),
+ Pair.create(WORK_TYPE_BG, 6)),
/* max */
- List.of(Pair.create(WORK_TYPE_TOP, 16), Pair.create(WORK_TYPE_EJ, 5),
- Pair.create(WORK_TYPE_BG, 16)));
+ List.of(Pair.create(WORK_TYPE_TOP, 16), Pair.create(WORK_TYPE_EJ, 4),
+ Pair.create(WORK_TYPE_BG, 12)));
check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
.setInt(KEY_MAX_TOTAL, 20)
- .setInt(KEY_MAX_BG, 20)
- .setInt(KEY_MIN_BG, 8)
+ .setFloat(KEY_MAX_RATIO_BG, 1f)
+ .setFloat(KEY_MIN_RATIO_BG, .4f)
.build(),
+ /* limit */ 16,
/*default*/ 9,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 9)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 9)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, .99f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, 1f)),
/*expected*/ true, 16,
- /* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 8)),
+ /* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_BG, 6)),
/* max */ List.of(Pair.create(WORK_TYPE_TOP, 16), Pair.create(WORK_TYPE_BG, 16)));
check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
.setInt(KEY_MAX_TOTAL, 16)
- .setInt(KEY_MAX_TOP, 16)
- .setInt(KEY_MIN_TOP, 1)
- .setInt(KEY_MAX_FGS, 15)
- .setInt(KEY_MIN_FGS, 2)
- .setInt(KEY_MAX_EJ, 14)
- .setInt(KEY_MIN_EJ, 3)
- .setInt(KEY_MAX_BG, 13)
- .setInt(KEY_MIN_BG, 4)
- .setInt(KEY_MAX_BGUSER_IMPORTANT, 12)
- .setInt(KEY_MIN_BGUSER_IMPORTANT, 5)
- .setInt(KEY_MAX_BGUSER, 11)
- .setInt(KEY_MIN_BGUSER, 6)
+ .setFloat(KEY_MAX_RATIO_TOP, 1f)
+ .setFloat(KEY_MIN_RATIO_TOP, 1.0f / 16)
+ .setFloat(KEY_MAX_RATIO_FGS, 15.0f / 16)
+ .setFloat(KEY_MIN_RATIO_FGS, 2.0f / 16)
+ .setFloat(KEY_MAX_RATIO_EJ, 14.0f / 16)
+ .setFloat(KEY_MIN_RATIO_EJ, 3.0f / 16)
+ .setFloat(KEY_MAX_RATIO_BG, 13.0f / 16)
+ .setFloat(KEY_MIN_RATIO_BG, 3.0f / 16)
+ .setFloat(KEY_MAX_RATIO_BGUSER_IMPORTANT, 12.0f / 16)
+ .setFloat(KEY_MIN_RATIO_BGUSER_IMPORTANT, 2.0f / 16)
+ .setFloat(KEY_MAX_RATIO_BGUSER, 11.0f / 16)
+ .setFloat(KEY_MIN_RATIO_BGUSER, 2.0f / 16)
.build(),
+ /* limit */ 16,
/*default*/ 9,
- /* min */ List.of(Pair.create(WORK_TYPE_BG, 9)),
- /* max */ List.of(Pair.create(WORK_TYPE_BG, 9)),
+ /* min */ List.of(Pair.create(WORK_TYPE_BG, .99f)),
+ /* max */ List.of(Pair.create(WORK_TYPE_BG, 1f)),
/*expected*/ true, 16,
/* min */ List.of(Pair.create(WORK_TYPE_TOP, 1), Pair.create(WORK_TYPE_FGS, 2),
- Pair.create(WORK_TYPE_EJ, 3), Pair.create(WORK_TYPE_BG, 4),
- Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 5),
- Pair.create(WORK_TYPE_BGUSER, 6)),
+ Pair.create(WORK_TYPE_EJ, 3), Pair.create(WORK_TYPE_BG, 3),
+ Pair.create(WORK_TYPE_BGUSER_IMPORTANT, 2),
+ Pair.create(WORK_TYPE_BGUSER, 2)),
/* max */
List.of(Pair.create(WORK_TYPE_TOP, 16), Pair.create(WORK_TYPE_FGS, 15),
Pair.create(WORK_TYPE_EJ, 14), Pair.create(WORK_TYPE_BG, 13),
diff --git a/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java
index 065aec5..07fda30 100644
--- a/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java
@@ -77,6 +77,7 @@
/* initiatingPackageName = */ null, /* initiatingPackageSigningInfo = */ null,
/* originatingPackageName = */ null,
/* installingPackageName = */ DEFAULT_INSTALLER_PACKAGE_NAME,
+ /* updateOwnerPackageName = */ null,
/* packageSource = */ PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
private LocaleManagerService mLocaleManagerService;
diff --git a/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java b/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java
index 494796e..9429462 100644
--- a/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java
@@ -89,6 +89,7 @@
/* initiatingPackageName = */ null, /* initiatingPackageSigningInfo = */ null,
/* originatingPackageName = */ null,
/* installingPackageName = */ DEFAULT_INSTALLER_PACKAGE_NAME,
+ /* updateOwnerPackageName = */ null,
/* packageSource = */ PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
@Mock
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
index 858f658..d9d0715 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
@@ -50,6 +50,8 @@
import android.content.ContextWrapper;
import android.content.pm.UserInfo;
import android.hardware.rebootescrow.IRebootEscrow;
+import android.net.ConnectivityManager;
+import android.net.Network;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.RemoteException;
@@ -72,6 +74,7 @@
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.function.Consumer;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
@@ -113,6 +116,7 @@
private RebootEscrowManager mService;
private SecretKey mAesKey;
private MockInjector mMockInjector;
+ private Handler mHandler;
public interface MockableRebootEscrowInjected {
int getBootCount();
@@ -131,6 +135,9 @@
private final RebootEscrowKeyStoreManager mKeyStoreManager;
private boolean mServerBased;
private RebootEscrowProviderInterface mRebootEscrowProviderInUse;
+ private ConnectivityManager.NetworkCallback mNetworkCallback;
+ private Consumer<ConnectivityManager.NetworkCallback> mNetworkConsumer;
+ private boolean mWaitForInternet;
MockInjector(Context context, UserManager userManager,
IRebootEscrow rebootEscrow,
@@ -140,6 +147,7 @@
super(context, storage);
mRebootEscrow = rebootEscrow;
mServerBased = false;
+ mWaitForInternet = false;
RebootEscrowProviderHalImpl.Injector halInjector =
new RebootEscrowProviderHalImpl.Injector() {
@Override
@@ -161,6 +169,7 @@
super(context, storage);
mRebootEscrow = null;
mServerBased = true;
+ mWaitForInternet = false;
RebootEscrowProviderServerBasedImpl.Injector injector =
new RebootEscrowProviderServerBasedImpl.Injector(serviceConnection) {
@Override
@@ -196,11 +205,33 @@
}
@Override
+ public boolean waitForInternet() {
+ return mWaitForInternet;
+ }
+
+ public void setWaitForNetwork(boolean waitForNetworkEnabled) {
+ mWaitForInternet = waitForNetworkEnabled;
+ }
+
+ @Override
public boolean isNetworkConnected() {
return false;
}
@Override
+ public boolean requestNetworkWithInternet(
+ ConnectivityManager.NetworkCallback networkCallback) {
+ mNetworkCallback = networkCallback;
+ mNetworkConsumer.accept(networkCallback);
+ return true;
+ }
+
+ @Override
+ public void stopRequestingNetwork(ConnectivityManager.NetworkCallback networkCallback) {
+ mNetworkCallback = null;
+ }
+
+ @Override
public RebootEscrowProviderInterface createRebootEscrowProviderIfNeeded() {
mRebootEscrowProviderInUse = mDefaultRebootEscrowProvider;
return mRebootEscrowProviderInUse;
@@ -239,6 +270,12 @@
}
@Override
+ public int getLoadEscrowTimeoutMillis() {
+ // Timeout in 3 seconds.
+ return 3000;
+ }
+
+ @Override
public String getVbmetaDigest(boolean other) {
return other ? "" : "fake digest";
}
@@ -288,6 +325,9 @@
mMockInjector = new MockInjector(mContext, mUserManager, mRebootEscrow,
mKeyStoreManager, mStorage, mInjected);
mService = new RebootEscrowManager(mMockInjector, mCallbacks, mStorage);
+ HandlerThread thread = new HandlerThread("RebootEscrowManagerTest");
+ thread.start();
+ mHandler = new Handler(thread.getLooper());
}
private void setServerBasedRebootEscrowProvider() throws Exception {
@@ -459,7 +499,7 @@
@Test
public void loadRebootEscrowDataIfAvailable_NothingAvailable_Success() throws Exception {
- mService.loadRebootEscrowDataIfAvailable(null);
+ mService.loadRebootEscrowDataIfAvailable(mHandler);
}
@Test
@@ -496,7 +536,7 @@
eq(20), eq(0) /* vbmeta status */, anyInt());
when(mRebootEscrow.retrieveKey()).thenAnswer(invocation -> keyByteCaptor.getValue());
- mService.loadRebootEscrowDataIfAvailable(null);
+ mService.loadRebootEscrowDataIfAvailable(mHandler);
verify(mRebootEscrow).retrieveKey();
assertTrue(metricsSuccessCaptor.getValue());
verify(mKeyStoreManager).clearKeyStoreEncryptionKey();
@@ -528,9 +568,16 @@
// pretend reboot happens here
when(mInjected.getBootCount()).thenReturn(1);
ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
- doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
- eq(0) /* error code */, eq(2) /* Server based */, eq(1) /* attempt count */,
- anyInt(), eq(0) /* vbmeta status */, anyInt());
+ doNothing()
+ .when(mInjected)
+ .reportMetric(
+ metricsSuccessCaptor.capture(),
+ eq(0) /* error code */,
+ eq(2) /* Server based */,
+ eq(1) /* attempt count */,
+ anyInt(),
+ eq(0) /* vbmeta status */,
+ anyInt());
when(mServiceConnection.unwrap(any(), anyLong()))
.thenAnswer(invocation -> invocation.getArgument(0));
@@ -566,15 +613,23 @@
when(mInjected.getBootCount()).thenReturn(1);
ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
ArgumentCaptor<Integer> metricsErrorCodeCaptor = ArgumentCaptor.forClass(Integer.class);
- doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
- metricsErrorCodeCaptor.capture(), eq(2) /* Server based */,
- eq(1) /* attempt count */, anyInt(), eq(0) /* vbmeta status */, anyInt());
+ doNothing()
+ .when(mInjected)
+ .reportMetric(
+ metricsSuccessCaptor.capture(),
+ metricsErrorCodeCaptor.capture(),
+ eq(2) /* Server based */,
+ eq(1) /* attempt count */,
+ anyInt(),
+ eq(0) /* vbmeta status */,
+ anyInt());
when(mServiceConnection.unwrap(any(), anyLong())).thenThrow(RemoteException.class);
mService.loadRebootEscrowDataIfAvailable(null);
verify(mServiceConnection).unwrap(any(), anyLong());
assertFalse(metricsSuccessCaptor.getValue());
- assertEquals(Integer.valueOf(RebootEscrowManager.ERROR_LOAD_ESCROW_KEY),
+ assertEquals(
+ Integer.valueOf(RebootEscrowManager.ERROR_LOAD_ESCROW_KEY),
metricsErrorCodeCaptor.getValue());
}
@@ -603,18 +658,24 @@
when(mInjected.getBootCount()).thenReturn(1);
ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
ArgumentCaptor<Integer> metricsErrorCodeCaptor = ArgumentCaptor.forClass(Integer.class);
- doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
- metricsErrorCodeCaptor.capture(), eq(2) /* Server based */,
- eq(2) /* attempt count */, anyInt(), eq(0) /* vbmeta status */, anyInt());
+ doNothing()
+ .when(mInjected)
+ .reportMetric(
+ metricsSuccessCaptor.capture(),
+ metricsErrorCodeCaptor.capture(),
+ eq(2) /* Server based */,
+ eq(2) /* attempt count */,
+ anyInt(),
+ eq(0) /* vbmeta status */,
+ anyInt());
when(mServiceConnection.unwrap(any(), anyLong())).thenThrow(IOException.class);
- HandlerThread thread = new HandlerThread("RebootEscrowManagerTest");
- thread.start();
- mService.loadRebootEscrowDataIfAvailable(new Handler(thread.getLooper()));
+ mService.loadRebootEscrowDataIfAvailable(mHandler);
// Sleep 5s for the retry to complete
Thread.sleep(5 * 1000);
assertFalse(metricsSuccessCaptor.getValue());
- assertEquals(Integer.valueOf(RebootEscrowManager.ERROR_NO_NETWORK),
+ assertEquals(
+ Integer.valueOf(RebootEscrowManager.ERROR_NO_NETWORK),
metricsErrorCodeCaptor.getValue());
}
@@ -642,16 +703,22 @@
// pretend reboot happens here
when(mInjected.getBootCount()).thenReturn(1);
ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
- doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
- anyInt(), anyInt(), eq(2) /* attempt count */, anyInt(), anyInt(), anyInt());
+ doNothing()
+ .when(mInjected)
+ .reportMetric(
+ metricsSuccessCaptor.capture(),
+ anyInt(),
+ anyInt(),
+ eq(2) /* attempt count */,
+ anyInt(),
+ anyInt(),
+ anyInt());
when(mServiceConnection.unwrap(any(), anyLong()))
.thenThrow(new IOException())
.thenAnswer(invocation -> invocation.getArgument(0));
- HandlerThread thread = new HandlerThread("RebootEscrowManagerTest");
- thread.start();
- mService.loadRebootEscrowDataIfAvailable(new Handler(thread.getLooper()));
+ mService.loadRebootEscrowDataIfAvailable(mHandler);
// Sleep 5s for the retry to complete
Thread.sleep(5 * 1000);
verify(mServiceConnection, times(2)).unwrap(any(), anyLong());
@@ -660,6 +727,447 @@
}
@Test
+ public void loadRebootEscrowDataIfAvailable_serverBasedWaitForInternet_success()
+ throws Exception {
+ setServerBasedRebootEscrowProvider();
+ mMockInjector.setWaitForNetwork(true);
+
+ when(mInjected.getBootCount()).thenReturn(0);
+ RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
+ mService.setRebootEscrowListener(mockListener);
+ mService.prepareRebootEscrow();
+
+ clearInvocations(mServiceConnection);
+ mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN);
+ verify(mockListener).onPreparedForReboot(eq(true));
+ verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong());
+
+ // Use x -> x for both wrap & unwrap functions.
+ when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
+ verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
+ assertTrue(mStorage.hasRebootEscrowServerBlob());
+
+ // pretend reboot happens here
+ when(mInjected.getBootCount()).thenReturn(1);
+ ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
+ doNothing()
+ .when(mInjected)
+ .reportMetric(
+ metricsSuccessCaptor.capture(),
+ eq(0) /* error code */,
+ eq(2) /* Server based */,
+ eq(1) /* attempt count */,
+ anyInt(),
+ eq(0) /* vbmeta status */,
+ anyInt());
+
+ // load escrow data
+ when(mServiceConnection.unwrap(any(), anyLong()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ Network mockNetwork = mock(Network.class);
+ mMockInjector.mNetworkConsumer =
+ (callback) -> {
+ callback.onAvailable(mockNetwork);
+ };
+
+ mService.loadRebootEscrowDataIfAvailable(mHandler);
+ verify(mServiceConnection).unwrap(any(), anyLong());
+ assertTrue(metricsSuccessCaptor.getValue());
+ verify(mKeyStoreManager).clearKeyStoreEncryptionKey();
+ assertNull(mMockInjector.mNetworkCallback);
+ }
+
+ @Test
+ public void loadRebootEscrowDataIfAvailable_serverBasedWaitForInternetRemoteException_Failure()
+ throws Exception {
+ setServerBasedRebootEscrowProvider();
+ mMockInjector.setWaitForNetwork(true);
+
+ when(mInjected.getBootCount()).thenReturn(0);
+ RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
+ mService.setRebootEscrowListener(mockListener);
+ mService.prepareRebootEscrow();
+
+ clearInvocations(mServiceConnection);
+ mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN);
+ verify(mockListener).onPreparedForReboot(eq(true));
+ verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong());
+
+ // Use x -> x for both wrap & unwrap functions.
+ when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
+ verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
+ assertTrue(mStorage.hasRebootEscrowServerBlob());
+
+ // pretend reboot happens here
+ when(mInjected.getBootCount()).thenReturn(1);
+ ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<Integer> metricsErrorCodeCaptor = ArgumentCaptor.forClass(Integer.class);
+ doNothing()
+ .when(mInjected)
+ .reportMetric(
+ metricsSuccessCaptor.capture(),
+ metricsErrorCodeCaptor.capture(),
+ eq(2) /* Server based */,
+ eq(1) /* attempt count */,
+ anyInt(),
+ eq(0) /* vbmeta status */,
+ anyInt());
+
+ // load escrow data
+ when(mServiceConnection.unwrap(any(), anyLong())).thenThrow(RemoteException.class);
+ Network mockNetwork = mock(Network.class);
+ mMockInjector.mNetworkConsumer =
+ (callback) -> {
+ callback.onAvailable(mockNetwork);
+ };
+
+ mService.loadRebootEscrowDataIfAvailable(mHandler);
+ verify(mServiceConnection).unwrap(any(), anyLong());
+ assertFalse(metricsSuccessCaptor.getValue());
+ assertEquals(
+ Integer.valueOf(RebootEscrowManager.ERROR_LOAD_ESCROW_KEY),
+ metricsErrorCodeCaptor.getValue());
+ assertNull(mMockInjector.mNetworkCallback);
+ }
+
+ @Test
+ public void loadRebootEscrowDataIfAvailable_waitForInternet_networkUnavailable()
+ throws Exception {
+ setServerBasedRebootEscrowProvider();
+ mMockInjector.setWaitForNetwork(true);
+
+ when(mInjected.getBootCount()).thenReturn(0);
+ RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
+ mService.setRebootEscrowListener(mockListener);
+ mService.prepareRebootEscrow();
+
+ clearInvocations(mServiceConnection);
+ mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN);
+ verify(mockListener).onPreparedForReboot(eq(true));
+ verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong());
+
+ // Use x -> x for both wrap & unwrap functions.
+ when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
+ verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
+ assertTrue(mStorage.hasRebootEscrowServerBlob());
+
+ // pretend reboot happens here
+ when(mInjected.getBootCount()).thenReturn(1);
+ ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<Integer> metricsErrorCodeCaptor = ArgumentCaptor.forClass(Integer.class);
+ doNothing()
+ .when(mInjected)
+ .reportMetric(
+ metricsSuccessCaptor.capture(),
+ metricsErrorCodeCaptor.capture(),
+ eq(2) /* Server based */,
+ eq(0) /* attempt count */,
+ anyInt(),
+ eq(0) /* vbmeta status */,
+ anyInt());
+
+ // Network is not available within timeout.
+ mMockInjector.mNetworkConsumer = ConnectivityManager.NetworkCallback::onUnavailable;
+ mService.loadRebootEscrowDataIfAvailable(mHandler);
+ assertFalse(metricsSuccessCaptor.getValue());
+ assertEquals(
+ Integer.valueOf(RebootEscrowManager.ERROR_NO_NETWORK),
+ metricsErrorCodeCaptor.getValue());
+ assertNull(mMockInjector.mNetworkCallback);
+ }
+
+ @Test
+ public void loadRebootEscrowDataIfAvailable_waitForInternet_networkLost() throws Exception {
+ setServerBasedRebootEscrowProvider();
+ mMockInjector.setWaitForNetwork(true);
+
+ when(mInjected.getBootCount()).thenReturn(0);
+ RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
+ mService.setRebootEscrowListener(mockListener);
+ mService.prepareRebootEscrow();
+
+ clearInvocations(mServiceConnection);
+ mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN);
+ verify(mockListener).onPreparedForReboot(eq(true));
+ verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong());
+
+ // Use x -> x for both wrap & unwrap functions.
+ when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
+ verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
+ assertTrue(mStorage.hasRebootEscrowServerBlob());
+
+ // pretend reboot happens here
+ when(mInjected.getBootCount()).thenReturn(1);
+ ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<Integer> metricsErrorCodeCaptor = ArgumentCaptor.forClass(Integer.class);
+ doNothing()
+ .when(mInjected)
+ .reportMetric(
+ metricsSuccessCaptor.capture(),
+ metricsErrorCodeCaptor.capture(),
+ eq(2) /* Server based */,
+ eq(2) /* attempt count */,
+ anyInt(),
+ eq(0) /* vbmeta status */,
+ anyInt());
+
+ // Network is available, then lost.
+ when(mServiceConnection.unwrap(any(), anyLong())).thenThrow(new IOException());
+ Network mockNetwork = mock(Network.class);
+ mMockInjector.mNetworkConsumer =
+ (callback) -> {
+ callback.onAvailable(mockNetwork);
+ callback.onLost(mockNetwork);
+ };
+ mService.loadRebootEscrowDataIfAvailable(mHandler);
+ // Sleep 5s for the retry to complete
+ Thread.sleep(5 * 1000);
+ assertFalse(metricsSuccessCaptor.getValue());
+ assertEquals(
+ Integer.valueOf(RebootEscrowManager.ERROR_NO_NETWORK),
+ metricsErrorCodeCaptor.getValue());
+ assertNull(mMockInjector.mNetworkCallback);
+ }
+
+ @Test
+ public void loadRebootEscrowDataIfAvailable_waitForInternet_networkAvailableWithDelay()
+ throws Exception {
+ setServerBasedRebootEscrowProvider();
+ mMockInjector.setWaitForNetwork(true);
+
+ when(mInjected.getBootCount()).thenReturn(0);
+ RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
+ mService.setRebootEscrowListener(mockListener);
+ mService.prepareRebootEscrow();
+
+ clearInvocations(mServiceConnection);
+ mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN);
+ verify(mockListener).onPreparedForReboot(eq(true));
+ verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong());
+
+ // Use x -> x for both wrap & unwrap functions.
+ when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
+ verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
+ assertTrue(mStorage.hasRebootEscrowServerBlob());
+
+ // pretend reboot happens here
+ when(mInjected.getBootCount()).thenReturn(1);
+ ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<Integer> metricsErrorCodeCaptor = ArgumentCaptor.forClass(Integer.class);
+ doNothing()
+ .when(mInjected)
+ .reportMetric(
+ metricsSuccessCaptor.capture(),
+ metricsErrorCodeCaptor.capture(),
+ eq(2) /* Server based */,
+ eq(1) /* attempt count */,
+ anyInt(),
+ eq(0) /* vbmeta status */,
+ anyInt());
+
+ // load escrow data
+ when(mServiceConnection.unwrap(any(), anyLong()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ // network available after 1 sec
+ Network mockNetwork = mock(Network.class);
+ mMockInjector.mNetworkConsumer =
+ (callback) -> {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ callback.onAvailable(mockNetwork);
+ };
+ mService.loadRebootEscrowDataIfAvailable(mHandler);
+ verify(mServiceConnection).unwrap(any(), anyLong());
+ assertTrue(metricsSuccessCaptor.getValue());
+ verify(mKeyStoreManager).clearKeyStoreEncryptionKey();
+ assertNull(mMockInjector.mNetworkCallback);
+ }
+
+ @Test
+ public void loadRebootEscrowDataIfAvailable_waitForInternet_timeoutExhausted()
+ throws Exception {
+ setServerBasedRebootEscrowProvider();
+ mMockInjector.setWaitForNetwork(true);
+
+ when(mInjected.getBootCount()).thenReturn(0);
+ RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
+ mService.setRebootEscrowListener(mockListener);
+ mService.prepareRebootEscrow();
+
+ clearInvocations(mServiceConnection);
+ mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN);
+ verify(mockListener).onPreparedForReboot(eq(true));
+ verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong());
+
+ // Use x -> x for both wrap & unwrap functions.
+ when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
+ verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
+ assertTrue(mStorage.hasRebootEscrowServerBlob());
+
+ // pretend reboot happens here
+ when(mInjected.getBootCount()).thenReturn(1);
+ ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<Integer> metricsErrorCodeCaptor = ArgumentCaptor.forClass(Integer.class);
+ doNothing()
+ .when(mInjected)
+ .reportMetric(
+ metricsSuccessCaptor.capture(),
+ metricsErrorCodeCaptor.capture(),
+ eq(2) /* Server based */,
+ eq(1) /* attempt count */,
+ anyInt(),
+ eq(0) /* vbmeta status */,
+ anyInt());
+
+ // load reboot escrow data
+ when(mServiceConnection.unwrap(any(), anyLong())).thenThrow(IOException.class);
+ Network mockNetwork = mock(Network.class);
+ // wait past timeout
+ mMockInjector.mNetworkConsumer =
+ (callback) -> {
+ try {
+ Thread.sleep(3500);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ callback.onAvailable(mockNetwork);
+ };
+ mService.loadRebootEscrowDataIfAvailable(mHandler);
+ verify(mServiceConnection).unwrap(any(), anyLong());
+ assertFalse(metricsSuccessCaptor.getValue());
+ assertEquals(
+ Integer.valueOf(RebootEscrowManager.ERROR_TIMEOUT_EXHAUSTED),
+ metricsErrorCodeCaptor.getValue());
+ assertNull(mMockInjector.mNetworkCallback);
+ }
+
+ @Test
+ public void loadRebootEscrowDataIfAvailable_serverBasedWaitForNetwork_retryCountExhausted()
+ throws Exception {
+ setServerBasedRebootEscrowProvider();
+ mMockInjector.setWaitForNetwork(true);
+
+ when(mInjected.getBootCount()).thenReturn(0);
+ RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
+ mService.setRebootEscrowListener(mockListener);
+ mService.prepareRebootEscrow();
+
+ clearInvocations(mServiceConnection);
+ mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN);
+ verify(mockListener).onPreparedForReboot(eq(true));
+ verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong());
+
+ // Use x -> x for both wrap & unwrap functions.
+ when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
+ verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
+ assertTrue(mStorage.hasRebootEscrowServerBlob());
+
+ // pretend reboot happens here
+ when(mInjected.getBootCount()).thenReturn(1);
+ ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<Integer> metricsErrorCodeCaptor = ArgumentCaptor.forClass(Integer.class);
+ doNothing()
+ .when(mInjected)
+ .reportMetric(
+ metricsSuccessCaptor.capture(),
+ metricsErrorCodeCaptor.capture(),
+ eq(2) /* Server based */,
+ eq(2) /* attempt count */,
+ anyInt(),
+ eq(0) /* vbmeta status */,
+ anyInt());
+
+ when(mServiceConnection.unwrap(any(), anyLong())).thenThrow(new IOException());
+ Network mockNetwork = mock(Network.class);
+ mMockInjector.mNetworkConsumer =
+ (callback) -> {
+ callback.onAvailable(mockNetwork);
+ };
+
+ mService.loadRebootEscrowDataIfAvailable(mHandler);
+ // Sleep 5s for the retry to complete
+ Thread.sleep(5 * 1000);
+ verify(mServiceConnection, times(2)).unwrap(any(), anyLong());
+ assertFalse(metricsSuccessCaptor.getValue());
+ assertEquals(
+ Integer.valueOf(RebootEscrowManager.ERROR_RETRY_COUNT_EXHAUSTED),
+ metricsErrorCodeCaptor.getValue());
+ assertNull(mMockInjector.mNetworkCallback);
+ }
+
+ @Test
+ public void loadRebootEscrowDataIfAvailable_ServerBasedWaitForInternet_RetrySuccess()
+ throws Exception {
+ setServerBasedRebootEscrowProvider();
+ mMockInjector.setWaitForNetwork(true);
+
+ when(mInjected.getBootCount()).thenReturn(0);
+ RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
+ mService.setRebootEscrowListener(mockListener);
+ mService.prepareRebootEscrow();
+
+ clearInvocations(mServiceConnection);
+ mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN);
+ verify(mockListener).onPreparedForReboot(eq(true));
+ verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong());
+
+ // Use x -> x for both wrap & unwrap functions.
+ when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
+ verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
+ assertTrue(mStorage.hasRebootEscrowServerBlob());
+
+ // pretend reboot happens here
+ when(mInjected.getBootCount()).thenReturn(1);
+ ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
+ doNothing()
+ .when(mInjected)
+ .reportMetric(
+ metricsSuccessCaptor.capture(),
+ anyInt(),
+ anyInt(),
+ eq(2) /* attempt count */,
+ anyInt(),
+ anyInt(),
+ anyInt());
+
+ when(mServiceConnection.unwrap(any(), anyLong()))
+ .thenThrow(new IOException())
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ Network mockNetwork = mock(Network.class);
+ mMockInjector.mNetworkConsumer =
+ (callback) -> {
+ callback.onAvailable(mockNetwork);
+ };
+
+ mService.loadRebootEscrowDataIfAvailable(mHandler);
+ // Sleep 5s for the retry to complete
+ Thread.sleep(5 * 1000);
+ verify(mServiceConnection, times(2)).unwrap(any(), anyLong());
+ assertTrue(metricsSuccessCaptor.getValue());
+ verify(mKeyStoreManager).clearKeyStoreEncryptionKey();
+ assertNull(mMockInjector.mNetworkCallback);
+ }
+
+ @Test
public void loadRebootEscrowDataIfAvailable_TooManyBootsInBetween_NoMetrics() throws Exception {
when(mInjected.getBootCount()).thenReturn(0);
@@ -684,7 +1192,7 @@
when(mInjected.getBootCount()).thenReturn(10);
when(mRebootEscrow.retrieveKey()).thenReturn(new byte[32]);
- mService.loadRebootEscrowDataIfAvailable(null);
+ mService.loadRebootEscrowDataIfAvailable(mHandler);
verify(mRebootEscrow).retrieveKey();
verify(mInjected, never()).reportMetric(anyBoolean(), anyInt(), anyInt(), anyInt(),
anyInt(), anyInt(), anyInt());
@@ -712,7 +1220,7 @@
when(mInjected.getBootCount()).thenReturn(10);
when(mRebootEscrow.retrieveKey()).thenReturn(new byte[32]);
- mService.loadRebootEscrowDataIfAvailable(null);
+ mService.loadRebootEscrowDataIfAvailable(mHandler);
verify(mInjected, never()).reportMetric(anyBoolean(), anyInt(), anyInt(), anyInt(),
anyInt(), anyInt(), anyInt());
}
@@ -750,7 +1258,7 @@
// Trigger a vbmeta digest mismatch
mStorage.setString(RebootEscrowManager.REBOOT_ESCROW_KEY_VBMETA_DIGEST,
"non sense value", USER_SYSTEM);
- mService.loadRebootEscrowDataIfAvailable(null);
+ mService.loadRebootEscrowDataIfAvailable(mHandler);
verify(mInjected).reportMetric(eq(true), eq(0) /* error code */, eq(1) /* HAL based */,
eq(1) /* attempt count */, anyInt(), eq(2) /* vbmeta status */, anyInt());
assertEquals(mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_KEY_VBMETA_DIGEST,
@@ -787,7 +1295,7 @@
eq(1) /* attempt count */, anyInt(), anyInt(), anyInt());
when(mRebootEscrow.retrieveKey()).thenAnswer(invocation -> null);
- mService.loadRebootEscrowDataIfAvailable(null);
+ mService.loadRebootEscrowDataIfAvailable(mHandler);
verify(mRebootEscrow).retrieveKey();
assertFalse(metricsSuccessCaptor.getValue());
assertEquals(Integer.valueOf(RebootEscrowManager.ERROR_LOAD_ESCROW_KEY),
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
index 281195d..1b983f0b 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
@@ -1073,7 +1073,9 @@
int uid = Binder.getCallingUid();
PendingIntent intent = PendingIntent.getBroadcast(
InstrumentationRegistry.getTargetContext(), /*requestCode=*/1,
- new Intent(), /*flags=*/ PendingIntent.FLAG_MUTABLE_UNAUDITED);
+ new Intent()
+ .setPackage(InstrumentationRegistry.getTargetContext().getPackageName()),
+ /*flags=*/ PendingIntent.FLAG_MUTABLE);
mRecoverableKeyStoreManager.setSnapshotCreatedPendingIntent(intent);
verify(mMockListenersStorage).setSnapshotListener(eq(uid), any(PendingIntent.class));
}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverySnapshotListenersStorageTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverySnapshotListenersStorageTest.java
index d9ebb4c..418d474 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverySnapshotListenersStorageTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverySnapshotListenersStorageTest.java
@@ -41,7 +41,9 @@
int recoveryAgentUid = 1000;
PendingIntent intent = PendingIntent.getBroadcast(
InstrumentationRegistry.getTargetContext(), /*requestCode=*/ 1,
- new Intent(), /*flags=*/ PendingIntent.FLAG_MUTABLE_UNAUDITED);
+ new Intent()
+ .setPackage(InstrumentationRegistry.getTargetContext().getPackageName()),
+ /*flags=*/ PendingIntent.FLAG_MUTABLE);
mStorage.setSnapshotListener(recoveryAgentUid, intent);
assertTrue(mStorage.hasListener(recoveryAgentUid));
@@ -54,7 +56,9 @@
int recoveryAgentUid = 1000;
mStorage.recoverySnapshotAvailable(recoveryAgentUid);
PendingIntent intent = PendingIntent.getBroadcast(
- context, /*requestCode=*/ 0, new Intent(TEST_INTENT_ACTION), /*flags=*/PendingIntent.FLAG_MUTABLE_UNAUDITED);
+ context, /*requestCode=*/ 0,
+ new Intent(TEST_INTENT_ACTION).setPackage(context.getPackageName()),
+ /*flags=*/PendingIntent.FLAG_MUTABLE);
CountDownLatch latch = new CountDownLatch(1);
context.registerReceiver(new BroadcastReceiver() {
@Override
@@ -75,7 +79,9 @@
int recoveryAgentUid = 1000;
mStorage.recoverySnapshotAvailable(recoveryAgentUid);
PendingIntent intent = PendingIntent.getBroadcast(
- context, /*requestCode=*/ 0, new Intent(TEST_INTENT_ACTION), /*flags=*/PendingIntent.FLAG_MUTABLE_UNAUDITED);
+ context, /*requestCode=*/ 0,
+ new Intent(TEST_INTENT_ACTION).setPackage(context.getPackageName()),
+ /*flags=*/PendingIntent.FLAG_MUTABLE);
CountDownLatch latch = new CountDownLatch(2);
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java
similarity index 98%
rename from services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
rename to services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java
index 17a5876..d9cd77d 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.net;
import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE;
import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY;
@@ -51,14 +51,13 @@
import android.os.Process;
import android.os.RemoteException;
import android.permission.PermissionCheckerManager;
+import android.platform.test.annotations.Presubmit;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.ArrayMap;
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.app.IBatteryStats;
-import com.android.server.NetworkManagementService.Dependencies;
-import com.android.server.net.BaseNetworkObserver;
import org.junit.After;
import org.junit.Before;
@@ -76,6 +75,7 @@
*/
@RunWith(AndroidJUnit4.class)
@SmallTest
+@Presubmit
public class NetworkManagementServiceTest {
private NetworkManagementService mNMService;
@Mock private Context mContext;
@@ -92,7 +92,7 @@
private final MockDependencies mDeps = new MockDependencies();
private final MockPermissionEnforcer mPermissionEnforcer = new MockPermissionEnforcer();
- private final class MockDependencies extends Dependencies {
+ private final class MockDependencies extends NetworkManagementService.Dependencies {
@Override
public IBinder getService(String name) {
switch (name) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java
index 2293808..a85c722 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java
@@ -327,7 +327,9 @@
}
private IntentSender makeResultIntent() {
- return PendingIntent.getActivity(getTestContext(), 0, new Intent(), PendingIntent.FLAG_MUTABLE_UNAUDITED).getIntentSender();
+ return PendingIntent.getActivity(getTestContext(), 0,
+ new Intent().setPackage(getTestContext().getPackageName()),
+ PendingIntent.FLAG_MUTABLE).getIntentSender();
}
public void testRequestPinShortcut_withCallback() {
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest9.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest9.java
index a47a8df..2fca3d0 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest9.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest9.java
@@ -150,7 +150,9 @@
public void testRequestPinAppWidget_withCallback() {
final PendingIntent resultIntent =
- PendingIntent.getActivity(getTestContext(), 0, new Intent(), PendingIntent.FLAG_MUTABLE_UNAUDITED);
+ PendingIntent.getActivity(getTestContext(), 0,
+ new Intent().setPackage(getTestContext().getPackageName()),
+ PendingIntent.FLAG_MUTABLE);
checkRequestPinAppWidget(resultIntent);
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserPropertiesTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserPropertiesTest.java
index 9625188..26d0ddf 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserPropertiesTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserPropertiesTest.java
@@ -63,6 +63,7 @@
.setInheritDevicePolicy(67)
.setUseParentsContacts(false)
.setCrossProfileIntentFilterAccessControl(10)
+ .setCrossProfileIntentResolutionStrategy(0)
.build();
final UserProperties actualProps = new UserProperties(defaultProps);
actualProps.setShowInLauncher(14);
@@ -70,6 +71,7 @@
actualProps.setInheritDevicePolicy(51);
actualProps.setUseParentsContacts(true);
actualProps.setCrossProfileIntentFilterAccessControl(20);
+ actualProps.setCrossProfileIntentResolutionStrategy(1);
// Write the properties to xml.
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -154,6 +156,8 @@
copy::getInheritDevicePolicy, exposeAll);
assertEqualGetterOrThrows(orig::getCrossProfileIntentFilterAccessControl,
copy::getCrossProfileIntentFilterAccessControl, exposeAll);
+ assertEqualGetterOrThrows(orig::getCrossProfileIntentResolutionStrategy,
+ copy::getCrossProfileIntentResolutionStrategy, exposeAll);
// Items requiring hasManagePermission - put them here using hasManagePermission.
assertEqualGetterOrThrows(orig::getShowInSettings, copy::getShowInSettings,
@@ -209,5 +213,7 @@
assertThat(expected.getUseParentsContacts()).isEqualTo(actual.getUseParentsContacts());
assertThat(expected.getCrossProfileIntentFilterAccessControl())
.isEqualTo(actual.getCrossProfileIntentFilterAccessControl());
+ assertThat(expected.getCrossProfileIntentResolutionStrategy())
+ .isEqualTo(actual.getCrossProfileIntentResolutionStrategy());
}
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserTypeTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserTypeTest.java
index 1151222..928c6ef 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserTypeTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserTypeTest.java
@@ -85,7 +85,8 @@
final UserProperties.Builder userProps = new UserProperties.Builder()
.setShowInLauncher(17)
.setUseParentsContacts(true)
- .setCrossProfileIntentFilterAccessControl(10);
+ .setCrossProfileIntentFilterAccessControl(10)
+ .setCrossProfileIntentResolutionStrategy(1);
final UserTypeDetails type = new UserTypeDetails.Builder()
.setName("a.name")
.setEnabled(1)
@@ -145,6 +146,8 @@
assertTrue(type.getDefaultUserPropertiesReference().getUseParentsContacts());
assertEquals(10, type.getDefaultUserPropertiesReference()
.getCrossProfileIntentFilterAccessControl());
+ assertEquals(1, type.getDefaultUserPropertiesReference()
+ .getCrossProfileIntentResolutionStrategy());
assertEquals(23, type.getBadgeLabel(0));
assertEquals(24, type.getBadgeLabel(1));
@@ -191,6 +194,8 @@
assertEquals(UserProperties.CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_ALL,
props.getCrossProfileIntentFilterAccessControl());
assertEquals(UserProperties.SHOW_IN_LAUNCHER_WITH_PARENT, props.getShowInLauncher());
+ assertEquals(UserProperties.CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_DEFAULT,
+ props.getCrossProfileIntentResolutionStrategy());
assertFalse(type.hasBadge());
}
@@ -273,7 +278,8 @@
.setShowInLauncher(19)
.setStartWithParent(true)
.setUseParentsContacts(true)
- .setCrossProfileIntentFilterAccessControl(10);
+ .setCrossProfileIntentFilterAccessControl(10)
+ .setCrossProfileIntentResolutionStrategy(1);
final ArrayMap<String, UserTypeDetails.Builder> builders = new ArrayMap<>();
builders.put(userTypeAosp1, new UserTypeDetails.Builder()
.setName(userTypeAosp1)
@@ -301,6 +307,8 @@
assertEquals(19, aospType.getDefaultUserPropertiesReference().getShowInLauncher());
assertEquals(10, aospType.getDefaultUserPropertiesReference()
.getCrossProfileIntentFilterAccessControl());
+ assertEquals(1, aospType.getDefaultUserPropertiesReference()
+ .getCrossProfileIntentResolutionStrategy());
assertTrue(aospType.getDefaultUserPropertiesReference().getStartWithParent());
assertTrue(aospType.getDefaultUserPropertiesReference()
.getUseParentsContacts());
@@ -335,6 +343,8 @@
assertEquals(2020, aospType.getDefaultUserPropertiesReference().getShowInLauncher());
assertEquals(20, aospType.getDefaultUserPropertiesReference()
.getCrossProfileIntentFilterAccessControl());
+ assertEquals(0, aospType.getDefaultUserPropertiesReference()
+ .getCrossProfileIntentResolutionStrategy());
assertFalse(aospType.getDefaultUserPropertiesReference().getStartWithParent());
assertFalse(aospType.getDefaultUserPropertiesReference()
.getUseParentsContacts());
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index 5059ef3..1889d9a 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -175,14 +175,14 @@
final UserProperties typeProps = userTypeDetails.getDefaultUserPropertiesReference();
// Test that only one clone user can be created
- final int primaryUserId = mUserManager.getPrimaryUser().id;
+ final int mainUserId = mUserManager.getMainUser().getIdentifier();
UserInfo userInfo = createProfileForUser("Clone user1",
UserManager.USER_TYPE_PROFILE_CLONE,
- primaryUserId);
+ mainUserId);
assertThat(userInfo).isNotNull();
UserInfo userInfo2 = createProfileForUser("Clone user2",
UserManager.USER_TYPE_PROFILE_CLONE,
- primaryUserId);
+ mainUserId);
assertThat(userInfo2).isNull();
final Context userContext = mContext.createPackageContextAsUser("system", 0,
@@ -208,14 +208,16 @@
assertThrows(SecurityException.class, cloneUserProperties::getStartWithParent);
assertThrows(SecurityException.class,
cloneUserProperties::getCrossProfileIntentFilterAccessControl);
+ assertThrows(SecurityException.class,
+ cloneUserProperties::getCrossProfileIntentResolutionStrategy);
// Verify clone user parent
- assertThat(mUserManager.getProfileParent(primaryUserId)).isNull();
+ assertThat(mUserManager.getProfileParent(mainUserId)).isNull();
UserInfo parentProfileInfo = mUserManager.getProfileParent(userInfo.id);
assertThat(parentProfileInfo).isNotNull();
- assertThat(primaryUserId).isEqualTo(parentProfileInfo.id);
+ assertThat(mainUserId).isEqualTo(parentProfileInfo.id);
removeUser(userInfo.id);
- assertThat(mUserManager.getProfileParent(primaryUserId)).isNull();
+ assertThat(mUserManager.getProfileParent(mainUserId)).isNull();
}
@MediumTest
@@ -373,6 +375,29 @@
@MediumTest
@Test
+ public void testRemoveUserWhenPossible_permanentAdminMainUserReturnsError() throws Exception {
+ assumeHeadlessModeEnabled();
+ assumeTrue("Main user is not permanent admin", isMainUserPermanentAdmin());
+
+ int currentUser = ActivityManager.getCurrentUser();
+ final UserInfo otherUser = createUser("User 1", /* flags= */ UserInfo.FLAG_ADMIN);
+ UserHandle mainUser = mUserManager.getMainUser();
+
+ switchUser(otherUser.id, null, true);
+
+ assertThat(mUserManager.removeUserWhenPossible(mainUser,
+ /* overrideDevicePolicy= */ false))
+ .isEqualTo(UserManager.REMOVE_RESULT_ERROR_MAIN_USER_PERMANENT_ADMIN);
+
+
+ assertThat(hasUser(mainUser.getIdentifier())).isTrue();
+
+ // Switch back to the starting user.
+ switchUser(currentUser, null, true);
+ }
+
+ @MediumTest
+ @Test
public void testRemoveUserWhenPossible_invalidUserReturnsError() throws Exception {
assertThat(hasUser(Integer.MAX_VALUE)).isFalse();
assertThat(mUserManager.removeUserWhenPossible(UserHandle.of(Integer.MAX_VALUE),
@@ -645,17 +670,16 @@
@Test
public void testGetProfileParent() throws Exception {
assumeManagedUsersSupported();
- final int primaryUserId = mUserManager.getPrimaryUser().id;
-
+ int mainUserId = mUserManager.getMainUser().getIdentifier();
UserInfo userInfo = createProfileForUser("Profile",
- UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
+ UserManager.USER_TYPE_PROFILE_MANAGED, mainUserId);
assertThat(userInfo).isNotNull();
- assertThat(mUserManager.getProfileParent(primaryUserId)).isNull();
+ assertThat(mUserManager.getProfileParent(mainUserId)).isNull();
UserInfo parentProfileInfo = mUserManager.getProfileParent(userInfo.id);
assertThat(parentProfileInfo).isNotNull();
- assertThat(primaryUserId).isEqualTo(parentProfileInfo.id);
+ assertThat(mainUserId).isEqualTo(parentProfileInfo.id);
removeUser(userInfo.id);
- assertThat(mUserManager.getProfileParent(primaryUserId)).isNull();
+ assertThat(mUserManager.getProfileParent(mainUserId)).isNull();
}
/** Test that UserManager returns the correct badge information for a managed profile. */
@@ -669,9 +693,9 @@
.that(userTypeDetails).isNotNull();
assertThat(userTypeDetails.getName()).isEqualTo(UserManager.USER_TYPE_PROFILE_MANAGED);
- final int primaryUserId = mUserManager.getPrimaryUser().id;
+ int mainUserId = mUserManager.getMainUser().getIdentifier();
UserInfo userInfo = createProfileForUser("Managed",
- UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
+ UserManager.USER_TYPE_PROFILE_MANAGED, mainUserId);
assertThat(userInfo).isNotNull();
final int userId = userInfo.id;
@@ -714,9 +738,9 @@
final UserProperties typeProps = userTypeDetails.getDefaultUserPropertiesReference();
// Create an actual user (of this user type) and get its properties.
- final int primaryUserId = mUserManager.getPrimaryUser().id;
+ int mainUserId = mUserManager.getMainUser().getIdentifier();
final UserInfo userInfo = createProfileForUser("Managed",
- UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
+ UserManager.USER_TYPE_PROFILE_MANAGED, mainUserId);
assertThat(userInfo).isNotNull();
final int userId = userInfo.id;
final UserProperties userProps = mUserManager.getUserProperties(UserHandle.of(userId));
@@ -727,6 +751,7 @@
assertThat(userProps.getShowInSettings()).isEqualTo(typeProps.getShowInSettings());
assertFalse(userProps.getUseParentsContacts());
assertThrows(SecurityException.class, userProps::getCrossProfileIntentFilterAccessControl);
+ assertThrows(SecurityException.class, userProps::getCrossProfileIntentResolutionStrategy);
assertThrows(SecurityException.class, userProps::getStartWithParent);
assertThrows(SecurityException.class, userProps::getInheritDevicePolicy);
}
@@ -736,11 +761,11 @@
@Test
public void testAddManagedProfile() throws Exception {
assumeManagedUsersSupported();
- final int primaryUserId = mUserManager.getPrimaryUser().id;
+ int mainUserId = mUserManager.getMainUser().getIdentifier();
UserInfo userInfo1 = createProfileForUser("Managed 1",
- UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
+ UserManager.USER_TYPE_PROFILE_MANAGED, mainUserId);
UserInfo userInfo2 = createProfileForUser("Managed 2",
- UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
+ UserManager.USER_TYPE_PROFILE_MANAGED, mainUserId);
assertThat(userInfo1).isNotNull();
assertThat(userInfo2).isNull();
@@ -759,9 +784,9 @@
@Test
public void testAddManagedProfile_withDisallowedPackages() throws Exception {
assumeManagedUsersSupported();
- final int primaryUserId = mUserManager.getPrimaryUser().id;
+ int mainUserId = mUserManager.getMainUser().getIdentifier();
UserInfo userInfo1 = createProfileForUser("Managed1",
- UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
+ UserManager.USER_TYPE_PROFILE_MANAGED, mainUserId);
// Verify that the packagesToVerify are installed by default.
for (String pkg : PACKAGES) {
if (!mPackageManager.isPackageAvailable(pkg)) {
@@ -775,7 +800,7 @@
removeUser(userInfo1.id);
UserInfo userInfo2 = createProfileForUser("Managed2",
- UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId, PACKAGES);
+ UserManager.USER_TYPE_PROFILE_MANAGED, mainUserId, PACKAGES);
// Verify that the packagesToVerify are not installed by default.
for (String pkg : PACKAGES) {
if (!mPackageManager.isPackageAvailable(pkg)) {
@@ -795,9 +820,9 @@
@Test
public void testAddManagedProfile_disallowedPackagesInstalledLater() throws Exception {
assumeManagedUsersSupported();
- final int primaryUserId = mUserManager.getPrimaryUser().id;
+ final int mainUserId = mUserManager.getMainUser().getIdentifier();
UserInfo userInfo = createProfileForUser("Managed",
- UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId, PACKAGES);
+ UserManager.USER_TYPE_PROFILE_MANAGED, mainUserId, PACKAGES);
// Verify that the packagesToVerify are not installed by default.
for (String pkg : PACKAGES) {
if (!mPackageManager.isPackageAvailable(pkg)) {
@@ -842,17 +867,17 @@
@MediumTest
@Test
public void testCreateUser_disallowAddClonedUserProfile() throws Exception {
- final int primaryUserId = ActivityManager.getCurrentUser();
- final UserHandle primaryUserHandle = asHandle(primaryUserId);
+ final int mainUserId = ActivityManager.getCurrentUser();
+ final UserHandle mainUserHandle = asHandle(mainUserId);
mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_CLONE_PROFILE,
- true, primaryUserHandle);
+ true, mainUserHandle);
try {
UserInfo cloneProfileUserInfo = createProfileForUser("Clone",
- UserManager.USER_TYPE_PROFILE_CLONE, primaryUserId);
+ UserManager.USER_TYPE_PROFILE_CLONE, mainUserId);
assertThat(cloneProfileUserInfo).isNull();
} finally {
mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_CLONE_PROFILE, false,
- primaryUserHandle);
+ mainUserHandle);
}
}
@@ -861,17 +886,17 @@
@Test
public void testCreateProfileForUser_disallowAddManagedProfile() throws Exception {
assumeManagedUsersSupported();
- final int primaryUserId = mUserManager.getPrimaryUser().id;
- final UserHandle primaryUserHandle = asHandle(primaryUserId);
+ final int mainUserId = mUserManager.getMainUser().getIdentifier();
+ final UserHandle mainUserHandle = asHandle(mainUserId);
mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, true,
- primaryUserHandle);
+ mainUserHandle);
try {
UserInfo userInfo = createProfileForUser("Managed",
- UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
+ UserManager.USER_TYPE_PROFILE_MANAGED, mainUserId);
assertThat(userInfo).isNull();
} finally {
mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, false,
- primaryUserHandle);
+ mainUserHandle);
}
}
@@ -880,17 +905,17 @@
@Test
public void testCreateProfileForUserEvenWhenDisallowed() throws Exception {
assumeManagedUsersSupported();
- final int primaryUserId = mUserManager.getPrimaryUser().id;
- final UserHandle primaryUserHandle = asHandle(primaryUserId);
+ final int mainUserId = mUserManager.getMainUser().getIdentifier();
+ final UserHandle mainUserHandle = asHandle(mainUserId);
mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, true,
- primaryUserHandle);
+ mainUserHandle);
try {
UserInfo userInfo = createProfileEvenWhenDisallowedForUser("Managed",
- UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
+ UserManager.USER_TYPE_PROFILE_MANAGED, mainUserId);
assertThat(userInfo).isNotNull();
} finally {
mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, false,
- primaryUserHandle);
+ mainUserHandle);
}
}
@@ -899,23 +924,23 @@
@Test
public void testCreateProfileForUser_disallowAddUser() throws Exception {
assumeManagedUsersSupported();
- final int primaryUserId = mUserManager.getPrimaryUser().id;
- final UserHandle primaryUserHandle = asHandle(primaryUserId);
- mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_USER, true, primaryUserHandle);
+ final int mainUserId = mUserManager.getMainUser().getIdentifier();
+ final UserHandle mainUserHandle = asHandle(mainUserId);
+ mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_USER, true, mainUserHandle);
try {
UserInfo userInfo = createProfileForUser("Managed",
- UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
+ UserManager.USER_TYPE_PROFILE_MANAGED, mainUserId);
assertThat(userInfo).isNotNull();
} finally {
mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_USER, false,
- primaryUserHandle);
+ mainUserHandle);
}
}
@MediumTest
@Test
public void testAddRestrictedProfile() throws Exception {
- if (isAutomotive()) return;
+ if (isAutomotive() || UserManager.isHeadlessSystemUserMode()) return;
assertWithMessage("There should be no associated restricted profiles before the test")
.that(mUserManager.hasRestrictedProfiles()).isFalse();
UserInfo userInfo = createRestrictedProfile("Profile");
@@ -947,10 +972,10 @@
@Test
public void testGetManagedProfileCreationTime() throws Exception {
assumeManagedUsersSupported();
- final int primaryUserId = mUserManager.getPrimaryUser().id;
+ final int mainUserId = mUserManager.getMainUser().getIdentifier();
final long startTime = System.currentTimeMillis();
UserInfo profile = createProfileForUser("Managed 1",
- UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
+ UserManager.USER_TYPE_PROFILE_MANAGED, mainUserId);
final long endTime = System.currentTimeMillis();
assertThat(profile).isNotNull();
if (System.currentTimeMillis() > EPOCH_PLUS_30_YEARS) {
@@ -963,8 +988,8 @@
assertThat(mUserManager.getUserCreationTime(asHandle(profile.id)))
.isEqualTo(profile.creationTime);
- long ownerCreationTime = mUserManager.getUserInfo(primaryUserId).creationTime;
- assertThat(mUserManager.getUserCreationTime(asHandle(primaryUserId)))
+ long ownerCreationTime = mUserManager.getUserInfo(mainUserId).creationTime;
+ assertThat(mUserManager.getUserCreationTime(asHandle(mainUserId)))
.isEqualTo(ownerCreationTime);
}
@@ -1200,14 +1225,14 @@
@Test
public void testCreateProfile_withContextUserId() throws Exception {
assumeManagedUsersSupported();
- final int primaryUserId = mUserManager.getPrimaryUser().id;
+ final int mainUserId = mUserManager.getMainUser().getIdentifier();
UserInfo userProfile = createProfileForUser("Managed 1",
- UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
+ UserManager.USER_TYPE_PROFILE_MANAGED, mainUserId);
assertThat(userProfile).isNotNull();
UserManager um = (UserManager) mContext.createPackageContextAsUser(
- "android", 0, mUserManager.getPrimaryUser().getUserHandle())
+ "android", 0, mUserManager.getMainUser())
.getSystemService(Context.USER_SERVICE);
List<UserHandle> profiles = um.getAllProfiles();
@@ -1219,10 +1244,10 @@
@Test
public void testSetUserName_withContextUserId() throws Exception {
assumeManagedUsersSupported();
- final int primaryUserId = mUserManager.getPrimaryUser().id;
+ final int mainUserId = mUserManager.getMainUser().getIdentifier();
UserInfo userInfo1 = createProfileForUser("Managed 1",
- UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
+ UserManager.USER_TYPE_PROFILE_MANAGED, mainUserId);
assertThat(userInfo1).isNotNull();
UserManager um = (UserManager) mContext.createPackageContextAsUser(
@@ -1268,10 +1293,10 @@
@Test
public void testGetUserIcon_withContextUserId() throws Exception {
assumeManagedUsersSupported();
- final int primaryUserId = mUserManager.getPrimaryUser().id;
+ final int mainUserId = mUserManager.getMainUser().getIdentifier();
UserInfo userInfo1 = createProfileForUser("Managed 1",
- UserManager.USER_TYPE_PROFILE_MANAGED, primaryUserId);
+ UserManager.USER_TYPE_PROFILE_MANAGED, mainUserId);
assertThat(userInfo1).isNotNull();
UserManager um = (UserManager) mContext.createPackageContextAsUser(
@@ -1420,4 +1445,10 @@
private static UserHandle asHandle(int userId) {
return new UserHandle(userId);
}
+
+ private boolean isMainUserPermanentAdmin() {
+ return Resources.getSystem()
+ .getBoolean(com.android.internal.R.bool.config_isMainUserPermanentAdmin);
+ }
+
}
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java b/services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java
index 856df359..50040b7 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/FakeTimeDetectorStrategy.java
@@ -62,6 +62,15 @@
}
@Override
+ public NetworkTimeSuggestion getLatestNetworkSuggestion() {
+ return null;
+ }
+
+ @Override
+ public void clearLatestNetworkSuggestion() {
+ }
+
+ @Override
public void suggestGnssTime(GnssTimeSuggestion timeSuggestion) {
}
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/NetworkTimeUpdateServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/NetworkTimeUpdateServiceTest.java
new file mode 100644
index 0000000..08d08b6
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timedetector/NetworkTimeUpdateServiceTest.java
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2022 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.server.timedetector;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.time.UnixEpochTime;
+import android.net.Network;
+import android.util.NtpTrustedTime;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.timedetector.NetworkTimeUpdateService.Engine.RefreshCallbacks;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.net.InetSocketAddress;
+import java.util.function.Supplier;
+
+@RunWith(AndroidJUnit4.class)
+public class NetworkTimeUpdateServiceTest {
+
+ private static final InetSocketAddress FAKE_SERVER_ADDRESS =
+ InetSocketAddress.createUnresolved("test", 123);
+ private static final long ARBITRARY_ELAPSED_REALTIME_MILLIS = 100000000L;
+ private static final long ARBITRARY_UNIX_EPOCH_TIME_MILLIS = 5555555555L;
+ private static final int ARBITRARY_UNCERTAINTY_MILLIS = 999;
+
+ private FakeElapsedRealtimeClock mFakeElapsedRealtimeClock;
+ private NtpTrustedTime mMockNtpTrustedTime;
+ private Network mDummyNetwork;
+
+ @Before
+ public void setUp() {
+ mFakeElapsedRealtimeClock = new FakeElapsedRealtimeClock();
+ mMockNtpTrustedTime = mock(NtpTrustedTime.class);
+ mDummyNetwork = mock(Network.class);
+ }
+
+ @Test
+ public void engineImpl_refreshIfRequiredAndReschedule_success() {
+ mFakeElapsedRealtimeClock.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS);
+
+ int normalPollingIntervalMillis = 7777777;
+ int shortPollingIntervalMillis = 3333;
+ int tryAgainTimesMax = 5;
+ NetworkTimeUpdateService.Engine engine = new NetworkTimeUpdateService.EngineImpl(
+ mFakeElapsedRealtimeClock,
+ normalPollingIntervalMillis, shortPollingIntervalMillis, tryAgainTimesMax,
+ mMockNtpTrustedTime);
+
+ // Simulated NTP client behavior: No cached time value available initially, then a
+ // successful refresh.
+ NtpTrustedTime.TimeResult timeResult = createNtpTimeResult(
+ mFakeElapsedRealtimeClock.getElapsedRealtimeMillis() - 1);
+ when(mMockNtpTrustedTime.getCachedTimeResult()).thenReturn(null, timeResult);
+ when(mMockNtpTrustedTime.forceRefresh(mDummyNetwork)).thenReturn(true);
+
+ RefreshCallbacks mockCallback = mock(RefreshCallbacks.class);
+ // Trigger the engine's logic.
+ engine.refreshIfRequiredAndReschedule(mDummyNetwork, "Test", mockCallback);
+
+ // Expect the refresh attempt to have been made.
+ verify(mMockNtpTrustedTime).forceRefresh(mDummyNetwork);
+
+ // Check everything happened that was supposed to.
+ long expectedDelayMillis = calculateRefreshDelayMillisForTimeResult(
+ timeResult, normalPollingIntervalMillis);
+ verify(mockCallback).scheduleNextRefresh(
+ mFakeElapsedRealtimeClock.getElapsedRealtimeMillis() + expectedDelayMillis);
+
+ NetworkTimeSuggestion expectedSuggestion = createExpectedSuggestion(timeResult);
+ verify(mockCallback).submitSuggestion(expectedSuggestion);
+ }
+
+ @Test
+ public void engineImpl_refreshIfRequiredAndReschedule_failThenFailRepeatedly() {
+ mFakeElapsedRealtimeClock.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS);
+
+ int normalPollingIntervalMillis = 7777777;
+ int shortPollingIntervalMillis = 3333;
+ int tryAgainTimesMax = 5;
+ NetworkTimeUpdateService.Engine engine = new NetworkTimeUpdateService.EngineImpl(
+ mFakeElapsedRealtimeClock,
+ normalPollingIntervalMillis, shortPollingIntervalMillis, tryAgainTimesMax,
+ mMockNtpTrustedTime);
+
+ for (int i = 0; i < tryAgainTimesMax + 1; i++) {
+ // Simulated NTP client behavior: No cached time value available and failure to refresh.
+ when(mMockNtpTrustedTime.getCachedTimeResult()).thenReturn(null);
+ when(mMockNtpTrustedTime.forceRefresh(mDummyNetwork)).thenReturn(false);
+
+ RefreshCallbacks mockCallback = mock(RefreshCallbacks.class);
+
+ // Trigger the engine's logic.
+ engine.refreshIfRequiredAndReschedule(mDummyNetwork, "Test", mockCallback);
+
+ // Expect a refresh attempt each time: there's no currently cached result.
+ verify(mMockNtpTrustedTime).forceRefresh(mDummyNetwork);
+
+ // Check everything happened that was supposed to.
+ long expectedDelayMillis;
+ if (i < tryAgainTimesMax) {
+ expectedDelayMillis = shortPollingIntervalMillis;
+ } else {
+ expectedDelayMillis = normalPollingIntervalMillis;
+ }
+ verify(mockCallback).scheduleNextRefresh(
+ mFakeElapsedRealtimeClock.getElapsedRealtimeMillis() + expectedDelayMillis);
+ verify(mockCallback, never()).submitSuggestion(any());
+
+ reset(mMockNtpTrustedTime);
+ }
+ }
+
+ @Test
+ public void engineImpl_refreshIfRequiredAndReschedule_successThenFailRepeatedly() {
+ mFakeElapsedRealtimeClock.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS);
+
+ int normalPollingIntervalMillis = 7777777;
+ int maxTimeResultAgeMillis = normalPollingIntervalMillis;
+ int shortPollingIntervalMillis = 3333;
+ int tryAgainTimesMax = 5;
+ NetworkTimeUpdateService.Engine engine = new NetworkTimeUpdateService.EngineImpl(
+ mFakeElapsedRealtimeClock,
+ normalPollingIntervalMillis, shortPollingIntervalMillis, tryAgainTimesMax,
+ mMockNtpTrustedTime);
+
+ NtpTrustedTime.TimeResult timeResult = createNtpTimeResult(
+ mFakeElapsedRealtimeClock.getElapsedRealtimeMillis() - 1);
+ NetworkTimeSuggestion expectedSuggestion = createExpectedSuggestion(timeResult);
+
+ {
+ // Simulated NTP client behavior: No cached time value available initially, with a
+ // successful refresh.
+ when(mMockNtpTrustedTime.getCachedTimeResult()).thenReturn(null, timeResult);
+ when(mMockNtpTrustedTime.forceRefresh(mDummyNetwork)).thenReturn(true);
+
+ RefreshCallbacks mockCallback = mock(RefreshCallbacks.class);
+
+ // Trigger the engine's logic.
+ engine.refreshIfRequiredAndReschedule(mDummyNetwork, "Test", mockCallback);
+
+ // Expect the refresh attempt to have been made: there is no cached network time
+ // initially.
+ verify(mMockNtpTrustedTime).forceRefresh(mDummyNetwork);
+
+ long expectedDelayMillis = calculateRefreshDelayMillisForTimeResult(
+ timeResult, normalPollingIntervalMillis);
+ verify(mockCallback).scheduleNextRefresh(
+ mFakeElapsedRealtimeClock.getElapsedRealtimeMillis() + expectedDelayMillis);
+ verify(mockCallback, times(1)).submitSuggestion(expectedSuggestion);
+ reset(mMockNtpTrustedTime);
+ }
+
+ // Increment the current time by enough so that an attempt to refresh the time should be
+ // made every time refreshIfRequiredAndReschedule() is called.
+ mFakeElapsedRealtimeClock.incrementMillis(maxTimeResultAgeMillis);
+
+ // Test multiple follow-up calls.
+ for (int i = 0; i < tryAgainTimesMax + 1; i++) {
+ // Simulated NTP client behavior: (Too old) cached time value available, unsuccessful
+ // refresh.
+ when(mMockNtpTrustedTime.getCachedTimeResult()).thenReturn(timeResult);
+ when(mMockNtpTrustedTime.forceRefresh(mDummyNetwork)).thenReturn(false);
+
+ RefreshCallbacks mockCallback = mock(RefreshCallbacks.class);
+
+ // Trigger the engine's logic.
+ engine.refreshIfRequiredAndReschedule(mDummyNetwork, "Test", mockCallback);
+
+ // Expect a refresh attempt each time as the cached network time is too old.
+ verify(mMockNtpTrustedTime).forceRefresh(mDummyNetwork);
+
+ // Check the scheduling.
+ long expectedDelayMillis;
+ if (i < tryAgainTimesMax) {
+ expectedDelayMillis = shortPollingIntervalMillis;
+ } else {
+ expectedDelayMillis = normalPollingIntervalMillis;
+ }
+ verify(mockCallback).scheduleNextRefresh(
+ mFakeElapsedRealtimeClock.getElapsedRealtimeMillis() + expectedDelayMillis);
+
+ // No valid time, no suggestion.
+ verify(mockCallback, never()).submitSuggestion(any());
+
+ reset(mMockNtpTrustedTime);
+ }
+ }
+
+ @Test
+ public void engineImpl_refreshIfRequiredAndReschedule_successFailSuccess() {
+ mFakeElapsedRealtimeClock.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS);
+
+ int normalPollingIntervalMillis = 7777777;
+ int maxTimeResultAgeMillis = normalPollingIntervalMillis;
+ int shortPollingIntervalMillis = 3333;
+ int tryAgainTimesMax = 5;
+ NetworkTimeUpdateService.Engine engine = new NetworkTimeUpdateService.EngineImpl(
+ mFakeElapsedRealtimeClock,
+ normalPollingIntervalMillis, shortPollingIntervalMillis, tryAgainTimesMax,
+ mMockNtpTrustedTime);
+
+ NtpTrustedTime.TimeResult timeResult1 = createNtpTimeResult(
+ mFakeElapsedRealtimeClock.getElapsedRealtimeMillis() - 1);
+ {
+ // Simulated NTP client behavior: No cached time value available initially, with a
+ // successful refresh.
+ when(mMockNtpTrustedTime.getCachedTimeResult()).thenReturn(null, timeResult1);
+ when(mMockNtpTrustedTime.forceRefresh(mDummyNetwork)).thenReturn(true);
+
+ RefreshCallbacks mockCallback = mock(RefreshCallbacks.class);
+
+ // Trigger the engine's logic.
+ engine.refreshIfRequiredAndReschedule(mDummyNetwork, "Test", mockCallback);
+
+ // Expect the refresh attempt to have been made: there is no cached network time
+ // initially.
+ verify(mMockNtpTrustedTime).forceRefresh(mDummyNetwork);
+
+ long expectedDelayMillis = calculateRefreshDelayMillisForTimeResult(
+ timeResult1, normalPollingIntervalMillis);
+ verify(mockCallback).scheduleNextRefresh(
+ mFakeElapsedRealtimeClock.getElapsedRealtimeMillis() + expectedDelayMillis);
+ NetworkTimeSuggestion expectedSuggestion = createExpectedSuggestion(timeResult1);
+ verify(mockCallback, times(1)).submitSuggestion(expectedSuggestion);
+ reset(mMockNtpTrustedTime);
+ }
+
+ // Increment the current time by enough so that the cached time result is too old and an
+ // attempt to refresh the time should be made every time refreshIfRequiredAndReschedule() is
+ // called.
+ mFakeElapsedRealtimeClock.incrementMillis(maxTimeResultAgeMillis);
+
+ {
+ // Simulated NTP client behavior: (Old) cached time value available initially, with an
+ // unsuccessful refresh.
+ when(mMockNtpTrustedTime.getCachedTimeResult()).thenReturn(timeResult1);
+ when(mMockNtpTrustedTime.forceRefresh(mDummyNetwork)).thenReturn(false);
+
+ RefreshCallbacks mockCallback = mock(RefreshCallbacks.class);
+
+ // Trigger the engine's logic.
+ engine.refreshIfRequiredAndReschedule(mDummyNetwork, "Test", mockCallback);
+
+ // Expect the refresh attempt to have been made: the timeResult is too old.
+ verify(mMockNtpTrustedTime).forceRefresh(mDummyNetwork);
+
+ long expectedDelayMillis = shortPollingIntervalMillis;
+ verify(mockCallback).scheduleNextRefresh(
+ mFakeElapsedRealtimeClock.getElapsedRealtimeMillis() + expectedDelayMillis);
+
+ // No valid time, no suggestion.
+ verify(mockCallback, never()).submitSuggestion(any());
+ reset(mMockNtpTrustedTime);
+ }
+
+ NtpTrustedTime.TimeResult timeResult2 = createNtpTimeResult(
+ mFakeElapsedRealtimeClock.getElapsedRealtimeMillis() - 1);
+
+ {
+ // Simulated NTP client behavior: (Old) cached time value available initially, with a
+ // successful refresh and a new cached time value.
+ when(mMockNtpTrustedTime.getCachedTimeResult()).thenReturn(timeResult1, timeResult2);
+ when(mMockNtpTrustedTime.forceRefresh(mDummyNetwork)).thenReturn(true);
+
+ RefreshCallbacks mockCallback = mock(RefreshCallbacks.class);
+
+ // Trigger the engine's logic.
+ engine.refreshIfRequiredAndReschedule(mDummyNetwork, "Test", mockCallback);
+
+ // Expect the refresh attempt to have been made: the timeResult is too old.
+ verify(mMockNtpTrustedTime).forceRefresh(mDummyNetwork);
+
+ long expectedDelayMillis = calculateRefreshDelayMillisForTimeResult(
+ timeResult2, normalPollingIntervalMillis);
+ verify(mockCallback).scheduleNextRefresh(
+ mFakeElapsedRealtimeClock.getElapsedRealtimeMillis() + expectedDelayMillis);
+ NetworkTimeSuggestion expectedSuggestion = createExpectedSuggestion(timeResult2);
+ verify(mockCallback, times(1)).submitSuggestion(expectedSuggestion);
+ reset(mMockNtpTrustedTime);
+ }
+ }
+
+ /**
+ * Confirms that if a refreshIfRequiredAndReschedule() call is made, e.g. for reasons besides
+ * scheduled alerts, and the latest time is not too old, then an NTP refresh won't be attempted.
+ * A suggestion will still be made.
+ */
+ @Test
+ public void engineImpl_refreshIfRequiredAndReschedule_noRefreshIfLatestIsNotTooOld() {
+ mFakeElapsedRealtimeClock.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS);
+
+ int normalPollingIntervalMillis = 7777777;
+ int maxTimeResultAgeMillis = normalPollingIntervalMillis;
+ int shortPollingIntervalMillis = 3333;
+ int tryAgainTimesMax = 5;
+ NetworkTimeUpdateService.Engine engine = new NetworkTimeUpdateService.EngineImpl(
+ mFakeElapsedRealtimeClock,
+ normalPollingIntervalMillis, shortPollingIntervalMillis, tryAgainTimesMax,
+ mMockNtpTrustedTime);
+
+ // Simulated NTP client behavior: A cached time value is available, increment the clock, but
+ // not enough to consider the cached value too old.
+ NtpTrustedTime.TimeResult timeResult = createNtpTimeResult(
+ mFakeElapsedRealtimeClock.getElapsedRealtimeMillis());
+ when(mMockNtpTrustedTime.getCachedTimeResult()).thenReturn(timeResult);
+ mFakeElapsedRealtimeClock.incrementMillis(maxTimeResultAgeMillis - 1);
+
+ RefreshCallbacks mockCallback = mock(RefreshCallbacks.class);
+ // Trigger the engine's logic.
+ engine.refreshIfRequiredAndReschedule(mDummyNetwork, "Test", mockCallback);
+
+ // Expect no refresh attempt to have been made.
+ verify(mMockNtpTrustedTime, never()).forceRefresh(any());
+
+ // The next wake-up should be rescheduled for when the cached time value will become too
+ // old.
+ long expectedDelayMillis = calculateRefreshDelayMillisForTimeResult(timeResult,
+ normalPollingIntervalMillis);
+ verify(mockCallback).scheduleNextRefresh(
+ mFakeElapsedRealtimeClock.getElapsedRealtimeMillis() + expectedDelayMillis);
+
+ // Suggestions must be made every time if the cached time value is not too old in case it
+ // was refreshed by a different component.
+ NetworkTimeSuggestion expectedSuggestion = createExpectedSuggestion(timeResult);
+ verify(mockCallback, times(1)).submitSuggestion(expectedSuggestion);
+ }
+
+ /**
+ * Confirms that if a refreshIfRequiredAndReschedule() call is made, e.g. for reasons besides
+ * scheduled alerts, and the latest time is not too old, then an NTP refresh won't be attempted.
+ * A suggestion will still be made.
+ */
+ @Test
+ public void engineImpl_refreshIfRequiredAndReschedule_failureHandlingAfterLatestIsTooOld() {
+ mFakeElapsedRealtimeClock.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS);
+
+ int normalPollingIntervalMillis = 7777777;
+ int maxTimeResultAgeMillis = normalPollingIntervalMillis;
+ int shortPollingIntervalMillis = 3333;
+ int tryAgainTimesMax = 5;
+ NetworkTimeUpdateService.Engine engine = new NetworkTimeUpdateService.EngineImpl(
+ mFakeElapsedRealtimeClock,
+ normalPollingIntervalMillis, shortPollingIntervalMillis, tryAgainTimesMax,
+ mMockNtpTrustedTime);
+
+ // Simulated NTP client behavior: A cached time value is available, increment the clock,
+ // enough to consider the cached value too old. The refresh attempt will fail.
+ NtpTrustedTime.TimeResult timeResult = createNtpTimeResult(
+ mFakeElapsedRealtimeClock.getElapsedRealtimeMillis());
+ when(mMockNtpTrustedTime.getCachedTimeResult()).thenReturn(timeResult);
+ mFakeElapsedRealtimeClock.incrementMillis(maxTimeResultAgeMillis);
+ when(mMockNtpTrustedTime.forceRefresh(mDummyNetwork)).thenReturn(false);
+
+ RefreshCallbacks mockCallback = mock(RefreshCallbacks.class);
+ // Trigger the engine's logic.
+ engine.refreshIfRequiredAndReschedule(mDummyNetwork, "Test", mockCallback);
+
+ // Expect a refresh attempt to have been made.
+ verify(mMockNtpTrustedTime, times(1)).forceRefresh(mDummyNetwork);
+
+ // The next wake-up should be rescheduled using the short polling interval.
+ long expectedDelayMillis = shortPollingIntervalMillis;
+ verify(mockCallback).scheduleNextRefresh(
+ mFakeElapsedRealtimeClock.getElapsedRealtimeMillis() + expectedDelayMillis);
+
+ // Suggestions should not be made if the cached time value is too old.
+ verify(mockCallback, never()).submitSuggestion(any());
+ }
+
+ private long calculateRefreshDelayMillisForTimeResult(NtpTrustedTime.TimeResult timeResult,
+ int normalPollingIntervalMillis) {
+ long currentElapsedRealtimeMillis = mFakeElapsedRealtimeClock.getElapsedRealtimeMillis();
+ long timeResultAgeMillis = timeResult.getAgeMillis(currentElapsedRealtimeMillis);
+ return normalPollingIntervalMillis - timeResultAgeMillis;
+ }
+
+ private static NetworkTimeSuggestion createExpectedSuggestion(
+ NtpTrustedTime.TimeResult timeResult) {
+ UnixEpochTime unixEpochTime = new UnixEpochTime(
+ timeResult.getElapsedRealtimeMillis(), timeResult.getTimeMillis());
+ return new NetworkTimeSuggestion(unixEpochTime, timeResult.getUncertaintyMillis());
+ }
+
+ private static NtpTrustedTime.TimeResult createNtpTimeResult(long elapsedRealtimeMillis) {
+ return new NtpTrustedTime.TimeResult(
+ ARBITRARY_UNIX_EPOCH_TIME_MILLIS,
+ elapsedRealtimeMillis,
+ ARBITRARY_UNCERTAINTY_MILLIS,
+ FAKE_SERVER_ADDRESS);
+ }
+
+ private static class FakeElapsedRealtimeClock implements Supplier<Long> {
+
+ private long mElapsedRealtimeMillis;
+
+ public void setElapsedRealtimeMillis(long elapsedRealtimeMillis) {
+ mElapsedRealtimeMillis = elapsedRealtimeMillis;
+ }
+
+ public long getElapsedRealtimeMillis() {
+ return mElapsedRealtimeMillis;
+ }
+
+ public long incrementMillis(int millis) {
+ mElapsedRealtimeMillis += millis;
+ return mElapsedRealtimeMillis;
+ }
+
+ @Override
+ public Long get() {
+ return getElapsedRealtimeMillis();
+ }
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
index a857238..0b339ad 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
@@ -380,6 +380,28 @@
}
@Test
+ public void testClearNetworkTime_withoutPermission() {
+ doThrow(new SecurityException("Mock"))
+ .when(mMockContext).enforceCallingPermission(anyString(), any());
+
+ assertThrows(SecurityException.class,
+ () -> mTimeDetectorService.clearNetworkTime());
+ verify(mMockContext).enforceCallingPermission(
+ eq(android.Manifest.permission.SET_TIME), anyString());
+ }
+
+ @Test
+ public void testClearNetworkTime() throws Exception {
+ doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
+
+ mTimeDetectorService.clearNetworkTime();
+
+ verify(mMockContext).enforceCallingPermission(
+ eq(android.Manifest.permission.SET_TIME), anyString());
+ verify(mFakeTimeDetectorStrategySpy).clearLatestNetworkSuggestion();
+ }
+
+ @Test
public void testLatestNetworkTime() {
NtpTrustedTime.TimeResult latestNetworkTime = new NtpTrustedTime.TimeResult(
1234L, 54321L, 999, InetSocketAddress.createUnresolved("test.timeserver", 123));
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
index caef494..37da2a2 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
@@ -874,6 +874,7 @@
long expectedSystemClockMillis =
script.calculateTimeInMillisForNow(timeSuggestion.getUnixEpochTime());
script.simulateNetworkTimeSuggestion(timeSuggestion)
+ .assertLatestNetworkSuggestion(timeSuggestion)
.verifySystemClockConfidence(TIME_CONFIDENCE_HIGH)
.verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis);
}
@@ -891,10 +892,55 @@
script.simulateTimePassing()
.simulateNetworkTimeSuggestion(timeSuggestion)
+ .assertLatestNetworkSuggestion(timeSuggestion)
.verifySystemClockWasNotSetAndResetCallTracking();
}
@Test
+ public void testClearLatestNetworkSuggestion() {
+ ConfigurationInternal configInternal =
+ new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
+ .setOriginPriorities(ORIGIN_NETWORK, ORIGIN_EXTERNAL)
+ .build();
+ Script script = new Script().simulateConfigurationInternalChange(configInternal);
+
+ // Create two different time suggestions for the current elapsedRealtimeMillis.
+ ExternalTimeSuggestion externalTimeSuggestion =
+ script.generateExternalTimeSuggestion(ARBITRARY_TEST_TIME);
+ NetworkTimeSuggestion networkTimeSuggestion =
+ script.generateNetworkTimeSuggestion(ARBITRARY_TEST_TIME.plus(Duration.ofHours(5)));
+ script.simulateTimePassing();
+
+ // Suggest an external time: This should cause the device to change time.
+ {
+ long expectedSystemClockMillis =
+ script.calculateTimeInMillisForNow(externalTimeSuggestion.getUnixEpochTime());
+ script.simulateExternalTimeSuggestion(externalTimeSuggestion)
+ .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis);
+ }
+
+ // Suggest a network time: This should cause the device to change time because
+ // network > external.
+ {
+ long expectedSystemClockMillis =
+ script.calculateTimeInMillisForNow(networkTimeSuggestion.getUnixEpochTime());
+ script.simulateNetworkTimeSuggestion(networkTimeSuggestion)
+ .assertLatestNetworkSuggestion(networkTimeSuggestion)
+ .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis);
+ }
+
+ // Clear the network time. This should cause the device to change back to the external time,
+ // which is now the best time available.
+ {
+ long expectedSystemClockMillis =
+ script.calculateTimeInMillisForNow(externalTimeSuggestion.getUnixEpochTime());
+ script.simulateClearLatestNetworkSuggestion()
+ .assertLatestNetworkSuggestion(null)
+ .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis);
+ }
+ }
+
+ @Test
public void testSuggestNetworkTime_rejectedBelowLowerBound() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
@@ -908,6 +954,7 @@
NetworkTimeSuggestion timeSuggestion =
script.generateNetworkTimeSuggestion(belowLowerBound);
script.simulateNetworkTimeSuggestion(timeSuggestion)
+ .assertLatestNetworkSuggestion(null)
.verifySystemClockConfidence(TIME_CONFIDENCE_LOW)
.verifySystemClockWasNotSetAndResetCallTracking();
}
@@ -926,6 +973,7 @@
NetworkTimeSuggestion timeSuggestion =
script.generateNetworkTimeSuggestion(aboveLowerBound);
script.simulateNetworkTimeSuggestion(timeSuggestion)
+ .assertLatestNetworkSuggestion(timeSuggestion)
.verifySystemClockConfidence(TIME_CONFIDENCE_HIGH)
.verifySystemClockWasSetAndResetCallTracking(aboveLowerBound.toEpochMilli());
}
@@ -944,6 +992,7 @@
NetworkTimeSuggestion timeSuggestion =
script.generateNetworkTimeSuggestion(aboveUpperBound);
script.simulateNetworkTimeSuggestion(timeSuggestion)
+ .assertLatestNetworkSuggestion(null)
.verifySystemClockConfidence(TIME_CONFIDENCE_LOW)
.verifySystemClockWasNotSetAndResetCallTracking();
}
@@ -962,6 +1011,7 @@
NetworkTimeSuggestion timeSuggestion =
script.generateNetworkTimeSuggestion(belowUpperBound);
script.simulateNetworkTimeSuggestion(timeSuggestion)
+ .assertLatestNetworkSuggestion(timeSuggestion)
.verifySystemClockConfidence(TIME_CONFIDENCE_HIGH)
.verifySystemClockWasSetAndResetCallTracking(belowUpperBound.toEpochMilli());
}
@@ -1745,7 +1795,7 @@
}
@Test
- public void suggestionsFromNetworkOriginNotInPriorityList_areIgnored() {
+ public void suggestionsFromNetworkOriginNotInPriorityList_areNotUsed() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_TELEPHONY)
@@ -1757,11 +1807,12 @@
script.simulateNetworkTimeSuggestion(timeSuggestion)
.assertLatestNetworkSuggestion(timeSuggestion)
+ .assertLatestNetworkSuggestion(timeSuggestion)
.verifySystemClockWasNotSetAndResetCallTracking();
}
@Test
- public void suggestionsFromGnssOriginNotInPriorityList_areIgnored() {
+ public void suggestionsFromGnssOriginNotInPriorityList_areNotUsed() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_TELEPHONY)
@@ -1777,7 +1828,7 @@
}
@Test
- public void suggestionsFromExternalOriginNotInPriorityList_areIgnored() {
+ public void suggestionsFromExternalOriginNotInPriorityList_areNotUsed() {
ConfigurationInternal configInternal =
new ConfigurationInternal.Builder(CONFIG_AUTO_ENABLED)
.setOriginPriorities(ORIGIN_TELEPHONY)
@@ -2015,6 +2066,11 @@
return this;
}
+ Script simulateClearLatestNetworkSuggestion() {
+ mTimeDetectorStrategy.clearLatestNetworkSuggestion();
+ return this;
+ }
+
Script simulateGnssTimeSuggestion(GnssTimeSuggestion timeSuggestion) {
mTimeDetectorStrategy.suggestGnssTime(timeSuggestion);
return this;
@@ -2056,6 +2112,12 @@
return this;
}
+ /** Calls {@link TimeDetectorStrategy#confirmTime(UnixEpochTime)}. */
+ Script simulateConfirmTime(UnixEpochTime confirmationTime, boolean expectedReturnValue) {
+ assertEquals(expectedReturnValue, mTimeDetectorStrategy.confirmTime(confirmationTime));
+ return this;
+ }
+
Script verifySystemClockWasNotSetAndResetCallTracking() {
mFakeEnvironment.verifySystemClockNotSet();
mFakeEnvironment.resetCallTracking();
@@ -2218,11 +2280,6 @@
long calculateTimeInMillisForNow(UnixEpochTime unixEpochTime) {
return unixEpochTime.at(peekElapsedRealtimeMillis()).getUnixEpochTimeMillis();
}
-
- Script simulateConfirmTime(UnixEpochTime confirmationTime, boolean expectedReturnValue) {
- assertEquals(expectedReturnValue, mTimeDetectorStrategy.confirmTime(confirmationTime));
- return this;
- }
}
private static TelephonyTimeSuggestion createTelephonyTimeSuggestion(int slotIndex,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index b64b281..19f3189 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -1703,6 +1703,7 @@
channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
channel.setShowBadge(true);
channel.setAllowBubbles(false);
+ channel.setImportantConversation(true);
int lockMask = 0;
for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
lockMask |= NotificationChannel.LOCKABLE_FIELDS[i];
@@ -1718,6 +1719,7 @@
assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights());
assertFalse(savedChannel.canBypassDnd());
assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility());
+ assertFalse(channel.isImportantConversation());
assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
assertEquals(channel.canBubble(), savedChannel.canBubble());
@@ -4396,7 +4398,7 @@
new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
channel2.setConversationId(calls.getId(), convoId);
channel2.setImportantConversation(true);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel2, false, false);
List<ConversationChannelWrapper> convos =
mHelper.getConversations(IntArray.wrap(new int[] {0}), false);
@@ -4473,7 +4475,7 @@
new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
channel2.setConversationId(calls.getId(), convoId);
channel2.setImportantConversation(true);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel2, false, false);
List<ConversationChannelWrapper> convos =
mHelper.getConversations(IntArray.wrap(new int[] {0}), false);
@@ -4501,13 +4503,13 @@
new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
channel.setConversationId(messages.getId(), convoId);
channel.setImportantConversation(true);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false);
NotificationChannel diffConvo =
new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
diffConvo.setConversationId(p.getId(), "different convo");
diffConvo.setImportantConversation(true);
- mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false);
+ mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, false, false);
NotificationChannel channel2 =
new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
@@ -4534,7 +4536,7 @@
new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
channel.setConversationId(messages.getId(), convoId);
channel.setImportantConversation(true);
- mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false);
mHelper.permanentlyDeleteNotificationChannel(PKG_O, UID_O, "messages");
@@ -4935,7 +4937,7 @@
"conversation", IMPORTANCE_DEFAULT);
friend.setConversationId(parent.getId(), "friend");
friend.setImportantConversation(true);
- mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
+ mHelper.createNotificationChannel(PKG_O, UID_O, friend, false, false);
ArrayList<StatsEvent> events = new ArrayList<>();
mHelper.pullPackageChannelPreferencesStats(events);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 4ee87d4..e02863e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -58,6 +58,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN;
import static android.view.WindowManager.TRANSIT_PIP;
@@ -3143,46 +3144,6 @@
assertFalse(activity.mDisplayContent.mClosingApps.contains(activity));
}
- @Test
- public void testImeInsetsFrozenFlag_resetWhenReparented() {
- final ActivityRecord activity = createActivityWithTask();
- final WindowState app = createWindow(null, TYPE_APPLICATION, activity, "app");
- final WindowState imeWindow = createWindow(null, TYPE_APPLICATION, "imeWindow");
- final Task newTask = new TaskBuilder(mSupervisor).build();
- makeWindowVisible(app, imeWindow);
- mDisplayContent.mInputMethodWindow = imeWindow;
- mDisplayContent.setImeLayeringTarget(app);
- mDisplayContent.setImeInputTarget(app);
-
- // Simulate app is closing and expect the last IME is shown and IME insets is frozen.
- app.mActivityRecord.commitVisibility(false, false);
- assertTrue(app.mActivityRecord.mLastImeShown);
- assertTrue(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
-
- // Expect IME insets frozen state will reset when the activity is reparent to the new task.
- activity.setState(RESUMED, "test");
- activity.reparent(newTask, 0 /* top */, "test");
- assertFalse(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
- }
-
- @SetupWindows(addWindows = W_INPUT_METHOD)
- @Test
- public void testImeInsetsFrozenFlag_resetWhenResized() {
- final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
- makeWindowVisibleAndDrawn(app, mImeWindow);
- mDisplayContent.setImeLayeringTarget(app);
- mDisplayContent.setImeInputTarget(app);
-
- // Simulate app is closing and expect the last IME is shown and IME insets is frozen.
- app.mActivityRecord.commitVisibility(false, false);
- assertTrue(app.mActivityRecord.mLastImeShown);
- assertTrue(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
-
- // Expect IME insets frozen state will reset when the activity is reparent to the new task.
- app.mActivityRecord.onResize();
- assertFalse(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
- }
-
@SetupWindows(addWindows = W_INPUT_METHOD)
@Test
public void testImeInsetsFrozenFlag_resetWhenNoImeFocusableInActivity() {
@@ -3216,6 +3177,10 @@
public void testImeInsetsFrozenFlag_resetWhenReportedToBeImeInputTarget() {
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+ mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_IME).setWindowContainer(
+ mImeWindow, null, null);
+ mImeWindow.getControllableInsetProvider().setServerVisible(true);
+
InsetsSource imeSource = new InsetsSource(ITYPE_IME, ime());
app.mAboveInsetsState.addSource(imeSource);
mDisplayContent.setImeLayeringTarget(app);
@@ -3233,8 +3198,10 @@
// Simulate app re-start input or turning screen off/on then unlocked by un-secure
// keyguard to back to the app, expect IME insets is not frozen
- mDisplayContent.updateImeInputAndControlTarget(app);
app.mActivityRecord.commitVisibility(true, false);
+ mDisplayContent.updateImeInputAndControlTarget(app);
+ mDisplayContent.mWmService.mRoot.performSurfacePlacement();
+
assertFalse(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
imeSource.setVisible(true);
@@ -3274,12 +3241,12 @@
assertTrue(app2.mActivityRecord.mImeInsetsFrozenUntilStartInput);
// Simulate switching to app2 to make it visible to be IME targets.
- makeWindowVisibleAndDrawn(app2);
spyOn(app2);
spyOn(app2.mClient);
ArgumentCaptor<InsetsState> insetsStateCaptor = ArgumentCaptor.forClass(InsetsState.class);
doReturn(true).when(app2).isReadyToDispatchInsetsState();
mDisplayContent.setImeLayeringTarget(app2);
+ app2.mActivityRecord.commitVisibility(true, false);
mDisplayContent.updateImeInputAndControlTarget(app2);
mDisplayContent.mWmService.mRoot.performSurfacePlacement();
@@ -3293,6 +3260,57 @@
}
@Test
+ public void testImeInsetsFrozenFlag_multiWindowActivities() {
+ final WindowToken imeToken = createTestWindowToken(TYPE_INPUT_METHOD, mDisplayContent);
+ final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, imeToken, "ime");
+ makeWindowVisibleAndDrawn(ime);
+
+ // Create a split-screen root task with activity1 and activity 2.
+ final Task task = new TaskBuilder(mSupervisor)
+ .setCreateParentTask(true).setCreateActivity(true).build();
+ task.getRootTask().setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+ final ActivityRecord activity1 = task.getTopNonFinishingActivity();
+ activity1.getTask().setResumedActivity(activity1, "testApp1");
+
+ final ActivityRecord activity2 = new TaskBuilder(mSupervisor)
+ .setWindowingMode(WINDOWING_MODE_MULTI_WINDOW)
+ .setCreateActivity(true).build().getTopMostActivity();
+ activity2.getTask().setResumedActivity(activity2, "testApp2");
+ activity2.getTask().setParent(task.getRootTask());
+
+ // Simulate activity1 and activity2 both have set mImeInsetsFrozenUntilStartInput when
+ // invisible to user.
+ activity1.mImeInsetsFrozenUntilStartInput = true;
+ activity2.mImeInsetsFrozenUntilStartInput = true;
+
+ final WindowState app1 = createWindow(null, TYPE_APPLICATION, activity1, "app1");
+ final WindowState app2 = createWindow(null, TYPE_APPLICATION, activity2, "app2");
+ makeWindowVisibleAndDrawn(app1, app2);
+
+ final InsetsStateController controller = mDisplayContent.getInsetsStateController();
+ controller.getSourceProvider(ITYPE_IME).setWindowContainer(
+ ime, null, null);
+ ime.getControllableInsetProvider().setServerVisible(true);
+
+ // app1 starts input and expect IME insets for all activities in split-screen will be
+ // frozen until the input started.
+ mDisplayContent.setImeLayeringTarget(app1);
+ mDisplayContent.updateImeInputAndControlTarget(app1);
+ mDisplayContent.mWmService.mRoot.performSurfacePlacement();
+
+ assertEquals(app1, mDisplayContent.getImeInputTarget());
+ assertFalse(activity1.mImeInsetsFrozenUntilStartInput);
+ assertFalse(activity2.mImeInsetsFrozenUntilStartInput);
+
+ app1.setRequestedVisibleTypes(ime());
+ controller.onInsetsModified(app1);
+
+ // Expect all activities in split-screen will get IME insets visible state
+ assertTrue(app1.getInsetsState().peekSource(ITYPE_IME).isVisible());
+ assertTrue(app2.getInsetsState().peekSource(ITYPE_IME).isVisible());
+ }
+
+ @Test
public void testInClosingAnimation_visibilityNotCommitted_doNotHideSurface() {
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
makeWindowVisibleAndDrawn(app);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java
index 8bb79e3..45b30b2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java
@@ -155,6 +155,18 @@
}
@Test
+ public void testTreatmentDisabledPerApp_noForceRotationOrRefresh()
+ throws Exception {
+ configureActivity(SCREEN_ORIENTATION_PORTRAIT);
+ when(mActivity.mLetterboxUiController.shouldForceRotateForCameraCompat())
+ .thenReturn(false);
+
+ mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+
+ assertNoForceRotationOrRefresh();
+ }
+
+ @Test
public void testMultiWindowMode_returnUnspecified_noForceRotationOrRefresh() throws Exception {
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
final TestSplitOrganizer organizer = new TestSplitOrganizer(mAtm, mDisplayContent);
@@ -327,7 +339,21 @@
}
@Test
- public void testOnActivityConfigurationChanging_refreshDisabled_noRefresh() throws Exception {
+ public void testOnActivityConfigurationChanging_refreshDisabledViaFlag_noRefresh()
+ throws Exception {
+ configureActivity(SCREEN_ORIENTATION_PORTRAIT);
+ when(mActivity.mLetterboxUiController.shouldRefreshActivityForCameraCompat())
+ .thenReturn(false);
+
+ mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+ callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ true);
+
+ assertActivityRefreshRequested(/* refreshRequested */ false);
+ }
+
+ @Test
+ public void testOnActivityConfigurationChanging_refreshDisabledPerApp_noRefresh()
+ throws Exception {
when(mLetterboxConfiguration.isCameraCompatRefreshEnabled()).thenReturn(false);
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
@@ -362,6 +388,19 @@
assertActivityRefreshRequested(/* refreshRequested */ true, /* cycleThroughStop */ false);
}
+ @Test
+ public void testOnActivityConfigurationChanging_cycleThroughStopDisabledForApp()
+ throws Exception {
+ configureActivity(SCREEN_ORIENTATION_PORTRAIT);
+ when(mActivity.mLetterboxUiController.shouldRefreshActivityViaPauseForCameraCompat())
+ .thenReturn(true);
+
+ mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+ callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ true);
+
+ assertActivityRefreshRequested(/* refreshRequested */ true, /* cycleThroughStop */ false);
+ }
+
private void configureActivity(@ScreenOrientation int activityOrientation) {
configureActivityAndDisplay(activityOrientation, ORIENTATION_PORTRAIT);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index cdb2642..4d69979 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -39,6 +39,7 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.spy;
@@ -411,7 +412,14 @@
final WindowState navBar = createTestWindow("navBar");
getController().getSourceProvider(ITYPE_IME).setWindowContainer(ime, null, null);
+
+ waitUntilHandlersIdle();
+ clearInvocations(mDisplayContent);
getController().getSourceProvider(ITYPE_IME).setClientVisible(true);
+ waitUntilHandlersIdle();
+ // The visibility change should trigger a traversal to notify the change.
+ verify(mDisplayContent).notifyInsetsChanged(any());
+
getController().getSourceProvider(ITYPE_STATUS_BAR).setWindowContainer(statusBar, null,
null);
getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindowContainer(navBar, null,
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
index 6d778afe..5e087f0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
@@ -16,8 +16,14 @@
package com.android.server.wm;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -74,6 +80,8 @@
mController = new LetterboxUiController(mWm, mActivity);
}
+ // shouldIgnoreRequestedOrientation
+
@Test
@EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
public void testShouldIgnoreRequestedOrientation_activityRelaunching_returnsTrue() {
@@ -134,7 +142,7 @@
}
@Test
- @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
public void testShouldIgnoreRequestedOrientation_flagIsDisabled_returnsFalse() {
prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
doReturn(false).when(mLetterboxConfiguration)
@@ -143,6 +151,163 @@
assertFalse(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
}
+ // shouldRefreshActivityForCameraCompat
+
+ @Test
+ public void testShouldRefreshActivityForCameraCompat_flagIsDisabled_returnsFalse() {
+ doReturn(false).when(mLetterboxConfiguration)
+ .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+
+ assertFalse(mController.shouldRefreshActivityForCameraCompat());
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
+ public void testShouldRefreshActivityForCameraCompat_overrideEnabled_returnsFalse() {
+ doReturn(true).when(mLetterboxConfiguration)
+ .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+
+ assertFalse(mController.shouldRefreshActivityForCameraCompat());
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
+ public void testShouldRefreshActivityForCameraCompat_propertyIsTrueAndOverride_returnsFalse()
+ throws Exception {
+ doReturn(true).when(mLetterboxConfiguration)
+ .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+ mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH, /* value */ true);
+
+ mController = new LetterboxUiController(mWm, mActivity);
+
+ assertFalse(mController.shouldRefreshActivityForCameraCompat());
+ }
+
+ @Test
+ public void testShouldRefreshActivityForCameraCompat_propertyIsFalse_returnsFalse()
+ throws Exception {
+ doReturn(true).when(mLetterboxConfiguration)
+ .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+ mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH, /* value */ false);
+
+ mController = new LetterboxUiController(mWm, mActivity);
+
+ assertFalse(mController.shouldRefreshActivityForCameraCompat());
+ }
+
+ @Test
+ public void testShouldRefreshActivityForCameraCompat_propertyIsTrue_returnsTrue()
+ throws Exception {
+ doReturn(true).when(mLetterboxConfiguration)
+ .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+ mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH, /* value */ true);
+
+ mController = new LetterboxUiController(mWm, mActivity);
+
+ assertTrue(mController.shouldRefreshActivityForCameraCompat());
+ }
+
+ // shouldRefreshActivityViaPauseForCameraCompat
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
+ public void testShouldRefreshActivityViaPauseForCameraCompat_flagIsDisabled_returnsFalse() {
+ doReturn(false).when(mLetterboxConfiguration)
+ .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+
+ assertFalse(mController.shouldRefreshActivityViaPauseForCameraCompat());
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
+ public void testShouldRefreshActivityViaPauseForCameraCompat_overrideEnabled_returnsTrue() {
+ doReturn(true).when(mLetterboxConfiguration)
+ .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+
+ assertTrue(mController.shouldRefreshActivityViaPauseForCameraCompat());
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
+ public void testShouldRefreshActivityViaPauseForCameraCompat_propertyIsFalseAndOverride_returnFalse()
+ throws Exception {
+ doReturn(true).when(mLetterboxConfiguration)
+ .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+ mockThatProperty(PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE, /* value */ false);
+
+ mController = new LetterboxUiController(mWm, mActivity);
+
+ assertFalse(mController.shouldRefreshActivityViaPauseForCameraCompat());
+ }
+
+ @Test
+ public void testShouldRefreshActivityViaPauseForCameraCompat_propertyIsTrue_returnsTrue()
+ throws Exception {
+ doReturn(true).when(mLetterboxConfiguration)
+ .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+ mockThatProperty(PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE, /* value */ true);
+
+ mController = new LetterboxUiController(mWm, mActivity);
+
+ assertTrue(mController.shouldRefreshActivityViaPauseForCameraCompat());
+ }
+
+ // shouldForceRotateForCameraCompat
+
+ @Test
+ public void testShouldForceRotateForCameraCompat_flagIsDisabled_returnsFalse() {
+ doReturn(false).when(mLetterboxConfiguration)
+ .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+
+ assertFalse(mController.shouldForceRotateForCameraCompat());
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION})
+ public void testShouldForceRotateForCameraCompat_overrideEnabled_returnsFalse() {
+ doReturn(true).when(mLetterboxConfiguration)
+ .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+
+ assertFalse(mController.shouldForceRotateForCameraCompat());
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION})
+ public void testShouldForceRotateForCameraCompat_propertyIsTrueAndOverride_returnsFalse()
+ throws Exception {
+ doReturn(true).when(mLetterboxConfiguration)
+ .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+ mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION, /* value */ true);
+
+ mController = new LetterboxUiController(mWm, mActivity);
+
+ assertFalse(mController.shouldForceRotateForCameraCompat());
+ }
+
+ @Test
+ public void testShouldForceRotateForCameraCompat_propertyIsFalse_returnsFalse()
+ throws Exception {
+ doReturn(true).when(mLetterboxConfiguration)
+ .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+ mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION, /* value */ false);
+
+ mController = new LetterboxUiController(mWm, mActivity);
+
+ assertFalse(mController.shouldForceRotateForCameraCompat());
+ }
+
+ @Test
+ public void testShouldForceRotateForCameraCompat_propertyIsTrue_returnsTrue()
+ throws Exception {
+ doReturn(true).when(mLetterboxConfiguration)
+ .isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
+ mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION, /* value */ true);
+
+ mController = new LetterboxUiController(mWm, mActivity);
+
+ assertTrue(mController.shouldForceRotateForCameraCompat());
+ }
+
private void mockThatProperty(String propertyName, boolean value) throws Exception {
Property property = new Property(propertyName, /* value */ value, /* packageName */ "",
/* className */ "");
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index d364dbb..74dd361 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -30,6 +30,7 @@
import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.os.Process.NOBODY_UID;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -1207,20 +1208,35 @@
@Test
public void testCreateRecentTaskInfo_detachedTask() {
- final Task task = createTaskBuilder(".Task").setCreateActivity(true).build();
+ final Task task = createTaskBuilder(".Task").build();
+ final ComponentName componentName = getUniqueComponentName();
+ new ActivityBuilder(mSupervisor.mService)
+ .setTask(task)
+ .setUid(NOBODY_UID)
+ .setComponent(componentName)
+ .build();
final TaskDisplayArea tda = task.getDisplayArea();
assertTrue(task.isAttached());
assertTrue(task.supportsMultiWindow());
- RecentTaskInfo info = mRecentTasks.createRecentTaskInfo(task, true);
+ RecentTaskInfo info = mRecentTasks.createRecentTaskInfo(task, true /* stripExtras */,
+ true /* getTasksAllowed */);
assertTrue(info.supportsMultiWindow);
+ info = mRecentTasks.createRecentTaskInfo(task, true /* stripExtras */,
+ false /* getTasksAllowed */);
+
+ assertFalse(info.topActivity.equals(componentName));
+ assertFalse(info.topActivityInfo.packageName.equals(componentName.getPackageName()));
+ assertFalse(info.baseActivity.equals(componentName));
+
// The task can be put in split screen even if it is not attached now.
task.removeImmediately();
- info = mRecentTasks.createRecentTaskInfo(task, true);
+ info = mRecentTasks.createRecentTaskInfo(task, true /* stripExtras */,
+ true /* getTasksAllowed */);
assertTrue(info.supportsMultiWindow);
@@ -1229,7 +1245,8 @@
doReturn(false).when(tda).supportsNonResizableMultiWindow();
doReturn(false).when(task).isResizeable();
- info = mRecentTasks.createRecentTaskInfo(task, true);
+ info = mRecentTasks.createRecentTaskInfo(task, true /* stripExtras */,
+ true /* getTasksAllowed */);
assertFalse(info.supportsMultiWindow);
@@ -1237,7 +1254,8 @@
// the device supports it.
doReturn(true).when(tda).supportsNonResizableMultiWindow();
- info = mRecentTasks.createRecentTaskInfo(task, true);
+ info = mRecentTasks.createRecentTaskInfo(task, true /* stripExtras */,
+ true /* getTasksAllowed */);
assertTrue(info.supportsMultiWindow);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
index b70d8bd..a405e5a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -23,7 +23,12 @@
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_OPEN;
+import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_DELETE_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS;
import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS;
+import static android.window.TaskFragmentOperation.OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
import static android.window.TaskFragmentOrganizer.KEY_ERROR_CALLBACK_OP_TYPE;
import static android.window.TaskFragmentOrganizer.KEY_ERROR_CALLBACK_THROWABLE;
import static android.window.TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_CHANGE;
@@ -36,13 +41,6 @@
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_INFO_CHANGED;
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED;
import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_VANISHED;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_CHILDREN;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS;
-import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -339,11 +337,11 @@
final Throwable exception = new IllegalArgumentException("Test exception");
mController.onTaskFragmentError(mTaskFragment.getTaskFragmentOrganizer(),
- mErrorToken, null /* taskFragment */, HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS,
+ mErrorToken, null /* taskFragment */, OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS,
exception);
mController.dispatchPendingEvents();
- assertTaskFragmentErrorTransaction(HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS,
+ assertTaskFragmentErrorTransaction(OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS,
exception.getClass());
}
@@ -519,50 +517,20 @@
@Test
public void testApplyTransaction_enforceHierarchyChange_deleteTaskFragment() {
doReturn(true).when(mTaskFragment).isAttached();
-
- // Throw exception if the transaction is trying to change a window that is not organized by
- // the organizer.
- mTransaction.deleteTaskFragment(mFragmentWindowToken);
-
- assertApplyTransactionDisallowed(mTransaction);
-
- // Allow transaction to change a TaskFragment created by the organizer.
- mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */,
- "Test:TaskFragmentOrganizer" /* processName */);
- clearInvocations(mAtm.mRootWindowContainer);
-
- assertApplyTransactionAllowed(mTransaction);
-
- // No lifecycle update when the TaskFragment is not recorded.
- verify(mAtm.mRootWindowContainer, never()).resumeFocusedTasksTopActivities();
-
mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment);
- assertApplyTransactionAllowed(mTransaction);
-
- verify(mAtm.mRootWindowContainer).resumeFocusedTasksTopActivities();
- }
-
- @Test
- public void testApplyTransaction_enforceHierarchyChange_setAdjacentRoots() {
- final TaskFragment taskFragment2 =
- new TaskFragment(mAtm, new Binder(), true /* createdByOrganizer */);
- final WindowContainerToken token2 = taskFragment2.mRemoteToken.toWindowContainerToken();
// Throw exception if the transaction is trying to change a window that is not organized by
// the organizer.
- mTransaction.setAdjacentRoots(mFragmentWindowToken, token2);
+ mTransaction.deleteTaskFragment(mFragmentToken);
assertApplyTransactionDisallowed(mTransaction);
// Allow transaction to change a TaskFragment created by the organizer.
mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */,
"Test:TaskFragmentOrganizer" /* processName */);
- taskFragment2.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */,
- "Test:TaskFragmentOrganizer" /* processName */);
clearInvocations(mAtm.mRootWindowContainer);
assertApplyTransactionAllowed(mTransaction);
-
verify(mAtm.mRootWindowContainer).resumeFocusedTasksTopActivities();
}
@@ -693,7 +661,7 @@
}
@Test
- public void testApplyTransaction_enforceTaskFragmentOrganized_setTaskFragmentOperation() {
+ public void testApplyTransaction_enforceTaskFragmentOrganized_addTaskFragmentOperation() {
final Task task = createTask(mDisplayContent);
mTaskFragment = new TaskFragmentBuilder(mAtm)
.setParentTask(task)
@@ -704,7 +672,7 @@
OP_TYPE_SET_ANIMATION_PARAMS)
.setAnimationParams(TaskFragmentAnimationParams.DEFAULT)
.build();
- mTransaction.setTaskFragmentOperation(mFragmentToken, operation);
+ mTransaction.addTaskFragmentOperation(mFragmentToken, operation);
mOrganizer.applyTransaction(mTransaction, TASK_FRAGMENT_TRANSIT_CHANGE,
false /* shouldApplyIndependently */);
@@ -718,7 +686,7 @@
}
@Test
- public void testSetTaskFragmentOperation() {
+ public void testAddTaskFragmentOperation() {
final Task task = createTask(mDisplayContent);
mTaskFragment = new TaskFragmentBuilder(mAtm)
.setParentTask(task)
@@ -736,7 +704,7 @@
OP_TYPE_SET_ANIMATION_PARAMS)
.setAnimationParams(animationParams)
.build();
- mTransaction.setTaskFragmentOperation(mFragmentToken, operation);
+ mTransaction.addTaskFragmentOperation(mFragmentToken, operation);
mOrganizer.applyTransaction(mTransaction, TASK_FRAGMENT_TRANSIT_CHANGE,
false /* shouldApplyIndependently */);
assertApplyTransactionAllowed(mTransaction);
@@ -811,23 +779,37 @@
}
@Test
- public void testApplyTransaction_enforceHierarchyChange_reparentChildren() {
- doReturn(true).when(mTaskFragment).isAttached();
-
- // Throw exception if the transaction is trying to change a window that is not organized by
- // the organizer.
- mTransaction.reparentChildren(mFragmentWindowToken, null /* newParent */);
-
- assertApplyTransactionDisallowed(mTransaction);
-
- // Allow transaction to change a TaskFragment created by the organizer.
- mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */,
- "Test:TaskFragmentOrganizer" /* processName */);
- clearInvocations(mAtm.mRootWindowContainer);
-
+ public void testApplyTransaction_createTaskFragment_withPairedActivityToken() {
+ final Task task = createTask(mDisplayContent);
+ final ActivityRecord activityAtBottom = createActivityRecord(task);
+ final int uid = Binder.getCallingUid();
+ activityAtBottom.info.applicationInfo.uid = uid;
+ activityAtBottom.getTask().effectiveUid = uid;
+ mTaskFragment = new TaskFragmentBuilder(mAtm)
+ .setParentTask(task)
+ .setFragmentToken(mFragmentToken)
+ .createActivityCount(1)
+ .build();
+ mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment);
+ final IBinder fragmentToken1 = new Binder();
+ final TaskFragmentCreationParams params = new TaskFragmentCreationParams.Builder(
+ mOrganizerToken, fragmentToken1, activityAtBottom.token)
+ .setPairedActivityToken(activityAtBottom.token)
+ .build();
+ mTransaction.setTaskFragmentOrganizer(mIOrganizer);
+ mTransaction.createTaskFragment(params);
assertApplyTransactionAllowed(mTransaction);
- verify(mAtm.mRootWindowContainer).resumeFocusedTasksTopActivities();
+ // Successfully created a TaskFragment.
+ final TaskFragment taskFragment = mWindowOrganizerController.getTaskFragment(
+ fragmentToken1);
+ assertNotNull(taskFragment);
+ // The new TaskFragment should be positioned right above the paired activity.
+ assertEquals(task.mChildren.indexOf(activityAtBottom) + 1,
+ task.mChildren.indexOf(taskFragment));
+ // The top TaskFragment should remain on top.
+ assertEquals(task.mChildren.indexOf(taskFragment) + 1,
+ task.mChildren.indexOf(mTaskFragment));
}
@Test
@@ -1006,7 +988,7 @@
any(), any(), anyInt(), anyInt(), any());
verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
eq(mErrorToken), eq(mTaskFragment),
- eq(HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT),
+ eq(OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT),
any(IllegalArgumentException.class));
}
@@ -1023,7 +1005,7 @@
verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
eq(mErrorToken), eq(mTaskFragment),
- eq(HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT),
+ eq(OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT),
any(IllegalArgumentException.class));
assertNull(activity.getOrganizedTaskFragment());
}
@@ -1040,8 +1022,7 @@
assertApplyTransactionAllowed(mTransaction);
verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
- eq(mErrorToken), eq(mTaskFragment),
- eq(HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS),
+ eq(mErrorToken), eq(mTaskFragment), eq(OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS),
any(IllegalArgumentException.class));
verify(mTaskFragment, never()).setAdjacentTaskFragment(any());
}
@@ -1060,7 +1041,7 @@
assertApplyTransactionAllowed(mTransaction);
verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
- eq(mErrorToken), eq(null), eq(HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT),
+ eq(mErrorToken), eq(null), eq(OP_TYPE_CREATE_TASK_FRAGMENT),
any(IllegalArgumentException.class));
assertNull(mWindowOrganizerController.getTaskFragment(fragmentToken));
}
@@ -1071,12 +1052,12 @@
spyOn(mWindowOrganizerController);
// Not allow to delete a TaskFragment that is in a PIP Task.
- mTransaction.deleteTaskFragment(mFragmentWindowToken)
+ mTransaction.deleteTaskFragment(mFragmentToken)
.setErrorCallbackToken(mErrorToken);
assertApplyTransactionAllowed(mTransaction);
verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
- eq(mErrorToken), eq(mTaskFragment), eq(HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT),
+ eq(mErrorToken), eq(mTaskFragment), eq(OP_TYPE_DELETE_TASK_FRAGMENT),
any(IllegalArgumentException.class));
assertNotNull(mWindowOrganizerController.getTaskFragment(mFragmentToken));
@@ -1389,43 +1370,7 @@
// The pending event will be dispatched on the handler (from requestTraversal).
waitHandlerIdle(mWm.mAnimationHandler);
- assertTaskFragmentErrorTransaction(HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT,
- SecurityException.class);
- }
-
- @Test
- public void testMinDimensionViolation_ReparentChildren() {
- final Task task = createTask(mDisplayContent);
- final IBinder oldFragToken = new Binder();
- final TaskFragment oldTaskFrag = new TaskFragmentBuilder(mAtm)
- .setParentTask(task)
- .createActivityCount(1)
- .setFragmentToken(oldFragToken)
- .setOrganizer(mOrganizer)
- .build();
- final ActivityRecord activity = oldTaskFrag.getTopMostActivity();
- // Make minWidth/minHeight exceeds mTaskFragment bounds.
- activity.info.windowLayout = new ActivityInfo.WindowLayout(
- 0, 0, 0, 0, 0, mTaskFragBounds.width() + 10, mTaskFragBounds.height() + 10);
- mTaskFragment = new TaskFragmentBuilder(mAtm)
- .setParentTask(task)
- .setFragmentToken(mFragmentToken)
- .setOrganizer(mOrganizer)
- .setBounds(mTaskFragBounds)
- .build();
- mWindowOrganizerController.mLaunchTaskFragments.put(oldFragToken, oldTaskFrag);
- mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment);
-
- // Reparent oldTaskFrag's children to mTaskFragment, which is smaller than activity's
- // minimum dimensions.
- mTransaction.reparentChildren(oldTaskFrag.mRemoteToken.toWindowContainerToken(),
- mTaskFragment.mRemoteToken.toWindowContainerToken())
- .setErrorCallbackToken(mErrorToken);
- assertApplyTransactionAllowed(mTransaction);
- // The pending event will be dispatched on the handler (from requestTraversal).
- waitHandlerIdle(mWm.mAnimationHandler);
-
- assertTaskFragmentErrorTransaction(HIERARCHY_OP_TYPE_REPARENT_CHILDREN,
+ assertTaskFragmentErrorTransaction(OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT,
SecurityException.class);
}
@@ -1600,7 +1545,8 @@
}
/** Asserts that there will be a transaction for TaskFragment error. */
- private void assertTaskFragmentErrorTransaction(int opType, @NonNull Class<?> exceptionClass) {
+ private void assertTaskFragmentErrorTransaction(@TaskFragmentOperation.OperationType int opType,
+ @NonNull Class<?> exceptionClass) {
verify(mOrganizer).onTransactionReady(mTransactionCaptor.capture());
final TaskFragmentTransaction transaction = mTransactionCaptor.getValue();
final List<TaskFragmentTransaction.Change> changes = transaction.getChanges();
diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
index a100b9a..ef2b691 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -393,7 +393,7 @@
dc.updateOrientation();
dc.sendNewConfiguration();
spyOn(wallpaperWindow);
- doReturn(new Rect(0, 0, width, height)).when(wallpaperWindow).getLastReportedBounds();
+ doReturn(new Rect(0, 0, width, height)).when(wallpaperWindow).getParentFrame();
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 5e0e209..6bce959 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -45,6 +45,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
@@ -980,6 +981,19 @@
assertFalse(sameTokenWindow.needsRelativeLayeringToIme());
}
+ @UseTestDisplay(addWindows = {W_ACTIVITY, W_INPUT_METHOD})
+ @Test
+ public void testNeedsRelativeLayeringToIme_systemDialog() {
+ WindowState systemDialogWindow = createWindow(null, TYPE_SECURE_SYSTEM_OVERLAY,
+ mDisplayContent,
+ "SystemDialog", true);
+ mDisplayContent.setImeLayeringTarget(mAppWindow);
+ mAppWindow.getRootTask().setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+ makeWindowVisible(mImeWindow);
+ systemDialogWindow.mAttrs.flags |= FLAG_ALT_FOCUSABLE_IM;
+ assertTrue(systemDialogWindow.needsRelativeLayeringToIme());
+ }
+
@Test
public void testSetFreezeInsetsState() {
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
diff --git a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
index a95fa5a..8c58158 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
@@ -22,6 +22,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
@@ -31,6 +32,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
@@ -543,4 +545,28 @@
assertZOrderGreaterThan(mTransaction, popupWindow.getSurfaceControl(),
mDisplayContent.getImeContainer().getSurfaceControl());
}
+
+ @Test
+ public void testSystemDialogWindow_expectHigherThanIme_inMultiWindow() {
+ // Simulate the app window is in multi windowing mode and being IME target
+ mAppWindow.getConfiguration().windowConfiguration.setWindowingMode(
+ WINDOWING_MODE_MULTI_WINDOW);
+ mDisplayContent.setImeLayeringTarget(mAppWindow);
+ mDisplayContent.setImeInputTarget(mAppWindow);
+ makeWindowVisible(mImeWindow);
+
+ // Create a popupWindow
+ final WindowState systemDialogWindow = createWindow(null, TYPE_SECURE_SYSTEM_OVERLAY,
+ mDisplayContent, "SystemDialog", true);
+ systemDialogWindow.mAttrs.flags |= FLAG_ALT_FOCUSABLE_IM;
+ spyOn(systemDialogWindow);
+
+ mDisplayContent.assignChildLayers(mTransaction);
+
+ // Verify the surface layer of the popupWindow should higher than IME
+ verify(systemDialogWindow).needsRelativeLayeringToIme();
+ assertThat(systemDialogWindow.needsRelativeLayeringToIme()).isTrue();
+ assertZOrderGreaterThan(mTransaction, systemDialogWindow.getSurfaceControl(),
+ mDisplayContent.getImeContainer().getSurfaceControl());
+ }
}
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index f920f0f..28d726e 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -46,11 +46,13 @@
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
+import android.hardware.usb.IDisplayPortAltModeInfoListener;
import android.hardware.usb.IUsbOperationInternal;
import android.hardware.usb.ParcelableUsbPort;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbPort;
import android.hardware.usb.UsbPortStatus;
+import android.hardware.usb.DisplayPortAltModeInfo;
import android.hardware.usb.V1_0.IUsb;
import android.hardware.usb.V1_0.PortRole;
import android.hardware.usb.V1_0.PortRoleType;
@@ -63,6 +65,8 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.HwBinder;
+import android.os.IBinder;
+import android.os.IInterface;
import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
@@ -90,8 +94,10 @@
import java.util.Arrays;
import java.util.ArrayList;
+import java.util.LinkedList;
import java.util.NoSuchElementException;
import java.util.Objects;
+import java.util.concurrent.Executor;
/**
* Allows trusted components to control the properties of physical USB ports
@@ -105,7 +111,7 @@
* (but we don't care today).
* </p>
*/
-public class UsbPortManager {
+public class UsbPortManager implements IBinder.DeathRecipient {
private static final String TAG = "UsbPortManager";
private static final int MSG_UPDATE_PORTS = 1;
@@ -158,6 +164,12 @@
private NotificationManager mNotificationManager;
+ // Maintains a list of DisplayPortAltModeInfo Event listeners,
+ // protected by mDisplayPortListenerLock for broadcasts/register/unregister events
+ private final Object mDisplayPortListenerLock = new Object();
+ private final ArrayMap<IBinder, IDisplayPortAltModeInfoListener> mDisplayPortListeners =
+ new ArrayMap<IBinder, IDisplayPortAltModeInfoListener>();
+
/**
* If there currently is a notification related to contaminated USB port management
* shown the id of the notification, or 0 if there is none.
@@ -673,6 +685,46 @@
}
}
+ @Override
+ public void binderDied() {
+ // All calls should go to binderDied(IBinder deadBinder)
+ Slog.wtf(TAG, "binderDied() called unexpectedly");
+ }
+
+ public void binderDied(IBinder deadBinder) {
+ synchronized (mDisplayPortListenerLock) {
+ mDisplayPortListeners.remove(deadBinder);
+ Slog.d(TAG, "DisplayPortEventDispatcherListener died at " + deadBinder);
+ }
+ }
+
+ public boolean registerForDisplayPortEvents(
+ @NonNull IDisplayPortAltModeInfoListener listener) {
+ synchronized (mDisplayPortListenerLock) {
+ if (!mDisplayPortListeners.containsKey(listener.asBinder())) {
+ try {
+ listener.asBinder().linkToDeath(this, 0);
+ } catch (RemoteException e) {
+ logAndPrintException(null, "Caught RemoteException in " +
+ "registerForDisplayPortEvents: ", e);
+ return false;
+ }
+ mDisplayPortListeners.put(listener.asBinder(), listener);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void unregisterForDisplayPortEvents(
+ @NonNull IDisplayPortAltModeInfoListener listener) {
+ synchronized (mDisplayPortListenerLock) {
+ if (mDisplayPortListeners.remove(listener.asBinder()) != null) {
+ listener.asBinder().unlinkToDeath(this, 0);
+ }
+ }
+ }
+
public void updatePorts(ArrayList<RawPortInfo> newPortInfo) {
Message message = mHandler.obtainMessage();
Bundle bundle = new Bundle();
@@ -683,8 +735,15 @@
}
public void addSimulatedPort(String portId, int supportedModes,
- boolean supportsComplianceWarnings,
- IndentingPrintWriter pw) {
+ boolean supportsComplianceWarnings, boolean supportsDisplayPortAltMode,
+ IndentingPrintWriter pw) {
+ int supportedAltModes = supportsDisplayPortAltMode ?
+ UsbPort.FLAG_ALT_MODE_TYPE_DISPLAYPORT : 0;
+ DisplayPortAltModeInfo displayPortAltModeInfo = null;
+
+ if (supportsDisplayPortAltMode) {
+ displayPortAltModeInfo = new DisplayPortAltModeInfo();
+ }
synchronized (mLock) {
if (mSimulatedPorts.containsKey(portId)) {
@@ -713,7 +772,10 @@
false,
UsbPortStatus.POWER_BRICK_STATUS_UNKNOWN,
supportsComplianceWarnings,
- new int[] {}));
+ new int[] {},
+ UsbPortStatus.PLUG_STATE_UNKNOWN,
+ supportedAltModes,
+ displayPortAltModeInfo));
updatePortsLocked(pw, null);
}
}
@@ -802,6 +864,25 @@
}
}
+
+ public void simulateDisplayPortAltModeInfo(String portId, int partnerSinkStatus,
+ int cableStatus, int numLanes, IndentingPrintWriter pw) {
+ synchronized (mLock) {
+ final RawPortInfo portInfo = mSimulatedPorts.get(portId);
+ if (portInfo == null) {
+ pw.println("Simulated port not found");
+ return;
+ }
+
+ DisplayPortAltModeInfo displayPortAltModeInfo =
+ new DisplayPortAltModeInfo(partnerSinkStatus, cableStatus, numLanes);
+ portInfo.displayPortAltModeInfo = displayPortAltModeInfo;
+ pw.println("Simulating DisplayPort Info: " + displayPortAltModeInfo);
+ updatePortsLocked(pw, null);
+ }
+
+ }
+
public void disconnectSimulatedPort(String portId, IndentingPrintWriter pw) {
synchronized (mLock) {
final RawPortInfo portInfo = mSimulatedPorts.get(portId);
@@ -893,6 +974,9 @@
portInfo.powerBrickConnectionStatus,
portInfo.supportsComplianceWarnings,
portInfo.complianceWarnings,
+ portInfo.plugState,
+ portInfo.supportedAltModes,
+ portInfo.displayPortAltModeInfo,
pw);
}
} else {
@@ -911,6 +995,9 @@
currentPortInfo.powerBrickConnectionStatus,
currentPortInfo.supportsComplianceWarnings,
currentPortInfo.complianceWarnings,
+ currentPortInfo.plugState,
+ currentPortInfo.supportedAltModes,
+ currentPortInfo.displayPortAltModeInfo,
pw);
}
}
@@ -937,6 +1024,9 @@
if (portInfo.mComplianceWarningChange == portInfo.COMPLIANCE_WARNING_CHANGED) {
handlePortComplianceWarningLocked(portInfo, pw);
}
+ if (portInfo.mDisplayPortAltModeChange == portInfo.ALTMODE_INFO_CHANGED) {
+ handleDpAltModeLocked(portInfo, pw);
+ }
}
}
@@ -955,6 +1045,9 @@
int powerBrickConnectionStatus,
boolean supportsComplianceWarnings,
@NonNull int[] complianceWarnings,
+ int plugState,
+ int supportedAltModes,
+ DisplayPortAltModeInfo displayPortAltModeInfo,
IndentingPrintWriter pw) {
// Only allow mode switch capability for dual role ports.
// Validate that the current mode matches the supported modes we expect.
@@ -1009,14 +1102,15 @@
portId, supportedModes, supportedContaminantProtectionModes,
supportsEnableContaminantPresenceProtection,
supportsEnableContaminantPresenceDetection,
- supportsComplianceWarnings);
+ supportsComplianceWarnings,
+ supportedAltModes);
portInfo.setStatus(currentMode, canChangeMode,
currentPowerRole, canChangePowerRole,
currentDataRole, canChangeDataRole,
supportedRoleCombinations, contaminantProtectionStatus,
contaminantDetectionStatus, usbDataStatus,
powerTransferLimited, powerBrickConnectionStatus,
- complianceWarnings);
+ complianceWarnings, plugState, displayPortAltModeInfo);
mPorts.put(portId, portInfo);
} else {
// Validate that ports aren't changing definition out from under us.
@@ -1054,7 +1148,7 @@
supportedRoleCombinations, contaminantProtectionStatus,
contaminantDetectionStatus, usbDataStatus,
powerTransferLimited, powerBrickConnectionStatus,
- complianceWarnings)) {
+ complianceWarnings, plugState, displayPortAltModeInfo)) {
portInfo.mDisposition = PortInfo.DISPOSITION_CHANGED;
} else {
portInfo.mDisposition = PortInfo.DISPOSITION_READY;
@@ -1086,6 +1180,11 @@
sendComplianceWarningBroadcastLocked(portInfo);
}
+ private void handleDpAltModeLocked(PortInfo portInfo, IndentingPrintWriter pw) {
+ logAndPrint(Log.INFO, pw, "USB port DisplayPort Alt Mode Status Changed: " + portInfo);
+ sendDpAltModeCallbackLocked(portInfo, pw);
+ }
+
private void handlePortRemovedLocked(PortInfo portInfo, IndentingPrintWriter pw) {
logAndPrint(Log.INFO, pw, "USB port removed: " + portInfo);
handlePortLocked(portInfo, pw);
@@ -1135,7 +1234,6 @@
return complianceWarningsProto.toArray();
}
-
private void sendPortChangedBroadcastLocked(PortInfo portInfo) {
final Intent intent = new Intent(UsbManager.ACTION_USB_PORT_CHANGED);
intent.addFlags(
@@ -1167,6 +1265,21 @@
Manifest.permission.MANAGE_USB));
}
+ private void sendDpAltModeCallbackLocked(PortInfo portInfo, IndentingPrintWriter pw) {
+ String portId = portInfo.mUsbPort.getId();
+ synchronized (mDisplayPortListenerLock) {
+ for (IDisplayPortAltModeInfoListener mListener : mDisplayPortListeners.values()) {
+ try {
+ mListener.onDisplayPortAltModeInfoChanged(portId,
+ portInfo.mUsbPortStatus.getDisplayPortAltModeInfo());
+ } catch (RemoteException e) {
+ logAndPrintException(pw, "Caught RemoteException at "
+ + "sendDpAltModeCallbackLocked", e);
+ }
+ }
+ }
+ }
+
private void enableContaminantDetectionIfNeeded(PortInfo portInfo, IndentingPrintWriter pw) {
if (!mConnected.containsKey(portInfo.mUsbPort.getId())) {
return;
@@ -1308,6 +1421,9 @@
public static final int COMPLIANCE_WARNING_UNCHANGED = 0;
public static final int COMPLIANCE_WARNING_CHANGED = 1;
+ public static final int ALTMODE_INFO_UNCHANGED = 0;
+ public static final int ALTMODE_INFO_CHANGED = 1;
+
public final UsbPort mUsbPort;
public UsbPortStatus mUsbPortStatus;
public boolean mCanChangeMode;
@@ -1321,18 +1437,23 @@
public long mLastConnectDurationMillis;
// default initialized to 0 which means no changes reported
public int mComplianceWarningChange;
+ // default initialized to 0 which means unchanged
+ public int mDisplayPortAltModeChange;
PortInfo(@NonNull UsbManager usbManager, @NonNull String portId, int supportedModes,
int supportedContaminantProtectionModes,
boolean supportsEnableContaminantPresenceDetection,
boolean supportsEnableContaminantPresenceProtection,
- boolean supportsComplianceWarnings) {
+ boolean supportsComplianceWarnings,
+ int supportedAltModes) {
mUsbPort = new UsbPort(usbManager, portId, supportedModes,
supportedContaminantProtectionModes,
supportsEnableContaminantPresenceDetection,
supportsEnableContaminantPresenceProtection,
- supportsComplianceWarnings);
+ supportsComplianceWarnings,
+ supportedAltModes);
mComplianceWarningChange = COMPLIANCE_WARNING_UNCHANGED;
+ mDisplayPortAltModeChange = ALTMODE_INFO_UNCHANGED;
}
public boolean complianceWarningsChanged(@NonNull int[] complianceWarnings) {
@@ -1344,6 +1465,34 @@
return true;
}
+ public boolean displayPortAltModeChanged(DisplayPortAltModeInfo
+ displayPortAltModeInfo) {
+ DisplayPortAltModeInfo currentDisplayPortAltModeInfo =
+ mUsbPortStatus.getDisplayPortAltModeInfo();
+
+ mDisplayPortAltModeChange = ALTMODE_INFO_UNCHANGED;
+
+ if (displayPortAltModeInfo == null
+ && currentDisplayPortAltModeInfo != null) {
+ mDisplayPortAltModeChange = ALTMODE_INFO_CHANGED;
+ return true;
+ }
+
+ if (currentDisplayPortAltModeInfo == null) {
+ if (displayPortAltModeInfo != null) {
+ mDisplayPortAltModeChange = ALTMODE_INFO_CHANGED;
+ return true;
+ }
+ return false;
+ }
+
+ if (!(currentDisplayPortAltModeInfo.equals(displayPortAltModeInfo))) {
+ mDisplayPortAltModeChange = ALTMODE_INFO_CHANGED;
+ return true;
+ }
+ return false;
+ }
+
public boolean setStatus(int currentMode, boolean canChangeMode,
int currentPowerRole, boolean canChangePowerRole,
int currentDataRole, boolean canChangeDataRole,
@@ -1364,7 +1513,7 @@
UsbPortStatus.CONTAMINANT_DETECTION_NOT_SUPPORTED,
UsbPortStatus.DATA_STATUS_UNKNOWN, false,
UsbPortStatus.POWER_BRICK_STATUS_UNKNOWN,
- new int[] {});
+ new int[] {}, 0, null);
dispositionChanged = true;
}
@@ -1410,7 +1559,7 @@
supportedRoleCombinations, contaminantProtectionStatus,
contaminantDetectionStatus, usbDataStatus,
powerTransferLimited, powerBrickConnectionStatus,
- new int[] {});
+ new int[] {}, 0, null);
dispositionChanged = true;
}
@@ -1431,8 +1580,16 @@
int supportedRoleCombinations, int contaminantProtectionStatus,
int contaminantDetectionStatus, int usbDataStatus,
boolean powerTransferLimited, int powerBrickConnectionStatus,
- @NonNull int[] complianceWarnings) {
+ @NonNull int[] complianceWarnings,
+ int plugState, DisplayPortAltModeInfo displayPortAltModeInfo) {
boolean dispositionChanged = false;
+ boolean complianceChanged = false;
+ boolean displayPortChanged = false;
+
+ if (mUsbPortStatus != null) {
+ complianceChanged = complianceWarningsChanged(complianceWarnings);
+ displayPortChanged = displayPortAltModeChanged(displayPortAltModeInfo);
+ }
mCanChangeMode = canChangeMode;
mCanChangePowerRole = canChangePowerRole;
@@ -1452,7 +1609,9 @@
|| mUsbPortStatus.isPowerTransferLimited()
!= powerTransferLimited
|| mUsbPortStatus.getPowerBrickConnectionStatus()
- != powerBrickConnectionStatus) {
+ != powerBrickConnectionStatus
+ || mUsbPortStatus.getPlugState()
+ != plugState) {
if (mUsbPortStatus == null && complianceWarnings.length > 0) {
mComplianceWarningChange = COMPLIANCE_WARNING_CHANGED;
}
@@ -1460,14 +1619,17 @@
supportedRoleCombinations, contaminantProtectionStatus,
contaminantDetectionStatus, usbDataStatus,
powerTransferLimited, powerBrickConnectionStatus,
- complianceWarnings);
+ complianceWarnings, plugState, displayPortAltModeInfo);
dispositionChanged = true;
- } else if (complianceWarningsChanged(complianceWarnings)) {
- mUsbPortStatus = new UsbPortStatus(currentMode, currentPowerRole, currentDataRole,
- supportedRoleCombinations, contaminantProtectionStatus,
- contaminantDetectionStatus, usbDataStatus,
- powerTransferLimited, powerBrickConnectionStatus,
- complianceWarnings);
+ // Case used in order to send compliance warning broadcast or signal DisplayPort
+ // listeners. These targeted broadcasts don't use dispositionChanged to broadcast to
+ // general ACTION_USB_PORT_CHANGED.
+ } else if (complianceChanged || displayPortChanged) {
+ mUsbPortStatus = new UsbPortStatus(currentMode, currentPowerRole,
+ currentDataRole, supportedRoleCombinations,
+ contaminantProtectionStatus, contaminantDetectionStatus,
+ usbDataStatus, powerTransferLimited, powerBrickConnectionStatus,
+ complianceWarnings, plugState, displayPortAltModeInfo);
}
if (mUsbPortStatus.isConnected() && mConnectedAtMillis == 0) {
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index 6eb04d9..7d84222 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -36,6 +36,7 @@
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.hardware.usb.IUsbManager;
+import android.hardware.usb.IDisplayPortAltModeInfoListener;
import android.hardware.usb.IUsbOperationInternal;
import android.hardware.usb.ParcelableUsbPort;
import android.hardware.usb.UsbAccessory;
@@ -43,6 +44,7 @@
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbPort;
import android.hardware.usb.UsbPortStatus;
+import android.hardware.usb.DisplayPortAltModeInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
@@ -902,6 +904,45 @@
}
}
+ @Override
+ public boolean registerForDisplayPortEvents(
+ @NonNull IDisplayPortAltModeInfoListener listener) {
+ Objects.requireNonNull(listener, "registerForDisplayPortEvents: listener " +
+ "must not be null.");
+
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ if (mPortManager != null) {
+ return mPortManager.registerForDisplayPortEvents(listener);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+
+ return false;
+ }
+
+ @Override
+ public void unregisterForDisplayPortEvents(
+ @NonNull IDisplayPortAltModeInfoListener listener) {
+ Objects.requireNonNull(listener, "unregisterForDisplayPortEvents: listener " +
+ "must not be null.");
+
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ if (mPortManager != null) {
+ mPortManager.unregisterForDisplayPortEvents(listener);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+
@NeverCompile // Avoid size overhead of debugging code.
@Override
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
@@ -993,6 +1034,7 @@
int i;
boolean supportsComplianceWarnings = false;
+ boolean supportsDisplayPortAltMode = false;
switch (args[2]) {
case "ufp":
supportedModes = MODE_UFP;
@@ -1015,14 +1057,17 @@
case "--compliance-warnings":
supportsComplianceWarnings = true;
continue;
+ case "--displayport":
+ supportsDisplayPortAltMode = true;
+ continue;
default:
pw.println("Invalid Identifier: " + args[i]);
}
}
if (mPortManager != null) {
mPortManager.addSimulatedPort(portId, supportedModes,
- supportsComplianceWarnings,
- pw);
+ supportsComplianceWarnings, supportsDisplayPortAltMode,
+ pw);
pw.println();
mPortManager.dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")),
"", 0);
@@ -1124,6 +1169,29 @@
mPortManager.dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")),
"", 0);
}
+ } else if ("set-displayport-status".equals(args[0]) && args.length == 5) {
+ final String portId = args[1];
+ final int partnerSinkStatus = Integer.parseInt(args[2]);
+ final int cableStatus = Integer.parseInt(args[3]);
+ final int displayPortNumLanes = Integer.parseInt(args[4]);
+ if (mPortManager != null) {
+ mPortManager.simulateDisplayPortAltModeInfo(portId,
+ partnerSinkStatus, cableStatus, displayPortNumLanes, pw);
+ pw.println();
+ mPortManager.dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")),
+ "", 0);
+ }
+ } else if ("reset-displayport-status".equals(args[0]) && args.length == 2) {
+ final String portId = args[1];
+ if (mPortManager != null) {
+ mPortManager.simulateDisplayPortAltModeInfo(portId,
+ DisplayPortAltModeInfo.DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN,
+ DisplayPortAltModeInfo.DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN,
+ 0, pw);
+ pw.println();
+ mPortManager.dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")),
+ "", 0);
+ }
} else if ("ports".equals(args[0]) && args.length == 1) {
if (mPortManager != null) {
mPortManager.dump(new DualDumpOutputStream(new IndentingPrintWriter(pw, " ")),
@@ -1138,6 +1206,7 @@
pw.println(" add-port <id> <ufp|dfp|dual|none> <optional args>");
pw.println(" <optional args> include:");
pw.println(" --compliance-warnings: enables compliance warnings on port");
+ pw.println(" --displayport: enables DisplayPort Alt Mode on port");
pw.println(" connect-port <id> <ufp|dfp><?> <source|sink><?> <host|device><?>");
pw.println(" (add ? suffix if mode, power role, or data role can be changed)");
pw.println(" disconnect-port <id>");
@@ -1148,7 +1217,8 @@
pw.println(" dumpsys usb set-port-roles \"default\" source device");
pw.println();
pw.println("Example USB type C port simulation with full capabilities:");
- pw.println(" dumpsys usb add-port \"matrix\" dual --compliance-warnings");
+ pw.println(" dumpsys usb add-port \"matrix\" dual --compliance-warnings "
+ + "--displayport");
pw.println(" dumpsys usb connect-port \"matrix\" ufp? sink? device?");
pw.println(" dumpsys usb ports");
pw.println(" dumpsys usb disconnect-port \"matrix\"");
@@ -1186,6 +1256,14 @@
pw.println(" 3: bc12");
pw.println(" 4: missing rp");
pw.println();
+ pw.println("Example simulate DisplayPort Alt Mode Changes:");
+ pw.println(" dumpsys usb add-port \"matrix\" dual --displayport");
+ pw.println(" dumpsys usb set-displayport-status \"matrix\" <partner-sink>"
+ + " <cable> <num-lanes>");
+ pw.println(" dumpsys usb reset-displayport-status \"matrix\"");
+ pw.println("reset-displayport-status can also be used in order to set");
+ pw.println("the DisplayPortInfo to default values.");
+ pw.println();
pw.println("Example USB device descriptors:");
pw.println(" dumpsys usb dump-descriptors -dump-short");
pw.println(" dumpsys usb dump-descriptors -dump-tree");
diff --git a/services/usb/java/com/android/server/usb/hal/port/RawPortInfo.java b/services/usb/java/com/android/server/usb/hal/port/RawPortInfo.java
index e6a3e53..ef32e93 100644
--- a/services/usb/java/com/android/server/usb/hal/port/RawPortInfo.java
+++ b/services/usb/java/com/android/server/usb/hal/port/RawPortInfo.java
@@ -15,7 +15,9 @@
*/
package com.android.server.usb.hal.port;
+import android.hardware.usb.UsbPort;
import android.hardware.usb.UsbPortStatus;
+import android.hardware.usb.DisplayPortAltModeInfo;
import android.os.Parcel;
import android.os.Parcelable;
@@ -42,6 +44,9 @@
public int powerBrickConnectionStatus;
public final boolean supportsComplianceWarnings;
public int[] complianceWarnings;
+ public int plugState;
+ public int supportedAltModes;
+ public DisplayPortAltModeInfo displayPortAltModeInfo;
public RawPortInfo(String portId, int supportedModes) {
this.portId = portId;
@@ -56,6 +61,9 @@
this.powerBrickConnectionStatus = UsbPortStatus.POWER_BRICK_STATUS_UNKNOWN;
this.supportsComplianceWarnings = false;
this.complianceWarnings = new int[] {};
+ this.plugState = UsbPortStatus.PLUG_STATE_UNKNOWN;
+ this.supportedAltModes = 0;
+ this.displayPortAltModeInfo = null;
}
public RawPortInfo(String portId, int supportedModes, int supportedContaminantProtectionModes,
@@ -76,7 +84,8 @@
supportsEnableContaminantPresenceProtection, contaminantProtectionStatus,
supportsEnableContaminantPresenceDetection, contaminantDetectionStatus,
usbDataStatus, powerTransferLimited, powerBrickConnectionStatus,
- false, new int[] {});
+ false, new int[] {}, UsbPortStatus.PLUG_STATE_UNKNOWN,
+ 0, null);
}
public RawPortInfo(String portId, int supportedModes, int supportedContaminantProtectionModes,
@@ -91,7 +100,10 @@
boolean powerTransferLimited,
int powerBrickConnectionStatus,
boolean supportsComplianceWarnings,
- int[] complianceWarnings) {
+ int[] complianceWarnings,
+ int plugState,
+ int supportedAltModes,
+ DisplayPortAltModeInfo displayPortAltModeInfo) {
this.portId = portId;
this.supportedModes = supportedModes;
this.supportedContaminantProtectionModes = supportedContaminantProtectionModes;
@@ -112,6 +124,9 @@
this.powerBrickConnectionStatus = powerBrickConnectionStatus;
this.supportsComplianceWarnings = supportsComplianceWarnings;
this.complianceWarnings = complianceWarnings;
+ this.plugState = plugState;
+ this.supportedAltModes = supportedAltModes;
+ this.displayPortAltModeInfo = displayPortAltModeInfo;
}
@Override
@@ -139,12 +154,19 @@
dest.writeInt(powerBrickConnectionStatus);
dest.writeBoolean(supportsComplianceWarnings);
dest.writeIntArray(complianceWarnings);
+ dest.writeInt(plugState);
+ dest.writeInt(supportedAltModes);
+ if ((supportedAltModes & UsbPort.FLAG_ALT_MODE_TYPE_DISPLAYPORT) != 0) {
+ displayPortAltModeInfo.writeToParcel(dest, 0);
+ }
}
public static final Parcelable.Creator<RawPortInfo> CREATOR =
new Parcelable.Creator<RawPortInfo>() {
@Override
public RawPortInfo createFromParcel(Parcel in) {
+ DisplayPortAltModeInfo displayPortAltModeInfo;
+
String id = in.readString();
int supportedModes = in.readInt();
int supportedContaminantProtectionModes = in.readInt();
@@ -163,6 +185,13 @@
int powerBrickConnectionStatus = in.readInt();
boolean supportsComplianceWarnings = in.readBoolean();
int[] complianceWarnings = in.createIntArray();
+ int plugState = in.readInt();
+ int supportedAltModes = in.readInt();
+ if ((supportedAltModes & UsbPort.FLAG_ALT_MODE_TYPE_DISPLAYPORT) != 0) {
+ displayPortAltModeInfo = DisplayPortAltModeInfo.CREATOR.createFromParcel(in);
+ } else {
+ displayPortAltModeInfo = null;
+ }
return new RawPortInfo(id, supportedModes,
supportedContaminantProtectionModes, currentMode, canChangeMode,
currentPowerRole, canChangePowerRole,
@@ -172,7 +201,8 @@
supportsEnableContaminantPresenceDetection,
contaminantDetectionStatus, usbDataStatus,
powerTransferLimited, powerBrickConnectionStatus,
- supportsComplianceWarnings, complianceWarnings);
+ supportsComplianceWarnings, complianceWarnings,
+ plugState, supportedAltModes, displayPortAltModeInfo);
}
@Override
diff --git a/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java b/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java
index ff4268f..b9ccace 100644
--- a/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java
+++ b/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java
@@ -35,6 +35,10 @@
import android.hardware.usb.PortRole;
import android.hardware.usb.PortStatus;
import android.hardware.usb.ComplianceWarning;
+import android.hardware.usb.DisplayPortAltModeInfo;
+import android.hardware.usb.AltModeData;
+import android.hardware.usb.AltModeData.DisplayPortAltModeData;
+import android.hardware.usb.DisplayPortAltModePinAssignment;
import android.os.Build;
import android.os.ServiceManager;
import android.os.IBinder;
@@ -600,6 +604,47 @@
return newComplianceWarnings.toArray();
}
+ private int toSupportedAltModesInt(android.hardware.usb.AltModeData[] supportedAltModes) {
+ int supportedAltModesInt = 0;
+ for (android.hardware.usb.AltModeData altModeData : supportedAltModes) {
+ switch (altModeData.getTag()) {
+ case AltModeData.displayPortAltModeData:
+ supportedAltModesInt |= UsbPort.FLAG_ALT_MODE_TYPE_DISPLAYPORT;
+ break;
+ }
+ }
+ return supportedAltModesInt;
+ }
+
+ private int toDisplayPortAltModeNumLanesInt(int pinAssignment) {
+ switch (pinAssignment) {
+ case DisplayPortAltModePinAssignment.A:
+ case DisplayPortAltModePinAssignment.C:
+ case DisplayPortAltModePinAssignment.E:
+ return 4;
+ case DisplayPortAltModePinAssignment.B:
+ case DisplayPortAltModePinAssignment.D:
+ case DisplayPortAltModePinAssignment.F:
+ return 2;
+ default:
+ return 0;
+ }
+ }
+
+ private DisplayPortAltModeInfo formatDisplayPortAltModeInfo(
+ android.hardware.usb.AltModeData[] supportedAltModes) {
+ for (android.hardware.usb.AltModeData altModeData : supportedAltModes) {
+ if (altModeData.getTag() == AltModeData.displayPortAltModeData) {
+ DisplayPortAltModeData displayPortData =
+ altModeData.getDisplayPortAltModeData();
+ return new DisplayPortAltModeInfo(displayPortData.partnerSinkStatus,
+ displayPortData.cableStatus,
+ toDisplayPortAltModeNumLanesInt(displayPortData.pinAssignment));
+ }
+ }
+ return null;
+ }
+
@Override
public void notifyPortStatusChange(
android.hardware.usb.PortStatus[] currentPortStatus, int retval) {
@@ -635,7 +680,10 @@
current.powerTransferLimited,
current.powerBrickStatus,
current.supportsComplianceWarnings,
- formatComplianceWarnings(current.complianceWarnings));
+ formatComplianceWarnings(current.complianceWarnings),
+ current.plugOrientation,
+ toSupportedAltModesInt(current.supportedAltModes),
+ formatDisplayPortAltModeInfo(current.supportedAltModes));
newPortInfo.add(temp);
UsbPortManager.logAndPrint(Log.INFO, mPw, "ClientCallback AIDL V1: "
+ current.portName);
diff --git a/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java b/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java
index 10403c1..a7ecabb 100644
--- a/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java
+++ b/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java
@@ -35,7 +35,8 @@
import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SOURCE;
import static android.hardware.usb.UsbPortStatus.DATA_STATUS_DISABLED_FORCE;
import static android.hardware.usb.UsbPortStatus.DATA_STATUS_UNKNOWN;
-
+import static android.hardware.usb.UsbPortStatus.PLUG_STATE_UNKNOWN;
+import static android.hardware.usb.DisplayPortAltModeInfo.DISPLAYPORT_ALT_MODE_STATUS_UNKNOWN;
import static com.android.server.usb.UsbPortManager.logAndPrint;
import static com.android.server.usb.UsbPortManager.logAndPrintException;
@@ -422,7 +423,10 @@
false, CONTAMINANT_PROTECTION_NONE,
false, CONTAMINANT_DETECTION_NOT_SUPPORTED, sUsbDataStatus,
false, POWER_BRICK_STATUS_UNKNOWN,
- false, new int[] {});
+ false, new int[] {},
+ PLUG_STATE_UNKNOWN,
+ 0,
+ null);
newPortInfo.add(temp);
UsbPortManager.logAndPrint(Log.INFO, mPw, "ClientCallback V1_0: "
+ current.portName);
@@ -457,7 +461,10 @@
false, CONTAMINANT_PROTECTION_NONE,
false, CONTAMINANT_DETECTION_NOT_SUPPORTED, sUsbDataStatus,
false, POWER_BRICK_STATUS_UNKNOWN,
- false, new int[] {});
+ false, new int[] {},
+ PLUG_STATE_UNKNOWN,
+ 0,
+ null);
newPortInfo.add(temp);
UsbPortManager.logAndPrint(Log.INFO, mPw, "ClientCallback V1_1: "
+ current.status.portName);
@@ -496,7 +503,10 @@
current.contaminantDetectionStatus,
sUsbDataStatus,
false, POWER_BRICK_STATUS_UNKNOWN,
- false, new int[] {});
+ false, new int[] {},
+ PLUG_STATE_UNKNOWN,
+ 0,
+ null);
newPortInfo.add(temp);
UsbPortManager.logAndPrint(Log.INFO, mPw, "ClientCallback V1_2: "
+ current.status_1_1.status.portName);
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index bbdc890..95c9061 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -2123,6 +2123,14 @@
* <p>
* No assumptions should be made as to how an In-Call UI or service will handle these
* extras. Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
+ * <p>
+ * Extras added using this method will be made available to the {@link ConnectionService}
+ * associated with this {@link Call} and notified via
+ * {@link Connection#onExtrasChanged(Bundle)}.
+ * <p>
+ * Extras added using this method will also be available to other running {@link InCallService}s
+ * and notified via {@link Call.Callback#onDetailsChanged(Call, Details)}. The extras can be
+ * accessed via {@link Details#getExtras()}.
*
* @param extras The extras to add.
*/
diff --git a/telecomm/java/android/telecom/CallControl.java b/telecomm/java/android/telecom/CallControl.java
index 867bcc7..770a374 100644
--- a/telecomm/java/android/telecom/CallControl.java
+++ b/telecomm/java/android/telecom/CallControl.java
@@ -31,6 +31,8 @@
import com.android.internal.telecom.ClientTransactionalServiceRepository;
import com.android.internal.telecom.ICallControl;
+import java.util.List;
+import java.util.Objects;
import java.util.concurrent.Executor;
/**
@@ -223,6 +225,42 @@
}
/**
+ * Request a CallEndpoint change. Clients should not define their own CallEndpoint when
+ * requesting a change. Instead, the new endpoint should be one of the valid endpoints provided
+ * by {@link CallEventCallback#onAvailableCallEndpointsChanged(List)}.
+ *
+ * @param callEndpoint ; The {@link CallEndpoint} to change to.
+ * @param executor ; The {@link Executor} on which the {@link OutcomeReceiver} callback
+ * will be called on.
+ * @param callback ; The {@link OutcomeReceiver} that will be completed on the Telecom side
+ * that details success or failure of the requested operation.
+ *
+ * {@link OutcomeReceiver#onResult} will be called if Telecom has
+ * successfully changed the CallEndpoint that was requested.
+ *
+ * {@link OutcomeReceiver#onError} will be called if Telecom has failed to
+ * switch to the requested CallEndpoint. A {@link CallException} will be
+ * passed that details why the operation failed.
+ */
+ public void requestCallEndpointChange(@NonNull CallEndpoint callEndpoint,
+ @CallbackExecutor @NonNull Executor executor,
+ @NonNull OutcomeReceiver<Void, CallException> callback) {
+ Objects.requireNonNull(callEndpoint);
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+ if (mServerInterface != null) {
+ try {
+ mServerInterface.requestCallEndpointChange(callEndpoint,
+ new CallControlResultReceiver("endpointChange", executor, callback));
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ } else {
+ throw new IllegalStateException(INTERFACE_ERROR_MSG);
+ }
+ }
+
+ /**
* This method should be called after
* {@link CallControl#disconnect(DisconnectCause, Executor, OutcomeReceiver)} or
* {@link CallControl#rejectCall(Executor, OutcomeReceiver)}
diff --git a/telecomm/java/android/telecom/CallEventCallback.java b/telecomm/java/android/telecom/CallEventCallback.java
index fd7e101..806febd 100644
--- a/telecomm/java/android/telecom/CallEventCallback.java
+++ b/telecomm/java/android/telecom/CallEventCallback.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
+import java.util.List;
import java.util.function.Consumer;
/**
@@ -95,13 +96,6 @@
void onDisconnect(@NonNull Consumer<Boolean> wasCompleted);
/**
- * update the client on the new {@link CallAudioState}
- *
- * @param callAudioState that is currently being used
- */
- void onCallAudioStateChanged(@NonNull CallAudioState callAudioState);
-
- /**
* Telecom is informing the client to set the call in streaming.
*
* @param wasCompleted The {@link Consumer} to be completed. If the client can stream the
@@ -118,4 +112,26 @@
* @param reason Code to indicate the reason of this failure
*/
void onCallStreamingFailed(@CallStreamingService.StreamingFailedReason int reason);
+
+ /**
+ * Telecom is informing the client the current {@link CallEndpoint} changed.
+ *
+ * @param newCallEndpoint The new {@link CallEndpoint} through which call media flows
+ * (i.e. speaker, bluetooth, etc.).
+ */
+ void onCallEndpointChanged(@NonNull CallEndpoint newCallEndpoint);
+
+ /**
+ * Telecom is informing the client that the available {@link CallEndpoint}s have changed.
+ *
+ * @param availableEndpoints The set of available {@link CallEndpoint}s reported by Telecom.
+ */
+ void onAvailableCallEndpointsChanged(@NonNull List<CallEndpoint> availableEndpoints);
+
+ /**
+ * Called when the mute state changes.
+ *
+ * @param isMuted The current mute state.
+ */
+ void onMuteStateChanged(boolean isMuted);
}
diff --git a/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java b/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java
index 16816ff..b2e921b 100644
--- a/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java
+++ b/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java
@@ -22,14 +22,15 @@
import android.os.OutcomeReceiver;
import android.os.ResultReceiver;
import android.telecom.CallAttributes;
-import android.telecom.CallAudioState;
import android.telecom.CallControl;
+import android.telecom.CallEndpoint;
import android.telecom.CallEventCallback;
import android.telecom.CallException;
import android.telecom.PhoneAccountHandle;
import android.text.TextUtils;
import android.util.Log;
+import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
@@ -140,6 +141,9 @@
private static final String ON_REJECT = "onReject";
private static final String ON_DISCONNECT = "onDisconnect";
private static final String ON_STREAMING_STARTED = "onStreamingStarted";
+ private static final String ON_REQ_ENDPOINT_CHANGE = "onRequestEndpointChange";
+ private static final String ON_AVAILABLE_CALL_ENDPOINTS = "onAvailableCallEndpointsChanged";
+ private static final String ON_MUTE_STATE_CHANGED = "onMuteStateChanged";
private void handleCallEventCallback(String action, String callId, int code,
ResultReceiver ackResultReceiver) {
@@ -246,14 +250,45 @@
}
@Override
- public void onCallAudioStateChanged(String callId, CallAudioState callAudioState) {
- Log.i(TAG, TextUtils.formatSimple("onCallAudioStateChanged: callId=[%s]", callId));
+ public void onCallEndpointChanged(String callId, CallEndpoint endpoint) {
+ handleEndpointUpdate(callId, ON_REQ_ENDPOINT_CHANGE, endpoint);
+ }
+
+ @Override
+ public void onAvailableCallEndpointsChanged(String callId, List<CallEndpoint> endpoints) {
+ handleEndpointUpdate(callId, ON_AVAILABLE_CALL_ENDPOINTS, endpoints);
+ }
+
+ @Override
+ public void onMuteStateChanged(String callId, boolean isMuted) {
+ handleEndpointUpdate(callId, ON_MUTE_STATE_CHANGED, isMuted);
+ }
+
+ public void handleEndpointUpdate(String callId, String action, Object arg) {
+ Log.d(TAG, TextUtils.formatSimple("[%s], callId=[%s]", action, callId));
// lookup the callEventCallback associated with the particular call
TransactionalCall call = mCallIdToTransactionalCall.get(callId);
if (call != null) {
CallEventCallback callback = call.getCallEventCallback();
Executor executor = call.getExecutor();
- executor.execute(() -> callback.onCallAudioStateChanged(callAudioState));
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> {
+ switch (action) {
+ case ON_REQ_ENDPOINT_CHANGE:
+ callback.onCallEndpointChanged((CallEndpoint) arg);
+ break;
+ case ON_AVAILABLE_CALL_ENDPOINTS:
+ callback.onAvailableCallEndpointsChanged((List<CallEndpoint>) arg);
+ break;
+ case ON_MUTE_STATE_CHANGED:
+ callback.onMuteStateChanged((boolean) arg);
+ break;
+ }
+ });
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
}
diff --git a/telecomm/java/com/android/internal/telecom/ICallControl.aidl b/telecomm/java/com/android/internal/telecom/ICallControl.aidl
index dc0aeac..a5c6e44 100644
--- a/telecomm/java/com/android/internal/telecom/ICallControl.aidl
+++ b/telecomm/java/com/android/internal/telecom/ICallControl.aidl
@@ -17,6 +17,7 @@
package com.android.internal.telecom;
import android.telecom.CallControl;
+import android.telecom.CallEndpoint;
import android.telecom.DisconnectCause;
import android.os.ResultReceiver;
@@ -29,4 +30,5 @@
void disconnect(String callId, in DisconnectCause disconnectCause, in ResultReceiver callback);
void rejectCall(String callId, in ResultReceiver callback);
void startCallStreaming(String callId, in ResultReceiver callback);
+ void requestCallEndpointChange(in CallEndpoint callEndpoint, in ResultReceiver callback);
}
\ No newline at end of file
diff --git a/telecomm/java/com/android/internal/telecom/ICallEventCallback.aidl b/telecomm/java/com/android/internal/telecom/ICallEventCallback.aidl
index c45ef97..fef5e9e 100644
--- a/telecomm/java/com/android/internal/telecom/ICallEventCallback.aidl
+++ b/telecomm/java/com/android/internal/telecom/ICallEventCallback.aidl
@@ -17,10 +17,12 @@
package com.android.internal.telecom;
import android.telecom.CallControl;
+import android.telecom.CallEndpoint;
import com.android.internal.telecom.ICallControl;
import android.os.ResultReceiver;
import android.telecom.CallAudioState;
import android.telecom.CallException;
+import java.util.List;
/**
* {@hide}
@@ -29,15 +31,19 @@
// publicly exposed. Client should override
void onAddCallControl(String callId, int resultCode, in ICallControl callControl,
in CallException exception);
+ // -- Call Event Actions / Call State Transitions
void onSetActive(String callId, in ResultReceiver callback);
void onSetInactive(String callId, in ResultReceiver callback);
void onAnswer(String callId, int videoState, in ResultReceiver callback);
void onReject(String callId, in ResultReceiver callback);
void onDisconnect(String callId, in ResultReceiver callback);
- void onCallAudioStateChanged(String callId, in CallAudioState callAudioState);
- // Streaming related. Client registered call streaming capabilities should override
+ // -- Streaming related. Client registered call streaming capabilities should override
void onCallStreamingStarted(String callId, in ResultReceiver callback);
void onCallStreamingFailed(String callId, int reason);
+ // -- Audio related.
+ void onCallEndpointChanged(String callId, in CallEndpoint endpoint);
+ void onAvailableCallEndpointsChanged(String callId, in List<CallEndpoint> endpoint);
+ void onMuteStateChanged(String callId, boolean isMuted);
// hidden methods that help with cleanup
void removeCallFromTransactionalServiceWrapper(String callId);
}
\ No newline at end of file
diff --git a/telephony/java/android/service/euicc/EuiccService.java b/telephony/java/android/service/euicc/EuiccService.java
index e19117b..2c0087e 100644
--- a/telephony/java/android/service/euicc/EuiccService.java
+++ b/telephony/java/android/service/euicc/EuiccService.java
@@ -490,6 +490,28 @@
int slotId, DownloadableSubscription subscription, boolean forceDeactivateSim);
/**
+ * Populate {@link DownloadableSubscription} metadata for the given downloadable subscription.
+ *
+ * @param slotId ID of the SIM slot to use for the operation.
+ * @param portIndex Index of the port from the slot. portIndex is used if the eUICC must
+ * be activated to perform the operation.
+ * @param subscription A subscription whose metadata needs to be populated.
+ * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the
+ * eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM}
+ * should be returned to allow the user to consent to this operation first.
+ * @return The result of the operation.
+ * @see android.telephony.euicc.EuiccManager#getDownloadableSubscriptionMetadata
+ */
+ @NonNull
+ public GetDownloadableSubscriptionMetadataResult onGetDownloadableSubscriptionMetadata(
+ int slotId, int portIndex, @NonNull DownloadableSubscription subscription,
+ boolean forceDeactivateSim) {
+ // stub implementation, LPA needs to implement this
+ throw new UnsupportedOperationException(
+ "LPA must override onGetDownloadableSubscriptionMetadata");
+ }
+
+ /**
* Return metadata for subscriptions which are available for download for this device.
*
* @param slotId ID of the SIM slot to use for the operation.
@@ -833,16 +855,31 @@
}
@Override
- public void getDownloadableSubscriptionMetadata(int slotId,
+ public void getDownloadableSubscriptionMetadata(int slotId, int portIndex,
DownloadableSubscription subscription,
- boolean forceDeactivateSim,
+ boolean switchAfterDownload, boolean forceDeactivateSim,
IGetDownloadableSubscriptionMetadataCallback callback) {
mExecutor.execute(new Runnable() {
@Override
public void run() {
- GetDownloadableSubscriptionMetadataResult result =
- EuiccService.this.onGetDownloadableSubscriptionMetadata(
+ GetDownloadableSubscriptionMetadataResult result;
+ if (switchAfterDownload) {
+ try {
+ result = EuiccService.this.onGetDownloadableSubscriptionMetadata(
+ slotId, portIndex, subscription, forceDeactivateSim);
+ } catch (UnsupportedOperationException | AbstractMethodError e) {
+ Log.w(TAG, "The new onGetDownloadableSubscriptionMetadata(int, int, "
+ + "DownloadableSubscription, boolean) is not implemented."
+ + " Fall back to the old one.", e);
+ result = EuiccService.this.onGetDownloadableSubscriptionMetadata(
slotId, subscription, forceDeactivateSim);
+ }
+ } else {
+ // When switchAfterDownload is false, this operation is port agnostic.
+ // Call API without portIndex.
+ result = EuiccService.this.onGetDownloadableSubscriptionMetadata(
+ slotId, subscription, forceDeactivateSim);
+ }
try {
callback.onComplete(result);
} catch (RemoteException e) {
diff --git a/telephony/java/android/service/euicc/IEuiccService.aidl b/telephony/java/android/service/euicc/IEuiccService.aidl
index 6b0397d..f8d5ae9 100644
--- a/telephony/java/android/service/euicc/IEuiccService.aidl
+++ b/telephony/java/android/service/euicc/IEuiccService.aidl
@@ -38,8 +38,10 @@
void downloadSubscription(int slotId, int portIndex, in DownloadableSubscription subscription,
boolean switchAfterDownload, boolean forceDeactivateSim, in Bundle resolvedBundle,
in IDownloadSubscriptionCallback callback);
- void getDownloadableSubscriptionMetadata(int slotId, in DownloadableSubscription subscription,
- boolean forceDeactivateSim, in IGetDownloadableSubscriptionMetadataCallback callback);
+ void getDownloadableSubscriptionMetadata(
+ int slotId, int portIndex, in DownloadableSubscription subscription,
+ boolean switchAfterDownload, boolean forceDeactivateSim,
+ in IGetDownloadableSubscriptionMetadataCallback callback);
void getEid(int slotId, in IGetEidCallback callback);
void getOtaStatus(int slotId, in IGetOtaStatusCallback callback);
void startOtaIfNecessary(int slotId, in IOtaStatusChangedCallback statusChangedCallback);
diff --git a/telephony/java/android/telephony/emergency/EmergencyNumber.java b/telephony/java/android/telephony/emergency/EmergencyNumber.java
index e78a1e1..64bcf71 100644
--- a/telephony/java/android/telephony/emergency/EmergencyNumber.java
+++ b/telephony/java/android/telephony/emergency/EmergencyNumber.java
@@ -25,6 +25,8 @@
import android.os.Parcelable;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneNumberUtils;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
import com.android.telephony.Rlog;
@@ -247,6 +249,17 @@
private final List<String> mEmergencyUrns;
private final int mEmergencyNumberSourceBitmask;
private final int mEmergencyCallRouting;
+ /**
+ * The source of the EmergencyNumber in the order of precedence.
+ */
+ private static final int[] EMERGENCY_NUMBER_SOURCE_PRECEDENCE;
+ static {
+ EMERGENCY_NUMBER_SOURCE_PRECEDENCE = new int[4];
+ EMERGENCY_NUMBER_SOURCE_PRECEDENCE[0] = EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING;
+ EMERGENCY_NUMBER_SOURCE_PRECEDENCE[1] = EMERGENCY_NUMBER_SOURCE_SIM;
+ EMERGENCY_NUMBER_SOURCE_PRECEDENCE[2] = EMERGENCY_NUMBER_SOURCE_DATABASE;
+ EMERGENCY_NUMBER_SOURCE_PRECEDENCE[3] = EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG;
+ }
/** @hide */
public EmergencyNumber(@NonNull String number, @NonNull String countryIso, @NonNull String mnc,
@@ -601,19 +614,44 @@
*/
public static void mergeSameNumbersInEmergencyNumberList(
List<EmergencyNumber> emergencyNumberList) {
+ mergeSameNumbersInEmergencyNumberList(emergencyNumberList, false);
+ }
+
+ /**
+ * In-place merge same emergency numbers in the emergency number list.
+ *
+ * A unique EmergencyNumber has a unique combination of ‘number’, ‘mcc’ and 'mnc' fields.
+ * If mergeServiceCategoriesAndUrns is true ignore comparing of 'urns' and
+ * 'categories' fields and determine these fields from most precedent number. Else compare
+ * to get unique combination of EmergencyNumber.
+ * Multiple Emergency Number Sources should be merged into one bitfield for the
+ * same EmergencyNumber.
+ *
+ * @param emergencyNumberList the emergency number list to process
+ * @param mergeServiceCategoriesAndUrns {@code true} determine service category and urns
+ * from most precedent number. {@code false} compare those fields for determing duplicate.
+ *
+ * @hide
+ */
+ public static void mergeSameNumbersInEmergencyNumberList(
+ @NonNull List<EmergencyNumber> emergencyNumberList,
+ boolean mergeServiceCategoriesAndUrns) {
if (emergencyNumberList == null) {
return;
}
+
Set<Integer> duplicatedEmergencyNumberPosition = new HashSet<>();
for (int i = 0; i < emergencyNumberList.size(); i++) {
for (int j = 0; j < i; j++) {
- if (areSameEmergencyNumbers(
- emergencyNumberList.get(i), emergencyNumberList.get(j))) {
- Rlog.e(LOG_TAG, "Found unexpected duplicate numbers: "
- + emergencyNumberList.get(i) + " vs " + emergencyNumberList.get(j));
+ if (areSameEmergencyNumbers(emergencyNumberList.get(i),
+ emergencyNumberList.get(j), mergeServiceCategoriesAndUrns)) {
+ Rlog.e(LOG_TAG, "Found unexpected duplicate numbers "
+ + emergencyNumberList.get(i)
+ + " vs " + emergencyNumberList.get(j));
// Set the merged emergency number in the current position
- emergencyNumberList.set(i, mergeSameEmergencyNumbers(
- emergencyNumberList.get(i), emergencyNumberList.get(j)));
+ emergencyNumberList.set(i,
+ mergeSameEmergencyNumbers(emergencyNumberList.get(i),
+ emergencyNumberList.get(j), mergeServiceCategoriesAndUrns));
// Mark the emergency number has been merged
duplicatedEmergencyNumberPosition.add(j);
}
@@ -632,18 +670,24 @@
/**
* Check if two emergency numbers are the same.
*
- * A unique EmergencyNumber has a unique combination of ‘number’, ‘mcc’, 'mnc' and
- * 'categories', and 'routing' fields. Multiple Emergency Number Sources should be
+ * A unique EmergencyNumber has a unique combination of ‘number’, ‘mcc’, 'mnc' fields.
+ * If mergeServiceCategoriesAndUrns is true ignore comparing of 'urns' and
+ * 'categories' fields and determine these fields from most precedent number. Else compare
+ * to get unique combination of EmergencyNumber.
+ * Multiple Emergency Number Sources should be
* merged into one bitfield for the same EmergencyNumber.
*
* @param first first EmergencyNumber to compare
* @param second second EmergencyNumber to compare
+ * @param ignoreServiceCategoryAndUrns {@code true} Ignore comparing of service category
+ * and Urns so that they can be determined from most precedent number. {@code false} compare
+ * those fields for determing duplicate.
* @return true if they are the same EmergencyNumbers; false otherwise.
*
* @hide
*/
public static boolean areSameEmergencyNumbers(@NonNull EmergencyNumber first,
- @NonNull EmergencyNumber second) {
+ @NonNull EmergencyNumber second, boolean ignoreServiceCategoryAndUrns) {
if (!first.getNumber().equals(second.getNumber())) {
return false;
}
@@ -653,12 +697,14 @@
if (!first.getMnc().equals(second.getMnc())) {
return false;
}
- if (first.getEmergencyServiceCategoryBitmask()
- != second.getEmergencyServiceCategoryBitmask()) {
- return false;
- }
- if (!first.getEmergencyUrns().equals(second.getEmergencyUrns())) {
- return false;
+ if (!ignoreServiceCategoryAndUrns) {
+ if (first.getEmergencyServiceCategoryBitmask()
+ != second.getEmergencyServiceCategoryBitmask()) {
+ return false;
+ }
+ if (!first.getEmergencyUrns().equals(second.getEmergencyUrns())) {
+ return false;
+ }
}
// Never merge two numbers if one of them is from test mode but the other one is not;
// This supports to remove a number from the test mode.
@@ -681,7 +727,7 @@
*/
public static EmergencyNumber mergeSameEmergencyNumbers(@NonNull EmergencyNumber first,
@NonNull EmergencyNumber second) {
- if (areSameEmergencyNumbers(first, second)) {
+ if (areSameEmergencyNumbers(first, second, false)) {
int routing = first.getEmergencyCallRouting();
if (second.isFromSources(EMERGENCY_NUMBER_SOURCE_DATABASE)) {
@@ -699,6 +745,115 @@
}
/**
+ * Get merged EmergencyUrns list from two same emergency numbers.
+ * By giving priority to the urns from first number.
+ *
+ * @param firstEmergencyUrns first number's Urns
+ * @param secondEmergencyUrns second number's Urns
+ * @return a merged Urns
+ *
+ * @hide
+ */
+ private static List<String> mergeEmergencyUrns(@NonNull List<String> firstEmergencyUrns,
+ @NonNull List<String> secondEmergencyUrns) {
+ List<String> mergedUrns = new ArrayList<String>();
+ mergedUrns.addAll(firstEmergencyUrns);
+ for (String urn : secondEmergencyUrns) {
+ if (!firstEmergencyUrns.contains(urn)) {
+ mergedUrns.add(urn);
+ }
+ }
+ return mergedUrns;
+ }
+
+ /**
+ * Get the highest precedence source of the given Emergency number. Then get service catergory
+ * and urns list fill in the respective map with key as source.
+ *
+ * @param num EmergencyNumber to get the source, service category & urns
+ * @param serviceCategoryArray Array to store the category of the given EmergencyNumber
+ * with key as highest precedence source
+ * @param urnsArray Array to store the list of Urns of the given EmergencyNumber
+ * with key as highest precedence source
+ *
+ * @hide
+ */
+ private static void fillServiceCategoryAndUrns(@NonNull EmergencyNumber num,
+ @NonNull SparseIntArray serviceCategoryArray,
+ @NonNull SparseArray<List<String>> urnsArray) {
+ int numberSrc = num.getEmergencyNumberSourceBitmask();
+ for (Integer source : EMERGENCY_NUMBER_SOURCE_PRECEDENCE) {
+ if ((numberSrc & source) == source) {
+ if (!num.isInEmergencyServiceCategories(EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED)) {
+ serviceCategoryArray.put(source, num.getEmergencyServiceCategoryBitmask());
+ }
+ urnsArray.put(source, num.getEmergencyUrns());
+ break;
+ }
+ }
+ }
+
+ /**
+ * Get a merged EmergencyNumber from two same emergency numbers from
+ * Emergency number list. Two emergency numbers are the same if
+ * {@link #areSameEmergencyNumbers} returns {@code true}.
+ *
+ * @param first first EmergencyNumber to compare
+ * @param second second EmergencyNumber to compare
+ * @param mergeServiceCategoriesAndUrns {@code true} then determine service category and urns
+ * Service catetory : set from most precedence source number(N/W, SIM, DB, modem_cfg)
+ * Urns : merge from both with first priority from most precedence source number
+ * {@code false} then call {@link #mergeSameEmergencyNumbers} to merge.
+ * @return a merged EmergencyNumber or null if they are not the same EmergencyNumber
+ *
+ * @hide
+ */
+ public static @NonNull EmergencyNumber mergeSameEmergencyNumbers(
+ @NonNull EmergencyNumber first, @NonNull EmergencyNumber second,
+ boolean mergeServiceCategoriesAndUrns) {
+ if (!mergeServiceCategoriesAndUrns) {
+ return mergeSameEmergencyNumbers(first, second);
+ }
+
+ int routing = first.getEmergencyCallRouting();
+ int serviceCategory = first.getEmergencyServiceCategoryBitmask();
+ List<String> mergedEmergencyUrns = new ArrayList<String>();
+ //Maps to store the service category and urns of both the first and second emergency number
+ // with key as most precedent source
+ SparseIntArray serviceCategoryArray = new SparseIntArray(2);
+ SparseArray<List<String>> urnsArray = new SparseArray(2);
+
+ fillServiceCategoryAndUrns(first, serviceCategoryArray, urnsArray);
+ fillServiceCategoryAndUrns(second, serviceCategoryArray, urnsArray);
+
+ if (second.isFromSources(EMERGENCY_NUMBER_SOURCE_DATABASE)) {
+ routing = second.getEmergencyCallRouting();
+ }
+
+ // Determine serviceCategory of most precedence number
+ for (int sourceOfCategory : EMERGENCY_NUMBER_SOURCE_PRECEDENCE) {
+ if (serviceCategoryArray.indexOfKey(sourceOfCategory) >= 0) {
+ serviceCategory = serviceCategoryArray.get(sourceOfCategory);
+ break;
+ }
+ }
+
+ // Merge Urns in precedence number
+ for (int sourceOfUrn : EMERGENCY_NUMBER_SOURCE_PRECEDENCE) {
+ if (urnsArray.contains(sourceOfUrn)) {
+ mergedEmergencyUrns = mergeEmergencyUrns(mergedEmergencyUrns,
+ urnsArray.get(sourceOfUrn));
+ }
+ }
+
+ return new EmergencyNumber(first.getNumber(), first.getCountryIso(), first.getMnc(),
+ serviceCategory, mergedEmergencyUrns,
+ first.getEmergencyNumberSourceBitmask()
+ | second.getEmergencyNumberSourceBitmask(),
+ routing);
+ }
+
+ /**
* Validate Emergency Number address that only contains the dialable character
* {@link PhoneNumberUtils#isDialable(char)}
*
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index 1686f38..153a951 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -894,11 +894,12 @@
"android.telephony.ims.feature.extra.IS_UNKNOWN_CALL";
/** @hide */
- @IntDef(flag = true,
- value = {
- AUDIO_HANDLER_ANDROID,
- AUDIO_HANDLER_BASEBAND
- })
+ @IntDef(
+ prefix = "AUDIO_HANDLER_",
+ value = {
+ AUDIO_HANDLER_ANDROID,
+ AUDIO_HANDLER_BASEBAND
+ })
@Retention(RetentionPolicy.SOURCE)
public @interface ImsAudioHandler {}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
index da3c62d..cb530da 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
@@ -16,7 +16,6 @@
package com.android.server.wm.flicker.ime
-import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.view.WindowInsets.Type.ime
import android.view.WindowInsets.Type.navigationBars
@@ -64,16 +63,6 @@
transitions { testApp.dismissDialog(wmHelper) }
}
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
-
/** Checks that [ComponentNameMatcher.IME] layer becomes visible during the transition */
@Presubmit @Test fun imeWindowIsAlwaysVisible() = flicker.imeWindowIsAlwaysVisible()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
index c2526d3..0e732b5 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
@@ -16,7 +16,7 @@
package com.android.server.wm.flicker.ime
-import android.platform.test.annotations.Postsubmit
+import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
@@ -68,25 +68,11 @@
teardown { imeTestApp.exit(wmHelper) }
}
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
-
- @Postsubmit
- @Test
- override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
-
@Presubmit @Test fun imeWindowBecomesVisible() = flicker.imeWindowBecomesVisible()
@Presubmit @Test fun imeLayerBecomesVisible() = flicker.imeLayerBecomesVisible()
- @Postsubmit
+ @FlakyTest(bugId = 240918620)
@Test
fun snapshotStartingWindowLayerCoversExactlyOnApp() {
Assume.assumeFalse(isShellTransitionsEnabled)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
index a6bbf54..477ddb3 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
@@ -17,7 +17,6 @@
package com.android.server.wm.flicker.ime
import android.platform.test.annotations.FlakyTest
-import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
@@ -92,52 +91,10 @@
wmHelper.StateSyncBuilder().withFullScreenApp(imeTestApp).waitForAndVerify()
}
}
-
/** {@inheritDoc} */
- @Postsubmit
+ @FlakyTest(bugId = 265016201)
@Test
- override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
-
- /** {@inheritDoc} */
- @Postsubmit @Test override fun entireScreenCovered() = super.entireScreenCovered()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun statusBarLayerIsVisibleAtStartAndEnd() =
- super.statusBarLayerIsVisibleAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun statusBarLayerPositionAtStartAndEnd() = super.statusBarLayerPositionAtStartAndEnd()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
- super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
- /** {@inheritDoc} */
- @Postsubmit
- @Test
- override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
- super.visibleWindowsShownMoreThanOneConsecutiveEntry()
+ override fun entireScreenCovered() = super.entireScreenCovered()
@Presubmit
@Test
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTestCfArm.kt
new file mode 100644
index 0000000..e6cdd1e
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTestCfArm.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 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.server.wm.flicker.quickswitch
+
+import com.android.server.wm.flicker.FlickerTest
+import com.android.server.wm.flicker.FlickerTestFactory
+import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
+import com.android.server.wm.traces.common.Rect
+import com.android.server.wm.traces.common.service.PlatformConsts
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class QuickSwitchBetweenTwoAppsBackTestCfArm(flicker: FlickerTest) :
+ QuickSwitchBetweenTwoAppsBackTest(flicker) {
+ companion object {
+ private var startDisplayBounds = Rect.EMPTY
+
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<FlickerTest> {
+ return FlickerTestFactory.nonRotationTests(
+ supportedNavigationModes = listOf(PlatformConsts.NavBar.MODE_GESTURAL)
+ )
+ }
+ }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTestCfArm.kt
new file mode 100644
index 0000000..aa9adf0
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTestCfArm.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 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.server.wm.flicker.quickswitch
+
+import com.android.server.wm.flicker.FlickerTest
+import com.android.server.wm.flicker.FlickerTestFactory
+import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
+import com.android.server.wm.traces.common.Rect
+import com.android.server.wm.traces.common.service.PlatformConsts
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class QuickSwitchBetweenTwoAppsForwardTestCfArm(flicker: FlickerTest) :
+ QuickSwitchBetweenTwoAppsForwardTest(flicker) {
+ companion object {
+ private var startDisplayBounds = Rect.EMPTY
+
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<FlickerTest> {
+ return FlickerTestFactory.nonRotationTests(
+ supportedNavigationModes = listOf(PlatformConsts.NavBar.MODE_GESTURAL)
+ )
+ }
+ }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
index df91754..e06a8d6 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
@@ -53,7 +53,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class QuickSwitchFromLauncherTest(flicker: FlickerTest) : BaseTest(flicker) {
+open class QuickSwitchFromLauncherTest(flicker: FlickerTest) : BaseTest(flicker) {
private val testApp = SimpleAppHelper(instrumentation)
/** {@inheritDoc} */
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTestCfArm.kt
new file mode 100644
index 0000000..8b21603
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTestCfArm.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 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.server.wm.flicker.quickswitch
+
+import com.android.server.wm.flicker.FlickerTest
+import com.android.server.wm.flicker.FlickerTestFactory
+import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
+import com.android.server.wm.traces.common.service.PlatformConsts
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class QuickSwitchFromLauncherTestCfArm(flicker: FlickerTest) :
+ QuickSwitchFromLauncherTest(flicker) {
+ companion object {
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<FlickerTest> {
+ return FlickerTestFactory.nonRotationTests(
+ supportedNavigationModes = listOf(PlatformConsts.NavBar.MODE_GESTURAL),
+ // TODO: Test with 90 rotation
+ supportedRotations = listOf(PlatformConsts.Rotation.ROTATION_0)
+ )
+ }
+ }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index 1b23952..8b250c3 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -16,7 +16,6 @@
package com.android.server.wm.flicker.rotation
-import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.IwTest
import android.platform.test.annotations.Presubmit
import androidx.test.filters.RequiresDevice
@@ -121,11 +120,6 @@
rotationLayerAppearsAndVanishesAssertion()
}
- /** {@inheritDoc} */
- @FlakyTest(bugId = 206753786)
- @Test
- override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
-
@Test
@IwTest(focusArea = "framework")
override fun cujCompleted() {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
index c26485b..d76c94d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -16,7 +16,6 @@
package com.android.server.wm.flicker.rotation
-import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.IwTest
import android.platform.test.annotations.Presubmit
import android.view.WindowManager
@@ -201,11 +200,6 @@
flicker.assertEventLog { this.focusDoesNotChange() }
}
- /** {@inheritDoc} */
- @FlakyTest
- @Test
- override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
-
@Test
@IwTest(focusArea = "framework")
override fun cujCompleted() {
@@ -224,6 +218,7 @@
runAndIgnoreAssumptionViolation { appLayerAlwaysVisible() }
runAndIgnoreAssumptionViolation { navBarLayerIsVisibleAtStartAndEnd() }
runAndIgnoreAssumptionViolation { navBarWindowIsAlwaysVisible() }
+ runAndIgnoreAssumptionViolation { navBarLayerPositionAtStartAndEnd() }
runAndIgnoreAssumptionViolation { taskBarLayerIsVisibleAtStartAndEnd() }
runAndIgnoreAssumptionViolation { taskBarWindowIsAlwaysVisible() }
}
diff --git a/tests/Input/Android.bp b/tests/Input/Android.bp
index de9bbb6..83893ba 100644
--- a/tests/Input/Android.bp
+++ b/tests/Input/Android.bp
@@ -18,6 +18,7 @@
static_libs: [
"androidx.test.ext.junit",
"androidx.test.rules",
+ "mockito-target-minus-junit4",
"services.core.unboosted",
"testables",
"truth-prebuilt",
diff --git a/tests/Input/src/com/android/test/input/InputDeviceTest.java b/tests/Input/src/com/android/test/input/InputDeviceTest.java
index 797e818..ddcc811 100644
--- a/tests/Input/src/com/android/test/input/InputDeviceTest.java
+++ b/tests/Input/src/com/android/test/input/InputDeviceTest.java
@@ -69,7 +69,7 @@
}
private void assertInputDeviceParcelUnparcel(KeyCharacterMap keyCharacterMap) {
- final InputDevice device = new InputDevice.Builder()
+ final InputDevice.Builder deviceBuilder = new InputDevice.Builder()
.setId(DEVICE_ID)
.setGeneration(42)
.setControllerNumber(43)
@@ -88,8 +88,20 @@
.setHasBattery(true)
.setKeyboardLanguageTag("en-US")
.setKeyboardLayoutType("qwerty")
- .setSupportsUsi(true)
- .build();
+ .setSupportsUsi(true);
+
+ for (int i = 0; i < 30; i++) {
+ deviceBuilder.addMotionRange(
+ MotionEvent.AXIS_GENERIC_1,
+ InputDevice.SOURCE_UNKNOWN,
+ i,
+ i + 1,
+ i + 2,
+ i + 3,
+ i + 4);
+ }
+
+ final InputDevice device = deviceBuilder.build();
Parcel parcel = Parcel.obtain();
device.writeToParcel(parcel, 0);
diff --git a/tests/Input/src/com/android/test/input/MotionPredictorTest.kt b/tests/Input/src/com/android/test/input/MotionPredictorTest.kt
new file mode 100644
index 0000000..46aad9f
--- /dev/null
+++ b/tests/Input/src/com/android/test/input/MotionPredictorTest.kt
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2023 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.test.input
+
+import android.content.Context
+import android.content.res.Resources
+import android.os.SystemProperties
+import android.view.InputDevice
+import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_DOWN
+import android.view.MotionEvent.ACTION_MOVE
+import android.view.MotionEvent.PointerCoords
+import android.view.MotionEvent.PointerProperties
+import android.view.MotionPredictor
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.`when`
+
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import java.time.Duration
+
+private fun getStylusMotionEvent(
+ eventTime: Duration,
+ action: Int,
+ x: Float,
+ y: Float,
+ ): MotionEvent{
+ // One-time: send a DOWN event
+ val pointerCount = 1
+ val properties = arrayOfNulls<MotionEvent.PointerProperties>(pointerCount)
+ val coords = arrayOfNulls<MotionEvent.PointerCoords>(pointerCount)
+
+ for (i in 0 until pointerCount) {
+ properties[i] = PointerProperties()
+ properties[i]!!.id = i
+ properties[i]!!.toolType = MotionEvent.TOOL_TYPE_STYLUS
+ coords[i] = PointerCoords()
+ coords[i]!!.x = x
+ coords[i]!!.y = y
+ }
+
+ return MotionEvent.obtain(/*downTime=*/0, eventTime.toMillis(), action, properties.size,
+ properties, coords, /*metaState=*/0, /*buttonState=*/0,
+ /*xPrecision=*/0f, /*yPrecision=*/0f, /*deviceId=*/0, /*edgeFlags=*/0,
+ InputDevice.SOURCE_STYLUS, /*flags=*/0)
+}
+
+private fun getPredictionContext(offset: Duration, enablePrediction: Boolean): Context {
+ val context = mock(Context::class.java)
+ val resources: Resources = mock(Resources::class.java)
+ `when`(context.getResources()).thenReturn(resources)
+ `when`(resources.getInteger(
+ com.android.internal.R.integer.config_motionPredictionOffsetNanos)).thenReturn(
+ offset.toNanos().toInt())
+ `when`(resources.getBoolean(
+ com.android.internal.R.bool.config_enableMotionPrediction)).thenReturn(enablePrediction)
+ return context
+}
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class MotionPredictorTest {
+ private val instrumentation = InstrumentationRegistry.getInstrumentation()
+ val initialPropertyValue = SystemProperties.get("persist.input.enable_motion_prediction")
+
+ @Before
+ fun setUp() {
+ instrumentation.uiAutomation.executeShellCommand(
+ "setprop persist.input.enable_motion_prediction true")
+ }
+
+ @After
+ fun tearDown() {
+ instrumentation.uiAutomation.executeShellCommand(
+ "setprop persist.input.enable_motion_prediction $initialPropertyValue")
+ }
+
+ /**
+ * In a typical usage, app will send the event to the predictor and then call .predict to draw
+ * a prediction. Here, we send 2 events to the predictor and check the returned event.
+ * Input:
+ * t = 0 x = 0 y = 0
+ * t = 1 x = 1 y = 2
+ * Output (expected):
+ * t = 3 x = 3 y = 6
+ *
+ * Historical data is ignored for simplicity.
+ */
+ @Test
+ fun testPredictedCoordinatesAndTime() {
+ val context = getPredictionContext(
+ /*offset=*/Duration.ofMillis(1), /*enablePrediction=*/true)
+ val predictor = MotionPredictor(context)
+ var eventTime = Duration.ofMillis(0)
+ val downEvent = getStylusMotionEvent(eventTime, ACTION_DOWN, /*x=*/0f, /*y=*/0f)
+ // ACTION_DOWN t=0 x=0 y=0
+ predictor.record(downEvent)
+
+ eventTime += Duration.ofMillis(1)
+ val moveEvent = getStylusMotionEvent(eventTime, ACTION_MOVE, /*x=*/1f, /*y=*/2f)
+ // ACTION_MOVE t=1 x=1 y=2
+ predictor.record(moveEvent)
+
+ val predicted = predictor.predict(Duration.ofMillis(2).toNanos())
+ assertEquals(1, predicted.size)
+ val event = predicted[0]
+ assertNotNull(event)
+
+ // Prediction will happen for t=3 (2 + 1, since offset is 1 and present time is 2)
+ assertEquals(3, event.eventTime)
+ assertEquals(3f, event.x, /*delta=*/0.001f)
+ assertEquals(6f, event.y, /*delta=*/0.001f)
+ }
+}
diff --git a/tests/MotionPrediction/Android.bp b/tests/MotionPrediction/Android.bp
new file mode 100644
index 0000000..b9d01da
--- /dev/null
+++ b/tests/MotionPrediction/Android.bp
@@ -0,0 +1,31 @@
+//
+// Copyright (C) 2023 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_app {
+ name: "MotionPrediction",
+ srcs: ["**/*.kt"],
+ platform_apis: true,
+ certificate: "platform",
+}
diff --git a/tests/MotionPrediction/AndroidManifest.xml b/tests/MotionPrediction/AndroidManifest.xml
new file mode 100644
index 0000000..3f8c2f2
--- /dev/null
+++ b/tests/MotionPrediction/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="test.motionprediction">
+
+ <application android:allowBackup="false"
+ android:icon="@mipmap/ic_launcher"
+ android:label="@string/app_name"
+ android:supportsRtl="true"
+ android:theme="@style/AppTheme">
+ <activity android:name=".MainActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/tests/MotionPrediction/OWNERS b/tests/MotionPrediction/OWNERS
new file mode 100644
index 0000000..c88bfe9
--- /dev/null
+++ b/tests/MotionPrediction/OWNERS
@@ -0,0 +1 @@
+include platform/frameworks/base:/INPUT_OWNERS
diff --git a/tests/MotionPrediction/res/layout/activity_main.xml b/tests/MotionPrediction/res/layout/activity_main.xml
new file mode 100644
index 0000000..65dc325
--- /dev/null
+++ b/tests/MotionPrediction/res/layout/activity_main.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ tools:context="test.motionprediction.MainActivity">
+
+ <test.motionprediction.DrawingView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/output" />
+
+</LinearLayout>
diff --git a/tests/MotionPrediction/res/mipmap-hdpi/ic_launcher.png b/tests/MotionPrediction/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
--- /dev/null
+++ b/tests/MotionPrediction/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/tests/MotionPrediction/res/mipmap-mdpi/ic_launcher.png b/tests/MotionPrediction/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
--- /dev/null
+++ b/tests/MotionPrediction/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/tests/MotionPrediction/res/mipmap-xhdpi/ic_launcher.png b/tests/MotionPrediction/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
--- /dev/null
+++ b/tests/MotionPrediction/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/tests/MotionPrediction/res/mipmap-xxhdpi/ic_launcher.png b/tests/MotionPrediction/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
--- /dev/null
+++ b/tests/MotionPrediction/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/tests/MotionPrediction/res/mipmap-xxxhdpi/ic_launcher.png b/tests/MotionPrediction/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..aee44e1
--- /dev/null
+++ b/tests/MotionPrediction/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/tests/MotionPrediction/res/values-w820dp/dimens.xml b/tests/MotionPrediction/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..95669e6
--- /dev/null
+++ b/tests/MotionPrediction/res/values-w820dp/dimens.xml
@@ -0,0 +1,20 @@
+<!-- Copyright (C) 2023 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.
+-->
+<resources>
+ <!-- Example customization of dimensions originally defined in res/values/dimens.xml
+ (such as screen margins) for screens with more than 820dp of available width. This
+ would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
+ <dimen name="activity_horizontal_margin">64dp</dimen>
+</resources>
diff --git a/tests/MotionPrediction/res/values/colors.xml b/tests/MotionPrediction/res/values/colors.xml
new file mode 100644
index 0000000..139eb1d
--- /dev/null
+++ b/tests/MotionPrediction/res/values/colors.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 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.
+-->
+<resources>
+ <color name="colorPrimary">#3F51B5</color>
+ <color name="colorPrimaryDark">#303F9F</color>
+ <color name="colorAccent">#FF4081</color>
+</resources>
diff --git a/tests/MotionPrediction/res/values/dimens.xml b/tests/MotionPrediction/res/values/dimens.xml
new file mode 100644
index 0000000..d26136f
--- /dev/null
+++ b/tests/MotionPrediction/res/values/dimens.xml
@@ -0,0 +1,19 @@
+<!-- Copyright (C) 2023 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.
+-->
+<resources>
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
diff --git a/tests/MotionPrediction/res/values/strings.xml b/tests/MotionPrediction/res/values/strings.xml
new file mode 100644
index 0000000..16a2bdf
--- /dev/null
+++ b/tests/MotionPrediction/res/values/strings.xml
@@ -0,0 +1,17 @@
+<!-- Copyright (C) 2023 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.
+-->
+<resources>
+ <string name="app_name">Motion Prediction</string>
+</resources>
diff --git a/tests/MotionPrediction/res/values/styles.xml b/tests/MotionPrediction/res/values/styles.xml
new file mode 100644
index 0000000..cfb5e3d
--- /dev/null
+++ b/tests/MotionPrediction/res/values/styles.xml
@@ -0,0 +1,23 @@
+<!-- Copyright (C) 2023 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.
+-->
+<resources>
+ <!-- Base application theme. -->
+ <style name="AppTheme" parent="@android:style/Theme.Material.Light.DarkActionBar">
+ <!-- Customize your theme here. -->
+ <item name="android:colorPrimary">@color/colorPrimary</item>
+ <item name="android:colorPrimaryDark">@color/colorPrimaryDark</item>
+ <item name="android:colorAccent">@color/colorAccent</item>
+ </style>
+</resources>
diff --git a/tests/MotionPrediction/src/test/motionprediction/DrawingView.kt b/tests/MotionPrediction/src/test/motionprediction/DrawingView.kt
new file mode 100644
index 0000000..f529bf7
--- /dev/null
+++ b/tests/MotionPrediction/src/test/motionprediction/DrawingView.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2023 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 test.motionprediction
+
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.Paint
+import android.util.AttributeSet
+import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_DOWN
+import android.view.MotionPredictor
+import android.view.View
+
+import java.util.Vector
+
+private fun drawLine(canvas: Canvas, from: MotionEvent, to: MotionEvent, paint: Paint) {
+ canvas.apply {
+ val x0 = from.getX()
+ val y0 = from.getY()
+ val x1 = to.getX()
+ val y1 = to.getY()
+ // TODO: handle historical data
+ drawLine(x0, y0, x1, y1, paint)
+ }
+}
+
+/**
+ * Draw the current stroke and predicted values
+ */
+class DrawingView(context: Context, attrs: AttributeSet) : View(context, attrs) {
+ private val TAG = "DrawingView"
+
+ val events: MutableMap<Int, Vector<MotionEvent>> = mutableMapOf<Int, Vector<MotionEvent>>()
+
+ var isPredictionAvailable = false
+ private val predictor = MotionPredictor(getContext())
+
+ private var predictionPaint = Paint()
+ private var realPaint = Paint()
+
+ init {
+ setBackgroundColor(Color.WHITE)
+ predictionPaint.color = Color.BLACK
+ predictionPaint.setStrokeWidth(5f)
+ realPaint.color = Color.RED
+ realPaint.setStrokeWidth(5f)
+ }
+
+ private fun addEvent(event: MotionEvent) {
+ if (event.getActionMasked() == ACTION_DOWN) {
+ events.remove(event.deviceId)
+ }
+ var vec = events.getOrPut(event.deviceId) { Vector<MotionEvent>() }
+ vec.add(MotionEvent.obtain(event))
+ predictor.record(event)
+ invalidate()
+ }
+
+ public override fun onTouchEvent(event: MotionEvent): Boolean {
+ isPredictionAvailable = predictor.isPredictionAvailable(event.getDeviceId(),
+ event.getSource())
+ addEvent(event)
+ return true
+ }
+
+ public override fun onDraw(canvas: Canvas) {
+ super.onDraw(canvas)
+ if (!isPredictionAvailable) {
+ canvas.apply {
+ drawRect(0f, 0f, 200f, 200f, realPaint)
+ }
+ }
+
+ var eventTime = 0L
+
+ // Draw real events
+ for ((_, vec) in events ) {
+ for (i in 1 until vec.size) {
+ drawLine(canvas, vec[i - 1], vec[i], realPaint)
+ }
+ eventTime = vec.lastElement().eventTime
+ }
+
+ // Draw predictions. Convert to nanos and hardcode to +20ms into the future
+ val predictionList = predictor.predict(eventTime * 1000000 + 20000000)
+ for (prediction in predictionList) {
+ val realEvents = events.get(prediction.deviceId)!!
+ drawLine(canvas, realEvents[realEvents.size - 1], prediction, predictionPaint)
+ }
+ }
+}
diff --git a/tests/MotionPrediction/src/test/motionprediction/MainActivity.kt b/tests/MotionPrediction/src/test/motionprediction/MainActivity.kt
new file mode 100644
index 0000000..cec2c06
--- /dev/null
+++ b/tests/MotionPrediction/src/test/motionprediction/MainActivity.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 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 test.motionprediction
+
+import android.app.Activity
+import android.os.Bundle
+
+class MainActivity : Activity() {
+ val TAG = "MotionPrediction"
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+ }
+}
diff --git a/tests/VectorDrawableTest/Android.bp b/tests/VectorDrawableTest/Android.bp
index 9da7c5f..099d874 100644
--- a/tests/VectorDrawableTest/Android.bp
+++ b/tests/VectorDrawableTest/Android.bp
@@ -26,5 +26,7 @@
android_test {
name: "VectorDrawableTest",
srcs: ["**/*.java"],
+ // certificate set as platform to allow testing of @hidden APIs
+ certificate: "platform",
platform_apis: true,
}
diff --git a/tests/VectorDrawableTest/AndroidManifest.xml b/tests/VectorDrawableTest/AndroidManifest.xml
index 5334dac..163e438 100644
--- a/tests/VectorDrawableTest/AndroidManifest.xml
+++ b/tests/VectorDrawableTest/AndroidManifest.xml
@@ -158,6 +158,15 @@
<category android:name="com.android.test.dynamic.TEST"/>
</intent-filter>
</activity>
+ <activity android:name="LottieDrawableTest"
+ android:label="Lottie test bed"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="com.android.test.dynamic.TEST" />
+ </intent-filter>
+ </activity>
</application>
</manifest>
diff --git a/tests/VectorDrawableTest/res/raw/lottie.json b/tests/VectorDrawableTest/res/raw/lottie.json
new file mode 100644
index 0000000..fea571c
--- /dev/null
+++ b/tests/VectorDrawableTest/res/raw/lottie.json
@@ -0,0 +1,123 @@
+{
+ "v":"4.6.9",
+ "fr":60,
+ "ip":0,
+ "op":200,
+ "w":800,
+ "h":600,
+ "nm":"Loader 1 JSON",
+ "ddd":0,
+
+
+ "layers":[
+ {
+ "ddd":0,
+ "ind":1,
+ "ty":4,
+ "nm":"Custom Path 1",
+ "ao": 0,
+ "ip": 0,
+ "op": 300,
+ "st": 0,
+ "sr": 1,
+ "bm": 0,
+ "ks": {
+ "o": { "a":0, "k":100 },
+ "r": { "a":1, "k": [
+ { "s": [ 0 ], "e": [ 360], "i": { "x":0.5, "y":0.5 }, "o": { "x":0.5, "y":0.5 }, "t": 0 },
+ { "t": 200 }
+ ] },
+ "p": { "a":0, "k":[ 300, 300, 0 ] },
+ "a": { "a":0, "k":[ 100, 100, 0 ] },
+ "s": { "a":1, "k":[
+ { "s": [ 100, 100 ], "e": [ 200, 200 ], "i": { "x":0.5, "y":0.5 }, "o": { "x":0.5, "y":0.5 }, "t": 0 },
+ { "s": [ 200, 200 ], "e": [ 100, 100 ], "i": { "x":0.5, "y":0.5 }, "o": { "x":0.5, "y":0.5 }, "t": 100 },
+ { "t": 200 }
+ ] }
+ },
+
+ "shapes":[
+ {
+ "ty":"gr",
+ "it":[
+ {
+ "ty" : "sh",
+ "nm" : "Path 1",
+ "ks" : {
+ "a" : 1,
+ "k" : [
+ {
+ "s": [ {
+ "i": [ [ 0, 50 ], [ -50, 0 ], [ 0, -50 ], [ 50, 0 ] ],
+ "o": [ [ 0, -50 ], [ 50, 0 ], [ 0, 50 ], [ -50, 0 ] ],
+ "v": [ [ 0, 100 ], [ 100, 0 ], [ 200, 100 ], [ 100, 200 ] ],
+ "c": true
+ } ],
+ "e": [ {
+ "i": [ [ 50, 50 ], [ -50, 0 ], [ -50, -50 ], [ 50, 50 ] ],
+ "o": [ [ 50, -50 ], [ 50, 0 ], [ -50, 50 ], [ -50, 50 ] ],
+ "v": [ [ 0, 100 ], [ 100, 0 ], [ 200, 100 ], [ 100, 200 ] ],
+ "c": true
+ } ],
+ "i": { "x":0.5, "y":0.5 },
+ "o": { "x":0.5, "y":0.5 },
+ "t": 0
+ },
+ {
+ "s": [ {
+ "i": [ [ 50, 50 ], [ -50, 0 ], [ -50, -50 ], [ 50, 50 ] ],
+ "o": [ [ 50, -50 ], [ 50, 0 ], [ -50, 50 ], [ -50, 50 ] ],
+ "v": [ [ 0, 100 ], [ 100, 0 ], [ 200, 100 ], [ 100, 200 ] ],
+ "c": true
+ } ],
+ "e": [ {
+ "i": [ [ 0, 50 ], [ -50, 0 ], [ 0, -50 ], [ 50, 0 ] ],
+ "o": [ [ 0, -50 ], [ 50, 0 ], [ 0, 50 ], [ -50, 0 ] ],
+ "v": [ [ 0, 100 ], [ 100, 0 ], [ 200, 100 ], [ 100, 200 ] ],
+ "c": true
+ } ],
+ "i": { "x":0.5, "y":0.5 },
+ "o": { "x":0.5, "y":0.5 },
+ "t": 100
+ },
+ {
+ "t": 200
+ }
+ ]
+ }
+ },
+
+ {
+ "ty": "st",
+ "nm": "Stroke 1",
+ "lc": 1,
+ "lj": 1,
+ "ml": 4,
+ "w" : { "a": 1, "k": [
+ { "s": [ 30 ], "e": [ 50 ], "i": { "x":0.5, "y":0.5 }, "o": { "x":0.5, "y":0.5 }, "t": 0 },
+ { "s": [ 50 ], "e": [ 30 ], "i": { "x":0.5, "y":0.5 }, "o": { "x":0.5, "y":0.5 }, "t": 100 },
+ { "t": 200 }
+ ] },
+ "o" : { "a": 0, "k": 100 },
+ "c" : { "a": 1, "k": [
+ { "s": [ 0, 1, 0 ], "e": [ 1, 0, 0 ], "i": { "x":0.5, "y":0.5 }, "o": { "x":0.5, "y":0.5 }, "t": 0 },
+ { "s": [ 1, 0, 0 ], "e": [ 0, 1, 0 ], "i": { "x":0.5, "y":0.5 }, "o": { "x":0.5, "y":0.5 }, "t": 100 },
+ { "t": 200 }
+ ] }
+ },
+
+ {
+ "ty":"tr",
+ "p" : { "a":0, "k":[ 0, 0 ] },
+ "a" : { "a":0, "k":[ 0, 0 ] },
+ "s" : { "a":0, "k":[ 100, 100 ] },
+ "r" : { "a":0, "k": 0 },
+ "o" : { "a":0, "k":100 },
+ "nm": "Transform"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/LottieDrawableTest.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/LottieDrawableTest.java
new file mode 100644
index 0000000..05eae7b
--- /dev/null
+++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/LottieDrawableTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 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.test.dynamic;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.LottieDrawable;
+import android.os.Bundle;
+import android.view.View;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Scanner;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class LottieDrawableTest extends Activity {
+ private static final String TAG = "LottieDrawableTest";
+ static final int BACKGROUND = 0xFFF44336;
+
+ class LottieDrawableView extends View {
+ private Rect mLottieBounds;
+
+ private LottieDrawable mLottie;
+
+ LottieDrawableView(Context context, InputStream is) {
+ super(context);
+ Scanner s = new Scanner(is).useDelimiter("\\A");
+ String json = s.hasNext() ? s.next() : "";
+ try {
+ mLottie = LottieDrawable.makeLottieDrawable(json);
+ } catch (IOException e) {
+ throw new RuntimeException(TAG + ": error parsing test Lottie");
+ }
+ mLottie.start();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ canvas.drawColor(BACKGROUND);
+
+ mLottie.setBounds(mLottieBounds);
+ mLottie.draw(canvas);
+ }
+
+ public void setLottieSize(Rect bounds) {
+ mLottieBounds = bounds;
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ InputStream is = getResources().openRawResource(R.raw.lottie);
+
+ LottieDrawableView view = new LottieDrawableView(this, is);
+ view.setLottieSize(new Rect(0, 0, 900, 900));
+ setContentView(view);
+ }
+}
diff --git a/tools/lint/common/src/main/java/com/google/android/lint/Constants.kt b/tools/lint/common/src/main/java/com/google/android/lint/Constants.kt
index 3d5d01c..0ef165f 100644
--- a/tools/lint/common/src/main/java/com/google/android/lint/Constants.kt
+++ b/tools/lint/common/src/main/java/com/google/android/lint/Constants.kt
@@ -35,6 +35,6 @@
Method(CLASS_ACTIVITY_MANAGER_INTERNAL, "enforceCallingPermission")
)
-const val ANNOTATION_PERMISSION_METHOD = "android.content.pm.PermissionMethod"
-const val ANNOTATION_PERMISSION_NAME = "android.content.pm.PermissionName"
+const val ANNOTATION_PERMISSION_METHOD = "android.annotation.PermissionMethod"
+const val ANNOTATION_PERMISSION_NAME = "android.annotation.PermissionName"
const val ANNOTATION_PERMISSION_RESULT = "android.content.pm.PackageManager.PermissionResult"