diff options
1524 files changed, 17787 insertions, 3215 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp index 599e5cfeeacb..7913ad1d09a5 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -15,12 +15,14 @@ aconfig_srcjars = [ ":android.app.usage.flags-aconfig-java{.generated_srcjars}", ":android.content.pm.flags-aconfig-java{.generated_srcjars}", + ":android.nfc.flags-aconfig-java{.generated_srcjars}", ":android.os.flags-aconfig-java{.generated_srcjars}", ":android.os.vibrator.flags-aconfig-java{.generated_srcjars}", ":android.security.flags-aconfig-java{.generated_srcjars}", ":android.view.flags-aconfig-java{.generated_srcjars}", ":camera_platform_flags_core_java_lib{.generated_srcjars}", ":com.android.window.flags.window-aconfig-java{.generated_srcjars}", + ":android.hardware.biometrics.flags-aconfig-java{.generated_srcjars}", ":com.android.hardware.input-aconfig-java{.generated_srcjars}", ":com.android.text.flags-aconfig-java{.generated_srcjars}", ":telecom_flags_core_java_lib{.generated_srcjars}", @@ -31,6 +33,8 @@ aconfig_srcjars = [ ":com.android.media.flags.bettertogether-aconfig-java{.generated_srcjars}", ":sdk_sandbox_flags_lib{.generated_srcjars}", ":android.permission.flags-aconfig-java{.generated_srcjars}", + ":hwui_flags_java_lib{.generated_srcjars}", + ":display_flags_lib{.generated_srcjars}", ] filegroup { @@ -120,6 +124,19 @@ cc_aconfig_library { aconfig_declarations: "com.android.text.flags-aconfig", } +// NFC +aconfig_declarations { + name: "android.nfc.flags-aconfig", + package: "android.nfc", + srcs: ["core/java/android/nfc/*.aconfig"], +} + +java_aconfig_library { + name: "android.nfc.flags-aconfig-java", + aconfig_declarations: "android.nfc.flags-aconfig", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} + // Security aconfig_declarations { name: "android.security.flags-aconfig", @@ -269,3 +286,30 @@ java_aconfig_library { aconfig_declarations: "android.permission.flags-aconfig", defaults: ["framework-minus-apex-aconfig-java-defaults"], } + +// Biometrics +aconfig_declarations { + name: "android.hardware.biometrics.flags-aconfig", + package: "android.hardware.biometrics", + srcs: ["core/java/android/hardware/biometrics/flags.aconfig"], +} + +java_aconfig_library { + name: "android.hardware.biometrics.flags-aconfig-java", + aconfig_declarations: "android.hardware.biometrics.flags-aconfig", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} + +// Graphics +java_aconfig_library { + name: "hwui_flags_java_lib", + aconfig_declarations: "hwui_flags", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} + +// Display +java_aconfig_library { + name: "display_flags_lib", + aconfig_declarations: "display_flags", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} diff --git a/apct-tests/perftests/core/src/android/view/ViewConfigurationPerfTest.java b/apct-tests/perftests/core/src/android/view/ViewConfigurationPerfTest.java new file mode 100644 index 000000000000..7a7250b9e910 --- /dev/null +++ b/apct-tests/perftests/core/src/android/view/ViewConfigurationPerfTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 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 static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; + +import android.content.Context; + +import androidx.benchmark.BenchmarkState; +import androidx.benchmark.junit4.BenchmarkRule; +import androidx.test.filters.SmallTest; + +import org.junit.Rule; +import org.junit.Test; + +@SmallTest +public class ViewConfigurationPerfTest { + @Rule + public final BenchmarkRule mBenchmarkRule = new BenchmarkRule(); + + private final Context mContext = getInstrumentation().getTargetContext(); + + @Test + public void testGet_newViewConfiguration() { + final BenchmarkState state = mBenchmarkRule.getState(); + + while (state.keepRunning()) { + state.pauseTiming(); + // Reset cache so that `ViewConfiguration#get` creates a new instance. + ViewConfiguration.resetCacheForTesting(); + state.resumeTiming(); + + ViewConfiguration.get(mContext); + } + } + + @Test + public void testGet_cachedViewConfiguration() { + final BenchmarkState state = mBenchmarkRule.getState(); + // Do `get` once to make sure there's something cached. + ViewConfiguration.get(mContext); + + while (state.keepRunning()) { + ViewConfiguration.get(mContext); + } + } +} diff --git a/apct-tests/perftests/surfaceflinger/Android.bp b/apct-tests/perftests/surfaceflinger/Android.bp index 0c28bcef469c..21d0d44fdd2f 100644 --- a/apct-tests/perftests/surfaceflinger/Android.bp +++ b/apct-tests/perftests/surfaceflinger/Android.bp @@ -32,6 +32,7 @@ android_test { "apct-perftests-utils", "collector-device-lib", "platform-test-annotations", + "cts-wm-util", ], test_suites: ["device-tests"], data: [":perfetto_artifacts"], diff --git a/apct-tests/perftests/surfaceflinger/AndroidManifest.xml b/apct-tests/perftests/surfaceflinger/AndroidManifest.xml index 26f25863f055..aa55b01cc787 100644 --- a/apct-tests/perftests/surfaceflinger/AndroidManifest.xml +++ b/apct-tests/perftests/surfaceflinger/AndroidManifest.xml @@ -16,9 +16,11 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.perftests.surfaceflinger"> - <!-- permission needed to write perfetto trace and read/write simpleperf report --> + <!-- permission needed to read/write simpleperf report --> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <!-- permission needed to disable tracing --> + <uses-permission android:name="android.permission.HARDWARE_TEST" /> <application android:label="SurfaceFlingerPerfTests"> <uses-library android:name="android.test.runner" /> diff --git a/apct-tests/perftests/surfaceflinger/AndroidTest.xml b/apct-tests/perftests/surfaceflinger/AndroidTest.xml index 58cf58b89782..6dcd86e156d9 100644 --- a/apct-tests/perftests/surfaceflinger/AndroidTest.xml +++ b/apct-tests/perftests/surfaceflinger/AndroidTest.xml @@ -44,17 +44,12 @@ <option name="hidden-api-checks" value="false"/> <!-- Listener related args for collecting the traces and waiting for the device to stabilize. --> - <option name="device-listeners" value="android.device.collectors.ProcLoadListener,android.device.collectors.PerfettoListener,android.device.collectors.SimpleperfListener" /> - - <!-- Guarantee that user defined RunListeners will be running before any of the default listeners defined in this runner. --> - <option name="instrumentation-arg" key="newRunListenerMode" value="true" /> + <option name="device-listeners" value="android.device.collectors.ProcLoadListener,android.device.collectors.SimpleperfListener" /> <option name="instrumentation-arg" key="profiling-iterations" value="525" /> - <!-- PerfettoListener related arguments --> - <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true" /> - <option name="instrumentation-arg" key="perfetto_config_file" value="trace_config.textproto" /> <!-- SimpleperfListener related arguments --> + <option name="instrumentation-arg" key="record" value="false"/> <option name="instrumentation-arg" key="report" value="true" /> <option name="instrumentation-arg" key="arguments" value="-g" /> <option name="instrumentation-arg" key="events_to_record" value="instructions,cpu-cycles,raw-l3d-cache-refill,sched:sched_waking" /> @@ -70,13 +65,11 @@ <option name="instrumentation-arg" key="proc-loadavg-threshold" value="3" /> <option name="instrumentation-arg" key="proc-loadavg-timeout" value="120000" /> <option name="instrumentation-arg" key="proc-loadavg-interval" value="10000" /> - </test> <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector"> <option name="directory-keys" value="/data/local/tmp/SurfaceFlingerPerfTests" /> <!-- Needed for pulling the collected trace config on to the host --> - <option name="pull-pattern-keys" value="perfetto_file_path" /> <option name="pull-pattern-keys" value="simpleperf_file_path" /> </metrics_collector> diff --git a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/BufferFlinger.java b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/BufferFlinger.java index 8a447bb801f2..8d6dd127645f 100644 --- a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/BufferFlinger.java +++ b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/BufferFlinger.java @@ -16,6 +16,10 @@ package android.surfaceflinger; +import static android.view.SurfaceControl.BUFFER_TRANSFORM_IDENTITY; +import static android.view.SurfaceControl.BUFFER_TRANSFORM_ROTATE_270; +import static android.view.SurfaceControl.BUFFER_TRANSFORM_ROTATE_90; + import android.annotation.ColorInt; import android.graphics.Canvas; import android.graphics.GraphicBuffer; @@ -33,9 +37,11 @@ import java.util.concurrent.ArrayBlockingQueue; * @hide */ public class BufferFlinger { + private final int mTransformHint; ArrayBlockingQueue<GraphicBuffer> mBufferQ; - public BufferFlinger(int numOfBuffers, @ColorInt int color) { + public BufferFlinger(int numOfBuffers, @ColorInt int color, int bufferTransformHint) { + mTransformHint = bufferTransformHint; mBufferQ = new ArrayBlockingQueue<>(numOfBuffers); while (numOfBuffers > 0) { @@ -56,12 +62,18 @@ public class BufferFlinger { public void addBuffer(SurfaceControl.Transaction t, SurfaceControl surfaceControl) { try { final GraphicBuffer buffer = mBufferQ.take(); - t.setBuffer(surfaceControl, + int transform = BUFFER_TRANSFORM_IDENTITY; + if (mTransformHint == BUFFER_TRANSFORM_ROTATE_90) { + transform = BUFFER_TRANSFORM_ROTATE_270; + } else if (mTransformHint == BUFFER_TRANSFORM_ROTATE_270) { + transform = BUFFER_TRANSFORM_ROTATE_90; + } + t.setBufferTransform(surfaceControl, transform); + t.setBuffer( + surfaceControl, HardwareBuffer.createFromGraphicBuffer(buffer), null, - (SyncFence fence) -> { - releaseCallback(fence, buffer); - }); + (SyncFence fence) -> releaseCallback(fence, buffer)); } catch (InterruptedException ignore) { } } diff --git a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java index dca818ec9708..fd9d99181fbf 100644 --- a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java +++ b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java @@ -16,6 +16,9 @@ package android.surfaceflinger; +import static android.server.wm.CtsWindowInfoUtils.waitForWindowOnTop; + +import android.app.Instrumentation; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; @@ -25,12 +28,13 @@ import android.view.SurfaceControl; import android.view.SurfaceHolder; import android.view.SurfaceView; - import androidx.test.ext.junit.rules.ActivityScenarioRule; import androidx.test.filters.LargeTest; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; +import com.android.helpers.SimpleperfHelper; + import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; @@ -39,6 +43,8 @@ import org.junit.Test; import org.junit.rules.RuleChain; import org.junit.runner.RunWith; +import java.io.IOException; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Random; @@ -63,12 +69,33 @@ public class SurfaceFlingerPerfTest { public final RuleChain mAllRules = RuleChain .outerRule(mActivityRule); + private int mTransformHint; + private SimpleperfHelper mSimpleperfHelper = new SimpleperfHelper(); + + /** Start simpleperf sampling. */ + public void startSimpleperf(String subcommand, String arguments) { + if (!mSimpleperfHelper.startCollecting(subcommand, arguments)) { + Log.e(TAG, "Simpleperf did not start successfully."); + } + } + + /** Stop simpleperf sampling and dump the collected file into the given path. */ + private void stopSimpleperf(Path path) { + if (!mSimpleperfHelper.stopCollecting(path.toString())) { + Log.e(TAG, "Failed to collect the simpleperf output."); + } + } + @BeforeClass public static void suiteSetup() { final Bundle arguments = InstrumentationRegistry.getArguments(); sProfilingIterations = Integer.parseInt( arguments.getString(ARGUMENT_PROFILING_ITERATIONS, DEFAULT_PROFILING_ITERATIONS)); Log.d(TAG, "suiteSetup: mProfilingIterations = " + sProfilingIterations); + // disable transaction tracing + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .executeShellCommand("service call SurfaceFlinger 1041 i32 -1"); } @Before @@ -77,17 +104,45 @@ public class SurfaceFlingerPerfTest { SurfaceControl.Transaction t = new SurfaceControl.Transaction(); for (int i = 0; i < MAX_BUFFERS; i++) { SurfaceControl sc = createSurfaceControl(); - BufferFlinger bufferTracker = createBufferTracker(Color.argb(getRandomColorComponent(), - getRandomColorComponent(), getRandomColorComponent(), - getRandomColorComponent())); + BufferFlinger bufferTracker = + createBufferTracker( + Color.argb( + getRandomColorComponent(), + getRandomColorComponent(), + getRandomColorComponent(), + getRandomColorComponent()), + mActivity.getBufferTransformHint()); bufferTracker.addBuffer(t, sc); t.setPosition(sc, i * 10, i * 10); } t.apply(true); + mBufferTrackers.get(0).addBuffer(mTransaction, mSurfaceControls.get(0)); + mTransaction.show(mSurfaceControls.get(0)).apply(true); + Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + + instrumentation.waitForIdleSync(); + // Wait for device animation that shows above the activity to leave. + try { + waitForWindowOnTop(mActivity.getWindow()); + } catch (InterruptedException e) { + Log.e(TAG, "Failed to wait for window", e); + } + String args = + "-o /data/local/tmp/perf.data -g -e" + + " instructions,cpu-cycles,raw-l3d-cache-refill,sched:sched_waking -p " + + mSimpleperfHelper.getPID("surfaceflinger") + + "," + + mSimpleperfHelper.getPID("android.perftests.surfaceflinger"); + startSimpleperf("record", args); } @After public void teardown() { + try { + mSimpleperfHelper.stopSimpleperf(); + } catch (IOException e) { + Log.e(TAG, "Failed to stop simpleperf", e); + } mSurfaceControls.forEach(SurfaceControl::release); mBufferTrackers.forEach(BufferFlinger::freeBuffers); } @@ -97,8 +152,9 @@ public class SurfaceFlingerPerfTest { } private final ArrayList<BufferFlinger> mBufferTrackers = new ArrayList<>(); - private BufferFlinger createBufferTracker(int color) { - BufferFlinger bufferTracker = new BufferFlinger(BUFFER_COUNT, color); + + private BufferFlinger createBufferTracker(int color, int bufferTransformHint) { + BufferFlinger bufferTracker = new BufferFlinger(BUFFER_COUNT, color, bufferTransformHint); mBufferTrackers.add(bufferTracker); return bufferTracker; } diff --git a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java index bb956596c7eb..5f1f44d826e5 100644 --- a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java +++ b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java @@ -16,12 +16,15 @@ package android.surfaceflinger; +import static android.view.Surface.FRAME_RATE_COMPATIBILITY_DEFAULT; + import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.view.SurfaceControl; import android.view.SurfaceHolder; import android.view.SurfaceView; +import android.view.View; import android.view.Window; import android.view.WindowManager; @@ -42,6 +45,11 @@ public class SurfaceFlingerTestActivity extends Activity { requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); + View decorView = getWindow().getDecorView(); + // Hide both the navigation bar and the status bar. + int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN; + decorView.setSystemUiVisibility(uiOptions); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); mTestSurfaceView = new TestSurfaceView(this); setContentView(mTestSurfaceView); @@ -51,6 +59,10 @@ public class SurfaceFlingerTestActivity extends Activity { return mTestSurfaceView.getChildSurfaceControlHelper(); } + public int getBufferTransformHint() { + return mTestSurfaceView.getRootSurfaceControl().getBufferTransformHint(); + } + public class TestSurfaceView extends SurfaceView { public TestSurfaceView(Context context) { super(context); @@ -79,6 +91,9 @@ public class SurfaceFlingerTestActivity extends Activity { // check to see if surface is valid if (holder.getSurface().isValid()) { mSurfaceControl = getSurfaceControl(); + new SurfaceControl.Transaction() + .setFrameRate(mSurfaceControl, 1000, FRAME_RATE_COMPATIBILITY_DEFAULT) + .apply(true); } return new SurfaceControl.Builder() .setName("ChildSurfaceControl") diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java index e7ea7c2dbcbe..a143d6fd4250 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java @@ -1762,8 +1762,16 @@ public class JobSchedulerService extends com.android.server.SystemService sEnqueuedJwiHighWaterMarkLogger.logSampleWithUid(uId, jobStatus.getWorkCount()); } - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED, - uId, null, jobStatus.getBatteryName(), + final int sourceUid = uId; + FrameworkStatsLog.write(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED, + jobStatus.isProxyJob() + ? new int[]{sourceUid, jobStatus.getUid()} : new int[]{sourceUid}, + // Given that the source tag is set by the calling app, it should be connected + // to the calling app in the attribution for a proxied job. + jobStatus.isProxyJob() + ? new String[]{null, jobStatus.getSourceTag()} + : new String[]{jobStatus.getSourceTag()}, + jobStatus.getBatteryName(), FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__SCHEDULED, JobProtoEnums.INTERNAL_STOP_REASON_UNKNOWN, jobStatus.getStandbyBucket(), jobStatus.getLoggingJobId(), @@ -2191,8 +2199,16 @@ public class JobSchedulerService extends com.android.server.SystemService cancelled, reason, internalReasonCode, debugReason); // If the job was running, the JobServiceContext should log with state FINISHED. if (!wasRunning) { - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED, - cancelled.getSourceUid(), null, cancelled.getBatteryName(), + final int sourceUid = cancelled.getSourceUid(); + FrameworkStatsLog.write(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED, + cancelled.isProxyJob() + ? new int[]{sourceUid, cancelled.getUid()} : new int[]{sourceUid}, + // Given that the source tag is set by the calling app, it should be connected + // to the calling app in the attribution for a proxied job. + cancelled.isProxyJob() + ? new String[]{null, cancelled.getSourceTag()} + : new String[]{cancelled.getSourceTag()}, + cancelled.getBatteryName(), FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__CANCELLED, internalReasonCode, cancelled.getStandbyBucket(), cancelled.getLoggingJobId(), diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java index b737041f838e..43d2ae9e077b 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java @@ -470,8 +470,15 @@ public final class JobServiceContext implements ServiceConnection { return false; } mJobPackageTracker.noteActive(job); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED, - job.getSourceUid(), null, job.getBatteryName(), + final int sourceUid = job.getSourceUid(); + FrameworkStatsLog.write(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED, + job.isProxyJob() ? new int[]{sourceUid, job.getUid()} : new int[]{sourceUid}, + // Given that the source tag is set by the calling app, it should be connected + // to the calling app in the attribution for a proxied job. + job.isProxyJob() + ? new String[]{null, job.getSourceTag()} + : new String[]{job.getSourceTag()}, + job.getBatteryName(), FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__STARTED, JobProtoEnums.INTERNAL_STOP_REASON_UNKNOWN, job.getStandbyBucket(), @@ -1531,8 +1538,16 @@ public final class JobServiceContext implements ServiceConnection { } mJobPackageTracker.noteInactive(completedJob, loggingInternalStopReason, loggingDebugReason); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED, - completedJob.getSourceUid(), null, completedJob.getBatteryName(), + final int sourceUid = completedJob.getSourceUid(); + FrameworkStatsLog.write(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED, + completedJob.isProxyJob() + ? new int[]{sourceUid, completedJob.getUid()} : new int[]{sourceUid}, + // Given that the source tag is set by the calling app, it should be connected + // to the calling app in the attribution for a proxied job. + completedJob.isProxyJob() + ? new String[]{null, completedJob.getSourceTag()} + : new String[]{completedJob.getSourceTag()}, + completedJob.getBatteryName(), FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__FINISHED, loggingInternalStopReason, completedJob.getStandbyBucket(), completedJob.getLoggingJobId(), diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java index e0c766f9c767..458ff35c30ee 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java @@ -255,6 +255,9 @@ public final class JobStatus { final String tag; + /** Whether this job was scheduled by one app on behalf of another. */ + final boolean mIsProxyJob; + private GrantedUriPermissions uriPerms; private boolean prepared; @@ -626,6 +629,9 @@ public final class JobStatus { : bnNamespace + job.getService().flattenToShortString(); this.tag = "*job*/" + this.batteryName + "#" + job.getId(); + final String componentPackage = job.getService().getPackageName(); + mIsProxyJob = !this.sourcePackageName.equals(componentPackage); + this.earliestRunTimeElapsedMillis = earliestRunTimeElapsedMillis; this.latestRunTimeElapsedMillis = latestRunTimeElapsedMillis; this.mOriginalLatestRunTimeElapsedMillis = latestRunTimeElapsedMillis; @@ -1048,6 +1054,11 @@ public final class JobStatus { return mLoggingJobId; } + /** Returns whether this job was scheduled by one app on behalf of another. */ + public boolean isProxyJob() { + return mIsProxyJob; + } + public void printUniqueId(PrintWriter pw) { if (mNamespace != null) { pw.print(mNamespace); @@ -1292,6 +1303,12 @@ public final class JobStatus { return mNamespaceHash; } + /** + * Returns the tag passed by the calling app to describe the source app work. This is primarily + * only valid if {@link #isProxyJob()} returns true, but may be non-null if an app uses + * {@link JobScheduler#scheduleAsPackage(JobInfo, String, int, String)} for itself. + */ + @Nullable public String getSourceTag() { return sourceTag; } @@ -1871,9 +1888,13 @@ public final class JobStatus { mReadyDynamicSatisfied = mDynamicConstraints != 0 && mDynamicConstraints == (satisfiedConstraints & mDynamicConstraints); if (STATS_LOG_ENABLED && (STATSD_CONSTRAINTS_TO_LOG & constraint) != 0) { - FrameworkStatsLog.write_non_chained( + FrameworkStatsLog.write( FrameworkStatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED, - sourceUid, null, getBatteryName(), getProtoConstraint(constraint), + isProxyJob() ? new int[]{sourceUid, getUid()} : new int[]{sourceUid}, + // Given that the source tag is set by the calling app, it should be connected + // to the calling app in the attribution for a proxied job. + isProxyJob() ? new String[]{null, sourceTag} : new String[]{sourceTag}, + getBatteryName(), getProtoConstraint(constraint), state ? FrameworkStatsLog.SCHEDULED_JOB_CONSTRAINT_CHANGED__STATE__SATISFIED : FrameworkStatsLog .SCHEDULED_JOB_CONSTRAINT_CHANGED__STATE__UNSATISFIED); diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java index 9dedf7025143..0d3dc4901d8d 100644 --- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java +++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java @@ -1246,6 +1246,40 @@ public class Bmgr { return "TRANSPORT_IS_NULL"; case BackupManagerMonitor.LOG_EVENT_ID_AGENT_LOGGING_RESULTS: return "AGENT_LOGGING_RESULTS"; + case BackupManagerMonitor.LOG_EVENT_ID_START_SYSTEM_RESTORE: + return "START_SYSTEM_RESTORE"; + case BackupManagerMonitor.LOG_EVENT_ID_START_RESTORE_AT_INSTALL: + return "START_RESTORE_AT_INSTALL"; + case BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_DURING_START_RESTORE: + return "TRANSPORT_ERROR_DURING_START_RESTORE"; + case BackupManagerMonitor.LOG_EVENT_ID_CANNOT_GET_NEXT_PKG_NAME: + return "CANNOT_GET_NEXT_PKG_NAME"; + case BackupManagerMonitor.LOG_EVENT_ID_UNKNOWN_RESTORE_TYPE: + return "UNKNOWN_RESTORE_TYPE"; + case BackupManagerMonitor.LOG_EVENT_ID_KV_RESTORE: + return "KV_RESTORE"; + case BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE: + return "FULL_RESTORE"; + case BackupManagerMonitor.LOG_EVENT_ID_NO_NEXT_RESTORE_TARGET: + return "NO_NEXT_RESTORE_TARGET"; + case BackupManagerMonitor.LOG_EVENT_ID_KV_AGENT_ERROR: + return "KV_AGENT_ERROR"; + case BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_RESTORE_FINISHED: + return "PACKAGE_RESTORE_FINISHED"; + case BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_KV_RESTORE: + return "TRANSPORT_ERROR_KV_RESTORE"; + case BackupManagerMonitor.LOG_EVENT_ID_NO_FEEDER_THREAD: + return "NO_FEEDER_THREAD"; + case BackupManagerMonitor.LOG_EVENT_ID_FULL_AGENT_ERROR: + return "FULL_AGENT_ERROR"; + case BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_FULL_RESTORE: + return "TRANSPORT_ERROR_FULL_RESTORE"; + case BackupManagerMonitor.LOG_EVENT_ID_RESTORE_COMPLETE: + return "RESTORE_COMPLETE"; + case BackupManagerMonitor.LOG_EVENT_ID_START_PACKAGE_RESTORE: + return "START_PACKAGE_RESTORE"; + case BackupManagerMonitor.LOG_EVENT_ID_AGENT_FAILURE: + return "AGENT_FAILURE"; default: return "UNKNOWN_ID"; } diff --git a/core/api/current.txt b/core/api/current.txt index d48685ba6f66..1eb9e97db42b 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -44888,6 +44888,7 @@ package android.telephony { method public int getSubscriptionType(); method public int getUsageSetting(); method public boolean isEmbedded(); + method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public boolean isNtn(); method public boolean isOpportunistic(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SubscriptionInfo> CREATOR; diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 3de774868bb7..9b8d2b496a30 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -554,6 +554,30 @@ package android.provider { } +package android.se.omapi { + + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public class SeFrameworkInitializer { + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @Nullable public static android.se.omapi.SeServiceManager getSeServiceManager(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public static void setSeServiceManager(@NonNull android.se.omapi.SeServiceManager); + } + + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public class SeServiceManager { + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public android.se.omapi.SeServiceManager.ServiceRegisterer getSeManagerServiceRegisterer(); + } + + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public static class SeServiceManager.ServiceNotFoundException extends java.lang.Exception { + ctor @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public SeServiceManager.ServiceNotFoundException(@NonNull String); + } + + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public static final class SeServiceManager.ServiceRegisterer { + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @Nullable public android.os.IBinder get(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public android.os.IBinder getOrThrow() throws android.se.omapi.SeServiceManager.ServiceNotFoundException; + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void register(@NonNull android.os.IBinder); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @Nullable public android.os.IBinder tryGet(); + } + +} + package android.telecom { public abstract class ConnectionService extends android.app.Service { diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 5c48b21ad35e..660859d6e66e 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -9627,6 +9627,73 @@ package android.nfc { } +package android.nfc.cardemulation { + + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public final class AidGroup implements android.os.Parcelable { + ctor @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public AidGroup(@NonNull java.util.List<java.lang.String>, @Nullable String); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @Nullable public static android.nfc.cardemulation.AidGroup createFromXml(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public int describeContents(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void dump(@NonNull android.util.proto.ProtoOutputStream); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public java.util.List<java.lang.String> getAids(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public String getCategory(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void writeAsXml(@NonNull org.xmlpull.v1.XmlSerializer) throws java.io.IOException; + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void writeToParcel(@NonNull android.os.Parcel, int); + field @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public static final android.os.Parcelable.Creator<android.nfc.cardemulation.AidGroup> CREATOR; + } + + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public final class ApduServiceInfo implements android.os.Parcelable { + ctor @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public ApduServiceInfo(@NonNull android.content.pm.PackageManager, @NonNull android.content.pm.ResolveInfo, boolean) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public int describeContents(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void dump(@NonNull android.os.ParcelFileDescriptor, @NonNull java.io.PrintWriter, @NonNull String[]); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void dumpDebug(@NonNull android.util.proto.ProtoOutputStream); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public java.util.List<android.nfc.cardemulation.AidGroup> getAidGroups(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public java.util.List<java.lang.String> getAids(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public String getCategoryForAid(@NonNull String); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public android.content.ComponentName getComponent(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public String getDescription(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public android.nfc.cardemulation.AidGroup getDynamicAidGroupForCategory(@NonNull String); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @Nullable public String getOffHostSecureElement(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public java.util.List<java.lang.String> getPrefixAids(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public String getSettingsActivityName(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public java.util.List<java.lang.String> getSubsetAids(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public int getUid(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public boolean hasCategory(@NonNull String); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public boolean isOnHost(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public CharSequence loadAppLabel(@NonNull android.content.pm.PackageManager); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public android.graphics.drawable.Drawable loadBanner(@NonNull android.content.pm.PackageManager); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public android.graphics.drawable.Drawable loadIcon(@NonNull android.content.pm.PackageManager); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public CharSequence loadLabel(@NonNull android.content.pm.PackageManager); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public boolean removeDynamicAidGroupForCategory(@NonNull String); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public boolean requiresScreenOn(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public boolean requiresUnlock(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void resetOffHostSecureElement(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void setDynamicAidGroup(@NonNull android.nfc.cardemulation.AidGroup); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void setOffHostSecureElement(@NonNull String); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void writeToParcel(@NonNull android.os.Parcel, int); + field @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public static final android.os.Parcelable.Creator<android.nfc.cardemulation.ApduServiceInfo> CREATOR; + } + + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public final class NfcFServiceInfo implements android.os.Parcelable { + ctor @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public NfcFServiceInfo(@NonNull android.content.pm.PackageManager, @NonNull android.content.pm.ResolveInfo) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public int describeContents(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void dump(@NonNull android.os.ParcelFileDescriptor, @NonNull java.io.PrintWriter, @NonNull String[]); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void dumpDebug(@NonNull android.util.proto.ProtoOutputStream); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public android.content.ComponentName getComponent(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public String getDescription(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public String getNfcid2(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public String getSystemCode(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public String getT3tPmm(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public int getUid(); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public android.graphics.drawable.Drawable loadIcon(@NonNull android.content.pm.PackageManager); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public CharSequence loadLabel(@NonNull android.content.pm.PackageManager); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void setDynamicNfcid2(@NonNull String); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void setDynamicSystemCode(@NonNull String); + method @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public void writeToParcel(@NonNull android.os.Parcel, int); + field @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public static final android.os.Parcelable.Creator<android.nfc.cardemulation.NfcFServiceInfo> CREATOR; + } + +} + package android.os { public class BatteryManager { @@ -10635,12 +10702,14 @@ package android.permission { method @BinderThread public abstract void onGetRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.OutputStream, @NonNull Runnable); method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_APP_HIBERNATION) public void onGetUnusedAppCount(@NonNull java.util.function.IntConsumer); method @BinderThread public abstract void onGrantOrUpgradeDefaultRuntimePermissions(@NonNull Runnable); - method @BinderThread public void onOneTimePermissionSessionTimeout(@NonNull String); + method @Deprecated @BinderThread public void onOneTimePermissionSessionTimeout(@NonNull String); + method @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS) @BinderThread public void onOneTimePermissionSessionTimeout(@NonNull String, int); method @Deprecated @BinderThread public void onRestoreDelayedRuntimePermissionsBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @Deprecated @BinderThread public void onRestoreRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream, @NonNull Runnable); method @BinderThread public abstract void onRevokeRuntimePermission(@NonNull String, @NonNull String, @NonNull Runnable); method @BinderThread public abstract void onRevokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull String, @NonNull java.util.function.Consumer<java.util.Map<java.lang.String,java.util.List<java.lang.String>>>); - method @BinderThread public void onRevokeSelfPermissionsOnKill(@NonNull String, @NonNull java.util.List<java.lang.String>, @NonNull Runnable); + method @Deprecated @BinderThread public void onRevokeSelfPermissionsOnKill(@NonNull String, @NonNull java.util.List<java.lang.String>, @NonNull Runnable); + method @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS) @BinderThread public void onRevokeSelfPermissionsOnKill(@NonNull String, @NonNull java.util.List<java.lang.String>, int, @NonNull Runnable); method @Deprecated @BinderThread public abstract void onSetRuntimePermissionGrantStateByDeviceAdmin(@NonNull String, @NonNull String, @NonNull String, int, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @BinderThread public void onSetRuntimePermissionGrantStateByDeviceAdmin(@NonNull String, @NonNull android.permission.AdminPermissionControlParams, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @BinderThread public void onStageAndApplyRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream, @NonNull Runnable); @@ -16706,6 +16775,7 @@ package android.telephony.satellite { field public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED = 3; // 0x3 field public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS = 2; // 0x2 field public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN = -1; // 0xffffffff + field @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_WAITING_TO_CONNECT = 8; // 0x8 field @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) public static final int SATELLITE_MODEM_STATE_CONNECTED = 7; // 0x7 field public static final int SATELLITE_MODEM_STATE_DATAGRAM_RETRYING = 3; // 0x3 field public static final int SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING = 2; // 0x2 diff --git a/core/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt index ee031db50b62..b11a686d8f32 100644 --- a/core/api/system-lint-baseline.txt +++ b/core/api/system-lint-baseline.txt @@ -251,6 +251,18 @@ UnflaggedApi: android.net.wifi.sharedconnectivity.app.NetworkProviderInfo#isBatt New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.isBatteryCharging() UnflaggedApi: android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder#setBatteryCharging(boolean): New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder.setBatteryCharging(boolean) +UnflaggedApi: android.nfc.cardemulation.AidGroup#CONTENTS_FILE_DESCRIPTOR: + New API must be flagged with @FlaggedApi: field android.nfc.cardemulation.AidGroup.CONTENTS_FILE_DESCRIPTOR +UnflaggedApi: android.nfc.cardemulation.AidGroup#PARCELABLE_WRITE_RETURN_VALUE: + New API must be flagged with @FlaggedApi: field android.nfc.cardemulation.AidGroup.PARCELABLE_WRITE_RETURN_VALUE +UnflaggedApi: android.nfc.cardemulation.ApduServiceInfo#CONTENTS_FILE_DESCRIPTOR: + New API must be flagged with @FlaggedApi: field android.nfc.cardemulation.ApduServiceInfo.CONTENTS_FILE_DESCRIPTOR +UnflaggedApi: android.nfc.cardemulation.ApduServiceInfo#PARCELABLE_WRITE_RETURN_VALUE: + New API must be flagged with @FlaggedApi: field android.nfc.cardemulation.ApduServiceInfo.PARCELABLE_WRITE_RETURN_VALUE +UnflaggedApi: android.nfc.cardemulation.NfcFServiceInfo#CONTENTS_FILE_DESCRIPTOR: + New API must be flagged with @FlaggedApi: field android.nfc.cardemulation.NfcFServiceInfo.CONTENTS_FILE_DESCRIPTOR +UnflaggedApi: android.nfc.cardemulation.NfcFServiceInfo#PARCELABLE_WRITE_RETURN_VALUE: + New API must be flagged with @FlaggedApi: field android.nfc.cardemulation.NfcFServiceInfo.PARCELABLE_WRITE_RETURN_VALUE UnflaggedApi: android.os.BugreportParams#BUGREPORT_MODE_ONBOARDING: New API must be flagged with @FlaggedApi: field android.os.BugreportParams.BUGREPORT_MODE_ONBOARDING UnflaggedApi: android.provider.Settings#ACTION_APP_PERMISSIONS_SETTINGS: diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index b4f6d6fe770d..4f4569134c19 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -5192,11 +5192,21 @@ public class ActivityManager { * @hide */ public static void broadcastStickyIntent(Intent intent, int appOp, Bundle options, int userId) { + broadcastStickyIntent(intent, null, appOp, options, userId); + } + + /** + * Convenience for sending a sticky broadcast. For internal use only. + * + * @hide + */ + public static void broadcastStickyIntent(Intent intent, String[] excludedPackages, + int appOp, Bundle options, int userId) { try { getService().broadcastIntentWithFeature( null, null, intent, null, null, Activity.RESULT_OK, null, null, null /*requiredPermissions*/, null /*excludedPermissions*/, - null /*excludedPackages*/, appOp, options, false, true, userId); + excludedPackages, appOp, options, false, true, userId); } catch (RemoteException ex) { } } diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 01912012f04a..25c48e630380 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -36,6 +36,7 @@ import static android.view.Display.INVALID_DISPLAY; import static android.window.ConfigurationHelper.freeTextLayoutCachesIfNeeded; import static android.window.ConfigurationHelper.isDifferentDisplay; import static android.window.ConfigurationHelper.shouldUpdateResources; + import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; import static com.android.internal.os.SafeZipPathValidatorCallback.VALIDATE_ZIP_PATH_FOR_PATH_TRAVERSAL; import static com.android.sdksandbox.flags.Flags.sandboxActivitySdkBasedContext; @@ -166,6 +167,8 @@ import android.provider.Downloads; import android.provider.FontsContract; import android.provider.Settings; import android.renderscript.RenderScriptCacheDir; +import android.se.omapi.SeFrameworkInitializer; +import android.se.omapi.SeServiceManager; import android.security.NetworkSecurityPolicy; import android.security.net.config.NetworkSecurityConfigProvider; import android.system.ErrnoException; @@ -265,6 +268,7 @@ import java.util.Objects; import java.util.TimeZone; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; /** * This manages the execution of the main thread in an @@ -382,6 +386,11 @@ public final class ActivityThread extends ClientTransactionHandler @GuardedBy("mAppThread") private int mLastProcessState = PROCESS_STATE_UNKNOWN; final ArrayList<WeakReference<AssistStructure>> mLastAssistStructures = new ArrayList<>(); + + @NonNull + private final ConfigurationChangedListenerController mConfigurationChangedListenerController = + new ConfigurationChangedListenerController(); + private int mLastSessionId; // Holds the value of the last reported device ID value from the server for the top activity. int mLastReportedDeviceId; @@ -3608,6 +3617,21 @@ public final class ActivityThread extends ClientTransactionHandler return mConfigurationController.getConfiguration(); } + /** + * @hide + */ + public void addConfigurationChangedListener(Executor executor, + Consumer<IBinder> consumer) { + mConfigurationChangedListenerController.addListener(executor, consumer); + } + + /** + * @hide + */ + public void removeConfigurationChangedListener(Consumer<IBinder> consumer) { + mConfigurationChangedListenerController.removeListener(consumer); + } + @Override public void updatePendingConfiguration(Configuration config) { final Configuration updatedConfig = @@ -3663,10 +3687,9 @@ public final class ActivityThread extends ClientTransactionHandler int resultCode, Intent data) { if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id + " req=" + requestCode + " res=" + resultCode + " data=" + data); - ArrayList<ResultInfo> list = new ArrayList<ResultInfo>(); + final ArrayList<ResultInfo> list = new ArrayList<>(); list.add(new ResultInfo(id, requestCode, resultCode, data)); - final ClientTransaction clientTransaction = ClientTransaction.obtain(mAppThread, - activityToken); + final ClientTransaction clientTransaction = ClientTransaction.obtain(mAppThread); clientTransaction.addCallback(ActivityResultItem.obtain(activityToken, list)); try { mAppThread.scheduleTransaction(clientTransaction); @@ -4441,7 +4464,7 @@ public final class ActivityThread extends ClientTransactionHandler } private void schedulePauseWithUserLeavingHint(ActivityClientRecord r) { - final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token); + final ClientTransaction transaction = ClientTransaction.obtain(mAppThread); transaction.setLifecycleStateRequest(PauseActivityItem.obtain(r.token, r.activity.isFinishing(), /* userLeaving */ true, r.activity.mConfigChangeFlags, /* dontReport */ false, /* autoEnteringPip */ false)); @@ -4449,7 +4472,7 @@ public final class ActivityThread extends ClientTransactionHandler } private void scheduleResume(ActivityClientRecord r) { - final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token); + final ClientTransaction transaction = ClientTransaction.obtain(mAppThread); transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(r.token, /* isForward */ false, /* shouldSendCompatFakeFocus */ false)); executeTransaction(transaction); @@ -6041,7 +6064,7 @@ public final class ActivityThread extends ClientTransactionHandler final ActivityLifecycleItem lifecycleRequest = TransactionExecutorHelper.getLifecycleRequestForCurrentState(r); // Schedule the transaction. - final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token); + final ClientTransaction transaction = ClientTransaction.obtain(mAppThread); transaction.addCallback(activityRelaunchItem); transaction.setLifecycleStateRequest(lifecycleRequest); executeTransaction(transaction); @@ -6252,6 +6275,8 @@ public final class ActivityThread extends ClientTransactionHandler " did not call through to super.onConfigurationChanged()"); } } + mConfigurationChangedListenerController + .dispatchOnConfigurationChanged(activity.getActivityToken()); return configToReport; } @@ -8379,8 +8404,8 @@ public final class ActivityThread extends ClientTransactionHandler BinderCallsStats.startForBluetooth(context); }); NfcFrameworkInitializer.setNfcServiceManager(new NfcServiceManager()); - DeviceConfigInitializer.setDeviceConfigServiceManager(new DeviceConfigServiceManager()); + SeFrameworkInitializer.setSeServiceManager(new SeServiceManager()); } private void purgePendingResources() { diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 04d04b9adbdd..e5a73be5023a 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -2943,6 +2943,17 @@ public class ApplicationPackageManager extends PackageManager { return isPackageSuspendedForUser(mContext.getOpPackageName(), getUserId()); } + @Override + public boolean isPackageQuarantined(@NonNull String packageName) throws NameNotFoundException { + try { + return mPM.isPackageQuarantinedForUser(packageName, getUserId()); + } catch (IllegalArgumentException ie) { + throw new NameNotFoundException(packageName); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** @hide */ @Override public void setApplicationCategoryHint(String packageName, int categoryHint) { diff --git a/core/java/android/app/ConfigurationChangedListenerController.java b/core/java/android/app/ConfigurationChangedListenerController.java new file mode 100644 index 000000000000..c644d57fb9a7 --- /dev/null +++ b/core/java/android/app/ConfigurationChangedListenerController.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.app; + +import android.annotation.NonNull; +import android.os.IBinder; + +import com.android.internal.annotations.GuardedBy; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executor; +import java.util.function.Consumer; + +/** + * Manages listeners for unfiltered configuration changes. + * @hide + */ +class ConfigurationChangedListenerController { + + private final Object mLock = new Object(); + + @GuardedBy("mLock") + private final List<ListenerContainer> mListenerContainers = new ArrayList<>(); + + /** + * Adds a listener to receive updates when they are dispatched. This only dispatches updates and + * does not relay the last emitted value. If called with the same listener then this method does + * not have any effect. + * @param executor an executor that is used to dispatch the updates. + * @param consumer a listener interested in receiving updates. + */ + void addListener(@NonNull Executor executor, + @NonNull Consumer<IBinder> consumer) { + synchronized (mLock) { + if (indexOf(consumer) > -1) { + return; + } + mListenerContainers.add(new ListenerContainer(executor, consumer)); + } + } + + /** + * Removes the listener that was previously registered. If the listener was not registered this + * method does not have any effect. + */ + void removeListener(@NonNull Consumer<IBinder> consumer) { + synchronized (mLock) { + final int index = indexOf(consumer); + if (index > -1) { + mListenerContainers.remove(index); + } + } + } + + /** + * Dispatches the update to all registered listeners + * @param activityToken a token for the {@link Activity} that received a configuration update. + */ + void dispatchOnConfigurationChanged(@NonNull IBinder activityToken) { + final List<ListenerContainer> consumers; + synchronized (mLock) { + consumers = new ArrayList<>(mListenerContainers); + } + for (int i = 0; i < consumers.size(); i++) { + consumers.get(i).accept(activityToken); + } + } + + @GuardedBy("mLock") + private int indexOf(Consumer<IBinder> consumer) { + for (int i = 0; i < mListenerContainers.size(); i++) { + if (mListenerContainers.get(i).isMatch(consumer)) { + return i; + } + } + return -1; + } + + private static final class ListenerContainer { + + @NonNull + private final Executor mExecutor; + @NonNull + private final Consumer<IBinder> mConsumer; + + ListenerContainer(@NonNull Executor executor, + @NonNull Consumer<IBinder> consumer) { + mExecutor = executor; + mConsumer = consumer; + } + + public boolean isMatch(@NonNull Consumer<IBinder> consumer) { + return mConsumer.equals(consumer); + } + + public void accept(@NonNull IBinder activityToken) { + mExecutor.execute(() -> mConsumer.accept(activityToken)); + } + + } +} diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index cbbf4e0f9adc..fa52968e4554 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -1647,6 +1647,12 @@ public final class SystemServiceRegistry { case Context.VIRTUALIZATION_SERVICE: case Context.VIRTUAL_DEVICE_SERVICE: return null; + case Context.SEARCH_SERVICE: + // Wear device does not support SEARCH_SERVICE so we do not print WTF here + PackageManager manager = ctx.getPackageManager(); + if (manager != null && manager.hasSystemFeature(PackageManager.FEATURE_WATCH)) { + return null; + } } Slog.wtf(TAG, "Manager wrapper not available: " + name); return null; diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java index 634089b73618..5f8b76508ef3 100644 --- a/core/java/android/app/TaskInfo.java +++ b/core/java/android/app/TaskInfo.java @@ -255,6 +255,12 @@ public class TaskInfo { public boolean isUserFullscreenOverrideEnabled; /** + * Whether the top activity fillsParent() is false + * @hide + */ + public boolean isTopActivityTransparent; + + /** * Hint about the letterbox state of the top activity. * @hide */ @@ -551,7 +557,8 @@ public class TaskInfo { && Objects.equals(mTopActivityLocusId, that.mTopActivityLocusId) && parentTaskId == that.parentTaskId && Objects.equals(topActivity, that.topActivity) - && isUserFullscreenOverrideEnabled == that.isUserFullscreenOverrideEnabled; + && isUserFullscreenOverrideEnabled == that.isUserFullscreenOverrideEnabled + && isTopActivityTransparent == that.isTopActivityTransparent; } /** @@ -583,7 +590,9 @@ public class TaskInfo { == that.configuration.getLayoutDirection()) && (!hasCompatUI() || configuration.uiMode == that.configuration.uiMode) && (!hasCompatUI() || isVisible == that.isVisible) - && isUserFullscreenOverrideEnabled == that.isUserFullscreenOverrideEnabled; + && isFocused == that.isFocused + && isUserFullscreenOverrideEnabled == that.isUserFullscreenOverrideEnabled + && isTopActivityTransparent == that.isTopActivityTransparent; } /** @@ -640,6 +649,7 @@ public class TaskInfo { topActivityLetterboxWidth = source.readInt(); topActivityLetterboxHeight = source.readInt(); isUserFullscreenOverrideEnabled = source.readBoolean(); + isTopActivityTransparent = source.readBoolean(); } /** @@ -697,6 +707,7 @@ public class TaskInfo { dest.writeInt(topActivityLetterboxWidth); dest.writeInt(topActivityLetterboxHeight); dest.writeBoolean(isUserFullscreenOverrideEnabled); + dest.writeBoolean(isTopActivityTransparent); } @Override @@ -744,6 +755,7 @@ public class TaskInfo { + " topActivityLetterboxWidth=" + topActivityLetterboxWidth + " topActivityLetterboxHeight=" + topActivityLetterboxHeight + " isUserFullscreenOverrideEnabled=" + isUserFullscreenOverrideEnabled + + " isTopActivityTransparent=" + isTopActivityTransparent + " locusId=" + mTopActivityLocusId + " displayAreaFeatureId=" + displayAreaFeatureId + " cameraCompatControlState=" diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index c31aa01a6b7c..fce5e4f1fd21 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -2429,11 +2429,8 @@ public class WallpaperManager { } /** - * Reset all wallpaper to the factory default. As opposed to {@link #clear()}, if the device - * is configured to have a live wallpaper by default, apply it. - * - * <p>This method requires the caller to hold the permission - * {@link android.Manifest.permission#SET_WALLPAPER}. + * Equivalent to {@link #clear()}. + * @see #clear() */ @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public void clearWallpaper() { @@ -2767,8 +2764,7 @@ public class WallpaperManager { /** * Remove any currently set system wallpaper, reverting to the system's built-in - * wallpaper. As opposed to {@link #clearWallpaper()}, this method always set a static wallpaper - * with the default image, even if the device is configured to have a live wallpaper by default. + * wallpaper. * On success, the intent {@link Intent#ACTION_WALLPAPER_CHANGED} is broadcast. * * <p>This method requires the caller to hold the permission @@ -2779,6 +2775,10 @@ public class WallpaperManager { */ @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public void clear() throws IOException { + if (isLockscreenLiveWallpaperEnabled()) { + clear(FLAG_SYSTEM | FLAG_LOCK); + return; + } setStream(openDefaultWallpaper(mContext, FLAG_SYSTEM), null, false); } @@ -2787,10 +2787,15 @@ public class WallpaperManager { * display for each one. On success, the intent {@link Intent#ACTION_WALLPAPER_CHANGED} * is broadcast. * <ul> - * <li> If {@link #FLAG_SYSTEM} is set in the {@code which} parameter, put the default - * wallpaper on both home and lock screen, removing any user defined wallpaper. </li> * <li> When called with {@code which=}{@link #FLAG_LOCK}, clear the lockscreen wallpaper. * The home screen wallpaper will become visible on the lock screen. </li> + * + * <li> When called with {@code which=}{@link #FLAG_SYSTEM}, revert the home screen + * wallpaper to default. The lockscreen wallpaper will be unchanged: if the previous + * wallpaper was shared between home and lock screen, it will become lock screen only. </li> + * + * <li> When called with {@code which=}({@link #FLAG_LOCK} | {@link #FLAG_SYSTEM}), put the + * default wallpaper on both home and lock screen, removing any user defined wallpaper.</li> * </ul> * * @param which A bitwise combination of {@link #FLAG_SYSTEM} or @@ -2799,9 +2804,12 @@ public class WallpaperManager { */ @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public void clear(@SetWallpaperFlags int which) throws IOException { + if (isLockscreenLiveWallpaperEnabled()) { + clearWallpaper(which, mContext.getUserId()); + return; + } if ((which & FLAG_SYSTEM) != 0) { clear(); - if (isLockscreenLiveWallpaperEnabled()) return; } if ((which & FLAG_LOCK) != 0) { clearWallpaper(FLAG_LOCK, mContext.getUserId()); diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 213e5cb4ad64..7704486b606c 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -10335,11 +10335,14 @@ public class DevicePolicyManager { * @return the current credential manager policy if null then this policy has not been * configured. */ + @UserHandleAware( + enabledSinceTargetSdkVersion = UPSIDE_DOWN_CAKE, + requiresPermissionIfNotCaller = INTERACT_ACROSS_USERS) public @Nullable PackagePolicy getCredentialManagerPolicy() { throwIfParentInstance("getCredentialManagerPolicy"); if (mService != null) { try { - return mService.getCredentialManagerPolicy(); + return mService.getCredentialManagerPolicy(myUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index c49b820b9e37..58f9d57763fa 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -346,7 +346,7 @@ interface IDevicePolicyManager { boolean hasManagedProfileCallerIdAccess(int userId, String packageName); void setCredentialManagerPolicy(in PackagePolicy policy); - PackagePolicy getCredentialManagerPolicy(); + PackagePolicy getCredentialManagerPolicy(int userId); void setManagedProfileContactsAccessPolicy(in PackagePolicy policy); PackagePolicy getManagedProfileContactsAccessPolicy(); diff --git a/core/java/android/app/backup/BackupManagerMonitor.java b/core/java/android/app/backup/BackupManagerMonitor.java index f73366b6af0c..812bf8e6be6a 100644 --- a/core/java/android/app/backup/BackupManagerMonitor.java +++ b/core/java/android/app/backup/BackupManagerMonitor.java @@ -18,6 +18,7 @@ package android.app.backup; import android.annotation.SystemApi; import android.app.backup.BackupAnnotations.OperationType; +import android.content.pm.PackageInfo; import android.os.Bundle; /** @@ -190,6 +191,56 @@ public class BackupManagerMonitor { public static final int LOG_EVENT_ID_TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED = 51; public static final int LOG_EVENT_ID_AGENT_LOGGING_RESULTS = 52; + /** @hide */ + public static final int LOG_EVENT_ID_START_SYSTEM_RESTORE = 53; + /** @hide */ + public static final int LOG_EVENT_ID_START_RESTORE_AT_INSTALL = 54; + /** A transport error happened during {@link PerformUnifiedRestoreTask#startRestore()} + @hide */ + public static final int LOG_EVENT_ID_TRANSPORT_ERROR_DURING_START_RESTORE = 55; + /** Unable to get the name of the next package in the queue during a restore operation + @hide */ + public static final int LOG_EVENT_ID_CANNOT_GET_NEXT_PKG_NAME = 56; + /** Attempting a restore operation that is neither KV nor full + @hide */ + public static final int LOG_EVENT_ID_UNKNOWN_RESTORE_TYPE = 57; + /** The package is part of KeyValue restore + @hide */ + public static final int LOG_EVENT_ID_KV_RESTORE = 58; + /** The package is part of Full restore + @hide */ + public static final int LOG_EVENT_ID_FULL_RESTORE = 59; + /** Unable to fetch the nest restore target in the queue + @hide */ + public static final int LOG_EVENT_ID_NO_NEXT_RESTORE_TARGET = 60; + /** An error occurred while attempting KeyValueRestore + @hide */ + public static final int LOG_EVENT_ID_KV_AGENT_ERROR = 61; + /** Restore operation finished for the given package + @hide */ + public static final int LOG_EVENT_ID_PACKAGE_RESTORE_FINISHED= 62; + /** A transport error happened during + * {@link PerformUnifiedRestoreTask#initiateOneRestore(PackageInfo, long)} + @hide */ + public static final int LOG_EVENT_ID_TRANSPORT_ERROR_KV_RESTORE = 63; + /** Unable to instantiate the feeder thread in full restore + @hide */ + public static final int LOG_EVENT_ID_NO_FEEDER_THREAD = 64; + /** An error occurred while attempting Full restore + @hide */ + public static final int LOG_EVENT_ID_FULL_AGENT_ERROR = 65; + /** A transport error happened during a full restore + @hide */ + public static final int LOG_EVENT_ID_TRANSPORT_ERROR_FULL_RESTORE = 66; + /** Start restore operation for a given package + @hide */ + public static final int LOG_EVENT_ID_START_PACKAGE_RESTORE = 67; + /** Whole restore operation is complete + @hide */ + public static final int LOG_EVENT_ID_RESTORE_COMPLETE = 68; + /** Agent error during {@link PerformUnifiedRestoreTask#restoreFinished()} + @hide */ + public static final int LOG_EVENT_ID_AGENT_FAILURE = 69; /** * This method will be called each time something important happens on BackupManager. diff --git a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java index c2c54278a84e..dd332c850d5d 100644 --- a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java +++ b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java @@ -41,7 +41,7 @@ public class ActivityConfigurationChangeItem extends ActivityTransactionItem { private Configuration mConfiguration; @Override - public void preExecute(@NonNull ClientTransactionHandler client, @Nullable IBinder token) { + public void preExecute(@NonNull ClientTransactionHandler client) { CompatibilityInfo.applyOverrideScaleIfNeeded(mConfiguration); // Notify the client of an upcoming change in the token configuration. This ensures that // batches of config change items only process the newest configuration. @@ -59,8 +59,7 @@ public class ActivityConfigurationChangeItem extends ActivityTransactionItem { @Nullable @Override - public Context getContextToUpdate(@NonNull ClientTransactionHandler client, - @Nullable IBinder token) { + public Context getContextToUpdate(@NonNull ClientTransactionHandler client) { return client.getActivity(getActivityToken()); } diff --git a/core/java/android/app/servertransaction/ActivityRelaunchItem.java b/core/java/android/app/servertransaction/ActivityRelaunchItem.java index 491d0260f6fb..a5dd115d78b3 100644 --- a/core/java/android/app/servertransaction/ActivityRelaunchItem.java +++ b/core/java/android/app/servertransaction/ActivityRelaunchItem.java @@ -56,7 +56,7 @@ public class ActivityRelaunchItem extends ActivityTransactionItem { private ActivityClientRecord mActivityClientRecord; @Override - public void preExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token) { + public void preExecute(@NonNull ClientTransactionHandler client) { // The local config is already scaled so only apply if this item is from server side. if (!client.isExecutingLocalTransaction()) { CompatibilityInfo.applyOverrideScaleIfNeeded(mConfig); @@ -78,7 +78,7 @@ public class ActivityRelaunchItem extends ActivityTransactionItem { } @Override - public void postExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token, + public void postExecute(@NonNull ClientTransactionHandler client, @NonNull PendingTransactionActions pendingActions) { final ActivityClientRecord r = getActivityClientRecord(client); client.reportRelaunch(r); diff --git a/core/java/android/app/servertransaction/ActivityTransactionItem.java b/core/java/android/app/servertransaction/ActivityTransactionItem.java index 0f8879e1429b..2a65b3528145 100644 --- a/core/java/android/app/servertransaction/ActivityTransactionItem.java +++ b/core/java/android/app/servertransaction/ActivityTransactionItem.java @@ -16,6 +16,8 @@ package android.app.servertransaction; +import static android.app.servertransaction.TransactionExecutorHelper.getActivityName; + import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; import android.annotation.CallSuper; @@ -28,6 +30,7 @@ import android.os.Parcel; import com.android.internal.annotations.VisibleForTesting; +import java.io.PrintWriter; import java.util.Objects; /** @@ -49,14 +52,14 @@ public abstract class ActivityTransactionItem extends ClientTransactionItem { ActivityTransactionItem() {} @Override - public final void execute(@NonNull ClientTransactionHandler client, @NonNull IBinder token, + public final void execute(@NonNull ClientTransactionHandler client, @NonNull PendingTransactionActions pendingActions) { final ActivityClientRecord r = getActivityClientRecord(client); execute(client, r, pendingActions); } /** - * Like {@link #execute(ClientTransactionHandler, IBinder, PendingTransactionActions)}, + * Like {@link #execute(ClientTransactionHandler, PendingTransactionActions)}, * but take non-null {@link ActivityClientRecord} as a parameter. */ @VisibleForTesting(visibility = PACKAGE) @@ -111,6 +114,14 @@ public abstract class ActivityTransactionItem extends ClientTransactionItem { mActivityToken = null; } + @Override + void dump(@NonNull String prefix, @NonNull PrintWriter pw, + @NonNull ClientTransactionHandler transactionHandler) { + super.dump(prefix, pw, transactionHandler); + pw.append(prefix).append("Target activity: ") + .println(getActivityName(mActivityToken, transactionHandler)); + } + // Subclass must override and call super.equals to compare the mActivityToken. @SuppressWarnings("EqualsGetClass") @CallSuper diff --git a/core/java/android/app/servertransaction/BaseClientRequest.java b/core/java/android/app/servertransaction/BaseClientRequest.java index c91e0ca5ffc1..f2751752abd8 100644 --- a/core/java/android/app/servertransaction/BaseClientRequest.java +++ b/core/java/android/app/servertransaction/BaseClientRequest.java @@ -16,8 +16,8 @@ package android.app.servertransaction; +import android.annotation.NonNull; import android.app.ClientTransactionHandler; -import android.os.IBinder; /** * Base interface for individual requests from server to client. @@ -27,31 +27,28 @@ import android.os.IBinder; public interface BaseClientRequest extends ObjectPoolItem { /** - * Prepare the client request before scheduling. + * Prepares the client request before scheduling. * An example of this might be informing about pending updates for some values. * * @param client Target client handler. - * @param token Target activity token. */ - default void preExecute(ClientTransactionHandler client, IBinder token) { + default void preExecute(@NonNull ClientTransactionHandler client) { } /** - * Execute the request. + * Executes the request. * @param client Target client handler. - * @param token Target activity token. * @param pendingActions Container that may have data pending to be used. */ - void execute(ClientTransactionHandler client, IBinder token, - PendingTransactionActions pendingActions); + void execute(@NonNull ClientTransactionHandler client, + @NonNull PendingTransactionActions pendingActions); /** - * Perform all actions that need to happen after execution, e.g. report the result to server. + * Performs all actions that need to happen after execution, e.g. report the result to server. * @param client Target client handler. - * @param token Target activity token. * @param pendingActions Container that may have data pending to be used. */ - default void postExecute(ClientTransactionHandler client, IBinder token, - PendingTransactionActions pendingActions) { + default void postExecute(@NonNull ClientTransactionHandler client, + @NonNull PendingTransactionActions pendingActions) { } } diff --git a/core/java/android/app/servertransaction/ClientTransaction.java b/core/java/android/app/servertransaction/ClientTransaction.java index ee14708c38a8..a5b0f18dad3b 100644 --- a/core/java/android/app/servertransaction/ClientTransaction.java +++ b/core/java/android/app/servertransaction/ClientTransaction.java @@ -16,6 +16,9 @@ package android.app.servertransaction; +import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; + +import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ClientTransactionHandler; import android.app.IApplicationThread; @@ -36,7 +39,7 @@ import java.util.Objects; * A container that holds a sequence of messages, which may be sent to a client. * This includes a list of callbacks and a final lifecycle state. * - * @see com.android.server.am.ClientLifecycleManager + * @see com.android.server.wm.ClientLifecycleManager * @see ClientTransactionItem * @see ActivityLifecycleItem * @hide @@ -56,9 +59,6 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem { /** Target client. */ private IApplicationThread mClient; - /** Target client activity. Might be null if the entire transaction is targeting an app. */ - private IBinder mActivityToken; - /** Get the target client of the transaction. */ public IApplicationThread getClient() { return mClient; @@ -68,7 +68,7 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem { * Add a message to the end of the sequence of callbacks. * @param activityCallback A single message that can contain a lifecycle request/callback. */ - public void addCallback(ClientTransactionItem activityCallback) { + public void addCallback(@NonNull ClientTransactionItem activityCallback) { if (mActivityCallbacks == null) { mActivityCallbacks = new ArrayList<>(); } @@ -87,11 +87,21 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem { @Nullable @UnsupportedAppUsage public IBinder getActivityToken() { - return mActivityToken; + // TODO(b/260873529): remove after we allow multiple activity items in one transaction. + if (mLifecycleStateRequest != null) { + return mLifecycleStateRequest.getActivityToken(); + } + for (int i = mActivityCallbacks.size() - 1; i >= 0; i--) { + final IBinder token = mActivityCallbacks.get(i).getActivityToken(); + if (token != null) { + return token; + } + } + return null; } /** Get the target state lifecycle request. */ - @VisibleForTesting + @VisibleForTesting(visibility = PACKAGE) @UnsupportedAppUsage public ActivityLifecycleItem getLifecycleStateRequest() { return mLifecycleStateRequest; @@ -101,7 +111,7 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem { * Set the lifecycle state in which the client should be after executing the transaction. * @param stateRequest A lifecycle request initialized with right parameters. */ - public void setLifecycleStateRequest(ActivityLifecycleItem stateRequest) { + public void setLifecycleStateRequest(@NonNull ActivityLifecycleItem stateRequest) { mLifecycleStateRequest = stateRequest; } @@ -110,15 +120,15 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem { * @param clientTransactionHandler Handler on the client side that will executed all operations * requested by transaction items. */ - public void preExecute(android.app.ClientTransactionHandler clientTransactionHandler) { + public void preExecute(@NonNull ClientTransactionHandler clientTransactionHandler) { if (mActivityCallbacks != null) { final int size = mActivityCallbacks.size(); for (int i = 0; i < size; ++i) { - mActivityCallbacks.get(i).preExecute(clientTransactionHandler, mActivityToken); + mActivityCallbacks.get(i).preExecute(clientTransactionHandler); } } if (mLifecycleStateRequest != null) { - mLifecycleStateRequest.preExecute(clientTransactionHandler, mActivityToken); + mLifecycleStateRequest.preExecute(clientTransactionHandler); } } @@ -141,14 +151,14 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem { private ClientTransaction() {} - /** Obtain an instance initialized with provided params. */ - public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) { + /** Obtains an instance initialized with provided params. */ + @NonNull + public static ClientTransaction obtain(@Nullable IApplicationThread client) { ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class); if (instance == null) { instance = new ClientTransaction(); } instance.mClient = client; - instance.mActivityToken = activityToken; return instance; } @@ -167,7 +177,6 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem { mLifecycleStateRequest = null; } mClient = null; - mActivityToken = null; ObjectPool.recycle(this); } @@ -175,12 +184,7 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem { /** Write to Parcel. */ @Override - public void writeToParcel(Parcel dest, int flags) { - final boolean writeActivityToken = mActivityToken != null; - dest.writeBoolean(writeActivityToken); - if (writeActivityToken) { - dest.writeStrongBinder(mActivityToken); - } + public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeParcelable(mLifecycleStateRequest, flags); final boolean writeActivityCallbacks = mActivityCallbacks != null; dest.writeBoolean(writeActivityCallbacks); @@ -190,11 +194,7 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem { } /** Read from Parcel. */ - private ClientTransaction(Parcel in) { - final boolean readActivityToken = in.readBoolean(); - if (readActivityToken) { - mActivityToken = in.readStrongBinder(); - } + private ClientTransaction(@NonNull Parcel in) { mLifecycleStateRequest = in.readParcelable(getClass().getClassLoader(), android.app.servertransaction.ActivityLifecycleItem.class); final boolean readActivityCallbacks = in.readBoolean(); if (readActivityCallbacks) { @@ -203,9 +203,8 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem { } } - public static final @android.annotation.NonNull Creator<ClientTransaction> CREATOR = - new Creator<ClientTransaction>() { - public ClientTransaction createFromParcel(Parcel in) { + public static final @NonNull Creator<ClientTransaction> CREATOR = new Creator<>() { + public ClientTransaction createFromParcel(@NonNull Parcel in) { return new ClientTransaction(in); } @@ -230,8 +229,7 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem { final ClientTransaction other = (ClientTransaction) o; return Objects.equals(mActivityCallbacks, other.mActivityCallbacks) && Objects.equals(mLifecycleStateRequest, other.mLifecycleStateRequest) - && mClient == other.mClient - && mActivityToken == other.mActivityToken; + && mClient == other.mClient; } @Override @@ -240,26 +238,32 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem { result = 31 * result + Objects.hashCode(mActivityCallbacks); result = 31 * result + Objects.hashCode(mLifecycleStateRequest); result = 31 * result + Objects.hashCode(mClient); - result = 31 * result + Objects.hashCode(mActivityToken); return result; } /** Dump transaction items callback items and final lifecycle state request. */ - public void dump(String prefix, PrintWriter pw) { + void dump(@NonNull String prefix, @NonNull PrintWriter pw, + @NonNull ClientTransactionHandler transactionHandler) { pw.append(prefix).println("ClientTransaction{"); pw.append(prefix).print(" callbacks=["); + final String itemPrefix = prefix + " "; final int size = mActivityCallbacks != null ? mActivityCallbacks.size() : 0; if (size > 0) { pw.println(); for (int i = 0; i < size; i++) { - pw.append(prefix).append(" ").println(mActivityCallbacks.get(i).toString()); + mActivityCallbacks.get(i).dump(itemPrefix, pw, transactionHandler); } pw.append(prefix).println(" ]"); } else { pw.println("]"); } - pw.append(prefix).append(" stateRequest=").println(mLifecycleStateRequest != null - ? mLifecycleStateRequest.toString() : null); + + pw.append(prefix).println(" stateRequest="); + if (mLifecycleStateRequest != null) { + mLifecycleStateRequest.dump(itemPrefix, pw, transactionHandler); + } else { + pw.append(itemPrefix).println("null"); + } pw.append(prefix).println("}"); } } diff --git a/core/java/android/app/servertransaction/ClientTransactionItem.java b/core/java/android/app/servertransaction/ClientTransactionItem.java index 30fc104a71b7..07e5a7dc5f02 100644 --- a/core/java/android/app/servertransaction/ClientTransactionItem.java +++ b/core/java/android/app/servertransaction/ClientTransactionItem.java @@ -30,6 +30,8 @@ import android.os.Parcelable; import com.android.internal.annotations.VisibleForTesting; +import java.io.PrintWriter; + /** * A callback message to a client that can be scheduled and executed. * Examples of these might be activity configuration change, multi-window mode change, activity @@ -56,8 +58,7 @@ public abstract class ClientTransactionItem implements BaseClientRequest, Parcel * it is updating; otherwise, returns {@code null}. */ @Nullable - public Context getContextToUpdate(@NonNull ClientTransactionHandler client, - @NonNull IBinder token) { + public Context getContextToUpdate(@NonNull ClientTransactionHandler client) { return null; } @@ -71,6 +72,12 @@ public abstract class ClientTransactionItem implements BaseClientRequest, Parcel return null; } + /** Dumps this transaction item. */ + void dump(@NonNull String prefix, @NonNull PrintWriter pw, + @NonNull ClientTransactionHandler transactionHandler) { + pw.append(prefix).println(this); + } + // Parcelable @Override diff --git a/core/java/android/app/servertransaction/ConfigurationChangeItem.java b/core/java/android/app/servertransaction/ConfigurationChangeItem.java index f72e2e04deca..96961aced987 100644 --- a/core/java/android/app/servertransaction/ConfigurationChangeItem.java +++ b/core/java/android/app/servertransaction/ConfigurationChangeItem.java @@ -23,7 +23,6 @@ import android.app.ClientTransactionHandler; import android.content.Context; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; -import android.os.IBinder; import android.os.Parcel; import java.util.Objects; @@ -38,21 +37,20 @@ public class ConfigurationChangeItem extends ClientTransactionItem { private int mDeviceId; @Override - public void preExecute(@NonNull ClientTransactionHandler client, @Nullable IBinder token) { + public void preExecute(@NonNull ClientTransactionHandler client) { CompatibilityInfo.applyOverrideScaleIfNeeded(mConfiguration); client.updatePendingConfiguration(mConfiguration); } @Override - public void execute(@NonNull ClientTransactionHandler client, @Nullable IBinder token, + public void execute(@NonNull ClientTransactionHandler client, @NonNull PendingTransactionActions pendingActions) { client.handleConfigurationChanged(mConfiguration, mDeviceId); } @Nullable @Override - public Context getContextToUpdate(@NonNull ClientTransactionHandler client, - @Nullable IBinder token) { + public Context getContextToUpdate(@NonNull ClientTransactionHandler client) { return ActivityThread.currentApplication(); } diff --git a/core/java/android/app/servertransaction/DestroyActivityItem.java b/core/java/android/app/servertransaction/DestroyActivityItem.java index a327a99435ce..ddb6df10517c 100644 --- a/core/java/android/app/servertransaction/DestroyActivityItem.java +++ b/core/java/android/app/servertransaction/DestroyActivityItem.java @@ -36,7 +36,7 @@ public class DestroyActivityItem extends ActivityLifecycleItem { private int mConfigChanges; @Override - public void preExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token) { + public void preExecute(@NonNull ClientTransactionHandler client) { client.getActivitiesToBeDestroyed().put(getActivityToken(), this); } diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java index 9b37a35cdb8f..a64c744c70ba 100644 --- a/core/java/android/app/servertransaction/LaunchActivityItem.java +++ b/core/java/android/app/servertransaction/LaunchActivityItem.java @@ -84,7 +84,7 @@ public class LaunchActivityItem extends ClientTransactionItem { private IActivityClientController mActivityClientController; @Override - public void preExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token) { + public void preExecute(@NonNull ClientTransactionHandler client) { client.countLaunchingActivities(1); client.updateProcessState(mProcState, false); CompatibilityInfo.applyOverrideScaleIfNeeded(mCurConfig); @@ -96,7 +96,7 @@ public class LaunchActivityItem extends ClientTransactionItem { } @Override - public void execute(@NonNull ClientTransactionHandler client, @NonNull IBinder token, + public void execute(@NonNull ClientTransactionHandler client, @NonNull PendingTransactionActions pendingActions) { Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); ActivityClientRecord r = new ActivityClientRecord(mActivityToken, mIntent, mIdent, mInfo, @@ -109,7 +109,7 @@ public class LaunchActivityItem extends ClientTransactionItem { } @Override - public void postExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token, + public void postExecute(@NonNull ClientTransactionHandler client, @NonNull PendingTransactionActions pendingActions) { client.countLaunchingActivities(-1); } diff --git a/core/java/android/app/servertransaction/MoveToDisplayItem.java b/core/java/android/app/servertransaction/MoveToDisplayItem.java index fb57bed94160..e56d3f862b1b 100644 --- a/core/java/android/app/servertransaction/MoveToDisplayItem.java +++ b/core/java/android/app/servertransaction/MoveToDisplayItem.java @@ -40,7 +40,7 @@ public class MoveToDisplayItem extends ActivityTransactionItem { private Configuration mConfiguration; @Override - public void preExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token) { + public void preExecute(@NonNull ClientTransactionHandler client) { CompatibilityInfo.applyOverrideScaleIfNeeded(mConfiguration); // Notify the client of an upcoming change in the token configuration. This ensures that // batches of config change items only process the newest configuration. diff --git a/core/java/android/app/servertransaction/PauseActivityItem.java b/core/java/android/app/servertransaction/PauseActivityItem.java index a8e6772b4e32..8f1e90b985e6 100644 --- a/core/java/android/app/servertransaction/PauseActivityItem.java +++ b/core/java/android/app/servertransaction/PauseActivityItem.java @@ -56,7 +56,7 @@ public class PauseActivityItem extends ActivityLifecycleItem { } @Override - public void postExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token, + public void postExecute(@NonNull ClientTransactionHandler client, @NonNull PendingTransactionActions pendingActions) { if (mDontReport) { return; diff --git a/core/java/android/app/servertransaction/RefreshCallbackItem.java b/core/java/android/app/servertransaction/RefreshCallbackItem.java index 00128f0d298f..368ed765b922 100644 --- a/core/java/android/app/servertransaction/RefreshCallbackItem.java +++ b/core/java/android/app/servertransaction/RefreshCallbackItem.java @@ -51,7 +51,7 @@ public class RefreshCallbackItem extends ActivityTransactionItem { @NonNull ActivityClientRecord r, @NonNull PendingTransactionActions pendingActions) {} @Override - public void postExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token, + public void postExecute(@NonNull ClientTransactionHandler client, @NonNull PendingTransactionActions pendingActions) { final ActivityClientRecord r = getActivityClientRecord(client); client.reportRefresh(r); diff --git a/core/java/android/app/servertransaction/ResumeActivityItem.java b/core/java/android/app/servertransaction/ResumeActivityItem.java index b11e73cbef96..4a0ea98ccb89 100644 --- a/core/java/android/app/servertransaction/ResumeActivityItem.java +++ b/core/java/android/app/servertransaction/ResumeActivityItem.java @@ -44,7 +44,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem { private boolean mShouldSendCompatFakeFocus; @Override - public void preExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token) { + public void preExecute(@NonNull ClientTransactionHandler client) { if (mUpdateProcState) { client.updateProcessState(mProcState, false); } @@ -60,7 +60,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem { } @Override - public void postExecute(@NonNull ClientTransactionHandler client, IBinder token, + public void postExecute(@NonNull ClientTransactionHandler client, @NonNull PendingTransactionActions pendingActions) { // TODO(lifecycler): Use interface callback instead of actual implementation. ActivityClient.getInstance().activityResumed(getActivityToken(), diff --git a/core/java/android/app/servertransaction/StopActivityItem.java b/core/java/android/app/servertransaction/StopActivityItem.java index f4325670c4fc..b8ce52da5a0c 100644 --- a/core/java/android/app/servertransaction/StopActivityItem.java +++ b/core/java/android/app/servertransaction/StopActivityItem.java @@ -46,7 +46,7 @@ public class StopActivityItem extends ActivityLifecycleItem { } @Override - public void postExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token, + public void postExecute(@NonNull ClientTransactionHandler client, @NonNull PendingTransactionActions pendingActions) { client.reportStop(pendingActions); } diff --git a/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java b/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java index 693599fa229c..23d4505c1c9e 100644 --- a/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java +++ b/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java @@ -43,7 +43,7 @@ public class TopResumedActivityChangeItem extends ActivityTransactionItem { } @Override - public void postExecute(@NonNull ClientTransactionHandler client, @NonNull IBinder token, + public void postExecute(@NonNull ClientTransactionHandler client, @NonNull PendingTransactionActions pendingActions) { if (mOnTop) { return; diff --git a/core/java/android/app/servertransaction/TransactionExecutor.java b/core/java/android/app/servertransaction/TransactionExecutor.java index d080162e4b8c..44336735254d 100644 --- a/core/java/android/app/servertransaction/TransactionExecutor.java +++ b/core/java/android/app/servertransaction/TransactionExecutor.java @@ -74,7 +74,7 @@ public class TransactionExecutor { * Then the client will cycle to the final lifecycle state if provided. Otherwise, it will * either remain in the initial state, or last state needed by a callback. */ - public void execute(ClientTransaction transaction) { + public void execute(@NonNull ClientTransaction transaction) { if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction"); final IBinder token = transaction.getActivityToken(); @@ -109,7 +109,7 @@ public class TransactionExecutor { /** Cycle through all states requested by callbacks and execute them at proper times. */ @VisibleForTesting - public void executeCallbacks(ClientTransaction transaction) { + public void executeCallbacks(@NonNull ClientTransaction transaction) { final List<ClientTransactionItem> callbacks = transaction.getCallbacks(); if (callbacks == null || callbacks.isEmpty()) { // No callbacks to execute, return early. @@ -117,9 +117,6 @@ public class TransactionExecutor { } if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callbacks in transaction"); - final IBinder token = transaction.getActivityToken(); - ActivityClientRecord r = mTransactionHandler.getActivityClient(token); - // In case when post-execution state of the last callback matches the final state requested // for the activity in this transaction, we won't do the last transition here and do it when // moving to final state instead (because it may contain additional parameters from server). @@ -135,6 +132,9 @@ public class TransactionExecutor { final int size = callbacks.size(); for (int i = 0; i < size; ++i) { final ClientTransactionItem item = callbacks.get(i); + final IBinder token = item.getActivityToken(); + ActivityClientRecord r = mTransactionHandler.getActivityClient(token); + if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item); final int postExecutionState = item.getPostExecutionState(); @@ -150,13 +150,13 @@ public class TransactionExecutor { final boolean isSyncWindowConfigUpdateFlagEnabled = !Process.isIsolated() && syncWindowConfigUpdateFlag(); final Context configUpdatedContext = isSyncWindowConfigUpdateFlagEnabled - ? item.getContextToUpdate(mTransactionHandler, token) + ? item.getContextToUpdate(mTransactionHandler) : null; final Configuration preExecutedConfig = configUpdatedContext != null ? new Configuration(configUpdatedContext.getResources().getConfiguration()) : null; - item.execute(mTransactionHandler, token, mPendingActions); + item.execute(mTransactionHandler, mPendingActions); if (configUpdatedContext != null) { final Configuration postExecutedConfig = configUpdatedContext.getResources() @@ -169,7 +169,7 @@ public class TransactionExecutor { } } - item.postExecute(mTransactionHandler, token, mPendingActions); + item.postExecute(mTransactionHandler, mPendingActions); if (r == null) { // Launch activity request will create an activity record. r = mTransactionHandler.getActivityClient(token); @@ -195,14 +195,14 @@ public class TransactionExecutor { } /** Transition to the final state if requested by the transaction. */ - private void executeLifecycleState(ClientTransaction transaction) { + private void executeLifecycleState(@NonNull ClientTransaction transaction) { final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest(); if (lifecycleItem == null) { // No lifecycle request, return early. return; } - final IBinder token = transaction.getActivityToken(); + final IBinder token = lifecycleItem.getActivityToken(); final ActivityClientRecord r = mTransactionHandler.getActivityClient(token); if (DEBUG_RESOLVER) { Slog.d(TAG, tId(transaction) + "Resolving lifecycle state: " @@ -219,8 +219,8 @@ public class TransactionExecutor { cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction); // Execute the final transition with proper parameters. - lifecycleItem.execute(mTransactionHandler, token, mPendingActions); - lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions); + lifecycleItem.execute(mTransactionHandler, mPendingActions); + lifecycleItem.postExecute(mTransactionHandler, mPendingActions); } /** Transition the client between states. */ diff --git a/core/java/android/app/servertransaction/TransactionExecutorHelper.java b/core/java/android/app/servertransaction/TransactionExecutorHelper.java index 0f9c517e2916..7e89a5b45a2d 100644 --- a/core/java/android/app/servertransaction/TransactionExecutorHelper.java +++ b/core/java/android/app/servertransaction/TransactionExecutorHelper.java @@ -26,6 +26,7 @@ import static android.app.servertransaction.ActivityLifecycleItem.ON_STOP; import static android.app.servertransaction.ActivityLifecycleItem.PRE_ON_CREATE; import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED; +import android.annotation.NonNull; import android.app.Activity; import android.app.ActivityThread.ActivityClientRecord; import android.app.ClientTransactionHandler; @@ -266,14 +267,12 @@ public class TransactionExecutorHelper { } /** Dump transaction to string. */ - static String transactionToString(ClientTransaction transaction, - ClientTransactionHandler transactionHandler) { + static String transactionToString(@NonNull ClientTransaction transaction, + @NonNull ClientTransactionHandler transactionHandler) { final StringWriter stringWriter = new StringWriter(); final PrintWriter pw = new PrintWriter(stringWriter); final String prefix = tId(transaction); - transaction.dump(prefix, pw); - pw.append(prefix + "Target activity: ") - .println(getActivityName(transaction.getActivityToken(), transactionHandler)); + transaction.dump(prefix, pw, transactionHandler); return stringWriter.toString(); } diff --git a/core/java/android/app/servertransaction/WindowContextInfoChangeItem.java b/core/java/android/app/servertransaction/WindowContextInfoChangeItem.java index 99824b000b70..375d1bf57174 100644 --- a/core/java/android/app/servertransaction/WindowContextInfoChangeItem.java +++ b/core/java/android/app/servertransaction/WindowContextInfoChangeItem.java @@ -41,15 +41,14 @@ public class WindowContextInfoChangeItem extends ClientTransactionItem { private WindowContextInfo mInfo; @Override - public void execute(@NonNull ClientTransactionHandler client, @NonNull IBinder token, + public void execute(@NonNull ClientTransactionHandler client, @NonNull PendingTransactionActions pendingActions) { client.handleWindowContextInfoChanged(mClientToken, mInfo); } @Nullable @Override - public Context getContextToUpdate(@NonNull ClientTransactionHandler client, - @Nullable IBinder token) { + public Context getContextToUpdate(@NonNull ClientTransactionHandler client) { return client.getWindowContext(mClientToken); } diff --git a/core/java/android/app/servertransaction/WindowContextWindowRemovalItem.java b/core/java/android/app/servertransaction/WindowContextWindowRemovalItem.java index ed52a6496e95..1bea4682928a 100644 --- a/core/java/android/app/servertransaction/WindowContextWindowRemovalItem.java +++ b/core/java/android/app/servertransaction/WindowContextWindowRemovalItem.java @@ -36,7 +36,7 @@ public class WindowContextWindowRemovalItem extends ClientTransactionItem { private IBinder mClientToken; @Override - public void execute(@NonNull ClientTransactionHandler client, @NonNull IBinder token, + public void execute(@NonNull ClientTransactionHandler client, @NonNull PendingTransactionActions pendingActions) { client.handleWindowContextWindowRemoval(mClientToken); } diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java index 3165e292166b..dbaa4c93d71c 100644 --- a/core/java/android/content/pm/LauncherApps.java +++ b/core/java/android/content/pm/LauncherApps.java @@ -75,7 +75,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.infra.AndroidFuture; import com.android.internal.util.function.pooled.PooledLambda; -import java.io.FileNotFoundException; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -1424,8 +1423,8 @@ public class LauncherApps { } try { return mContext.getContentResolver().openFileDescriptor(Uri.parse(uri), "r"); - } catch (FileNotFoundException e) { - Log.e(TAG, "Icon file not found: " + uri); + } catch (Exception e) { + Log.e(TAG, "Failed to open icon file: " + uri, e); return null; } } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 3bd6a099ba2f..3fc515d3d37d 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -9877,6 +9877,18 @@ public abstract class PackageManager { } /** + * Query if an app is currently quarantined. + * + * @return {@code true} if the given package is quarantined, {@code false} otherwise + * @throws NameNotFoundException if the package could not be found. + * + * @hide + */ + public boolean isPackageQuarantined(@NonNull String packageName) throws NameNotFoundException { + throw new UnsupportedOperationException("isPackageQuarantined not implemented"); + } + + /** * Provide a hint of what the {@link ApplicationInfo#category} value should * be for the given package. * <p> diff --git a/core/java/android/hardware/CameraSessionStats.java b/core/java/android/hardware/CameraSessionStats.java index 1c2cbbc81971..b1d6ac4b4cd2 100644 --- a/core/java/android/hardware/CameraSessionStats.java +++ b/core/java/android/hardware/CameraSessionStats.java @@ -64,6 +64,7 @@ public class CameraSessionStats implements Parcelable { private ArrayList<CameraStreamStats> mStreamStats; private String mUserTag; private int mVideoStabilizationMode; + private boolean mUsedUltraWide; private int mSessionIndex; private CameraExtensionSessionStats mCameraExtensionSessionStats; @@ -82,6 +83,7 @@ public class CameraSessionStats implements Parcelable { mDeviceError = false; mStreamStats = new ArrayList<CameraStreamStats>(); mVideoStabilizationMode = -1; + mUsedUltraWide = false; mSessionIndex = 0; mCameraExtensionSessionStats = new CameraExtensionSessionStats(); } @@ -102,6 +104,8 @@ public class CameraSessionStats implements Parcelable { mSessionType = sessionType; mInternalReconfigure = internalReconfigure; mStreamStats = new ArrayList<CameraStreamStats>(); + mVideoStabilizationMode = -1; + mUsedUltraWide = false; mSessionIndex = sessionIdx; mCameraExtensionSessionStats = new CameraExtensionSessionStats(); } @@ -147,6 +151,7 @@ public class CameraSessionStats implements Parcelable { dest.writeTypedList(mStreamStats); dest.writeString(mUserTag); dest.writeInt(mVideoStabilizationMode); + dest.writeBoolean(mUsedUltraWide); dest.writeInt(mSessionIndex); mCameraExtensionSessionStats.writeToParcel(dest, 0); } @@ -173,6 +178,9 @@ public class CameraSessionStats implements Parcelable { mUserTag = in.readString(); mVideoStabilizationMode = in.readInt(); + + mUsedUltraWide = in.readBoolean(); + mSessionIndex = in.readInt(); mCameraExtensionSessionStats = CameraExtensionSessionStats.CREATOR.createFromParcel(in); } @@ -245,6 +253,10 @@ public class CameraSessionStats implements Parcelable { return mVideoStabilizationMode; } + public boolean getUsedUltraWide() { + return mUsedUltraWide; + } + public int getSessionIndex() { return mSessionIndex; } diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java index 257ad7162e9e..5b24fb6860a2 100644 --- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java +++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java @@ -218,7 +218,8 @@ public interface BiometricFingerprintConstants { FINGERPRINT_ACQUIRED_UNKNOWN, FINGERPRINT_ACQUIRED_IMMOBILE, FINGERPRINT_ACQUIRED_TOO_BRIGHT, - FINGERPRINT_ACQUIRED_POWER_PRESSED}) + FINGERPRINT_ACQUIRED_POWER_PRESSED, + FINGERPRINT_ACQUIRED_RE_ENROLL}) @Retention(RetentionPolicy.SOURCE) @interface FingerprintAcquired {} @@ -310,6 +311,12 @@ public interface BiometricFingerprintConstants { int FINGERPRINT_ACQUIRED_POWER_PRESSED = 11; /** + * This message is sent to encourage the user to re-enroll their fingerprints. + * @hide + */ + int FINGERPRINT_ACQUIRED_RE_ENROLL = 12; + + /** * @hide */ int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000; diff --git a/core/java/android/hardware/biometrics/flags.aconfig b/core/java/android/hardware/biometrics/flags.aconfig new file mode 100644 index 000000000000..66429e5046d8 --- /dev/null +++ b/core/java/android/hardware/biometrics/flags.aconfig @@ -0,0 +1,9 @@ +package: "android.hardware.biometrics" + +flag { + name: "add_key_agreement_crypto_object" + namespace: "biometrics" + description: "Feature flag for adding KeyAgreement api to CryptoObject." + bug: "282058146" +} + diff --git a/core/java/android/nfc/cardemulation/AidGroup.java b/core/java/android/nfc/cardemulation/AidGroup.java index 2436e57b74bc..958669ee5852 100644 --- a/core/java/android/nfc/cardemulation/AidGroup.java +++ b/core/java/android/nfc/cardemulation/AidGroup.java @@ -16,7 +16,11 @@ package android.nfc.cardemulation; -import android.compat.annotation.UnsupportedAppUsage; +import android.annotation.FlaggedApi; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.nfc.Flags; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; @@ -29,6 +33,11 @@ import org.xmlpull.v1.XmlSerializer; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Locale; + +/********************************************************************** + * This file is not a part of the NFC mainline module * + * *******************************************************************/ /** * The AidGroup class represents a group of Application Identifiers (AIDs). @@ -39,28 +48,30 @@ import java.util.List; * * @hide */ +@SystemApi +@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public final class AidGroup implements Parcelable { /** * The maximum number of AIDs that can be present in any one group. */ - public static final int MAX_NUM_AIDS = 256; + private static final int MAX_NUM_AIDS = 256; + + private static final String TAG = "AidGroup"; - static final String TAG = "AidGroup"; - @UnsupportedAppUsage - final List<String> aids; - @UnsupportedAppUsage - final String category; - @UnsupportedAppUsage - final String description; + private final List<String> mAids; + private final String mCategory; + @SuppressWarnings("unused") // Unused as of now, but part of the XML input. + private final String mDescription; /** * Creates a new AidGroup object. * - * @param aids The list of AIDs present in the group - * @param category The category of this group, e.g. {@link CardEmulation#CATEGORY_PAYMENT} + * @param aids list of AIDs present in the group + * @param category category of this group, e.g. {@link CardEmulation#CATEGORY_PAYMENT} */ - public AidGroup(List<String> aids, String category) { + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public AidGroup(@NonNull List<String> aids, @Nullable String category) { if (aids == null || aids.size() == 0) { throw new IllegalArgumentException("No AIDS in AID group."); } @@ -73,45 +84,55 @@ public final class AidGroup implements Parcelable { } } if (isValidCategory(category)) { - this.category = category; + this.mCategory = category; } else { - this.category = CardEmulation.CATEGORY_OTHER; + this.mCategory = CardEmulation.CATEGORY_OTHER; } - this.aids = new ArrayList<String>(aids.size()); + this.mAids = new ArrayList<String>(aids.size()); for (String aid : aids) { - this.aids.add(aid.toUpperCase()); + this.mAids.add(aid.toUpperCase(Locale.US)); } - this.description = null; + this.mDescription = null; } - @UnsupportedAppUsage - AidGroup(String category, String description) { - this.aids = new ArrayList<String>(); - this.category = category; - this.description = description; + /** + * Creates a new AidGroup object. + * + * @param category category of this group, e.g. {@link CardEmulation#CATEGORY_PAYMENT} + * @param description description of this group + */ + AidGroup(@NonNull String category, @NonNull String description) { + this.mAids = new ArrayList<String>(); + this.mCategory = category; + this.mDescription = description; } /** + * Returns the category of this group. * @return the category of this AID group */ - @UnsupportedAppUsage + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull public String getCategory() { - return category; + return mCategory; } /** + * Returns the list of AIDs in this group. + * * @return the list of AIDs in this group */ - @UnsupportedAppUsage + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull public List<String> getAids() { - return aids; + return mAids; } @Override public String toString() { - StringBuilder out = new StringBuilder("Category: " + category + - ", AIDs:"); - for (String aid : aids) { + StringBuilder out = new StringBuilder("Category: " + mCategory + + ", AIDs:"); + for (String aid : mAids) { out.append(aid); out.append(", "); } @@ -119,41 +140,44 @@ public final class AidGroup implements Parcelable { } /** - * Dump debugging info as AidGroupProto + * Dump debugging info as AidGroupProto. * * If the output belongs to a sub message, the caller is responsible for wrapping this function * between {@link ProtoOutputStream#start(long)} and {@link ProtoOutputStream#end(long)}. * * @param proto the ProtoOutputStream to write to */ - public void dump(ProtoOutputStream proto) { - proto.write(AidGroupProto.CATEGORY, category); - for (String aid : aids) { + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public void dump(@NonNull ProtoOutputStream proto) { + proto.write(AidGroupProto.CATEGORY, mCategory); + for (String aid : mAids) { proto.write(AidGroupProto.AIDS, aid); } } + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @Override public int describeContents() { return 0; } + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(category); - dest.writeInt(aids.size()); - if (aids.size() > 0) { - dest.writeStringList(aids); + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeString8(mCategory); + dest.writeInt(mAids.size()); + if (mAids.size() > 0) { + dest.writeStringList(mAids); } } - @UnsupportedAppUsage - public static final @android.annotation.NonNull Parcelable.Creator<AidGroup> CREATOR = + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public static final @NonNull Parcelable.Creator<AidGroup> CREATOR = new Parcelable.Creator<AidGroup>() { @Override public AidGroup createFromParcel(Parcel source) { - String category = source.readString(); + String category = source.readString8(); int listSize = source.readInt(); ArrayList<String> aidList = new ArrayList<String>(); if (listSize > 0) { @@ -168,8 +192,17 @@ public final class AidGroup implements Parcelable { } }; - @UnsupportedAppUsage - static public AidGroup createFromXml(XmlPullParser parser) throws XmlPullParserException, IOException { + /** + * Create an instance of AID group from XML file. + * + * @param parser input xml parser stream + * @throws XmlPullParserException If an error occurs parsing the element. + * @throws IOException If an error occurs reading the element. + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @Nullable + public static AidGroup createFromXml(@NonNull XmlPullParser parser) + throws XmlPullParserException, IOException { String category = null; ArrayList<String> aids = new ArrayList<String>(); AidGroup group = null; @@ -210,11 +243,16 @@ public final class AidGroup implements Parcelable { return group; } - @UnsupportedAppUsage - public void writeAsXml(XmlSerializer out) throws IOException { + /** + * Serialize instance of AID group to XML file. + * @param out XML serializer stream + * @throws IOException If an error occurs reading the element. + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public void writeAsXml(@NonNull XmlSerializer out) throws IOException { out.startTag(null, "aid-group"); - out.attribute(null, "category", category); - for (String aid : aids) { + out.attribute(null, "category", mCategory); + for (String aid : mAids) { out.startTag(null, "aid"); out.attribute(null, "value", aid); out.endTag(null, "aid"); @@ -222,7 +260,7 @@ public final class AidGroup implements Parcelable { out.endTag(null, "aid-group"); } - static boolean isValidCategory(String category) { + private static boolean isValidCategory(String category) { return CardEmulation.CATEGORY_PAYMENT.equals(category) || CardEmulation.CATEGORY_OTHER.equals(category); } diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java index 793a70e93f56..18ec914860fb 100644 --- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java +++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java @@ -14,10 +14,16 @@ * limitations under the License. */ +/********************************************************************** + * This file is not a part of the NFC mainline module * + * *******************************************************************/ + package android.nfc.cardemulation; +import android.annotation.FlaggedApi; +import android.annotation.NonNull; import android.annotation.Nullable; -import android.compat.annotation.UnsupportedAppUsage; +import android.annotation.SystemApi; import android.content.ComponentName; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; @@ -28,7 +34,9 @@ import android.content.res.Resources.NotFoundException; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; +import android.nfc.Flags; import android.os.Parcel; +import android.os.ParcelFileDescriptor; import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; @@ -38,7 +46,6 @@ import android.util.proto.ProtoOutputStream; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; @@ -47,82 +54,82 @@ import java.util.List; import java.util.Map; /** + * Class holding APDU service info. + * * @hide */ +@SystemApi +@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public final class ApduServiceInfo implements Parcelable { - static final String TAG = "ApduServiceInfo"; + private static final String TAG = "ApduServiceInfo"; /** * The service that implements this */ - @UnsupportedAppUsage - final ResolveInfo mService; + private final ResolveInfo mService; /** * Description of the service */ - final String mDescription; + private final String mDescription; /** * Whether this service represents AIDs running on the host CPU */ - final boolean mOnHost; + private final boolean mOnHost; /** * Offhost reader name. * eg: SIM, eSE etc */ - String mOffHostName; + private String mOffHostName; /** * Offhost reader name from manifest file. - * Used for unsetOffHostSecureElement() + * Used for resetOffHostSecureElement() */ - final String mStaticOffHostName; + private final String mStaticOffHostName; /** * Mapping from category to static AID group */ - @UnsupportedAppUsage - final HashMap<String, AidGroup> mStaticAidGroups; + private final HashMap<String, AidGroup> mStaticAidGroups; /** * Mapping from category to dynamic AID group */ - @UnsupportedAppUsage - final HashMap<String, AidGroup> mDynamicAidGroups; + private final HashMap<String, AidGroup> mDynamicAidGroups; /** * Whether this service should only be started when the device is unlocked. */ - final boolean mRequiresDeviceUnlock; + private final boolean mRequiresDeviceUnlock; /** * Whether this service should only be started when the device is screen on. */ - final boolean mRequiresDeviceScreenOn; + private final boolean mRequiresDeviceScreenOn; /** * The id of the service banner specified in XML. */ - final int mBannerResourceId; + private final int mBannerResourceId; /** * The uid of the package the service belongs to */ - final int mUid; + private final int mUid; /** * Settings Activity for this service */ - final String mSettingsActivityName; + private final String mSettingsActivityName; /** * @hide */ - @UnsupportedAppUsage public ApduServiceInfo(ResolveInfo info, boolean onHost, String description, - ArrayList<AidGroup> staticAidGroups, ArrayList<AidGroup> dynamicAidGroups, + List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups, boolean requiresUnlock, int bannerResource, int uid, String settingsActivityName, String offHost, String staticOffHost) { this(info, onHost, description, staticAidGroups, dynamicAidGroups, @@ -134,7 +141,7 @@ public final class ApduServiceInfo implements Parcelable { * @hide */ public ApduServiceInfo(ResolveInfo info, boolean onHost, String description, - ArrayList<AidGroup> staticAidGroups, ArrayList<AidGroup> dynamicAidGroups, + List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups, boolean requiresUnlock, boolean requiresScreenOn, int bannerResource, int uid, String settingsActivityName, String offHost, String staticOffHost) { this.mService = info; @@ -147,19 +154,28 @@ public final class ApduServiceInfo implements Parcelable { this.mRequiresDeviceUnlock = requiresUnlock; this.mRequiresDeviceScreenOn = requiresScreenOn; for (AidGroup aidGroup : staticAidGroups) { - this.mStaticAidGroups.put(aidGroup.category, aidGroup); + this.mStaticAidGroups.put(aidGroup.getCategory(), aidGroup); } for (AidGroup aidGroup : dynamicAidGroups) { - this.mDynamicAidGroups.put(aidGroup.category, aidGroup); + this.mDynamicAidGroups.put(aidGroup.getCategory(), aidGroup); } this.mBannerResourceId = bannerResource; this.mUid = uid; this.mSettingsActivityName = settingsActivityName; } - @UnsupportedAppUsage - public ApduServiceInfo(PackageManager pm, ResolveInfo info, boolean onHost) throws - XmlPullParserException, IOException { + /** + * Creates a new ApduServiceInfo object. + * + * @param pm packageManager instance + * @param info app component info + * @param onHost whether service is on host or not (secure element) + * @throws XmlPullParserException If an error occurs parsing the element. + * @throws IOException If an error occurs reading the element. + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public ApduServiceInfo(@NonNull PackageManager pm, @NonNull ResolveInfo info, boolean onHost) + throws XmlPullParserException, IOException { ServiceInfo si = info.serviceInfo; XmlResourceParser parser = null; try { @@ -277,9 +293,9 @@ public final class ApduServiceInfo implements Parcelable { groupAttrs.recycle(); } else if (eventType == XmlPullParser.END_TAG && "aid-group".equals(tagName) && currentGroup != null) { - if (currentGroup.aids.size() > 0) { - if (!mStaticAidGroups.containsKey(currentGroup.category)) { - mStaticAidGroups.put(currentGroup.category, currentGroup); + if (currentGroup.getAids().size() > 0) { + if (!mStaticAidGroups.containsKey(currentGroup.getCategory())) { + mStaticAidGroups.put(currentGroup.getCategory(), currentGroup); } } else { Log.e(TAG, "Not adding <aid-group> with empty or invalid AIDs"); @@ -291,8 +307,8 @@ public final class ApduServiceInfo implements Parcelable { com.android.internal.R.styleable.AidFilter); String aid = a.getString(com.android.internal.R.styleable.AidFilter_name). toUpperCase(); - if (CardEmulation.isValidAid(aid) && !currentGroup.aids.contains(aid)) { - currentGroup.aids.add(aid); + if (CardEmulation.isValidAid(aid) && !currentGroup.getAids().contains(aid)) { + currentGroup.getAids().add(aid); } else { Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid); } @@ -305,8 +321,8 @@ public final class ApduServiceInfo implements Parcelable { toUpperCase(); // Add wildcard char to indicate prefix aid = aid.concat("*"); - if (CardEmulation.isValidAid(aid) && !currentGroup.aids.contains(aid)) { - currentGroup.aids.add(aid); + if (CardEmulation.isValidAid(aid) && !currentGroup.getAids().contains(aid)) { + currentGroup.getAids().add(aid); } else { Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid); } @@ -319,8 +335,8 @@ public final class ApduServiceInfo implements Parcelable { toUpperCase(); // Add wildcard char to indicate suffix aid = aid.concat("#"); - if (CardEmulation.isValidAid(aid) && !currentGroup.aids.contains(aid)) { - currentGroup.aids.add(aid); + if (CardEmulation.isValidAid(aid) && !currentGroup.getAids().contains(aid)) { + currentGroup.getAids().add(aid); } else { Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid); } @@ -336,11 +352,25 @@ public final class ApduServiceInfo implements Parcelable { mUid = si.applicationInfo.uid; } + /** + * Returns the app component corresponding to this APDU service. + * + * @return app component for this service + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull public ComponentName getComponent() { return new ComponentName(mService.serviceInfo.packageName, mService.serviceInfo.name); } + /** + * Returns the offhost secure element name (if the service is offhost). + * + * @return offhost secure element name for offhost services + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @Nullable public String getOffHostSecureElement() { return mOffHostName; } @@ -353,18 +383,30 @@ public final class ApduServiceInfo implements Parcelable { * for that category. * @return List of AIDs registered by the service */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull public List<String> getAids() { final ArrayList<String> aids = new ArrayList<String>(); for (AidGroup group : getAidGroups()) { - aids.addAll(group.aids); + aids.addAll(group.getAids()); } return aids; } + /** + * Returns a consolidated list of AIDs with prefixes from the AID groups + * registered by this service. Note that if a service has both + * a static (manifest-based) AID group for a category and a dynamic + * AID group, only the dynamically registered AIDs will be returned + * for that category. + * @return List of prefix AIDs registered by the service + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull public List<String> getPrefixAids() { final ArrayList<String> prefixAids = new ArrayList<String>(); for (AidGroup group : getAidGroups()) { - for (String aid : group.aids) { + for (String aid : group.getAids()) { if (aid.endsWith("*")) { prefixAids.add(aid); } @@ -373,10 +415,20 @@ public final class ApduServiceInfo implements Parcelable { return prefixAids; } + /** + * Returns a consolidated list of AIDs with subsets from the AID groups + * registered by this service. Note that if a service has both + * a static (manifest-based) AID group for a category and a dynamic + * AID group, only the dynamically registered AIDs will be returned + * for that category. + * @return List of prefix AIDs registered by the service + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull public List<String> getSubsetAids() { final ArrayList<String> subsetAids = new ArrayList<String>(); for (AidGroup group : getAidGroups()) { - for (String aid : group.aids) { + for (String aid : group.getAids()) { if (aid.endsWith("#")) { subsetAids.add(aid); } @@ -384,14 +436,28 @@ public final class ApduServiceInfo implements Parcelable { } return subsetAids; } + /** * Returns the registered AID group for this category. + * + * @param category category name + * @return {@link AidGroup} instance for the provided category */ - public AidGroup getDynamicAidGroupForCategory(String category) { + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull + public AidGroup getDynamicAidGroupForCategory(@NonNull String category) { return mDynamicAidGroups.get(category); } - public boolean removeDynamicAidGroupForCategory(String category) { + /** + * Removes the registered AID group for this category. + * + * @param category category name + * @return {@code true} if an AID group existed + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull + public boolean removeDynamicAidGroupForCategory(@NonNull String category) { return (mDynamicAidGroups.remove(category) != null); } @@ -403,7 +469,9 @@ public final class ApduServiceInfo implements Parcelable { * for that category. * @return List of AIDs registered by the service */ - public ArrayList<AidGroup> getAidGroups() { + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull + public List<AidGroup> getAidGroups() { final ArrayList<AidGroup> groups = new ArrayList<AidGroup>(); for (Map.Entry<String, AidGroup> entry : mDynamicAidGroups.entrySet()) { groups.add(entry.getValue()); @@ -421,49 +489,83 @@ public final class ApduServiceInfo implements Parcelable { /** * Returns the category to which this service has attributed the AID that is passed in, * or null if we don't know this AID. + * @param aid AID to lookup for + * @return category name corresponding to this AID */ - public String getCategoryForAid(String aid) { - ArrayList<AidGroup> groups = getAidGroups(); + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull + public String getCategoryForAid(@NonNull String aid) { + List<AidGroup> groups = getAidGroups(); for (AidGroup group : groups) { - if (group.aids.contains(aid.toUpperCase())) { - return group.category; + if (group.getAids().contains(aid.toUpperCase())) { + return group.getCategory(); } } return null; } - public boolean hasCategory(String category) { + /** + * Returns whether there is any AID group for this category. + * @param category category name + * @return {@code true} if an AID group exists + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public boolean hasCategory(@NonNull String category) { return (mStaticAidGroups.containsKey(category) || mDynamicAidGroups.containsKey(category)); } - @UnsupportedAppUsage + /** + * Returns whether the service is on host or not. + * @return true if the service is on host (not secure element) + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public boolean isOnHost() { return mOnHost; } - @UnsupportedAppUsage + /** + * Returns whether the service requires device unlock. + * @return whether the service requires device unlock + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public boolean requiresUnlock() { return mRequiresDeviceUnlock; } /** * Returns whether this service should only be started when the device is screen on. + * @return whether the service requires screen on */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public boolean requiresScreenOn() { return mRequiresDeviceScreenOn; } - @UnsupportedAppUsage + /** + * Returns description of service. + * @return user readable description of service + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull public String getDescription() { return mDescription; } - @UnsupportedAppUsage + /** + * Returns uid of service. + * @return uid of the service + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public int getUid() { return mUid; } - public void setOrReplaceDynamicAidGroup(AidGroup aidGroup) { + /** + * Add or replace an AID group to this service. + * @param aidGroup instance of aid group to set or replace + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public void setDynamicAidGroup(@NonNull AidGroup aidGroup) { mDynamicAidGroups.put(aidGroup.getCategory(), aidGroup); } @@ -476,7 +578,8 @@ public final class ApduServiceInfo implements Parcelable { * TS26_NFC_REQ_070: For embedded SE, Secure Element Name SHALL be eSE[number] * (e.g. eSE/eSE1, eSE2, etc.). */ - public void setOffHostSecureElement(String offHost) { + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public void setOffHostSecureElement(@NonNull String offHost) { mOffHostName = offHost; } @@ -484,15 +587,30 @@ public final class ApduServiceInfo implements Parcelable { * Resets the off host Secure Element to statically defined * by the service in the manifest file. */ - public void unsetOffHostSecureElement() { + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public void resetOffHostSecureElement() { mOffHostName = mStaticOffHostName; } - public CharSequence loadLabel(PackageManager pm) { + /** + * Load label for this service. + * @param pm packagemanager instance + * @return label name corresponding to service + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull + public CharSequence loadLabel(@NonNull PackageManager pm) { return mService.loadLabel(pm); } - public CharSequence loadAppLabel(PackageManager pm) { + /** + * Load application label for this service. + * @param pm packagemanager instance + * @return app label name corresponding to service + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull + public CharSequence loadAppLabel(@NonNull PackageManager pm) { try { return pm.getApplicationLabel(pm.getApplicationInfo( mService.resolvePackageName, PackageManager.GET_META_DATA)); @@ -501,12 +619,25 @@ public final class ApduServiceInfo implements Parcelable { } } - public Drawable loadIcon(PackageManager pm) { + /** + * Load application icon for this service. + * @param pm packagemanager instance + * @return app icon corresponding to service + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull + public Drawable loadIcon(@NonNull PackageManager pm) { return mService.loadIcon(pm); } - @UnsupportedAppUsage - public Drawable loadBanner(PackageManager pm) { + /** + * Load application banner for this service. + * @param pm packagemanager instance + * @return app banner corresponding to service + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull + public Drawable loadBanner(@NonNull PackageManager pm) { Resources res; try { res = pm.getResourcesForApplication(mService.serviceInfo.packageName); @@ -521,7 +652,12 @@ public final class ApduServiceInfo implements Parcelable { } } - @UnsupportedAppUsage + /** + * Load activity name for this service. + * @return activity name for this service + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull public String getSettingsActivityName() { return mSettingsActivityName; } @Override @@ -556,14 +692,15 @@ public final class ApduServiceInfo implements Parcelable { return getComponent().hashCode(); } - + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @Override public int describeContents() { return 0; } + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @Override - public void writeToParcel(Parcel dest, int flags) { + public void writeToParcel(@NonNull Parcel dest, int flags) { mService.writeToParcel(dest, flags); dest.writeString(mDescription); dest.writeInt(mOnHost ? 1 : 0); @@ -584,8 +721,8 @@ public final class ApduServiceInfo implements Parcelable { dest.writeString(mSettingsActivityName); }; - @UnsupportedAppUsage - public static final @android.annotation.NonNull Parcelable.Creator<ApduServiceInfo> CREATOR = + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public static final @NonNull Parcelable.Creator<ApduServiceInfo> CREATOR = new Parcelable.Creator<ApduServiceInfo>() { @Override public ApduServiceInfo createFromParcel(Parcel source) { @@ -620,7 +757,15 @@ public final class ApduServiceInfo implements Parcelable { } }; - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + /** + * Dump contents for debugging. + * @param fd parcelfiledescriptor instance + * @param pw printwriter instance + * @param args args for dumping + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public void dump(@NonNull ParcelFileDescriptor fd, @NonNull PrintWriter pw, + @NonNull String[] args) { pw.println(" " + getComponent() + " (Description: " + getDescription() + ")" + " (UID: " + getUid() + ")"); @@ -633,15 +778,15 @@ public final class ApduServiceInfo implements Parcelable { } pw.println(" Static AID groups:"); for (AidGroup group : mStaticAidGroups.values()) { - pw.println(" Category: " + group.category); - for (String aid : group.aids) { + pw.println(" Category: " + group.getCategory()); + for (String aid : group.getAids()) { pw.println(" AID: " + aid); } } pw.println(" Dynamic AID groups:"); for (AidGroup group : mDynamicAidGroups.values()) { - pw.println(" Category: " + group.category); - for (String aid : group.aids) { + pw.println(" Category: " + group.getCategory()); + for (String aid : group.getAids()) { pw.println(" AID: " + aid); } } @@ -651,7 +796,7 @@ public final class ApduServiceInfo implements Parcelable { } /** - * Dump debugging info as ApduServiceInfoProto + * Dump debugging info as ApduServiceInfoProto. * * If the output belongs to a sub message, the caller is responsible for wrapping this function * between {@link ProtoOutputStream#start(long)} and {@link ProtoOutputStream#end(long)}. @@ -659,7 +804,8 @@ public final class ApduServiceInfo implements Parcelable { * * @param proto the ProtoOutputStream to write to */ - public void dumpDebug(ProtoOutputStream proto) { + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public void dumpDebug(@NonNull ProtoOutputStream proto) { Utils.dumpDebugComponentName(getComponent(), proto, ApduServiceInfoProto.COMPONENT_NAME); proto.write(ApduServiceInfoProto.DESCRIPTION, getDescription()); proto.write(ApduServiceInfoProto.ON_HOST, mOnHost); diff --git a/core/java/android/nfc/cardemulation/NfcFServiceInfo.java b/core/java/android/nfc/cardemulation/NfcFServiceInfo.java index 7a36b269240c..ec919e4d66bc 100644 --- a/core/java/android/nfc/cardemulation/NfcFServiceInfo.java +++ b/core/java/android/nfc/cardemulation/NfcFServiceInfo.java @@ -14,9 +14,16 @@ * limitations under the License. */ +/********************************************************************** + * This file is not a part of the NFC mainline module * + * *******************************************************************/ + package android.nfc.cardemulation; +import android.annotation.FlaggedApi; +import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.content.ComponentName; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; @@ -26,7 +33,9 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; +import android.nfc.Flags; import android.os.Parcel; +import android.os.ParcelFileDescriptor; import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; @@ -36,13 +45,16 @@ import android.util.proto.ProtoOutputStream; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; /** + * Class to hold NfcF service info. + * * @hide */ +@SystemApi +@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public final class NfcFServiceInfo implements Parcelable { static final String TAG = "NfcFServiceInfo"; @@ -51,42 +63,42 @@ public final class NfcFServiceInfo implements Parcelable { /** * The service that implements this */ - final ResolveInfo mService; + private final ResolveInfo mService; /** * Description of the service */ - final String mDescription; + private final String mDescription; /** * System Code of the service */ - final String mSystemCode; + private final String mSystemCode; /** * System Code of the service registered by API */ - String mDynamicSystemCode; + private String mDynamicSystemCode; /** * NFCID2 of the service */ - final String mNfcid2; + private final String mNfcid2; /** * NFCID2 of the service registered by API */ - String mDynamicNfcid2; + private String mDynamicNfcid2; /** * The uid of the package the service belongs to */ - final int mUid; + private final int mUid; /** * LF_T3T_PMM of the service */ - final String mT3tPmm; + private final String mT3tPmm; /** * @hide @@ -104,7 +116,16 @@ public final class NfcFServiceInfo implements Parcelable { this.mT3tPmm = t3tPmm; } - public NfcFServiceInfo(PackageManager pm, ResolveInfo info) + /** + * Creates a new NfcFServiceInfo object. + * + * @param pm packageManager instance + * @param info app component info + * @throws XmlPullParserException If an error occurs parsing the element. + * @throws IOException If an error occurs reading the element. + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public NfcFServiceInfo(@NonNull PackageManager pm, @NonNull ResolveInfo info) throws XmlPullParserException, IOException { ServiceInfo si = info.serviceInfo; XmlResourceParser parser = null; @@ -192,44 +213,107 @@ public final class NfcFServiceInfo implements Parcelable { mUid = si.applicationInfo.uid; } + /** + * Returns the app component corresponding to this NFCF service. + * + * @return app component for this service + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull public ComponentName getComponent() { return new ComponentName(mService.serviceInfo.packageName, mService.serviceInfo.name); } + /** + * Returns the system code corresponding to this service. + * + * @return system code for this service + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull public String getSystemCode() { return (mDynamicSystemCode == null ? mSystemCode : mDynamicSystemCode); } - public void setOrReplaceDynamicSystemCode(String systemCode) { + /** + * Add or replace a system code to this service. + * @param systemCode system code to set or replace + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public void setDynamicSystemCode(@NonNull String systemCode) { mDynamicSystemCode = systemCode; } + /** + * Returns NFC ID2. + * + * @return nfc id2 to return + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull public String getNfcid2() { return (mDynamicNfcid2 == null ? mNfcid2 : mDynamicNfcid2); } - public void setOrReplaceDynamicNfcid2(String nfcid2) { + /** + * Set or replace NFC ID2 + * + * @param nfcid2 NFC ID2 string + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public void setDynamicNfcid2(@NonNull String nfcid2) { mDynamicNfcid2 = nfcid2; } + /** + * Returns description of service. + * @return user readable description of service + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull public String getDescription() { return mDescription; } + /** + * Returns uid of service. + * @return uid of the service + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) public int getUid() { return mUid; } + /** + * Returns LF_T3T_PMM of the service + * @return returns LF_T3T_PMM of the service + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull public String getT3tPmm() { return mT3tPmm; } - public CharSequence loadLabel(PackageManager pm) { + /** + * Load application label for this service. + * @param pm packagemanager instance + * @return label name corresponding to service + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull + public CharSequence loadLabel(@NonNull PackageManager pm) { return mService.loadLabel(pm); } - public Drawable loadIcon(PackageManager pm) { + /** + * Load application icon for this service. + * @param pm packagemanager instance + * @return app icon corresponding to service + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull + public Drawable loadIcon(@NonNull PackageManager pm) { return mService.loadIcon(pm); } @@ -270,13 +354,15 @@ public final class NfcFServiceInfo implements Parcelable { return getComponent().hashCode(); } + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @Override public int describeContents() { return 0; } + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @Override - public void writeToParcel(Parcel dest, int flags) { + public void writeToParcel(@NonNull Parcel dest, int flags) { mService.writeToParcel(dest, flags); dest.writeString(mDescription); dest.writeString(mSystemCode); @@ -293,7 +379,8 @@ public final class NfcFServiceInfo implements Parcelable { dest.writeString(mT3tPmm); }; - public static final @android.annotation.NonNull Parcelable.Creator<NfcFServiceInfo> CREATOR = + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public static final @NonNull Parcelable.Creator<NfcFServiceInfo> CREATOR = new Parcelable.Creator<NfcFServiceInfo>() { @Override public NfcFServiceInfo createFromParcel(Parcel source) { @@ -322,7 +409,15 @@ public final class NfcFServiceInfo implements Parcelable { } }; - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + /** + * Dump contents of the service for debugging. + * @param fd parcelfiledescriptor instance + * @param pw printwriter instance + * @param args args for dumping + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public void dump(@NonNull ParcelFileDescriptor fd, @NonNull PrintWriter pw, + @NonNull String[] args) { pw.println(" " + getComponent() + " (Description: " + getDescription() + ")" + " (UID: " + getUid() + ")"); @@ -332,14 +427,15 @@ public final class NfcFServiceInfo implements Parcelable { } /** - * Dump debugging info as NfcFServiceInfoProto + * Dump debugging info as NfcFServiceInfoProto. * * If the output belongs to a sub message, the caller is responsible for wrapping this function * between {@link ProtoOutputStream#start(long)} and {@link ProtoOutputStream#end(long)}. * * @param proto the ProtoOutputStream to write to */ - public void dumpDebug(ProtoOutputStream proto) { + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public void dumpDebug(@NonNull ProtoOutputStream proto) { Utils.dumpDebugComponentName(getComponent(), proto, NfcFServiceInfoProto.COMPONENT_NAME); proto.write(NfcFServiceInfoProto.DESCRIPTION, getDescription()); proto.write(NfcFServiceInfoProto.SYSTEM_CODE, getSystemCode()); @@ -347,4 +443,3 @@ public final class NfcFServiceInfo implements Parcelable { proto.write(NfcFServiceInfoProto.T3T_PMM, getT3tPmm()); } } - diff --git a/core/java/android/nfc/flags.aconfig b/core/java/android/nfc/flags.aconfig new file mode 100644 index 000000000000..e3faf3978856 --- /dev/null +++ b/core/java/android/nfc/flags.aconfig @@ -0,0 +1,8 @@ +package: "android.nfc" + +flag { + name: "enable_nfc_mainline" + namespace: "nfc" + description: "Flag for NFC mainline changes" + bug: "292140387" +} diff --git a/core/java/android/os/incremental/V4Signature.java b/core/java/android/os/incremental/V4Signature.java index 2044502b10e8..38d885f503c5 100644 --- a/core/java/android/os/incremental/V4Signature.java +++ b/core/java/android/os/incremental/V4Signature.java @@ -254,7 +254,10 @@ public class V4Signature { this.signingInfos = signingInfos; } - private static V4Signature readFrom(InputStream stream) throws IOException { + /** + * Constructs a V4Signature from an InputStream. + */ + public static V4Signature readFrom(InputStream stream) throws IOException { final int version = readIntLE(stream); int maxSize = INCFS_MAX_SIGNATURE_SIZE; final byte[] hashingInfo = readBytes(stream, maxSize); diff --git a/core/java/android/permission/IPermissionController.aidl b/core/java/android/permission/IPermissionController.aidl index e3f02e73a41f..1cb7930928d0 100644 --- a/core/java/android/permission/IPermissionController.aidl +++ b/core/java/android/permission/IPermissionController.aidl @@ -43,7 +43,7 @@ oneway interface IPermissionController { void setRuntimePermissionGrantStateByDeviceAdminFromParams(String callerPackageName, in AdminPermissionControlParams params, in AndroidFuture callback); void grantOrUpgradeDefaultRuntimePermissions(in AndroidFuture callback); - void notifyOneTimePermissionSessionTimeout(String packageName); + void notifyOneTimePermissionSessionTimeout(String packageName, int deviceId); void updateUserSensitiveForApp(int uid, in AndroidFuture callback); void getPrivilegesDescriptionStringForProfile( in String deviceProfileName, @@ -60,5 +60,5 @@ oneway interface IPermissionController { in String packageName, in AndroidFuture callback); void revokeSelfPermissionsOnKill(in String packageName, in List<String> permissions, - in AndroidFuture callback); + int deviceId, in AndroidFuture callback); } diff --git a/core/java/android/permission/IPermissionManager.aidl b/core/java/android/permission/IPermissionManager.aidl index 18ede44dca20..7cecfdca851a 100644 --- a/core/java/android/permission/IPermissionManager.aidl +++ b/core/java/android/permission/IPermissionManager.aidl @@ -78,7 +78,7 @@ interface IPermissionManager { List<SplitPermissionInfoParcelable> getSplitPermissions(); @EnforcePermission("MANAGE_ONE_TIME_PERMISSION_SESSIONS") - void startOneTimePermissionSession(String packageName, int userId, long timeout, + void startOneTimePermissionSession(String packageName, int deviceId, int userId, long timeout, long revokeAfterKilledDelay); @EnforcePermission("MANAGE_ONE_TIME_PERMISSION_SESSIONS") diff --git a/core/java/android/permission/PermissionControllerManager.java b/core/java/android/permission/PermissionControllerManager.java index 84a197a96531..ba7591814a7b 100644 --- a/core/java/android/permission/PermissionControllerManager.java +++ b/core/java/android/permission/PermissionControllerManager.java @@ -764,13 +764,14 @@ public final class PermissionControllerManager { * inactive. * * @param packageName The package which became inactive - * + * @param deviceId The device ID refers either the primary device i.e. the phone or + * a virtual device. See {@link Context#DEVICE_ID_DEFAULT} * @hide */ @RequiresPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) - public void notifyOneTimePermissionSessionTimeout(@NonNull String packageName) { - mRemoteService.run( - service -> service.notifyOneTimePermissionSessionTimeout(packageName)); + public void notifyOneTimePermissionSessionTimeout(@NonNull String packageName, int deviceId) { + mRemoteService.run(service -> service.notifyOneTimePermissionSessionTimeout( + packageName, deviceId)); } /** @@ -930,12 +931,14 @@ public final class PermissionControllerManager { @NonNull List<String> permissions) { mRemoteService.postAsync(service -> { AndroidFuture<Void> callback = new AndroidFuture<>(); - service.revokeSelfPermissionsOnKill(packageName, permissions, callback); + service.revokeSelfPermissionsOnKill(packageName, permissions, mContext.getDeviceId(), + callback); return callback; }).whenComplete((result, err) -> { if (err != null) { Log.e(TAG, "Failed to self revoke " + String.join(",", permissions) - + " for package " + packageName, err); + + " for package " + packageName + ", and device " + mContext.getDeviceId(), + err); } }); } diff --git a/core/java/android/permission/PermissionControllerService.java b/core/java/android/permission/PermissionControllerService.java index 11005a6d265b..9fe2599dd39b 100644 --- a/core/java/android/permission/PermissionControllerService.java +++ b/core/java/android/permission/PermissionControllerService.java @@ -30,6 +30,7 @@ import static com.android.internal.util.Preconditions.checkStringNotEmpty; import android.Manifest; import android.annotation.BinderThread; +import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; @@ -37,6 +38,7 @@ import android.app.Service; import android.app.admin.DevicePolicyManager.PermissionGrantState; import android.compat.annotation.ChangeId; import android.compat.annotation.Disabled; +import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; @@ -46,6 +48,7 @@ import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.UserHandle; import android.permission.PermissionControllerManager.CountPermissionAppsFlag; +import android.permission.flags.Flags; import android.util.ArrayMap; import android.util.Log; @@ -296,13 +299,32 @@ public abstract class PermissionControllerService extends Service { * This method is called at the end of a one-time permission session * * @param packageName The package that has been inactive + * + * @deprecated Implement {@link #onOneTimePermissionSessionTimeout(String, int)} instead. */ + @Deprecated @BinderThread public void onOneTimePermissionSessionTimeout(@NonNull String packageName) { throw new AbstractMethodError("Must be overridden in implementing class"); } /** + * Called when a package is considered inactive based on the criteria given by + * {@link PermissionManager#startOneTimePermissionSession(String, long, long, int, int)}. + * This method is called at the end of a one-time permission session + * + * @param packageName The package that has been inactive + * @param deviceId The device ID refers either the primary device i.e. the phone or + * a virtual device. See {@link Context#DEVICE_ID_DEFAULT} + */ + @BinderThread + @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS) + public void onOneTimePermissionSessionTimeout(@NonNull String packageName, + int deviceId) { + onOneTimePermissionSessionTimeout(packageName); + } + + /** * Get the platform permissions which belong to a particular permission group * * @param permissionGroupName The permission group whose permissions are desired @@ -341,13 +363,42 @@ public abstract class PermissionControllerService extends Service { * @param callback Callback waiting for operation to be complete. * * @see android.content.Context#revokeSelfPermissionsOnKill(java.util.Collection) + * + * @deprecated Implement {@link #onRevokeSelfPermissionsOnKill(String, List, int, Runnable)} + * instead. */ + @Deprecated @BinderThread public void onRevokeSelfPermissionsOnKill(@NonNull String packageName, @NonNull List<String> permissions, @NonNull Runnable callback) { throw new AbstractMethodError("Must be overridden in implementing class"); } + /** + * Triggers the revocation of one or more permissions for a package and device. + * This should only be called at the request of {@code packageName}. + * <p> + * Background permissions which have no corresponding foreground permission still granted once + * the revocation is effective will also be revoked. + * <p> + * This revocation happens asynchronously and kills all processes running in the same UID as + * {@code packageName}. It will be triggered once it is safe to do so. + * + * @param packageName The name of the package for which the permissions will be revoked. + * @param permissions List of permissions to be revoked. + * @param deviceId The device ID refers either the primary device i.e. the phone or + * a virtual device. See {@link Context#DEVICE_ID_DEFAULT} + * @param callback Callback waiting for operation to be complete. + * + * @see android.content.Context#revokeSelfPermissionsOnKill(java.util.Collection) + */ + @BinderThread + @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS) + public void onRevokeSelfPermissionsOnKill(@NonNull String packageName, + @NonNull List<String> permissions, int deviceId, @NonNull Runnable callback) { + onRevokeSelfPermissionsOnKill(packageName, permissions, callback); + } + // TODO(b/272129940): Remove this API and device profile role description when we drop T // support. /** @@ -613,12 +664,12 @@ public abstract class PermissionControllerService extends Service { } @Override - public void notifyOneTimePermissionSessionTimeout(String packageName) { + public void notifyOneTimePermissionSessionTimeout(String packageName, int deviceId) { enforceSomePermissionsGrantedToCaller( Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); packageName = Preconditions.checkNotNull(packageName, "packageName cannot be null"); - onOneTimePermissionSessionTimeout(packageName); + onOneTimePermissionSessionTimeout(packageName, deviceId); } @Override @@ -710,7 +761,8 @@ public abstract class PermissionControllerService extends Service { @Override public void revokeSelfPermissionsOnKill(@NonNull String packageName, - @NonNull List<String> permissions, @NonNull AndroidFuture callback) { + @NonNull List<String> permissions, int deviceId, + @NonNull AndroidFuture callback) { try { Objects.requireNonNull(callback); @@ -721,7 +773,7 @@ public abstract class PermissionControllerService extends Service { enforceSomePermissionsGrantedToCaller( Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); } - onRevokeSelfPermissionsOnKill(packageName, permissions, + onRevokeSelfPermissionsOnKill(packageName, permissions, deviceId, () -> callback.complete(null)); } catch (Throwable t) { callback.completeExceptionally(t); diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java index 7d3921049712..e10ea10e2a29 100644 --- a/core/java/android/permission/PermissionManager.java +++ b/core/java/android/permission/PermissionManager.java @@ -214,6 +214,12 @@ public final class PermissionManager { public static final boolean DEBUG_TRACE_PERMISSION_UPDATES = false; /** + * Additional debug log for virtual device permissions. + * @hide + */ + public static final boolean DEBUG_DEVICE_PERMISSIONS = false; + + /** * Intent extra: List of PermissionGroupUsages * <p> * Type: {@code List<PermissionGroupUsage>} @@ -1392,8 +1398,8 @@ public final class PermissionManager { @ActivityManager.RunningAppProcessInfo.Importance int importanceToResetTimer, @ActivityManager.RunningAppProcessInfo.Importance int importanceToKeepSessionAlive) { try { - mPermissionManager.startOneTimePermissionSession(packageName, mContext.getUserId(), - timeoutMillis, revokeAfterKilledDelayMillis); + mPermissionManager.startOneTimePermissionSession(packageName, mContext.getDeviceId(), + mContext.getUserId(), timeoutMillis, revokeAfterKilledDelayMillis); } catch (RemoteException e) { e.rethrowFromSystemServer(); } diff --git a/core/java/android/printservice/PrintService.java b/core/java/android/printservice/PrintService.java index ecf17707a5c8..dc024701fbef 100644 --- a/core/java/android/printservice/PrintService.java +++ b/core/java/android/printservice/PrintService.java @@ -178,7 +178,7 @@ public abstract class PrintService extends Service { * <pre> <print-service * android:vendor="SomeVendor" * android:settingsActivity="foo.bar.MySettingsActivity" - * andorid:addPrintersActivity="foo.bar.MyAddPrintersActivity." + * android:addPrintersActivity="foo.bar.MyAddPrintersActivity." * . . . * /></pre> * <p> diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java index cf3707b8e105..a39157103f71 100644 --- a/core/java/android/provider/Telephony.java +++ b/core/java/android/provider/Telephony.java @@ -4915,6 +4915,14 @@ public final class Telephony { public static final String COLUMN_SATELLITE_ATTACH_ENABLED_FOR_CARRIER = "satellite_attach_enabled_for_carrier"; + /** + * TelephonyProvider column name to identify eSIM profile of a non-terrestrial network. + * By default, it's disabled. + * + * @hide + */ + public static final String COLUMN_IS_NTN = "is_ntn"; + /** All columns in {@link SimInfo} table. */ private static final List<String> ALL_COLUMNS = List.of( COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID, @@ -4985,7 +4993,8 @@ public final class Telephony { COLUMN_TP_MESSAGE_REF, COLUMN_USER_HANDLE, COLUMN_SATELLITE_ENABLED, - COLUMN_SATELLITE_ATTACH_ENABLED_FOR_CARRIER + COLUMN_SATELLITE_ATTACH_ENABLED_FOR_CARRIER, + COLUMN_IS_NTN ); /** diff --git a/core/java/android/util/apk/ApkSignatureSchemeV4Verifier.java b/core/java/android/util/apk/ApkSignatureSchemeV4Verifier.java index 6b26155eced4..52102714eb5f 100644 --- a/core/java/android/util/apk/ApkSignatureSchemeV4Verifier.java +++ b/core/java/android/util/apk/ApkSignatureSchemeV4Verifier.java @@ -27,9 +27,14 @@ import android.os.incremental.V4Signature; import android.util.ArrayMap; import android.util.Pair; +import com.android.internal.security.VerityUtils; + import java.io.ByteArrayInputStream; +import java.io.EOFException; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.security.DigestException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.KeyFactory; @@ -60,7 +65,7 @@ public class ApkSignatureSchemeV4Verifier { * certificates associated with each signer. */ public static VerifiedSigner extractCertificates(String apkFile) - throws SignatureNotFoundException, SecurityException { + throws SignatureNotFoundException, SignatureException, SecurityException { Pair<V4Signature.HashingInfo, V4Signature.SigningInfos> pair = extractSignature(apkFile); return verify(apkFile, pair.first, pair.second, APK_SIGNATURE_SCHEME_DEFAULT); } @@ -69,15 +74,37 @@ public class ApkSignatureSchemeV4Verifier { * Extracts APK Signature Scheme v4 signature of the provided APK. */ public static Pair<V4Signature.HashingInfo, V4Signature.SigningInfos> extractSignature( - String apkFile) throws SignatureNotFoundException { - final File apk = new File(apkFile); - final byte[] signatureBytes = IncrementalManager.unsafeGetFileSignature( - apk.getAbsolutePath()); - if (signatureBytes == null || signatureBytes.length == 0) { - throw new SignatureNotFoundException("Failed to obtain signature bytes from IncFS."); - } + String apkFile) throws SignatureNotFoundException, SignatureException { try { - final V4Signature signature = V4Signature.readFrom(signatureBytes); + final File apk = new File(apkFile); + boolean needsConsistencyCheck; + + // 1. Try IncFS first. IncFS verifies the file according to the integrity metadata + // (including the root hash of Merkle tree) it keeps track of with signature check. No + // further consistentcy check is needed. + byte[] signatureBytes = IncrementalManager.unsafeGetFileSignature( + apk.getAbsolutePath()); + V4Signature signature; + if (signatureBytes != null && signatureBytes.length > 0) { + needsConsistencyCheck = false; + signature = V4Signature.readFrom(signatureBytes); + } else if (android.security.Flags.extendVbChainToUpdatedApk()) { + // 2. Try fs-verity next. fs-verity checks against the Merkle tree, but the + // v4 signature file (including a raw root hash) is managed separately. We need to + // ensure the signed data from the file is consistent with the actual file. + needsConsistencyCheck = true; + + final File idsig = new File(apk.getAbsolutePath() + V4Signature.EXT); + try (var fis = new FileInputStream(idsig.getAbsolutePath())) { + signature = V4Signature.readFrom(fis); + } catch (IOException e) { + throw new SignatureNotFoundException( + "Failed to obtain signature bytes from .idsig"); + } + } else { + throw new SignatureNotFoundException( + "Failed to obtain signature bytes from IncFS."); + } if (!signature.isVersionSupported()) { throw new SecurityException( "v4 signature version " + signature.version + " is not supported"); @@ -86,9 +113,26 @@ public class ApkSignatureSchemeV4Verifier { signature.hashingInfo); final V4Signature.SigningInfos signingInfos = V4Signature.SigningInfos.fromByteArray( signature.signingInfos); + + if (needsConsistencyCheck) { + final byte[] actualDigest = VerityUtils.getFsverityDigest(apk.getAbsolutePath()); + if (actualDigest == null) { + throw new SecurityException("The APK does not have fs-verity"); + } + final byte[] computedDigest = + VerityUtils.generateFsVerityDigest(apk.length(), hashingInfo); + if (!Arrays.equals(computedDigest, actualDigest)) { + throw new SignatureException("Actual digest does not match the v4 signature"); + } + } + return Pair.create(hashingInfo, signingInfos); + } catch (EOFException e) { + throw new SignatureException("V4 signature is invalid.", e); } catch (IOException e) { throw new SignatureNotFoundException("Failed to read V4 signature.", e); + } catch (DigestException | NoSuchAlgorithmException e) { + throw new SecurityException("Failed to calculate the digest", e); } } @@ -107,7 +151,7 @@ public class ApkSignatureSchemeV4Verifier { signingInfo); final Pair<Certificate, byte[]> result = verifySigner(signingInfo, signedData); - // Populate digests enforced by IncFS driver. + // Populate digests enforced by IncFS driver and fs-verity. Map<Integer, byte[]> contentDigests = new ArrayMap<>(); contentDigests.put(convertToContentDigestType(hashingInfo.hashAlgorithm), hashingInfo.rawRootHash); @@ -217,7 +261,7 @@ public class ApkSignatureSchemeV4Verifier { public final byte[] apkDigest; // Algorithm -> digest map of signed digests in the signature. - // These are continuously enforced by the IncFS driver. + // These are continuously enforced by the IncFS driver and fs-verity. public final Map<Integer, byte[]> contentDigests; public VerifiedSigner(Certificate[] certs, byte[] apkDigest, diff --git a/core/java/android/view/HapticScrollFeedbackProvider.java b/core/java/android/view/HapticScrollFeedbackProvider.java index a2f1d37c2c11..1310b0ccd3a9 100644 --- a/core/java/android/view/HapticScrollFeedbackProvider.java +++ b/core/java/android/view/HapticScrollFeedbackProvider.java @@ -47,9 +47,17 @@ public class HapticScrollFeedbackProvider implements ScrollFeedbackProvider { public @interface HapticScrollFeedbackAxis {} private static final int TICK_INTERVAL_NO_TICK = 0; + private static final boolean INITIAL_END_OF_LIST_HAPTICS_ENABLED = false; private final View mView; private final ViewConfiguration mViewConfig; + /** + * Flag to disable the logic in this class if the View-based scroll haptics implementation is + * enabled. If {@code false}, this class will continue to run despite the View's scroll + * haptics implementation being enabled. This value should be set to {@code true} when this + * class is directly used by the View class. + */ + private final boolean mDisabledIfViewPlaysScrollHaptics; // Info about the cause of the latest scroll event. @@ -63,18 +71,21 @@ public class HapticScrollFeedbackProvider implements ScrollFeedbackProvider { /** The tick interval corresponding to the current InputDevice/source/axis. */ private int mTickIntervalPixels = TICK_INTERVAL_NO_TICK; private int mTotalScrollPixels = 0; - private boolean mCanPlayLimitFeedback = true; + private boolean mCanPlayLimitFeedback = INITIAL_END_OF_LIST_HAPTICS_ENABLED; private boolean mHapticScrollFeedbackEnabled = false; public HapticScrollFeedbackProvider(@NonNull View view) { - this(view, ViewConfiguration.get(view.getContext())); + this(view, ViewConfiguration.get(view.getContext()), + /* disabledIfViewPlaysScrollHaptics= */ true); } /** @hide */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) - public HapticScrollFeedbackProvider(View view, ViewConfiguration viewConfig) { + public HapticScrollFeedbackProvider( + View view, ViewConfiguration viewConfig, boolean disabledIfViewPlaysScrollHaptics) { mView = view; mViewConfig = viewConfig; + mDisabledIfViewPlaysScrollHaptics = disabledIfViewPlaysScrollHaptics; } @Override @@ -136,13 +147,19 @@ public class HapticScrollFeedbackProvider implements ScrollFeedbackProvider { private void maybeUpdateCurrentConfig(int deviceId, int source, int axis) { if (mAxis != axis || mSource != source || mDeviceId != deviceId) { + if (mDisabledIfViewPlaysScrollHaptics + && (source == InputDevice.SOURCE_ROTARY_ENCODER) + && mViewConfig.isViewBasedRotaryEncoderHapticScrollFeedbackEnabled()) { + mHapticScrollFeedbackEnabled = false; + return; + } mSource = source; mAxis = axis; mDeviceId = deviceId; mHapticScrollFeedbackEnabled = mViewConfig.isHapticScrollFeedbackEnabled(deviceId, axis, source); - mCanPlayLimitFeedback = true; + mCanPlayLimitFeedback = INITIAL_END_OF_LIST_HAPTICS_ENABLED; mTotalScrollPixels = 0; updateTickIntervals(deviceId, source, axis); } diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java index bb4cc8fc8d45..b17d2d1800e5 100644 --- a/core/java/android/view/KeyEvent.java +++ b/core/java/android/view/KeyEvent.java @@ -1990,8 +1990,23 @@ public class KeyEvent extends InputEvent implements Parcelable { } /** - * Returns whether this key will be sent to the - * {@link android.media.session.MediaSession.Callback} if not handled. + * Returns whether this key will be sent to the {@link + * android.media.session.MediaSession.Callback} if not handled. + * + * <p>The following key codes are considered {@link android.media.session.MediaSession} keys: + * + * <ul> + * <li>{@link #KEYCODE_MEDIA_PLAY} + * <li>{@link #KEYCODE_MEDIA_PAUSE} + * <li>{@link #KEYCODE_MEDIA_PLAY_PAUSE} + * <li>{@link #KEYCODE_HEADSETHOOK} + * <li>{@link #KEYCODE_MEDIA_STOP} + * <li>{@link #KEYCODE_MEDIA_NEXT} + * <li>{@link #KEYCODE_MEDIA_PREVIOUS} + * <li>{@link #KEYCODE_MEDIA_REWIND} + * <li>{@link #KEYCODE_MEDIA_RECORD} + * <li>{@link #KEYCODE_MEDIA_FAST_FORWARD} + * </ul> */ public static final boolean isMediaSessionKey(int keyCode) { switch (keyCode) { diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 052c28325545..be6fb313b230 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -263,6 +263,8 @@ public final class SurfaceControl implements Parcelable { long nativeObject, int compatibility); private static native void nativeSetFrameRateCategory( long transactionObj, long nativeObject, int category); + private static native void nativeSetFrameRateSelectionStrategy( + long transactionObj, long nativeObject, int strategy); private static native long nativeGetHandle(long nativeObject); private static native void nativeSetFixedTransformHint(long transactionObj, long nativeObject, @@ -850,6 +852,35 @@ public final class SurfaceControl implements Parcelable { */ public static final int METADATA_GAME_MODE = 8; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"FRAME_RATE_SELECTION_STRATEGY_"}, + value = {FRAME_RATE_SELECTION_STRATEGY_SELF, + FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN}) + public @interface FrameRateSelectionStrategy {} + + // From window.h. Keep these in sync. + /** + * Default value. The layer uses its own frame rate specifications, assuming it has any + * specifications, instead of its parent's. + * However, {@link #FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN} on an ancestor layer + * supersedes this behavior, meaning that this layer will inherit the frame rate specifications + * of that ancestor layer. + * @hide + */ + public static final int FRAME_RATE_SELECTION_STRATEGY_SELF = 0; + + /** + * The layer's frame rate specifications will propagate to and override those of its descendant + * layers. + * The layer with this strategy has the {@link #FRAME_RATE_SELECTION_STRATEGY_SELF} behavior + * for itself. This does mean that any parent or ancestor layer that also has the strategy + * {@link FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN} will override this layer's + * frame rate specifications. + * @hide + */ + public static final int FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN = 1; + /** * Builder class for {@link SurfaceControl} objects. * @@ -3669,6 +3700,31 @@ public final class SurfaceControl implements Parcelable { } /** + * Sets the frame rate selection strategy for the {@link SurfaceControl}. + * + * This instructs the system on how to choose a display refresh rate, following the + * strategy for the layer's frame rate specifications relative to other layers'. + * + * @param sc The SurfaceControl to specify the frame rate category of. + * @param strategy The frame rate selection strategy. + * + * @return This transaction object. + * + * @see #setFrameRate(SurfaceControl, float, int, int) + * @see #setFrameRateCategory(SurfaceControl, int) + * @see #setDefaultFrameRateCompatibility(SurfaceControl, int) + * + * @hide + */ + @NonNull + public Transaction setFrameRateSelectionStrategy( + @NonNull SurfaceControl sc, @FrameRateSelectionStrategy int strategy) { + checkPreconditions(sc); + nativeSetFrameRateSelectionStrategy(mNativeObject, sc.mNativeObject, strategy); + return this; + } + + /** * Sets focus on the window identified by the input {@code token} if the window is focusable * otherwise the request is dropped. * diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 4d53b2c6b821..55374b994cd4 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -919,6 +919,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ private static boolean sCompatibilityDone = false; + /** @hide */ + public HapticScrollFeedbackProvider mScrollFeedbackProvider = null; + /** * Use the old (broken) way of building MeasureSpecs. */ @@ -3605,6 +3608,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * 1 PFLAG4_IMPORTANT_FOR_CREDENTIAL_MANAGER * 1 PFLAG4_TRAVERSAL_TRACING_ENABLED * 1 PFLAG4_RELAYOUT_TRACING_ENABLED + * 1 PFLAG4_ROTARY_HAPTICS_DETERMINED + * 1 PFLAG4_ROTARY_HAPTICS_ENABLED + * 1 PFLAG4_ROTARY_HAPTICS_SCROLL_SINCE_LAST_ROTARY_INPUT + * 1 PFLAG4_ROTARY_HAPTICS_WAITING_FOR_SCROLL_EVENT * |-------|-------|-------|-------| */ @@ -3703,6 +3710,24 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ private static final int PFLAG4_RELAYOUT_TRACING_ENABLED = 0x000080000; + /** Indicates if rotary scroll haptics support for the view has been determined. */ + private static final int PFLAG4_ROTARY_HAPTICS_DETERMINED = 0x100000; + + /** + * Indicates if rotary scroll haptics is enabled for this view. + * The source of truth for this info is a ViewConfiguration API; this bit only caches the value. + */ + private static final int PFLAG4_ROTARY_HAPTICS_ENABLED = 0x200000; + + /** Indicates if there has been a scroll event since the last rotary input. */ + private static final int PFLAG4_ROTARY_HAPTICS_SCROLL_SINCE_LAST_ROTARY_INPUT = 0x400000; + + /** + * Indicates if there has been a rotary input that may generate a scroll event. + * This flag is important so that a scroll event can be properly attributed to a rotary input. + */ + private static final int PFLAG4_ROTARY_HAPTICS_WAITING_FOR_SCROLL_EVENT = 0x800000; + /* End of masks for mPrivateFlags4 */ /** @hide */ @@ -15894,6 +15919,28 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } private boolean dispatchGenericMotionEventInternal(MotionEvent event) { + final boolean isRotaryEncoderEvent = event.isFromSource(InputDevice.SOURCE_ROTARY_ENCODER); + if (isRotaryEncoderEvent) { + // Determine and cache rotary scroll haptics support if it's not yet determined. + // Caching the support is important for two reasons: + // 1) Limits call to `ViewConfiguration#get`, which we should avoid if possible. + // 2) Limits latency from the `ViewConfiguration` API, which may be slow due to feature + // flag querying. + if ((mPrivateFlags4 & PFLAG4_ROTARY_HAPTICS_DETERMINED) == 0) { + if (ViewConfiguration.get(mContext) + .isViewBasedRotaryEncoderHapticScrollFeedbackEnabled()) { + mPrivateFlags4 |= PFLAG4_ROTARY_HAPTICS_ENABLED; + } + mPrivateFlags4 |= PFLAG4_ROTARY_HAPTICS_DETERMINED; + } + } + final boolean processForRotaryScrollHaptics = + isRotaryEncoderEvent && ((mPrivateFlags4 & PFLAG4_ROTARY_HAPTICS_ENABLED) != 0); + if (processForRotaryScrollHaptics) { + mPrivateFlags4 &= ~PFLAG4_ROTARY_HAPTICS_SCROLL_SINCE_LAST_ROTARY_INPUT; + mPrivateFlags4 |= PFLAG4_ROTARY_HAPTICS_WAITING_FOR_SCROLL_EVENT; + } + //noinspection SimplifiableIfStatement ListenerInfo li = mListenerInfo; if (li != null && li.mOnGenericMotionListener != null @@ -15902,7 +15949,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return true; } - if (onGenericMotionEvent(event)) { + final boolean onGenericMotionEventResult = onGenericMotionEvent(event); + // Process scroll haptics after `onGenericMotionEvent`, since that's where scrolling usually + // happens. Some views may return false from `onGenericMotionEvent` even if they have done + // scrolling, so disregard the return value when processing for scroll haptics. + if (processForRotaryScrollHaptics) { + if ((mPrivateFlags4 & PFLAG4_ROTARY_HAPTICS_SCROLL_SINCE_LAST_ROTARY_INPUT) != 0) { + doRotaryProgressForScrollHaptics(event); + } else { + doRotaryLimitForScrollHaptics(event); + } + } + if (onGenericMotionEventResult) { return true; } @@ -17783,6 +17841,38 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } + private HapticScrollFeedbackProvider getScrollFeedbackProvider() { + if (mScrollFeedbackProvider == null) { + mScrollFeedbackProvider = new HapticScrollFeedbackProvider(this, + ViewConfiguration.get(mContext), /* disabledIfViewPlaysScrollHaptics= */ false); + } + return mScrollFeedbackProvider; + } + + private void doRotaryProgressForScrollHaptics(MotionEvent rotaryEvent) { + final float axisScrollValue = rotaryEvent.getAxisValue(MotionEvent.AXIS_SCROLL); + final float verticalScrollFactor = + ViewConfiguration.get(mContext).getScaledVerticalScrollFactor(); + final int scrollAmount = -Math.round(axisScrollValue * verticalScrollFactor); + getScrollFeedbackProvider().onScrollProgress( + rotaryEvent.getDeviceId(), InputDevice.SOURCE_ROTARY_ENCODER, + MotionEvent.AXIS_SCROLL, scrollAmount); + } + + private void doRotaryLimitForScrollHaptics(MotionEvent rotaryEvent) { + final boolean isStart = rotaryEvent.getAxisValue(MotionEvent.AXIS_SCROLL) > 0; + getScrollFeedbackProvider().onScrollLimit( + rotaryEvent.getDeviceId(), InputDevice.SOURCE_ROTARY_ENCODER, + MotionEvent.AXIS_SCROLL, isStart); + } + + private void processScrollEventForRotaryEncoderHaptics() { + if ((mPrivateFlags4 |= PFLAG4_ROTARY_HAPTICS_WAITING_FOR_SCROLL_EVENT) != 0) { + mPrivateFlags4 |= PFLAG4_ROTARY_HAPTICS_SCROLL_SINCE_LAST_ROTARY_INPUT; + mPrivateFlags4 &= ~PFLAG4_ROTARY_HAPTICS_WAITING_FOR_SCROLL_EVENT; + } + } + /** * This is called in response to an internal scroll in this view (i.e., the * view scrolled its own contents). This is typically as a result of @@ -17798,6 +17888,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, notifySubtreeAccessibilityStateChangedIfNeeded(); postSendViewScrolledAccessibilityEventCallback(l - oldl, t - oldt); + processScrollEventForRotaryEncoderHaptics(); + mBackgroundSizeChanged = true; mDefaultFocusHighlightSizeChanged = true; if (mForegroundInfo != null) { diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index a3ae6cf20725..2cf5d5d63596 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -40,6 +40,8 @@ import android.util.SparseArray; import android.util.TypedValue; import android.view.flags.Flags; +import com.android.internal.annotations.VisibleForTesting; + /** * Contains methods to standard constants used in the UI for timeouts, sizes, and distances. */ @@ -375,6 +377,7 @@ public class ViewConfiguration { private final int mSmartSelectionInitializedTimeout; private final int mSmartSelectionInitializingTimeout; private final boolean mPreferKeepClearForFocusEnabled; + private final boolean mViewBasedRotaryEncoderScrollHapticsEnabledConfig; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768915) private boolean sHasPermanentMenuKey; @@ -399,6 +402,7 @@ public class ViewConfiguration { mMaximumRotaryEncoderFlingVelocity = MAXIMUM_FLING_VELOCITY; mRotaryEncoderHapticScrollFeedbackEnabled = false; mRotaryEncoderHapticScrollFeedbackTickIntervalPixels = NO_HAPTIC_SCROLL_TICK_INTERVAL; + mViewBasedRotaryEncoderScrollHapticsEnabledConfig = false; mScrollbarSize = SCROLL_BAR_SIZE; mTouchSlop = TOUCH_SLOP; mHandwritingSlop = HANDWRITING_SLOP; @@ -575,6 +579,9 @@ public class ViewConfiguration { com.android.internal.R.integer.config_smartSelectionInitializingTimeoutMillis); mPreferKeepClearForFocusEnabled = res.getBoolean( com.android.internal.R.bool.config_preferKeepClearForFocus); + mViewBasedRotaryEncoderScrollHapticsEnabledConfig = + res.getBoolean( + com.android.internal.R.bool.config_viewBasedRotaryEncoderHapticsEnabled); } /** @@ -590,8 +597,7 @@ public class ViewConfiguration { public static ViewConfiguration get(@NonNull @UiContext Context context) { StrictMode.assertConfigurationContext(context, "ViewConfiguration"); - final DisplayMetrics metrics = context.getResources().getDisplayMetrics(); - final int density = (int) (100.0f * metrics.density); + final int density = getDisplayDensity(context); ViewConfiguration configuration = sConfigurations.get(density); if (configuration == null) { @@ -603,6 +609,28 @@ public class ViewConfiguration { } /** + * Removes cached ViewConfiguration instances, so that we can ensure `get` constructs a new + * ViewConfiguration instance. This is useful for testing the behavior and performance of + * creating ViewConfiguration the first time. + * + * @hide + */ + @VisibleForTesting + public static void resetCacheForTesting() { + sConfigurations.clear(); + } + + /** + * Sets the ViewConfiguration cached instanc for a given Context for testing. + * + * @hide + */ + @VisibleForTesting + public static void setInstanceForTesting(Context context, ViewConfiguration instance) { + sConfigurations.put(getDisplayDensity(context), instance); + } + + /** * @return The width of the horizontal scrollbar and the height of the vertical * scrollbar in dips * @@ -1311,6 +1339,20 @@ public class ViewConfiguration { return NO_HAPTIC_SCROLL_TICK_INTERVAL; } + /** + * Checks if the View-based haptic scroll feedback implementation is enabled for + * {@link InputDevice#SOURCE_ROTARY_ENCODER}s. + * + * <p>If this method returns {@code true}, the {@link HapticScrollFeedbackProvider} will be + * muted for rotary encoders in favor of View's scroll haptics implementation. + * + * @hide + */ + public boolean isViewBasedRotaryEncoderHapticScrollFeedbackEnabled() { + return mViewBasedRotaryEncoderScrollHapticsEnabledConfig + && Flags.useViewBasedRotaryEncoderScrollHaptics(); + } + private static boolean isInputDeviceInfoValid(int id, int axis, int source) { InputDevice device = InputManagerGlobal.getInstance().getInputDevice(id); return device != null && device.getMotionRange(axis, source) != null; @@ -1420,4 +1462,9 @@ public class ViewConfiguration { public static int getHoverTooltipHideShortTimeout() { return HOVER_TOOLTIP_HIDE_SHORT_TIMEOUT; } + + private static final int getDisplayDensity(Context context) { + final DisplayMetrics metrics = context.getResources().getDisplayMetrics(); + return (int) (100.0f * metrics.density); + } } diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 432f6e183731..4cb8788ab9f2 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -1474,7 +1474,7 @@ public final class AutofillManager { } for (int i = 0; i < infos.size(); i++) { final VirtualViewFillInfo info = infos.valueAt(i); - final int virtualId = infos.indexOfKey(i); + final int virtualId = infos.keyAt(i); notifyViewReadyInner(getAutofillId(view, virtualId), (info == null) ? null : info.getAutofillHints()); } @@ -1488,9 +1488,6 @@ public final class AutofillManager { * @hide */ public void notifyViewEnteredForFillDialog(View v) { - if (sDebug) { - Log.d(TAG, "notifyViewEnteredForFillDialog:" + v.getAutofillId()); - } if (v.isCredential() && mIsFillAndSaveDialogDisabledForCredentialManager) { if (sDebug) { @@ -1503,11 +1500,14 @@ public final class AutofillManager { notifyViewReadyInner(v.getAutofillId(), v.getAutofillHints()); } - private void notifyViewReadyInner(AutofillId id, String[] autofillHints) { + private void notifyViewReadyInner(AutofillId id, @Nullable String[] autofillHints) { + if (sDebug) { + Log.d(TAG, "notifyViewReadyInner:" + id); + } + if (!hasAutofillFeature()) { return; } - synchronized (mLock) { if (mAllTrackedViews.contains(id)) { // The id is tracked and will not trigger pre-fill request again. @@ -1543,26 +1543,38 @@ public final class AutofillManager { final boolean clientAdded = tryAddServiceClientIfNeededLocked(); if (clientAdded) { startSessionLocked(/* id= */ AutofillId.NO_AUTOFILL_ID, /* bounds= */ null, - /* value= */ null, /* flags= */ FLAG_PCC_DETECTION); + /* value= */ null, /* flags= */ FLAG_PCC_DETECTION); } else { if (sVerbose) { Log.v(TAG, "not starting session: no service client"); } } - } } } - if (mIsFillDialogEnabled - || ArrayUtils.containsAny(autofillHints, mFillDialogEnabledHints)) { + // Check if framework should send pre-fill request for fill dialog + boolean shouldSendPreFillRequestForFillDialog = false; + if (mIsFillDialogEnabled) { + shouldSendPreFillRequestForFillDialog = true; + } else if (autofillHints != null) { + // check if supported autofill hint is present + for (String autofillHint : autofillHints) { + for (String filldialogEnabledHint : mFillDialogEnabledHints) { + if (filldialogEnabledHint.equalsIgnoreCase(autofillHint)) { + shouldSendPreFillRequestForFillDialog = true; + break; + } + } + if (shouldSendPreFillRequestForFillDialog) break; + } + } + if (shouldSendPreFillRequestForFillDialog) { if (sDebug) { Log.d(TAG, "Triggering pre-emptive request for fill dialog."); } - int flags = FLAG_SUPPORTS_FILL_DIALOG; flags |= FLAG_VIEW_NOT_FOCUSED; - synchronized (mLock) { // To match the id of the IME served view, used AutofillId.NO_AUTOFILL_ID on prefill // request, because IME will reset the id of IME served view to 0 when activity @@ -1570,9 +1582,10 @@ public final class AutofillManager { // not match the IME served view's, Autofill will be blocking to wait inline // request from the IME. notifyViewEnteredLocked(/* view= */ null, AutofillId.NO_AUTOFILL_ID, - /* bounds= */ null, /* value= */ null, flags); + /* bounds= */ null, /* value= */ null, flags); } } + return; } private boolean hasFillDialogUiFeature() { diff --git a/core/java/android/view/flags/scroll_feedback_flags.aconfig b/core/java/android/view/flags/scroll_feedback_flags.aconfig index 62c569152ee9..d1d871c2dbda 100644 --- a/core/java/android/view/flags/scroll_feedback_flags.aconfig +++ b/core/java/android/view/flags/scroll_feedback_flags.aconfig @@ -5,4 +5,11 @@ flag { name: "scroll_feedback_api" description: "Enable the scroll feedback APIs" bug: "239594271" +} + +flag { + namespace: "toolkit" + name: "use_view_based_rotary_encoder_scroll_haptics" + description: "If enabled, the rotary encoder scroll haptic implementation in the View class will be used, and the HapticScrollFeedbackProvider logic for rotary encoder haptic will be muted." + bug: "299587011" }
\ No newline at end of file diff --git a/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java b/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java index 61470f2bc71a..3557f16a6dc8 100644 --- a/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java +++ b/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java @@ -417,7 +417,9 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub { if (mBeamer == null) { return; } - mBeamer.forget(token); + dispatch(() -> { + mBeamer.forget(token); + }); } @Override diff --git a/core/java/android/window/ScreenCapture.java b/core/java/android/window/ScreenCapture.java index e42193d45949..95e9e861bea2 100644 --- a/core/java/android/window/ScreenCapture.java +++ b/core/java/android/window/ScreenCapture.java @@ -24,6 +24,7 @@ import android.graphics.PixelFormat; import android.graphics.Rect; import android.hardware.HardwareBuffer; import android.os.Build; +import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; @@ -34,6 +35,7 @@ import libcore.util.NativeAllocationRegistry; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.function.ObjIntConsumer; + /** * Handles display and layer captures for the system. * @@ -43,6 +45,8 @@ public class ScreenCapture { private static final String TAG = "ScreenCapture"; private static final int SCREENSHOT_WAIT_TIME_S = 4 * Build.HW_TIMEOUT_MULTIPLIER; + private static native int nativeCaptureDisplay(DisplayCaptureArgs captureArgs, + long captureListener); private static native int nativeCaptureLayers(LayerCaptureArgs captureArgs, long captureListener); private static native long nativeCreateScreenCaptureListener( @@ -52,6 +56,37 @@ public class ScreenCapture { private static native long getNativeListenerFinalizer(); /** + * @param captureArgs Arguments about how to take the screenshot + * @param captureListener A listener to receive the screenshot callback + * @hide + */ + public static int captureDisplay(@NonNull DisplayCaptureArgs captureArgs, + @NonNull ScreenCaptureListener captureListener) { + return nativeCaptureDisplay(captureArgs, captureListener.mNativeObject); + } + + /** + * Captures all the surfaces in a display and returns a {@link ScreenshotHardwareBuffer} with + * the content. + * + * @hide + */ + public static ScreenshotHardwareBuffer captureDisplay( + DisplayCaptureArgs captureArgs) { + SynchronousScreenCaptureListener syncScreenCapture = createSyncCaptureListener(); + int status = captureDisplay(captureArgs, syncScreenCapture); + if (status != 0) { + return null; + } + + try { + return syncScreenCapture.getBuffer(); + } catch (Exception e) { + return null; + } + } + + /** * Captures a layer and its children and returns a {@link HardwareBuffer} with the content. * * @param layer The root layer to capture. @@ -484,6 +519,92 @@ public class ScreenCapture { } /** + * The arguments class used to make display capture requests. + * + * @hide + * @see #nativeCaptureDisplay(DisplayCaptureArgs, long) + */ + public static class DisplayCaptureArgs extends CaptureArgs { + private final IBinder mDisplayToken; + private final int mWidth; + private final int mHeight; + private final boolean mUseIdentityTransform; + + private DisplayCaptureArgs(Builder builder) { + super(builder); + mDisplayToken = builder.mDisplayToken; + mWidth = builder.mWidth; + mHeight = builder.mHeight; + mUseIdentityTransform = builder.mUseIdentityTransform; + } + + /** + * The Builder class used to construct {@link DisplayCaptureArgs} + */ + public static class Builder extends CaptureArgs.Builder<Builder> { + private IBinder mDisplayToken; + private int mWidth; + private int mHeight; + private boolean mUseIdentityTransform; + + /** + * Construct a new {@link LayerCaptureArgs} with the set parameters. The builder + * remains valid. + */ + public DisplayCaptureArgs build() { + if (mDisplayToken == null) { + throw new IllegalStateException( + "Can't take screenshot with null display token"); + } + return new DisplayCaptureArgs(this); + } + + public Builder(IBinder displayToken) { + setDisplayToken(displayToken); + } + + /** + * The display to take the screenshot of. + */ + public Builder setDisplayToken(IBinder displayToken) { + mDisplayToken = displayToken; + return this; + } + + /** + * Set the desired size of the returned buffer. The raw screen will be scaled down to + * this size + * + * @param width The desired width of the returned buffer. Caller may pass in 0 if no + * scaling is desired. + * @param height The desired height of the returned buffer. Caller may pass in 0 if no + * scaling is desired. + */ + public Builder setSize(int width, int height) { + mWidth = width; + mHeight = height; + return this; + } + + /** + * Replace the rotation transform of the display with the identity transformation while + * taking the screenshot. This ensures the screenshot is taken in the ROTATION_0 + * orientation. Set this value to false if the screenshot should be taken in the + * current screen orientation. + */ + public Builder setUseIdentityTransform(boolean useIdentityTransform) { + mUseIdentityTransform = useIdentityTransform; + return this; + } + + @Override + Builder getThis() { + return this; + } + } + } + + /** * The arguments class used to make layer capture requests. * * @hide @@ -561,6 +682,7 @@ public class ScreenCapture { /** * The object used to receive the results when invoking screen capture requests via + * {@link #captureDisplay(DisplayCaptureArgs, ScreenCaptureListener)} or * {@link #captureLayers(LayerCaptureArgs, ScreenCaptureListener)} * * This listener can only be used for a single call to capture content call. @@ -662,7 +784,8 @@ public class ScreenCapture { /** * Helper class to synchronously get the {@link ScreenshotHardwareBuffer} when calling - * {@link #captureLayers(LayerCaptureArgs, ScreenCaptureListener)} + * {@link #captureLayers(LayerCaptureArgs, ScreenCaptureListener)} or + * {@link #captureDisplay(DisplayCaptureArgs, ScreenCaptureListener)} */ public abstract static class SynchronousScreenCaptureListener extends ScreenCaptureListener { SynchronousScreenCaptureListener(ObjIntConsumer<ScreenshotHardwareBuffer> consumer) { diff --git a/core/java/android/window/flags/windowing_sdk.aconfig b/core/java/android/window/flags/windowing_sdk.aconfig index b8d251fc5cc5..ec5d4ff16ee5 100644 --- a/core/java/android/window/flags/windowing_sdk.aconfig +++ b/core/java/android/window/flags/windowing_sdk.aconfig @@ -15,3 +15,10 @@ flag { description: "Whether the overlay presentation feature is enabled" bug: "243518738" } + +flag { + namespace: "windowing_sdk" + name: "task_fragment_system_organizer_flag" + description: "Whether the TaskFragment system organizer feature is enabled" + bug: "284050041" +} diff --git a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java index 8de448be440b..cb2d93474971 100644 --- a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java +++ b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java @@ -80,6 +80,15 @@ public class SystemUiSystemPropertiesFlags { public static final Flag PROPAGATE_CHANNEL_UPDATES_TO_CONVERSATIONS = releasedFlag( "persist.sysui.notification.propagate_channel_updates_to_conversations"); + + // TODO: b/291907312 - remove feature flags + /** Gating the NMS->NotificationAttentionHelper buzzBeepBlink refactor */ + public static final Flag ENABLE_ATTENTION_HELPER_REFACTOR = devFlag( + "persist.debug.sysui.notification.enable_attention_helper_refactor"); + + /** b/301242692: Visit extra URIs used in notifications to prevent security issues. */ + public static final Flag VISIT_RISKY_URIS = devFlag( + "persist.sysui.notification.visit_risky_uris"); } //// == End of flags. Everything below this line is the implementation. == //// diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java index 18414cf93bc8..556c246e16d6 100644 --- a/core/java/com/android/internal/infra/AbstractRemoteService.java +++ b/core/java/com/android/internal/infra/AbstractRemoteService.java @@ -355,9 +355,10 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I obtainMessage(AbstractRemoteService::handleFinishRequest, this, finshedRequest)); } - private void handleFinishRequest(@NonNull BasePendingRequest<S, I> finshedRequest) { - mUnfinishedRequests.remove(finshedRequest); - + private void handleFinishRequest(@NonNull BasePendingRequest<S, I> finishedRequest) { + synchronized (mUnfinishedRequests) { + mUnfinishedRequests.remove(finishedRequest); + } if (mUnfinishedRequests.isEmpty()) { scheduleUnbind(); } @@ -460,7 +461,9 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I } else { if (mVerbose) Slog.v(mTag, "handlePendingRequest(): " + pendingRequest); - mUnfinishedRequests.add(pendingRequest); + synchronized (mUnfinishedRequests) { + mUnfinishedRequests.add(pendingRequest); + } cancelScheduledUnbind(); pendingRequest.run(); diff --git a/core/java/com/android/internal/security/VerityUtils.java b/core/java/com/android/internal/security/VerityUtils.java index 74a9d16c890d..7f7ea8b28546 100644 --- a/core/java/com/android/internal/security/VerityUtils.java +++ b/core/java/com/android/internal/security/VerityUtils.java @@ -17,8 +17,10 @@ package com.android.internal.security; import android.annotation.NonNull; +import android.annotation.Nullable; import android.os.Build; import android.os.SystemProperties; +import android.os.incremental.V4Signature; import android.system.Os; import android.system.OsConstants; import android.util.Slog; @@ -40,6 +42,9 @@ import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; +import java.security.DigestException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; @@ -192,9 +197,9 @@ public abstract class VerityUtils { * * @see <a href="https://www.kernel.org/doc/html/latest/filesystems/fsverity.html#file-digest-computation"> * File digest computation in Linux kernel documentation</a> - * @return Bytes of fs-verity digest + * @return Bytes of fs-verity digest, or null if the file does not have fs-verity enabled */ - public static byte[] getFsverityDigest(@NonNull String filePath) { + public static @Nullable byte[] getFsverityDigest(@NonNull String filePath) { byte[] result = new byte[HASH_SIZE_BYTES]; int retval = measureFsverityNative(filePath, result); if (retval < 0) { @@ -206,6 +211,34 @@ public abstract class VerityUtils { return result; } + /** + * Generates an fs-verity digest from a V4Signature.HashingInfo and the file's size. + */ + public static @NonNull byte[] generateFsVerityDigest(long fileSize, + @NonNull V4Signature.HashingInfo hashingInfo) + throws DigestException, NoSuchAlgorithmException { + if (hashingInfo.rawRootHash == null || hashingInfo.rawRootHash.length != 32) { + throw new IllegalArgumentException("Expect a 32-byte rootHash for SHA256"); + } + if (hashingInfo.log2BlockSize != 12) { + throw new IllegalArgumentException( + "Unsupported log2BlockSize: " + hashingInfo.log2BlockSize); + } + + var buffer = ByteBuffer.allocate(256); // sizeof(fsverity_descriptor) + buffer.order(ByteOrder.LITTLE_ENDIAN); + buffer.put((byte) 1); // version + buffer.put((byte) 1); // Merkle tree hash algorithm, 1 for SHA256 + buffer.put(hashingInfo.log2BlockSize); // log2(block-size), only log2(4096) is supported + buffer.put((byte) 0); // size of salt in bytes; 0 if none + buffer.putInt(0); // reserved, must be 0 + buffer.putLong(fileSize); // size of file the Merkle tree is built over + buffer.put(hashingInfo.rawRootHash); // Merkle tree root hash + // The rest are zeros, including the latter half of root hash unused for SHA256. + + return MessageDigest.getInstance("SHA-256").digest(buffer.array()); + } + /** @hide */ @VisibleForTesting public static byte[] toFormattedDigest(byte[] digest) { diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 6ed0a8a047f5..041f9c7edeef 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -158,12 +158,8 @@ static struct thread_dispatch_offsets_t // **************************************************************************** // **************************************************************************** -static constexpr int32_t PROXY_WARN_INTERVAL = 5000; static constexpr uint32_t GC_INTERVAL = 1000; -static std::atomic<uint32_t> gNumProxies(0); -static std::atomic<uint32_t> gProxiesWarned(0); - // Number of GlobalRefs held by JavaBBinders. static std::atomic<uint32_t> gNumLocalRefsCreated(0); static std::atomic<uint32_t> gNumLocalRefsDeleted(0); @@ -776,19 +772,7 @@ jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) return NULL; } BinderProxyNativeData* actualNativeData = getBPNativeData(env, object); - if (actualNativeData == nativeData) { - // Created a new Proxy - uint32_t numProxies = gNumProxies.fetch_add(1, std::memory_order_relaxed); - uint32_t numLastWarned = gProxiesWarned.load(std::memory_order_relaxed); - if (numProxies >= numLastWarned + PROXY_WARN_INTERVAL) { - // Multiple threads can get here, make sure only one of them gets to - // update the warn counter. - if (gProxiesWarned.compare_exchange_strong(numLastWarned, - numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed)) { - ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies); - } - } - } else { + if (actualNativeData != nativeData) { delete nativeData; } @@ -1143,7 +1127,7 @@ jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz) jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz) { - return gNumProxies.load(); + return BpBinder::getBinderProxyCount(); } jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz) @@ -1428,7 +1412,6 @@ static void BinderProxy_destroy(void* rawNativeData) nativeData->mObject.get(), nativeData->mOrgue.get()); delete nativeData; IPCThreadState::self()->flushCommands(); - --gNumProxies; } JNIEXPORT jlong JNICALL android_os_BinderProxy_getNativeFinalizer(JNIEnv*, jclass) { diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 74f64b758ff7..9384f41e26f5 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -967,6 +967,13 @@ static void nativeSetFrameRateCategory(JNIEnv* env, jclass clazz, jlong transact transaction->setFrameRateCategory(ctrl, static_cast<int8_t>(category)); } +static void nativeSetFrameRateSelectionStrategy(JNIEnv* env, jclass clazz, jlong transactionObj, + jlong nativeObject, jint strategy) { + auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); + const auto ctrl = reinterpret_cast<SurfaceControl*>(nativeObject); + transaction->setFrameRateSelectionStrategy(ctrl, static_cast<int8_t>(strategy)); +} + static void nativeSetFixedTransformHint(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject, jint transformHint) { auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); @@ -2173,6 +2180,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeSetDefaultFrameRateCompatibility}, {"nativeSetFrameRateCategory", "(JJI)V", (void*)nativeSetFrameRateCategory}, + {"nativeSetFrameRateSelectionStrategy", "(JJI)V", + (void*)nativeSetFrameRateSelectionStrategy}, {"nativeSetDisplaySurface", "(JLandroid/os/IBinder;J)V", (void*)nativeSetDisplaySurface }, {"nativeSetDisplayLayerStack", "(JLandroid/os/IBinder;I)V", diff --git a/core/jni/android_window_ScreenCapture.cpp b/core/jni/android_window_ScreenCapture.cpp index beb8c9b2d12f..bdf7eaa8aace 100644 --- a/core/jni/android_window_ScreenCapture.cpp +++ b/core/jni/android_window_ScreenCapture.cpp @@ -50,6 +50,13 @@ static struct { } gCaptureArgsClassInfo; static struct { + jfieldID displayToken; + jfieldID width; + jfieldID height; + jfieldID useIdentityTransform; +} gDisplayCaptureArgsClassInfo; + +static struct { jfieldID layer; jfieldID childrenOnly; } gLayerCaptureArgsClassInfo; @@ -174,6 +181,39 @@ static void getCaptureArgs(JNIEnv* env, jobject captureArgsObject, CaptureArgs& gCaptureArgsClassInfo.hintForSeamlessTransition); } +static DisplayCaptureArgs displayCaptureArgsFromObject(JNIEnv* env, + jobject displayCaptureArgsObject) { + DisplayCaptureArgs captureArgs; + getCaptureArgs(env, displayCaptureArgsObject, captureArgs); + + captureArgs.displayToken = + ibinderForJavaObject(env, + env->GetObjectField(displayCaptureArgsObject, + gDisplayCaptureArgsClassInfo.displayToken)); + captureArgs.width = + env->GetIntField(displayCaptureArgsObject, gDisplayCaptureArgsClassInfo.width); + captureArgs.height = + env->GetIntField(displayCaptureArgsObject, gDisplayCaptureArgsClassInfo.height); + captureArgs.useIdentityTransform = + env->GetBooleanField(displayCaptureArgsObject, + gDisplayCaptureArgsClassInfo.useIdentityTransform); + return captureArgs; +} + +static jint nativeCaptureDisplay(JNIEnv* env, jclass clazz, jobject displayCaptureArgsObject, + jlong screenCaptureListenerObject) { + const DisplayCaptureArgs captureArgs = + displayCaptureArgsFromObject(env, displayCaptureArgsObject); + + if (captureArgs.displayToken == nullptr) { + return BAD_VALUE; + } + + sp<gui::IScreenCaptureListener> captureListener = + reinterpret_cast<gui::IScreenCaptureListener*>(screenCaptureListenerObject); + return ScreenshotClient::captureDisplay(captureArgs, captureListener); +} + static jint nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptureArgsObject, jlong screenCaptureListenerObject) { LayerCaptureArgs captureArgs; @@ -243,6 +283,8 @@ static jlong getNativeListenerFinalizer(JNIEnv* env, jclass clazz) { static const JNINativeMethod sScreenCaptureMethods[] = { // clang-format off + {"nativeCaptureDisplay", "(Landroid/window/ScreenCapture$DisplayCaptureArgs;J)I", + (void*)nativeCaptureDisplay }, {"nativeCaptureLayers", "(Landroid/window/ScreenCapture$LayerCaptureArgs;J)I", (void*)nativeCaptureLayers }, {"nativeCreateScreenCaptureListener", "(Ljava/util/function/ObjIntConsumer;)J", @@ -275,6 +317,17 @@ int register_android_window_ScreenCapture(JNIEnv* env) { gCaptureArgsClassInfo.hintForSeamlessTransition = GetFieldIDOrDie(env, captureArgsClazz, "mHintForSeamlessTransition", "Z"); + jclass displayCaptureArgsClazz = + FindClassOrDie(env, "android/window/ScreenCapture$DisplayCaptureArgs"); + gDisplayCaptureArgsClassInfo.displayToken = + GetFieldIDOrDie(env, displayCaptureArgsClazz, "mDisplayToken", "Landroid/os/IBinder;"); + gDisplayCaptureArgsClassInfo.width = + GetFieldIDOrDie(env, displayCaptureArgsClazz, "mWidth", "I"); + gDisplayCaptureArgsClassInfo.height = + GetFieldIDOrDie(env, displayCaptureArgsClazz, "mHeight", "I"); + gDisplayCaptureArgsClassInfo.useIdentityTransform = + GetFieldIDOrDie(env, displayCaptureArgsClazz, "mUseIdentityTransform", "Z"); + jclass layerCaptureArgsClazz = FindClassOrDie(env, "android/window/ScreenCapture$LayerCaptureArgs"); gLayerCaptureArgsClassInfo.layer = diff --git a/core/res/res/layout/autofill_fill_dialog.xml b/core/res/res/layout/autofill_fill_dialog.xml index 37d2fa0540f0..196af6dfb6df 100644 --- a/core/res/res/layout/autofill_fill_dialog.xml +++ b/core/res/res/layout/autofill_fill_dialog.xml @@ -27,7 +27,7 @@ android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" - android:layout_marginTop="@dimen/autofill_save_outer_top_margin" + android:layout_marginTop="@dimen/autofill_save_outer_margin" android:layout_marginBottom="24dp" android:layout_marginStart="24dp" android:layout_marginEnd="24dp" diff --git a/core/res/res/layout/autofill_save.xml b/core/res/res/layout/autofill_save.xml index bed19a87eb16..8b6c90141bb7 100644 --- a/core/res/res/layout/autofill_save.xml +++ b/core/res/res/layout/autofill_save.xml @@ -22,59 +22,66 @@ android:background="@drawable/autofill_bottomsheet_background" android:orientation="vertical"> - <LinearLayout + <com.android.server.autofill.ui.BottomSheetLayout android:id="@+id/autofill_save" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/autofill_save_outer_top_margin" - android:layout_marginStart="24dp" - android:layout_marginEnd="24dp" + android:layout_marginTop="@dimen/autofill_save_outer_margin" android:background="?android:attr/colorSurface" android:gravity="center_horizontal" android:orientation="vertical"> - - <LinearLayout + <ScrollView android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:orientation="vertical"> - - <ImageView - android:id="@+id/autofill_save_icon" - android:scaleType="fitCenter" - android:layout_gravity="center" - android:layout_height="@dimen/autofill_save_icon_max_height" - android:layout_width="fill_parent"/> - - <TextView - android:id="@+id/autofill_save_title" + android:layout_height="0dp" + android:fillViewport="true" + android:layout_weight="1" + android:layout_marginBottom="8dp"> + <LinearLayout + android:layout_marginStart="@dimen/autofill_save_outer_margin" + android:layout_marginEnd="@dimen/autofill_save_outer_margin" android:layout_width="fill_parent" + android:orientation="vertical" android:layout_height="wrap_content" - android:text="@string/autofill_save_title" - android:layout_marginTop="16dp" - android:paddingBottom="24dp" - android:gravity="center" - android:textAppearance="@style/AutofillSaveUiTitle"> - </TextView> - - <com.android.server.autofill.ui.CustomScrollView - android:id="@+id/autofill_save_custom_subtitle" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:visibility="gone"/> - - </LinearLayout> + > + <ImageView + android:id="@+id/autofill_save_icon" + android:scaleType="fitCenter" + android:layout_gravity="center" + android:layout_height="@dimen/autofill_save_icon_max_height" + android:layout_width="fill_parent"/> + + <TextView + android:id="@+id/autofill_save_title" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="@string/autofill_save_title" + android:layout_marginTop="16dp" + android:paddingBottom="24dp" + android:gravity="center" + android:textAppearance="@style/AutofillSaveUiTitle"> + </TextView> + <LinearLayout + android:id="@+id/autofill_save_custom_subtitle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:visibility="gone"/> + + </LinearLayout> + </ScrollView> <com.android.internal.widget.ButtonBarLayout android:layout_width="match_parent" android:layout_height="48dp" android:layout_gravity="end" android:clipToPadding="false" - android:layout_marginTop="32dp" - android:layout_marginBottom="18dp" + android:layout_marginTop="16dp" + android:layout_marginBottom="8dp" android:theme="@style/Theme.DeviceDefault.AutofillHalfScreenDialogButton" android:orientation="horizontal" - android:gravity="center_vertical"> - + android:gravity="center_vertical" + android:layout_marginStart="@dimen/autofill_save_outer_margin" + android:layout_marginEnd="@dimen/autofill_save_outer_margin" + > <Button android:id="@+id/autofill_save_no" android:layout_width="wrap_content" @@ -106,6 +113,5 @@ </com.android.internal.widget.ButtonBarLayout> - </LinearLayout> - -</LinearLayout> + </com.android.server.autofill.ui.BottomSheetLayout> +</LinearLayout>
\ No newline at end of file diff --git a/core/res/res/layout/simple_list_item_multiple_choice.xml b/core/res/res/layout/simple_list_item_multiple_choice.xml index 440b6fd8e1b1..fd9bf76aade5 100644 --- a/core/res/res/layout/simple_list_item_multiple_choice.xml +++ b/core/res/res/layout/simple_list_item_multiple_choice.xml @@ -17,7 +17,8 @@ <CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="match_parent" - android:layout_height="?android:attr/listPreferredItemHeightSmall" + android:layout_height="wrap_content" + android:minHeight="?android:attr/listPreferredItemHeightSmall" android:textAppearance="?android:attr/textAppearanceListItemSmall" android:gravity="center_vertical" android:checkMark="?android:attr/listChoiceIndicatorMultiple" diff --git a/core/res/res/layout/simple_list_item_single_choice.xml b/core/res/res/layout/simple_list_item_single_choice.xml index 02cb7f77645c..a66308e1ad02 100644 --- a/core/res/res/layout/simple_list_item_single_choice.xml +++ b/core/res/res/layout/simple_list_item_single_choice.xml @@ -17,7 +17,8 @@ <CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="match_parent" - android:layout_height="?android:attr/listPreferredItemHeightSmall" + android:layout_height="wrap_content" + android:minHeight="?android:attr/listPreferredItemHeightSmall" android:textAppearance="?android:attr/textAppearanceListItemSmall" android:gravity="center_vertical" android:checkMark="?android:attr/listChoiceIndicatorSingle" diff --git a/core/res/res/values-sw640dp/dimens.xml b/core/res/res/values-sw640dp/dimens.xml new file mode 100644 index 000000000000..c632176ba1dd --- /dev/null +++ b/core/res/res/values-sw640dp/dimens.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> + <!-- Top and side margins for autofill dialog on tablets --> + <dimen name="autofill_save_outer_margin">32dp</dimen> +</resources>
\ No newline at end of file diff --git a/core/res/res/values-w640dp/bools.xml b/core/res/res/values-w640dp/bools.xml new file mode 100644 index 000000000000..64b20f7eaa96 --- /dev/null +++ b/core/res/res/values-w640dp/bools.xml @@ -0,0 +1,21 @@ +<?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> + <!-- Whether or not to include horizontal space around the dialog --> + <bool name="autofill_dialog_horizontal_space_included">true</bool> +</resources>
\ No newline at end of file diff --git a/core/res/res/values-w640dp/dimens.xml b/core/res/res/values-w640dp/dimens.xml new file mode 100644 index 000000000000..1f0c0b878610 --- /dev/null +++ b/core/res/res/values-w640dp/dimens.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> + <!-- How much extra space should be left around the autofill dialog --> + <dimen name="autofill_dialog_offset">56dp</dimen> +</resources>
\ No newline at end of file diff --git a/core/res/res/values-watch/config.xml b/core/res/res/values-watch/config.xml index 4027f5c78035..af305329da1a 100644 --- a/core/res/res/values-watch/config.xml +++ b/core/res/res/values-watch/config.xml @@ -41,6 +41,10 @@ measured in dips per second. Setting this to -1dp disables rotary encoder fling. --> <dimen name="config_viewMaxRotaryEncoderFlingVelocity">8000dp</dimen> + <!-- Whether the View-based scroll haptic feedback implementation is enabled for + {@link InputDevice#SOURCE_ROTARY_ENCODER}s. --> + <bool name="config_viewBasedRotaryEncoderHapticsEnabled">true</bool> + <!-- Number of notifications to keep in the notification service historical archive. Reduced intentionally for watches to retain minimal memory footprint --> <integer name="config_notificationServiceArchiveSize">1</integer> diff --git a/core/res/res/values/bools.xml b/core/res/res/values/bools.xml index fe296c704095..b097a613ebc1 100644 --- a/core/res/res/values/bools.xml +++ b/core/res/res/values/bools.xml @@ -30,4 +30,6 @@ lockscreen, setting this to true should come with customized drawables. --> <bool name="use_lock_pattern_drawable">false</bool> <bool name="resolver_landscape_phone">true</bool> + <!-- Whether or not to include horizontal space around the dialog --> + <bool name="autofill_dialog_horizontal_space_included">false</bool> </resources> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 2e2ec5ba52b3..3d0af3dbde3d 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -6711,4 +6711,7 @@ {@link MotionEvent#AXIS_SCROLL} generated by {@link InputDevice#SOURCE_ROTARY_ENCODER} devices. --> <bool name="config_viewRotaryEncoderHapticScrollFedbackEnabled">false</bool> + <!-- Whether the View-based scroll haptic feedback implementation is enabled for + {@link InputDevice#SOURCE_ROTARY_ENCODER}s. --> + <bool name="config_viewBasedRotaryEncoderHapticsEnabled">false</bool> </resources> diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml index 9bf3ce4268dd..878e6b306571 100644 --- a/core/res/res/values/config_telephony.xml +++ b/core/res/res/values/config_telephony.xml @@ -190,6 +190,11 @@ </string-array> <java-symbol type="array" name="config_satellite_services_supported_by_providers" /> + <!-- The identifier of the satellite's eSIM profile preloaded on the device. The identifier is + composed of MCC and MNC of the satellite PLMN with the format "mccmnc". --> + <string name="config_satellite_esim_identifier" translatable="false"></string> + <java-symbol type="string" name="config_satellite_esim_identifier" /> + <!-- Whether enhanced IWLAN handover check is enabled. If enabled, telephony frameworks will not perform handover if the target transport is out of service, or VoPS not supported. The network will be torn down on the source transport, and will be diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 0f2c264a5bd6..49295fd235ae 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -874,7 +874,7 @@ <dimen name="autofill_dataset_picker_max_height">90%</dimen> <!-- Autofill save dialog padding --> - <dimen name="autofill_save_outer_top_margin">24dp</dimen> + <dimen name="autofill_save_outer_margin">24dp</dimen> <dimen name="autofill_save_outer_top_padding">16dp</dimen> <dimen name="autofill_elevation">32dp</dimen> <dimen name="autofill_save_inner_padding">16dp</dimen> @@ -885,6 +885,9 @@ <dimen name="autofill_save_button_bar_padding">16dp</dimen> <dimen name="autofill_dialog_corner_radius">24dp</dimen> + <!-- How much extra space should be left around the autofill dialog --> + <dimen name="autofill_dialog_offset">72dp</dimen> + <!-- Max height of the the autofill save custom subtitle as a fraction of the screen width/height --> <dimen name="autofill_save_custom_subtitle_max_height">20%</dimen> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index fe1144958c52..83fb0986a19f 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3653,6 +3653,7 @@ <java-symbol type="layout" name="autofill_dataset_picker_fullscreen"/> <java-symbol type="layout" name="autofill_dataset_picker_header_footer"/> <java-symbol type="layout" name="autofill_fill_dialog"/> + <java-symbol type="id" name="autofill_save_icon"/> <java-symbol type="id" name="autofill" /> <java-symbol type="id" name="autofill_dataset_footer"/> <java-symbol type="id" name="autofill_dataset_header"/> @@ -3709,6 +3710,10 @@ <java-symbol type="dimen" name="autofill_save_custom_subtitle_max_height"/> <java-symbol type="integer" name="autofill_max_visible_datasets" /> <java-symbol type="dimen" name="autofill_dialog_max_width" /> + <java-symbol type="dimen" name="autofill_dialog_offset"/> + <java-symbol type="dimen" name="autofill_save_outer_margin"/> + + <java-symbol type="bool" name="autofill_dialog_horizontal_space_included"/> <java-symbol type="style" name="Theme.DeviceDefault.Autofill" /> <java-symbol type="style" name="Theme.DeviceDefault.Light.Autofill" /> @@ -5235,4 +5240,5 @@ <java-symbol type="array" name="config_tvExternalInputLoggingDeviceOnScreenDisplayNames" /> <java-symbol type="array" name="config_tvExternalInputLoggingDeviceBrandNames" /> <java-symbol type="bool" name="config_viewRotaryEncoderHapticScrollFedbackEnabled" /> + <java-symbol type="bool" name="config_viewBasedRotaryEncoderHapticsEnabled" /> </resources> diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml index 3b099e8ccafc..af8c69ea1441 100644 --- a/core/res/res/xml/sms_short_codes.xml +++ b/core/res/res/xml/sms_short_codes.xml @@ -216,6 +216,9 @@ <!-- Pakistan --> <shortcode country="pk" pattern="\\d{1,5}" free="2057" /> + <!-- Palestine: 5 digits, known premium codes listed --> + <shortcode country="ps" pattern="\\d{1,5}" free="37477" /> + <!-- Poland: 4-5 digits (not confirmed), known premium codes listed, plus EU --> <shortcode country="pl" pattern="\\d{4,5}" premium="74240|79(?:10|866)|92525" free="116\\d{3}|8012|80921" /> diff --git a/core/tests/GameManagerTests/src/android/app/GameManagerTests.java b/core/tests/GameManagerTests/src/android/app/GameManagerTests.java index fac3a0ecdec2..d34c91ee48ba 100644 --- a/core/tests/GameManagerTests/src/android/app/GameManagerTests.java +++ b/core/tests/GameManagerTests/src/android/app/GameManagerTests.java @@ -86,16 +86,6 @@ public final class GameManagerTests { GameModeInfo gameModeInfo = mGameManager.getGameModeInfo(mPackageName); assertNotNull(gameModeInfo); assertNull(gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_CUSTOM)); - GameModeConfiguration unsupportedFpsConfig = - new GameModeConfiguration.Builder().setFpsOverride( - 70).setScalingFactor(0.5f).build(); - mGameManager.updateCustomGameModeConfiguration(mPackageName, unsupportedFpsConfig); - gameModeInfo = mGameManager.getGameModeInfo(mPackageName); - assertNotNull(gameModeInfo); - // TODO(b/243448953): update to non-zero FPS when matching is implemented - assertEquals(new GameModeConfiguration.Builder().setFpsOverride( - GameModeConfiguration.FPS_OVERRIDE_NONE).setScalingFactor(0.5f).build(), - gameModeInfo.getGameModeConfiguration(GameManager.GAME_MODE_CUSTOM)); GameModeConfiguration supportedFpsConfig = new GameModeConfiguration.Builder().setFpsOverride( diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java index 89355072e29e..36e122301ba2 100644 --- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java +++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java @@ -33,7 +33,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -import android.annotation.Nullable; +import android.annotation.NonNull; import android.app.Activity; import android.app.ActivityThread; import android.app.ActivityThread.ActivityClientRecord; @@ -226,7 +226,7 @@ public class ActivityThreadTest { CompatibilityInfo.setOverrideInvertedScale(scale); try { // Send process level config change. - ClientTransaction transaction = newTransaction(activityThread, null); + ClientTransaction transaction = newTransaction(activityThread); transaction.addCallback(ConfigurationChangeItem.obtain( new Configuration(newConfig), DEVICE_ID_INVALID)); appThread.scheduleTransaction(transaction); @@ -243,7 +243,7 @@ public class ActivityThreadTest { // Send activity level config change. newConfig.seq++; newConfig.smallestScreenWidthDp++; - transaction = newTransaction(activityThread, activity.getActivityToken()); + transaction = newTransaction(activityThread); transaction.addCallback(ActivityConfigurationChangeItem.obtain( activity.getActivityToken(), new Configuration(newConfig))); appThread.scheduleTransaction(transaction); @@ -444,12 +444,12 @@ public class ActivityThreadTest { activity.mConfigLatch = new CountDownLatch(1); activity.mTestLatch = new CountDownLatch(1); - ClientTransaction transaction = newTransaction(activityThread, null); + ClientTransaction transaction = newTransaction(activityThread); transaction.addCallback(ConfigurationChangeItem.obtain( processConfigLandscape, DEVICE_ID_INVALID)); appThread.scheduleTransaction(transaction); - transaction = newTransaction(activityThread, activity.getActivityToken()); + transaction = newTransaction(activityThread); transaction.addCallback(ActivityConfigurationChangeItem.obtain( activity.getActivityToken(), activityConfigLandscape)); transaction.addCallback(ConfigurationChangeItem.obtain( @@ -829,7 +829,8 @@ public class ActivityThreadTest { return thread.getActivityClient(token); } - private static ClientTransaction newRelaunchResumeTransaction(Activity activity) { + @NonNull + private static ClientTransaction newRelaunchResumeTransaction(@NonNull Activity activity) { final Configuration currentConfig = activity.getResources().getConfiguration(); final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain( activity.getActivityToken(), null, null, 0, @@ -846,7 +847,8 @@ public class ActivityThreadTest { return transaction; } - private static ClientTransaction newResumeTransaction(Activity activity) { + @NonNull + private static ClientTransaction newResumeTransaction(@NonNull Activity activity) { final ResumeActivityItem resumeStateRequest = ResumeActivityItem.obtain(activity.getActivityToken(), true /* isForward */, false /* shouldSendCompatFakeFocus */); @@ -857,7 +859,8 @@ public class ActivityThreadTest { return transaction; } - private static ClientTransaction newStopTransaction(Activity activity) { + @NonNull + private static ClientTransaction newStopTransaction(@NonNull Activity activity) { final StopActivityItem stopStateRequest = StopActivityItem.obtain( activity.getActivityToken(), 0 /* configChanges */); @@ -867,8 +870,9 @@ public class ActivityThreadTest { return transaction; } - private static ClientTransaction newActivityConfigTransaction(Activity activity, - Configuration config) { + @NonNull + private static ClientTransaction newActivityConfigTransaction(@NonNull Activity activity, + @NonNull Configuration config) { final ActivityConfigurationChangeItem item = ActivityConfigurationChangeItem.obtain( activity.getActivityToken(), config); @@ -878,8 +882,9 @@ public class ActivityThreadTest { return transaction; } - private static ClientTransaction newNewIntentTransaction(Activity activity, - List<ReferrerIntent> intents, boolean resume) { + @NonNull + private static ClientTransaction newNewIntentTransaction(@NonNull Activity activity, + @NonNull List<ReferrerIntent> intents, boolean resume) { final NewIntentItem item = NewIntentItem.obtain(activity.getActivityToken(), intents, resume); @@ -889,13 +894,14 @@ public class ActivityThreadTest { return transaction; } - private static ClientTransaction newTransaction(Activity activity) { - return newTransaction(activity.getActivityThread(), activity.getActivityToken()); + @NonNull + private static ClientTransaction newTransaction(@NonNull Activity activity) { + return newTransaction(activity.getActivityThread()); } - private static ClientTransaction newTransaction(ActivityThread activityThread, - @Nullable IBinder activityToken) { - return ClientTransaction.obtain(activityThread.getApplicationThread(), activityToken); + @NonNull + private static ClientTransaction newTransaction(@NonNull ActivityThread activityThread) { + return ClientTransaction.obtain(activityThread.getApplicationThread()); } // Test activity diff --git a/core/tests/coretests/src/android/app/servertransaction/ActivityConfigurationChangeItemTest.java b/core/tests/coretests/src/android/app/servertransaction/ActivityConfigurationChangeItemTest.java index 08033cc4009c..785a8a1ced60 100644 --- a/core/tests/coretests/src/android/app/servertransaction/ActivityConfigurationChangeItemTest.java +++ b/core/tests/coretests/src/android/app/servertransaction/ActivityConfigurationChangeItemTest.java @@ -66,7 +66,7 @@ public class ActivityConfigurationChangeItemTest { final ActivityConfigurationChangeItem item = ActivityConfigurationChangeItem .obtain(mToken, mConfiguration); - final Context context = item.getContextToUpdate(mHandler, mToken); + final Context context = item.getContextToUpdate(mHandler); assertEquals(mActivity, context); } diff --git a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java index 3d252fbddb80..531404bffd50 100644 --- a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java +++ b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java @@ -21,7 +21,6 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.app.ClientTransactionHandler; -import android.os.IBinder; import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; @@ -46,22 +45,21 @@ public class ClientTransactionTests { @Test public void testPreExecute() { - ClientTransactionItem callback1 = mock(ClientTransactionItem.class); - ClientTransactionItem callback2 = mock(ClientTransactionItem.class); - ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class); - ClientTransactionHandler clientTransactionHandler = mock(ClientTransactionHandler.class); - IBinder token = mock(IBinder.class); + final ClientTransactionItem callback1 = mock(ClientTransactionItem.class); + final ClientTransactionItem callback2 = mock(ClientTransactionItem.class); + final ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class); + final ClientTransactionHandler clientTransactionHandler = + mock(ClientTransactionHandler.class); - ClientTransaction transaction = ClientTransaction.obtain(null /* client */, - token /* activityToken */); + final ClientTransaction transaction = ClientTransaction.obtain(null /* client */); transaction.addCallback(callback1); transaction.addCallback(callback2); transaction.setLifecycleStateRequest(stateRequest); transaction.preExecute(clientTransactionHandler); - verify(callback1, times(1)).preExecute(clientTransactionHandler, token); - verify(callback2, times(1)).preExecute(clientTransactionHandler, token); - verify(stateRequest, times(1)).preExecute(clientTransactionHandler, token); + verify(callback1, times(1)).preExecute(clientTransactionHandler); + verify(callback2, times(1)).preExecute(clientTransactionHandler); + verify(stateRequest, times(1)).preExecute(clientTransactionHandler); } } diff --git a/core/tests/coretests/src/android/app/servertransaction/ConfigurationChangeItemTest.java b/core/tests/coretests/src/android/app/servertransaction/ConfigurationChangeItemTest.java index 3926cfb14194..d9f5523c9782 100644 --- a/core/tests/coretests/src/android/app/servertransaction/ConfigurationChangeItemTest.java +++ b/core/tests/coretests/src/android/app/servertransaction/ConfigurationChangeItemTest.java @@ -24,7 +24,6 @@ import android.app.ActivityThread; import android.app.ClientTransactionHandler; import android.content.Context; import android.content.res.Configuration; -import android.os.IBinder; import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; @@ -49,8 +48,6 @@ public class ConfigurationChangeItemTest { @Mock private ClientTransactionHandler mHandler; - @Mock - private IBinder mToken; // Can't mock final class. private final Configuration mConfiguration = new Configuration(); @@ -63,7 +60,7 @@ public class ConfigurationChangeItemTest { public void testGetContextToUpdate() { final ConfigurationChangeItem item = ConfigurationChangeItem .obtain(mConfiguration, DEVICE_ID_DEFAULT); - final Context context = item.getContextToUpdate(mHandler, mToken); + final Context context = item.getContextToUpdate(mHandler); assertEquals(ActivityThread.currentApplication(), context); } diff --git a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java index c8d8f4be9e0a..4bbde0cd6366 100644 --- a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java +++ b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java @@ -27,6 +27,7 @@ import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import android.app.ActivityOptions; +import android.app.IApplicationThread; import android.app.servertransaction.TestUtils.LaunchActivityItemBuilder; import android.content.Intent; import android.content.pm.ActivityInfo; @@ -41,8 +42,11 @@ import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import java.util.function.Supplier; @@ -60,7 +64,15 @@ import java.util.function.Supplier; @Presubmit public class ObjectPoolTests { - private final IBinder mActivityToken = new Binder(); + @Mock + private IApplicationThread mApplicationThread; + @Mock + private IBinder mActivityToken; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + } // 1. Check if two obtained objects from pool are not the same. // 2. Check if the state of the object is cleared after recycling. @@ -309,15 +321,15 @@ public class ObjectPoolTests { @Test public void testRecycleClientTransaction() { - ClientTransaction emptyItem = ClientTransaction.obtain(null, null); - ClientTransaction item = ClientTransaction.obtain(null, new Binder()); + ClientTransaction emptyItem = ClientTransaction.obtain(null); + ClientTransaction item = ClientTransaction.obtain(mApplicationThread); assertNotSame(item, emptyItem); assertNotEquals(item, emptyItem); item.recycle(); assertEquals(item, emptyItem); - ClientTransaction item2 = ClientTransaction.obtain(null, new Binder()); + ClientTransaction item2 = ClientTransaction.obtain(mApplicationThread); assertSame(item, item2); assertNotEquals(item2, emptyItem); } diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java index a998b26b09c1..a1a2bdbe0f15 100644 --- a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java +++ b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java @@ -37,6 +37,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.annotation.NonNull; import android.app.Activity; import android.app.ActivityThread.ActivityClientRecord; import android.app.ClientTransactionHandler; @@ -230,8 +231,7 @@ public class TransactionExecutorTests { when(stateRequest.getActivityToken()).thenReturn(token); when(mTransactionHandler.getActivity(token)).thenReturn(mock(Activity.class)); - ClientTransaction transaction = ClientTransaction.obtain(null /* client */, - token /* activityToken */); + ClientTransaction transaction = ClientTransaction.obtain(null /* client */); transaction.addCallback(callback1); transaction.addCallback(callback2); transaction.setLifecycleStateRequest(stateRequest); @@ -240,8 +240,8 @@ public class TransactionExecutorTests { mExecutor.execute(transaction); InOrder inOrder = inOrder(mTransactionHandler, callback1, callback2, stateRequest); - inOrder.verify(callback1).execute(eq(mTransactionHandler), eq(token), any()); - inOrder.verify(callback2).execute(eq(mTransactionHandler), eq(token), any()); + inOrder.verify(callback1).execute(eq(mTransactionHandler), any()); + inOrder.verify(callback2).execute(eq(mTransactionHandler), any()); inOrder.verify(stateRequest).execute(eq(mTransactionHandler), eq(mClientRecord), any()); } @@ -254,8 +254,7 @@ public class TransactionExecutorTests { // An incoming destroy transaction enters binder thread (preExecute). final IBinder token = mock(IBinder.class); - final ClientTransaction destroyTransaction = ClientTransaction.obtain(null /* client */, - token /* activityToken */); + final ClientTransaction destroyTransaction = ClientTransaction.obtain(null /* client */); destroyTransaction.setLifecycleStateRequest( DestroyActivityItem.obtain(token, false /* finished */, 0 /* configChanges */)); destroyTransaction.preExecute(mTransactionHandler); @@ -263,8 +262,7 @@ public class TransactionExecutorTests { assertEquals(1, mTransactionHandler.getActivitiesToBeDestroyed().size()); // A previous queued launch transaction runs on main thread (execute). - final ClientTransaction launchTransaction = ClientTransaction.obtain(null /* client */, - token /* activityToken */); + final ClientTransaction launchTransaction = ClientTransaction.obtain(null /* client */); final LaunchActivityItem launchItem = spy(new LaunchActivityItemBuilder().setActivityToken(token).build()); launchTransaction.addCallback(launchItem); @@ -272,7 +270,7 @@ public class TransactionExecutorTests { // The launch transaction should not be executed because its token is in the // to-be-destroyed container. - verify(launchItem, never()).execute(any(), any(), any()); + verify(launchItem, never()).execute(any(), any()); // After the destroy transaction has been executed, the token should be removed. mExecutor.execute(destroyTransaction); @@ -286,8 +284,7 @@ public class TransactionExecutorTests { PostExecItem postExecItem = new PostExecItem(ON_RESUME); IBinder token = mock(IBinder.class); - ClientTransaction transaction = ClientTransaction.obtain(null /* client */, - token /* activityToken */); + ClientTransaction transaction = ClientTransaction.obtain(null /* client */); transaction.addCallback(postExecItem); // Verify resolution that should get to onPause @@ -439,7 +436,7 @@ public class TransactionExecutorTests { final ActivityTransactionItem activityItem = mock(ActivityTransactionItem.class); when(activityItem.getPostExecutionState()).thenReturn(UNDEFINED); final IBinder token = mock(IBinder.class); - final ClientTransaction transaction = ClientTransaction.obtain(null /* client */, token); + final ClientTransaction transaction = ClientTransaction.obtain(null /* client */); transaction.addCallback(activityItem); when(mTransactionHandler.getActivityClient(token)).thenReturn(null); @@ -449,7 +446,7 @@ public class TransactionExecutorTests { @Test public void testActivityItemExecute() { final IBinder token = mock(IBinder.class); - final ClientTransaction transaction = ClientTransaction.obtain(null /* client */, token); + final ClientTransaction transaction = ClientTransaction.obtain(null /* client */); final ActivityTransactionItem activityItem = mock(ActivityTransactionItem.class); when(activityItem.getPostExecutionState()).thenReturn(UNDEFINED); when(activityItem.getActivityToken()).thenReturn(token); @@ -504,12 +501,12 @@ public class TransactionExecutorTests { private StubItem() { } - private StubItem(Parcel in) { + private StubItem(@NonNull Parcel in) { } @Override - public void execute(ClientTransactionHandler client, IBinder token, - PendingTransactionActions pendingActions) { + public void execute(@NonNull ClientTransactionHandler client, + @NonNull PendingTransactionActions pendingActions) { } @Override @@ -517,12 +514,11 @@ public class TransactionExecutorTests { } @Override - public void writeToParcel(Parcel dest, int flags) { + public void writeToParcel(@NonNull Parcel dest, int flags) { } - public static final Parcelable.Creator<StubItem> CREATOR = - new Parcelable.Creator<StubItem>() { - public StubItem createFromParcel(Parcel in) { + public static final Parcelable.Creator<StubItem> CREATOR = new Parcelable.Creator<>() { + public StubItem createFromParcel(@NonNull Parcel in) { return new StubItem(in); } diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java index abc5d6b35b02..7d047c93520f 100644 --- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java +++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java @@ -284,9 +284,7 @@ public class TransactionParcelTests { StopActivityItem lifecycleRequest = StopActivityItem.obtain(mActivityToken, 78 /* configChanges */); - Binder activityToken = new Binder(); - - ClientTransaction transaction = ClientTransaction.obtain(null, activityToken); + ClientTransaction transaction = ClientTransaction.obtain(null /* client */); transaction.addCallback(callback1); transaction.addCallback(callback2); transaction.setLifecycleStateRequest(lifecycleRequest); @@ -307,9 +305,7 @@ public class TransactionParcelTests { ActivityConfigurationChangeItem callback2 = ActivityConfigurationChangeItem.obtain( mActivityToken, config()); - Binder activityToken = new Binder(); - - ClientTransaction transaction = ClientTransaction.obtain(null, activityToken); + ClientTransaction transaction = ClientTransaction.obtain(null /* client */); transaction.addCallback(callback1); transaction.addCallback(callback2); @@ -328,9 +324,7 @@ public class TransactionParcelTests { StopActivityItem lifecycleRequest = StopActivityItem.obtain(mActivityToken, 78 /* configChanges */); - Binder activityToken = new Binder(); - - ClientTransaction transaction = ClientTransaction.obtain(null, activityToken); + ClientTransaction transaction = ClientTransaction.obtain(null /* client */); transaction.setLifecycleStateRequest(lifecycleRequest); writeAndPrepareForReading(transaction); diff --git a/core/tests/coretests/src/android/app/servertransaction/WindowContextInfoChangeItemTest.java b/core/tests/coretests/src/android/app/servertransaction/WindowContextInfoChangeItemTest.java index db76d26b063e..a801a76d16c9 100644 --- a/core/tests/coretests/src/android/app/servertransaction/WindowContextInfoChangeItemTest.java +++ b/core/tests/coretests/src/android/app/servertransaction/WindowContextInfoChangeItemTest.java @@ -53,8 +53,6 @@ public class WindowContextInfoChangeItemTest { @Mock private ClientTransactionHandler mHandler; @Mock - private IBinder mToken; - @Mock private PendingTransactionActions mPendingActions; @Mock private IBinder mClientToken; @@ -72,7 +70,7 @@ public class WindowContextInfoChangeItemTest { public void testExecute() { final WindowContextInfoChangeItem item = WindowContextInfoChangeItem .obtain(mClientToken, mConfiguration, DEFAULT_DISPLAY); - item.execute(mHandler, mToken, mPendingActions); + item.execute(mHandler, mPendingActions); verify(mHandler).handleWindowContextInfoChanged(mClientToken, new WindowContextInfo(mConfiguration, DEFAULT_DISPLAY)); @@ -84,7 +82,7 @@ public class WindowContextInfoChangeItemTest { final WindowContextInfoChangeItem item = WindowContextInfoChangeItem .obtain(mClientToken, mConfiguration, DEFAULT_DISPLAY); - final Context context = item.getContextToUpdate(mHandler, mToken); + final Context context = item.getContextToUpdate(mHandler); assertEquals(mWindowContext, context); } diff --git a/core/tests/coretests/src/android/app/servertransaction/WindowContextWindowRemovalItemTest.java b/core/tests/coretests/src/android/app/servertransaction/WindowContextWindowRemovalItemTest.java index 17e0ebc1edbc..cf9935f2822f 100644 --- a/core/tests/coretests/src/android/app/servertransaction/WindowContextWindowRemovalItemTest.java +++ b/core/tests/coretests/src/android/app/servertransaction/WindowContextWindowRemovalItemTest.java @@ -45,8 +45,6 @@ public class WindowContextWindowRemovalItemTest { @Mock private ClientTransactionHandler mHandler; @Mock - private IBinder mToken; - @Mock private PendingTransactionActions mPendingActions; @Mock private IBinder mClientToken; @@ -60,7 +58,7 @@ public class WindowContextWindowRemovalItemTest { public void testExecute() { final WindowContextWindowRemovalItem item = WindowContextWindowRemovalItem.obtain( mClientToken); - item.execute(mHandler, mToken, mPendingActions); + item.execute(mHandler, mPendingActions); verify(mHandler).handleWindowContextWindowRemoval(mClientToken); } diff --git a/core/tests/coretests/src/android/view/HapticScrollFeedbackProviderTest.java b/core/tests/coretests/src/android/view/HapticScrollFeedbackProviderTest.java index d2af2a734330..3dfeb7f0fc05 100644 --- a/core/tests/coretests/src/android/view/HapticScrollFeedbackProviderTest.java +++ b/core/tests/coretests/src/android/view/HapticScrollFeedbackProviderTest.java @@ -26,6 +26,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.platform.test.annotations.Presubmit; +import android.view.flags.FeatureFlags; import androidx.test.InstrumentationRegistry; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -49,6 +50,7 @@ public final class HapticScrollFeedbackProviderTest { private TestView mView; @Mock ViewConfiguration mMockViewConfig; + @Mock FeatureFlags mMockFeatureFlags; private HapticScrollFeedbackProvider mProvider; @@ -56,9 +58,52 @@ public final class HapticScrollFeedbackProviderTest { public void setUp() { mMockViewConfig = mock(ViewConfiguration.class); setHapticScrollFeedbackEnabled(true); + when(mMockViewConfig.isViewBasedRotaryEncoderHapticScrollFeedbackEnabled()) + .thenReturn(false); mView = new TestView(InstrumentationRegistry.getContext()); - mProvider = new HapticScrollFeedbackProvider(mView, mMockViewConfig); + mProvider = new HapticScrollFeedbackProvider(mView, mMockViewConfig, + /* disabledIfViewPlaysScrollHaptics= */ true); + } + + @Test + public void testRotaryEncoder_noFeedbackWhenViewBasedFeedbackIsEnabled() { + when(mMockViewConfig.isViewBasedRotaryEncoderHapticScrollFeedbackEnabled()) + .thenReturn(true); + setHapticScrollTickInterval(5); + + mProvider.onScrollProgress( + INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, + /* deltaInPixels= */ 10); + mProvider.onSnapToItem( + INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL); + mProvider.onScrollLimit( + INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, + /* isStart= */ true); + + assertNoFeedback(mView); + } + + @Test + public void testRotaryEncoder_feedbackWhenDisregardingViewBasedScrollHaptics() { + mProvider = new HapticScrollFeedbackProvider(mView, mMockViewConfig, + /* disabledIfViewPlaysScrollHaptics= */ false); + when(mMockViewConfig.isViewBasedRotaryEncoderHapticScrollFeedbackEnabled()) + .thenReturn(true); + setHapticScrollTickInterval(5); + + mProvider.onScrollProgress( + INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, + /* deltaInPixels= */ 10); + mProvider.onSnapToItem( + INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL); + mProvider.onScrollLimit( + INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, + /* isStart= */ true); + + assertFeedbackCount(mView, SCROLL_TICK, 1); + assertFeedbackCount(mView, SCROLL_ITEM_FOCUS, 1); + assertFeedbackCount(mView, SCROLL_LIMIT, 1); } @Test @@ -94,20 +139,26 @@ public final class HapticScrollFeedbackProviderTest { @Test public void testScrollLimit_start() { + mProvider.onSnapToItem( + INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL); + mProvider.onScrollLimit( INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ true); - assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT); + assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1); } @Test public void testScrollLimit_stop() { + mProvider.onSnapToItem( + INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL); + mProvider.onScrollLimit( INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ false); - assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT); + assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1); } @Test @@ -207,8 +258,6 @@ public final class HapticScrollFeedbackProviderTest { INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* deltaInPixels= */ 60); - - assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_TICK, 2); } @@ -225,6 +274,9 @@ public final class HapticScrollFeedbackProviderTest { @Test public void testScrollLimit_startAndEndLimit_playsOnlyOneFeedback() { + mProvider.onSnapToItem( + INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL); + mProvider.onScrollLimit( INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ false); @@ -232,11 +284,14 @@ public final class HapticScrollFeedbackProviderTest { INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ true); - assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT); + assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1); } @Test public void testScrollLimit_doubleStartLimit_playsOnlyOneFeedback() { + mProvider.onSnapToItem( + INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL); + mProvider.onScrollLimit( INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ true); @@ -244,11 +299,14 @@ public final class HapticScrollFeedbackProviderTest { INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ true); - assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT); + assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1); } @Test public void testScrollLimit_doubleEndLimit_playsOnlyOneFeedback() { + mProvider.onSnapToItem( + INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL); + mProvider.onScrollLimit( INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ false); @@ -256,11 +314,13 @@ public final class HapticScrollFeedbackProviderTest { INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ false); - assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT); + assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1); } @Test public void testScrollLimit_notEnabledWithZeroProgress() { + mProvider.onSnapToItem( + INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL); mProvider.onScrollLimit( INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ false); @@ -275,11 +335,13 @@ public final class HapticScrollFeedbackProviderTest { INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ false); - assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1); + assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1); } @Test public void testScrollLimit_enabledWithProgress() { + mProvider.onSnapToItem( + INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL); mProvider.onScrollLimit( INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ false); @@ -291,11 +353,13 @@ public final class HapticScrollFeedbackProviderTest { INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ false); - assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT, 2); + assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 2); } @Test public void testScrollLimit_enabledWithSnap() { + mProvider.onSnapToItem( + INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL); mProvider.onScrollLimit( INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ false); @@ -310,7 +374,9 @@ public final class HapticScrollFeedbackProviderTest { } @Test - public void testScrollLimit_enabledWithDissimilarSnap() { + public void testScrollLimit_notEnabledWithDissimilarSnap() { + mProvider.onSnapToItem( + INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL); mProvider.onScrollLimit( INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ false); @@ -321,11 +387,13 @@ public final class HapticScrollFeedbackProviderTest { INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ false); - assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 2); + assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1); } @Test public void testScrollLimit_enabledWithDissimilarProgress() { + mProvider.onSnapToItem( + INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL); mProvider.onScrollLimit( INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ false); @@ -337,28 +405,27 @@ public final class HapticScrollFeedbackProviderTest { INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ false); - assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT, 2); + assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 2); } @Test - public void testScrollLimit_enabledWithMotionFromDifferentDeviceId() { + public void testScrollLimit_doesNotEnabledWithMotionFromDifferentDeviceId() { + mProvider.onSnapToItem( + INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL); mProvider.onScrollLimit( INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ false); - mProvider.onScrollLimit( - INPUT_DEVICE_2, - InputDevice.SOURCE_ROTARY_ENCODER, - MotionEvent.AXIS_SCROLL, - /* isStart= */ false); + mProvider.onSnapToItem( + INPUT_DEVICE_2, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL); mProvider.onScrollLimit( INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, /* isStart= */ false); - assertOnlyFeedback(mView, HapticFeedbackConstants.SCROLL_LIMIT, 3); + assertFeedbackCount(mView, HapticFeedbackConstants.SCROLL_LIMIT, 1); } diff --git a/core/tests/coretests/src/android/view/RotaryScrollHapticsTest.java b/core/tests/coretests/src/android/view/RotaryScrollHapticsTest.java new file mode 100644 index 000000000000..9a5c1c5112e6 --- /dev/null +++ b/core/tests/coretests/src/android/view/RotaryScrollHapticsTest.java @@ -0,0 +1,259 @@ +/* + * 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 static android.view.InputDevice.SOURCE_CLASS_POINTER; +import static android.view.InputDevice.SOURCE_ROTARY_ENCODER; +import static android.view.MotionEvent.ACTION_SCROLL; +import static android.view.MotionEvent.AXIS_HSCROLL; +import static android.view.MotionEvent.AXIS_SCROLL; +import static android.view.MotionEvent.AXIS_VSCROLL; + +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import android.content.Context; +import android.platform.test.annotations.Presubmit; + +import androidx.test.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; + +/** Test for the rotary scroll haptics implementation in the View class. */ +@SmallTest +@RunWith(AndroidJUnit4.class) +@Presubmit +public final class RotaryScrollHapticsTest { + private static final int TEST_ROTARY_DEVICE_ID = 1; + private static final int TEST_RANDOM_DEVICE_ID = 2; + + private static final float TEST_SCALED_VERTICAL_SCROLL_FACTOR = 5f; + + @Mock ViewConfiguration mMockViewConfig; + @Mock HapticScrollFeedbackProvider mMockScrollFeedbackProvider; + + private TestGenericMotionEventControllingView mView; + + @Before + public void setUp() { + mMockViewConfig = mock(ViewConfiguration.class); + mMockScrollFeedbackProvider = mock(HapticScrollFeedbackProvider.class); + + Context context = InstrumentationRegistry.getTargetContext(); + mView = new TestGenericMotionEventControllingView(context); + mView.mScrollFeedbackProvider = mMockScrollFeedbackProvider; + + ViewConfiguration.setInstanceForTesting(context, mMockViewConfig); + when(mMockViewConfig.getScaledVerticalScrollFactor()) + .thenReturn(TEST_SCALED_VERTICAL_SCROLL_FACTOR); + mockRotaryScrollHapticsEnabled(true); + } + + @After + public void tearDown() { + ViewConfiguration.resetCacheForTesting(); + } + + @Test + public void testRotaryScrollHapticsDisabled_producesNoHapticEvent() { + mockRotaryScrollHapticsEnabled(false); + + mView.configureGenericMotion(/* result= */ false, /* scroll= */ false); + mView.dispatchGenericMotionEvent(createRotaryEvent(-20)); + + mView.configureGenericMotion(/* result= */ false, /* scroll= */ true); + mView.dispatchGenericMotionEvent(createRotaryEvent(20)); + + mView.configureGenericMotion(/* result= */ true, /* scroll= */ true); + mView.dispatchGenericMotionEvent(createRotaryEvent(10)); + + mView.configureGenericMotion(/* result= */ true, /* scroll= */ false); + mView.dispatchGenericMotionEvent(createRotaryEvent(-10)); + + verifyNoScrollLimit(); + verifyNoScrollProgress(); + } + + @Test + public void testNonRotaryEncoderMotion_producesNoHapticEvent() { + mView.configureGenericMotion(/* result= */ false, /* scroll= */ false); + mView.dispatchGenericMotionEvent(createGenericPointerEvent(1, 2)); + + mView.configureGenericMotion(/* result= */ false, /* scroll= */ true); + mView.dispatchGenericMotionEvent(createGenericPointerEvent(2, 2)); + + mView.configureGenericMotion(/* result= */ true, /* scroll= */ true); + mView.dispatchGenericMotionEvent(createGenericPointerEvent(1, 3)); + + mView.configureGenericMotion(/* result= */ true, /* scroll= */ false); + mView.dispatchGenericMotionEvent(createGenericPointerEvent(-1, -2)); + + verifyNoScrollLimit(); + verifyNoScrollProgress(); + } + + @Test + public void testScrollLimit_start_genericMotionEventCallbackReturningFalse_doesScrollLimit() { + mView.configureGenericMotion(/* result= */ false, /* scroll= */ false); + + mView.dispatchGenericMotionEvent(createRotaryEvent(20)); + + verifyScrollLimit(/* isStart= */ true); + verifyNoScrollProgress(); + } + + @Test + public void testScrollLimit_start_genericMotionEventCallbackReturningTrue_doesScrollLimit() { + mView.configureGenericMotion(/* result= */ true, /* scroll= */ false); + + mView.dispatchGenericMotionEvent(createRotaryEvent(20)); + + verifyScrollLimit(/* isStart= */ true); + verifyNoScrollProgress(); + } + + @Test + public void testScrollLimit_end_genericMotionEventCallbackReturningFalse_doesScrollLimit() { + mView.configureGenericMotion(/* result= */ false, /* scroll= */ false); + + mView.dispatchGenericMotionEvent(createRotaryEvent(-20)); + + verifyScrollLimit(/* isStart= */ false); + verifyNoScrollProgress(); + } + + @Test + public void testScrollLimit_end_genericMotionEventCallbackReturningTrue_doesScrollLimit() { + mView.configureGenericMotion(/* result= */ true, /* scroll= */ false); + + mView.dispatchGenericMotionEvent(createRotaryEvent(-20)); + + verifyScrollLimit(/* isStart= */ false); + verifyNoScrollProgress(); + } + + @Test + public void testScrollProgress_genericMotionEventCallbackReturningFalse_doesScrollProgress() { + mView.configureGenericMotion(/* result= */ false, /* scroll= */ true); + + mView.dispatchGenericMotionEvent(createRotaryEvent(20)); + + verifyScrollProgress(-1 * 20 * (int) TEST_SCALED_VERTICAL_SCROLL_FACTOR); + verifyNoScrollLimit(); + } + + @Test + public void testScrollProgress_genericMotionEventCallbackReturningTrue_doesScrollProgress() { + mView.configureGenericMotion(/* result= */ true, /* scroll= */ true); + + mView.dispatchGenericMotionEvent(createRotaryEvent(-20)); + + verifyScrollProgress(-1 * -20 * (int) TEST_SCALED_VERTICAL_SCROLL_FACTOR); + verifyNoScrollLimit(); + } + + private void verifyScrollProgress(int scrollPixels) { + verify(mMockScrollFeedbackProvider).onScrollProgress( + TEST_ROTARY_DEVICE_ID, SOURCE_ROTARY_ENCODER, AXIS_SCROLL, scrollPixels); + } + + private void verifyNoScrollProgress() { + verify(mMockScrollFeedbackProvider, never()).onScrollProgress( + anyInt(), anyInt(), anyInt(), anyInt()); + } + + private void verifyScrollLimit(boolean isStart) { + verify(mMockScrollFeedbackProvider).onScrollLimit( + TEST_ROTARY_DEVICE_ID, SOURCE_ROTARY_ENCODER, AXIS_SCROLL, isStart); + } + + private void verifyNoScrollLimit() { + verify(mMockScrollFeedbackProvider, never()).onScrollLimit( + anyInt(), anyInt(), anyInt(), anyBoolean()); + } + + private void mockRotaryScrollHapticsEnabled(boolean enabled) { + when(mMockViewConfig.isViewBasedRotaryEncoderHapticScrollFeedbackEnabled()) + .thenReturn(enabled); + } + + /** + * Test implementation for View giving control on behavior of + * {@link View#onGenericMotionEvent(MotionEvent)}. + */ + private static final class TestGenericMotionEventControllingView extends View { + private boolean mGenericMotionResult; + private boolean mScrollOnGenericMotion; + + TestGenericMotionEventControllingView(Context context) { + super(context); + } + + void configureGenericMotion(boolean result, boolean scroll) { + mGenericMotionResult = result; + mScrollOnGenericMotion = scroll; + } + + @Override + public boolean onGenericMotionEvent(MotionEvent event) { + if (mScrollOnGenericMotion) { + scrollTo(100, 200); // scroll values random (not relevant for tests). + } + return mGenericMotionResult; + } + } + + private static MotionEvent createRotaryEvent(float scroll) { + MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords(); + coords.setAxisValue(AXIS_SCROLL, scroll); + + return createGenericMotionEvent( + TEST_ROTARY_DEVICE_ID, SOURCE_ROTARY_ENCODER, ACTION_SCROLL, coords); + } + + private static MotionEvent createGenericPointerEvent(float hScroll, float vScroll) { + MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords(); + coords.setAxisValue(AXIS_HSCROLL, hScroll); + coords.setAxisValue(AXIS_VSCROLL, vScroll); + + return createGenericMotionEvent( + TEST_RANDOM_DEVICE_ID, SOURCE_CLASS_POINTER, ACTION_SCROLL, coords); + } + + private static MotionEvent createGenericMotionEvent( + int deviceId, int source, int action, MotionEvent.PointerCoords coords) { + MotionEvent.PointerProperties props = new MotionEvent.PointerProperties(); + props.id = 0; + + return MotionEvent.obtain( + /* downTime= */ 0, /* eventTime= */ 100, action, /* pointerCount= */ 1, + new MotionEvent.PointerProperties[] {props}, + new MotionEvent.PointerCoords[] {coords}, + /* metaState= */ 0, /* buttonState= */ 0, /* xPrecision= */ 0, /* yPrecision= */ 0, + deviceId, /* edgeFlags= */ 0, source, /* flags= */ 0); + } +} diff --git a/core/tests/fuzzers/ParcelFuzzer/ReadUtils.java b/core/tests/fuzzers/ParcelFuzzer/ReadUtils.java index b5e5b258b7d6..cb988555d5f7 100644 --- a/core/tests/fuzzers/ParcelFuzzer/ReadUtils.java +++ b/core/tests/fuzzers/ParcelFuzzer/ReadUtils.java @@ -364,6 +364,12 @@ public class ReadUtils { TestClassLoader loader = new TestClassLoader(); parcel.readParcelableArray(loader); }, + (parcel, provider) -> { + parcel.readParcelable(null); + }, + (parcel, provider) -> { + parcel.readParcelableArray(null); + }, // read lists (parcel, provider) -> { diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.bp b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.bp index d0645b0d8b12..23a2a7fbf0e5 100644 --- a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.bp +++ b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.bp @@ -28,7 +28,7 @@ android_test_helper_app { srcs: ["src/**/*.java"], - sdk_version: "16", + sdk_version: "19", javacflags: ["-nowarn"], @@ -43,5 +43,5 @@ android_test_helper_app { enabled: false, }, - min_sdk_version: "16", + min_sdk_version: "19", } diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.bp b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.bp index c0c8aba2d2f0..4ddaeef0e4a2 100644 --- a/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.bp +++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestApp/Android.bp @@ -40,7 +40,7 @@ android_test_helper_app { enabled: false, }, - min_sdk_version: "16", + min_sdk_version: "19", } android_test_helper_app { @@ -66,5 +66,5 @@ android_test_helper_app { enabled: false, }, - min_sdk_version: "16", + min_sdk_version: "19", } diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests/Android.bp b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests/Android.bp index fe294168586d..afb111d7e2d4 100644 --- a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests/Android.bp +++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests/Android.bp @@ -28,7 +28,7 @@ android_test { javacflags: ["-nowarn"], - min_sdk_version: "16", + min_sdk_version: "19", instrumentation_for: "MultiDexLegacyTestApp", } diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests2/Android.bp b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests2/Android.bp index c558153c6a4e..8c57df6707f2 100644 --- a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests2/Android.bp +++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppTests2/Android.bp @@ -31,7 +31,7 @@ android_test { javacflags: ["-nowarn"], - min_sdk_version: "16", + min_sdk_version: "19", instrumentation_for: "MultiDexLegacyTestApp", } @@ -51,7 +51,7 @@ android_test { javacflags: ["-nowarn"], - min_sdk_version: "16", + min_sdk_version: "19", instrumentation_for: "MultiDexLegacyTestApp", } diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppWithCorruptedDex/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppWithCorruptedDex/AndroidManifest.xml index 9a4c3c5d6e81..840daabc2ba9 100644 --- a/core/tests/hosttests/test-apps/MultiDexLegacyTestAppWithCorruptedDex/AndroidManifest.xml +++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestAppWithCorruptedDex/AndroidManifest.xml @@ -5,8 +5,8 @@ android:versionCode="1" android:versionName="1.0"> - <uses-sdk android:minSdkVersion="18" - android:targetSdkVersion="18"/> + <uses-sdk android:minSdkVersion="19" + android:targetSdkVersion="19"/> <application android:name="androidx.multidex.MultiDexApplication" android:allowBackup="true" diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyTestServicesTests2/Android.bp b/core/tests/hosttests/test-apps/MultiDexLegacyTestServicesTests2/Android.bp index 75c753cef0fd..2244a830e254 100644 --- a/core/tests/hosttests/test-apps/MultiDexLegacyTestServicesTests2/Android.bp +++ b/core/tests/hosttests/test-apps/MultiDexLegacyTestServicesTests2/Android.bp @@ -24,5 +24,5 @@ android_test { libs: ["android-support-multidex"], static_libs: ["androidx.test.rules"], - sdk_version: "16", + sdk_version: "19", } diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index e46ba9abc9a6..ad0ead78f492 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -3973,12 +3973,6 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, - "1563836923": { - "message": "Content Recording: Unable to record task since feature is disabled %d", - "level": "VERBOSE", - "group": "WM_DEBUG_CONTENT_RECORDING", - "at": "com\/android\/server\/wm\/ContentRecorder.java" - }, "1577579529": { "message": "win=%s destroySurfaces: appStopped=%b win.mWindowRemovalAllowed=%b win.mRemoveOnExit=%b", "level": "ERROR", diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java index c3d8f9a99d79..a663f9fafb50 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java @@ -20,7 +20,6 @@ import android.app.ActivityTaskManager; import android.app.ActivityThread; import android.app.Application; import android.content.Context; -import android.window.TaskFragmentOrganizer; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -83,13 +82,7 @@ public class WindowExtensionsImpl implements WindowExtensions { Context context = getApplication(); DeviceStateManagerFoldingFeatureProducer producer = getFoldingFeatureProducer(); - // TODO(b/263263909) Use the organizer to tell if an Activity is embededed. - // Need to improve our Dependency Injection and centralize the logic. - TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(command -> { - throw new RuntimeException("Not allowed!"); - }); - mWindowLayoutComponent = new WindowLayoutComponentImpl(context, organizer, - producer); + mWindowLayoutComponent = new WindowLayoutComponentImpl(context, producer); } } } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java index ba57b76020b4..9b84a48cdbda 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java @@ -17,6 +17,7 @@ package androidx.window.extensions.layout; import static android.view.Display.DEFAULT_DISPLAY; + import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_FLAT; import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_HALF_OPENED; import static androidx.window.util.ExtensionHelper.isZero; @@ -24,7 +25,7 @@ import static androidx.window.util.ExtensionHelper.rotateRectToDisplayRotation; import static androidx.window.util.ExtensionHelper.transformToWindowSpaceRect; import android.app.Activity; -import android.app.ActivityClient; +import android.app.ActivityThread; import android.app.Application; import android.app.WindowConfiguration; import android.content.ComponentCallbacks; @@ -34,8 +35,7 @@ import android.graphics.Rect; import android.os.Bundle; import android.os.IBinder; import android.util.ArrayMap; -import android.view.WindowManager; -import android.window.TaskFragmentOrganizer; +import android.util.Log; import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; @@ -51,7 +51,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; /** @@ -63,7 +62,7 @@ import java.util.Set; * Please refer to {@link androidx.window.sidecar.SampleSidecarImpl} instead. */ public class WindowLayoutComponentImpl implements WindowLayoutComponent { - private static final String TAG = "SampleExtension"; + private static final String TAG = WindowLayoutComponentImpl.class.getSimpleName(); private final Object mLock = new Object(); @@ -85,16 +84,15 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { private final Map<java.util.function.Consumer<WindowLayoutInfo>, Consumer<WindowLayoutInfo>> mJavaToExtConsumers = new ArrayMap<>(); - private final TaskFragmentOrganizer mTaskFragmentOrganizer; + private final RawConfigurationChangedListener mRawConfigurationChangedListener = + new RawConfigurationChangedListener(); public WindowLayoutComponentImpl(@NonNull Context context, - @NonNull TaskFragmentOrganizer taskFragmentOrganizer, @NonNull DeviceStateManagerFoldingFeatureProducer foldingFeatureProducer) { ((Application) context.getApplicationContext()) .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged()); mFoldingFeatureProducer = foldingFeatureProducer; mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged); - mTaskFragmentOrganizer = taskFragmentOrganizer; } /** @@ -109,6 +107,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { final Consumer<WindowLayoutInfo> extConsumer = consumer::accept; synchronized (mLock) { mJavaToExtConsumers.put(consumer, extConsumer); + updateListenerRegistrations(); } addWindowLayoutInfoListener(activity, extConsumer); } @@ -162,6 +161,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { final Consumer<WindowLayoutInfo> extConsumer; synchronized (mLock) { extConsumer = mJavaToExtConsumers.remove(consumer); + updateListenerRegistrations(); } if (extConsumer != null) { removeWindowLayoutInfoListener(extConsumer); @@ -192,6 +192,17 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { } @GuardedBy("mLock") + private void updateListenerRegistrations() { + ActivityThread currentThread = ActivityThread.currentActivityThread(); + if (mJavaToExtConsumers.isEmpty()) { + currentThread.removeConfigurationChangedListener(mRawConfigurationChangedListener); + } else { + currentThread.addConfigurationChangedListener(Runnable::run, + mRawConfigurationChangedListener); + } + } + + @GuardedBy("mLock") @NonNull private Set<Context> getContextsListeningForLayoutChanges() { return mWindowLayoutChangeListeners.keySet(); @@ -336,25 +347,28 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { continue; } if (featureRect.left != 0 && featureRect.top != 0) { - throw new IllegalArgumentException("Bounding rectangle must start at the top or " + Log.wtf(TAG, "Bounding rectangle must start at the top or " + "left of the window. BaseFeatureRect: " + baseFeature.getRect() + ", FeatureRect: " + featureRect + ", WindowConfiguration: " + windowConfiguration); + continue; } if (featureRect.left == 0 && featureRect.width() != windowConfiguration.getBounds().width()) { - throw new IllegalArgumentException("Horizontal FoldingFeature must have full width." + Log.wtf(TAG, "Horizontal FoldingFeature must have full width." + " BaseFeatureRect: " + baseFeature.getRect() + ", FeatureRect: " + featureRect + ", WindowConfiguration: " + windowConfiguration); + continue; } if (featureRect.top == 0 && featureRect.height() != windowConfiguration.getBounds().height()) { - throw new IllegalArgumentException("Vertical FoldingFeature must have full height." + Log.wtf(TAG, "Vertical FoldingFeature must have full height." + " BaseFeatureRect: " + baseFeature.getRect() + ", FeatureRect: " + featureRect + ", WindowConfiguration: " + windowConfiguration); + continue; } features.add(new FoldingFeature(featureRect, baseFeature.getType(), state)); } @@ -374,38 +388,11 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { // Display features are not supported on secondary displays. return false; } - final int windowingMode; - IBinder activityToken = context.getActivityToken(); - if (activityToken != null) { - final Configuration taskConfig = ActivityClient.getInstance().getTaskConfiguration( - activityToken); - if (taskConfig == null) { - // If we cannot determine the task configuration for any reason, it is likely that - // we won't be able to determine its position correctly as well. DisplayFeatures' - // bounds in this case can't be computed correctly, so we should skip. - return false; - } - final Rect taskBounds = taskConfig.windowConfiguration.getBounds(); - final WindowManager windowManager = Objects.requireNonNull( - context.getSystemService(WindowManager.class)); - final Rect maxBounds = windowManager.getMaximumWindowMetrics().getBounds(); - boolean isTaskExpanded = maxBounds.equals(taskBounds); - /* - * We need to proxy being in full screen because when a user enters PiP and exits PiP - * the task windowingMode will report multi-window/pinned until the transition is - * finished in WM Shell. - * maxBounds == taskWindowBounds is a proxy check to verify the window is full screen - */ - return isTaskExpanded; - } else { - // TODO(b/242674941): use task windowing mode for window context that associates with - // activity. - windowingMode = context.getResources().getConfiguration().windowConfiguration - .getWindowingMode(); - } - // It is recommended not to report any display features in multi-window mode, since it - // won't be possible to synchronize the display feature positions with window movement. - return !WindowConfiguration.inMultiWindowMode(windowingMode); + + // We do not report folding features for Activities in PiP because the bounds are + // not updated fast enough and the window is too small for the UI to adapt. + return context.getResources().getConfiguration().windowConfiguration + .getWindowingMode() != WindowConfiguration.WINDOWING_MODE_PINNED; } @GuardedBy("mLock") @@ -434,6 +421,16 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { } } + private final class RawConfigurationChangedListener implements + java.util.function.Consumer<IBinder> { + @Override + public void accept(IBinder activityToken) { + synchronized (mLock) { + onDisplayFeaturesChangedIfListening(activityToken); + } + } + } + private final class ConfigurationChangeListener implements ComponentCallbacks { final IBinder mToken; diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_handle_menu_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_handle_menu_background.xml index 4ee10f429b37..15837adc2c77 100644 --- a/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_handle_menu_background.xml +++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_handle_menu_background.xml @@ -15,7 +15,8 @@ ~ limitations under the License. --> <shape android:shape="rectangle" - xmlns:android="http://schemas.android.com/apk/res/android"> - <solid android:color="@android:color/white" /> + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"> <corners android:radius="@dimen/desktop_mode_handle_menu_corner_radius" /> + <solid android:color="?androidprv:attr/materialColorSurfaceBright" /> </shape> diff --git a/libs/WindowManager/Shell/res/drawable/ic_baseline_expand_more_24.xml b/libs/WindowManager/Shell/res/drawable/ic_baseline_expand_more_24.xml index 3e0297ab612b..e9df936c3f94 100644 --- a/libs/WindowManager/Shell/res/drawable/ic_baseline_expand_more_24.xml +++ b/libs/WindowManager/Shell/res/drawable/ic_baseline_expand_more_24.xml @@ -14,8 +14,14 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License --> -<vector android:height="24dp" android:tint="#000000" - android:viewportHeight="24" android:viewportWidth="24" - android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> - <path android:fillColor="@android:color/black" android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z"/> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="?android:attr/textColorSecondary"> + <path + android:fillColor="#FF000000" + android:pathData="M5.41,7.59L4,9l8,8 8,-8 -1.41,-1.41L12,14.17"/> </vector> + diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml index 7e0c2071dc86..fa56516e0d22 100644 --- a/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml +++ b/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml @@ -31,35 +31,35 @@ android:orientation="horizontal" android:clickable="true" android:focusable="true" - android:paddingStart="8dp"> + android:paddingStart="16dp"> <ImageView android:id="@+id/application_icon" android:layout_width="24dp" android:layout_height="24dp" - android:layout_margin="4dp" android:layout_gravity="center_vertical" android:contentDescription="@string/app_icon_text" /> <TextView android:id="@+id/application_name" android:layout_width="0dp" - android:layout_height="match_parent" + android:layout_height="20dp" android:minWidth="80dp" android:textColor="@color/desktop_mode_caption_app_name_dark" + android:textAppearance="@android:style/TextAppearance.Material.Title" android:textSize="14sp" android:textFontWeight="500" - android:gravity="center_vertical" + android:lineHeight="20dp" + android:layout_gravity="center_vertical" android:layout_weight="1" - android:paddingStart="4dp" - android:paddingEnd="4dp" + android:paddingStart="8dp" + android:paddingEnd="8dp" tools:text="Gmail"/> <ImageButton android:id="@+id/expand_menu_button" - android:layout_width="32dp" - android:layout_height="32dp" - android:padding="4dp" + android:layout_width="16dp" + android:layout_height="16dp" android:contentDescription="@string/expand_menu_text" android:src="@drawable/ic_baseline_expand_more_24" android:tint="@color/desktop_mode_caption_expand_button_dark" diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_app_info_pill.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_app_info_pill.xml index c03d240d59f2..c2ee3066d059 100644 --- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_app_info_pill.xml +++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_app_info_pill.xml @@ -15,6 +15,7 @@ ~ limitations under the License. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="@dimen/desktop_mode_handle_menu_width" android:layout_height="@dimen/desktop_mode_handle_menu_app_info_pill_height" @@ -35,7 +36,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" tools:text="Gmail" - android:textColor="@color/desktop_mode_caption_menu_text_color" + android:textColor="?androidprv:attr/materialColorOnSurface" android:textSize="14sp" android:textFontWeight="500" android:lineHeight="20dp" @@ -52,6 +53,6 @@ android:contentDescription="@string/collapse_menu_text" android:src="@drawable/ic_baseline_expand_more_24" android:rotation="180" - android:tint="@color/desktop_mode_caption_menu_buttons_color_inactive" + android:tint="?androidprv:attr/materialColorOnSurface" android:background="?android:selectableItemBackgroundBorderless"/> </LinearLayout>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_more_actions_pill.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_more_actions_pill.xml index cdf4937599c9..e637671937bd 100644 --- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_more_actions_pill.xml +++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_more_actions_pill.xml @@ -15,6 +15,7 @@ ~ limitations under the License. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" android:layout_width="@dimen/desktop_mode_handle_menu_width" android:layout_height="@dimen/desktop_mode_handle_menu_more_actions_pill_height" android:orientation="vertical" @@ -25,7 +26,7 @@ android:contentDescription="@string/screenshot_text" android:text="@string/screenshot_text" android:drawableStart="@drawable/desktop_mode_ic_handle_menu_screenshot" - android:drawableTint="@color/desktop_mode_caption_menu_buttons_color_inactive" + android:drawableTint="?androidprv:attr/materialColorOnSurface" style="@style/DesktopModeHandleMenuActionButton"/> <Button @@ -33,15 +34,14 @@ android:contentDescription="@string/select_text" android:text="@string/select_text" android:drawableStart="@drawable/desktop_mode_ic_handle_menu_select" - android:drawableTint="@color/desktop_mode_caption_menu_buttons_color_inactive" + android:drawableTint="?androidprv:attr/materialColorOnSurface" style="@style/DesktopModeHandleMenuActionButton"/> - <Button android:id="@+id/close_button" android:contentDescription="@string/close_text" android:text="@string/close_text" android:drawableStart="@drawable/desktop_mode_ic_handle_menu_close" - android:drawableTint="@color/desktop_mode_caption_menu_buttons_color_inactive" + android:drawableTint="?androidprv:attr/materialColorOnSurface" style="@style/DesktopModeHandleMenuActionButton"/> </LinearLayout>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_windowing_pill.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_windowing_pill.xml index 08d91498b338..c4b688daeb6e 100644 --- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_windowing_pill.xml +++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_windowing_pill.xml @@ -15,6 +15,7 @@ ~ limitations under the License. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" android:layout_width="@dimen/desktop_mode_handle_menu_width" android:layout_height="@dimen/desktop_mode_handle_menu_windowing_pill_height" android:orientation="horizontal" @@ -26,7 +27,7 @@ android:layout_marginEnd="4dp" android:contentDescription="@string/fullscreen_text" android:src="@drawable/desktop_mode_ic_handle_menu_fullscreen" - android:tint="@color/desktop_mode_caption_menu_buttons_color_inactive" + android:tint="?androidprv:attr/materialColorOnSurface" android:layout_weight="1" style="@style/DesktopModeHandleMenuWindowingButton"/> @@ -36,7 +37,7 @@ android:layout_marginEnd="4dp" android:contentDescription="@string/split_screen_text" android:src="@drawable/desktop_mode_ic_handle_menu_splitscreen" - android:tint="@color/desktop_mode_caption_menu_buttons_color_inactive" + android:tint="?androidprv:attr/materialColorOnSurface" android:layout_weight="1" style="@style/DesktopModeHandleMenuWindowingButton"/> @@ -46,7 +47,7 @@ android:layout_marginEnd="4dp" android:contentDescription="@string/float_button_text" android:src="@drawable/desktop_mode_ic_handle_menu_floating" - android:tint="@color/desktop_mode_caption_menu_buttons_color_inactive" + android:tint="?androidprv:attr/materialColorOnSurface" android:layout_weight="1" style="@style/DesktopModeHandleMenuWindowingButton"/> @@ -55,7 +56,7 @@ android:layout_marginStart="4dp" android:contentDescription="@string/desktop_text" android:src="@drawable/desktop_mode_ic_handle_menu_desktop" - android:tint="@color/desktop_mode_caption_menu_buttons_color_active" + android:tint="?androidprv:attr/materialColorOnSurface" android:layout_weight="1" style="@style/DesktopModeHandleMenuWindowingButton"/> diff --git a/libs/WindowManager/Shell/res/values/colors.xml b/libs/WindowManager/Shell/res/values/colors.xml index f76a346a8f5d..9bfd1b44dcca 100644 --- a/libs/WindowManager/Shell/res/values/colors.xml +++ b/libs/WindowManager/Shell/res/values/colors.xml @@ -68,9 +68,6 @@ <color name="desktop_mode_caption_maximize_button_dark">#1C1C17</color> <color name="desktop_mode_caption_app_name_light">#EFF1F2</color> <color name="desktop_mode_caption_app_name_dark">#1C1C17</color> - <color name="desktop_mode_caption_menu_text_color">#191C1D</color> - <color name="desktop_mode_caption_menu_buttons_color_inactive">#191C1D</color> - <color name="desktop_mode_caption_menu_buttons_color_active">#00677E</color> <color name="desktop_mode_resize_veil_light">#EFF1F2</color> <color name="desktop_mode_resize_veil_dark">#1C1C17</color> <color name="desktop_mode_maximize_menu_button">#DDDACD</color> diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml index d902fd49ba60..468cfd5260cc 100644 --- a/libs/WindowManager/Shell/res/values/styles.xml +++ b/libs/WindowManager/Shell/res/values/styles.xml @@ -14,7 +14,8 @@ limitations under the License. --> -<resources xmlns:android="http://schemas.android.com/apk/res/android"> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"> <!-- Theme used for the activity that shows when the system forced an app to be resizable --> <style name="ForcedResizableTheme" parent="@android:style/Theme.Translucent.NoTitleBar"> <item name="android:windowBackground">@drawable/forced_resizable_background</item> @@ -37,7 +38,7 @@ <item name="android:padding">16dp</item> <item name="android:textSize">14sp</item> <item name="android:textFontWeight">500</item> - <item name="android:textColor">@color/desktop_mode_caption_menu_text_color</item> + <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item> <item name="android:drawablePadding">16dp</item> <item name="android:background">?android:selectableItemBackground</item> </style> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java index 39e3180ffe2a..bb30c5eeebcf 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java @@ -155,14 +155,14 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask Bitmap rawBadgeBitmap; // Only populated when showing in taskbar - BubbleBarExpandedView bubbleBarExpandedView; + @Nullable BubbleBarExpandedView bubbleBarExpandedView; // These are only populated when not showing in taskbar - BadgedImageView imageView; - BubbleExpandedView expandedView; + @Nullable BadgedImageView imageView; + @Nullable BubbleExpandedView expandedView; int dotColor; Path dotPath; - Bubble.FlyoutMessage flyoutMessage; + @Nullable Bubble.FlyoutMessage flyoutMessage; Bitmap bubbleBitmap; Bitmap badgeBitmap; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java index a5000feae239..f9a286ec804f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java @@ -19,6 +19,7 @@ package com.android.wm.shell.common.split; import static android.view.WindowManager.DOCKED_INVALID; import static android.view.WindowManager.DOCKED_LEFT; import static android.view.WindowManager.DOCKED_RIGHT; + import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_30_70; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_70_30; @@ -36,6 +37,8 @@ import android.hardware.display.DisplayManager; import android.view.Display; import android.view.DisplayInfo; +import androidx.annotation.Nullable; + import java.util.ArrayList; /** @@ -203,6 +206,21 @@ public class DividerSnapAlgorithm { } } + /** + * Gets the SnapTarget corresponding to the given {@link SnapPosition}, or null if no such + * SnapTarget exists. + */ + @Nullable + public SnapTarget findSnapTarget(@SnapPosition int snapPosition) { + for (SnapTarget t : mTargets) { + if (t.snapPosition == snapPosition) { + return t; + } + } + + return null; + } + public float calculateDismissingFraction(int position) { if (position < mFirstSplitTarget.position) { return 1f - (float) (position - getStartInset()) @@ -356,9 +374,9 @@ public class DividerSnapAlgorithm { * Adds a target at {@param position} but only if the area with size of {@param smallerSize} * meets the minimal size requirement. */ - private void maybeAddTarget(int position, int smallerSize, @SnapPosition int snapTo) { + private void maybeAddTarget(int position, int smallerSize, @SnapPosition int snapPosition) { if (smallerSize >= mMinimalSizeResizableTask) { - mTargets.add(new SnapTarget(position, position, snapTo)); + mTargets.add(new SnapTarget(position, position, snapPosition)); } } @@ -419,6 +437,13 @@ public class DividerSnapAlgorithm { } /** + * Finds the {@link SnapPosition} nearest to the given position. + */ + public int calculateNearestSnapPosition(int currentPosition) { + return snap(currentPosition, /* hardDismiss */ true).snapPosition; + } + + /** * Cycles through all non-dismiss targets with a stepping of {@param increment}. It moves left * if {@param increment} is negative and moves right otherwise. */ @@ -454,7 +479,7 @@ public class DividerSnapAlgorithm { /** * An int describing the placement of the divider in this snap target. */ - public final @SnapPosition int snapTo; + public final @SnapPosition int snapPosition; public boolean isMiddleTarget; @@ -464,15 +489,15 @@ public class DividerSnapAlgorithm { */ private final float distanceMultiplier; - public SnapTarget(int position, int taskPosition, @SnapPosition int snapTo) { - this(position, taskPosition, snapTo, 1f); + public SnapTarget(int position, int taskPosition, @SnapPosition int snapPosition) { + this(position, taskPosition, snapPosition, 1f); } - public SnapTarget(int position, int taskPosition, @SnapPosition int snapTo, + public SnapTarget(int position, int taskPosition, @SnapPosition int snapPosition, float distanceMultiplier) { this.position = position; this.taskPosition = taskPosition; - this.snapTo = snapTo; + this.snapPosition = snapPosition; this.distanceMultiplier = distanceMultiplier; } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java index 4af03fd5b955..26b5a5052594 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java @@ -23,6 +23,7 @@ import static android.view.WindowManager.DOCKED_INVALID; import static android.view.WindowManager.DOCKED_LEFT; import static android.view.WindowManager.DOCKED_RIGHT; import static android.view.WindowManager.DOCKED_TOP; + import static com.android.internal.jank.InteractionJankMonitor.CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER; import static com.android.internal.jank.InteractionJankMonitor.CUJ_SPLIT_SCREEN_RESIZE; import static com.android.wm.shell.animation.Interpolators.DIM_INTERPOLATOR; @@ -66,6 +67,7 @@ import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.InteractionJankMonitorUtils; +import com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition; import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition; import java.io.PrintWriter; @@ -115,7 +117,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange @VisibleForTesting DividerSnapAlgorithm mDividerSnapAlgorithm; private WindowContainerToken mWinToken1; private WindowContainerToken mWinToken2; - private int mDividePosition; + private int mDividerPosition; private boolean mInitialized = false; private boolean mFreezeDividerWindow = false; private int mOrientation; @@ -267,7 +269,14 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange } int getDividePosition() { - return mDividePosition; + return mDividerPosition; + } + + /** + * Finds the {@link SnapPosition} nearest to the current divider position. + */ + public int calculateCurrentSnapPosition() { + return mDividerSnapAlgorithm.calculateNearestSnapPosition(mDividerPosition); } /** @@ -344,16 +353,16 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange } private void initDividerPosition(Rect oldBounds) { - final float snapRatio = (float) mDividePosition + final float snapRatio = (float) mDividerPosition / (float) (isLandscape(oldBounds) ? oldBounds.width() : oldBounds.height()); // Estimate position by previous ratio. final float length = (float) (isLandscape() ? mRootBounds.width() : mRootBounds.height()); final int estimatePosition = (int) (length * snapRatio); // Init divider position by estimated position using current bounds snap algorithm. - mDividePosition = mDividerSnapAlgorithm.calculateNonDismissingSnapTarget( + mDividerPosition = mDividerSnapAlgorithm.calculateNonDismissingSnapTarget( estimatePosition).position; - updateBounds(mDividePosition); + updateBounds(mDividerPosition); } private void updateBounds(int position) { @@ -467,27 +476,29 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange } void setDividePosition(int position, boolean applyLayoutChange) { - mDividePosition = position; - updateBounds(mDividePosition); + mDividerPosition = position; + updateBounds(mDividerPosition); if (applyLayoutChange) { mSplitLayoutHandler.onLayoutSizeChanged(this); } } /** Updates divide position and split bounds base on the ratio within root bounds. */ - public void setDivideRatio(float ratio) { - final int position = isLandscape() - ? mRootBounds.left + (int) (mRootBounds.width() * ratio) - : mRootBounds.top + (int) (mRootBounds.height() * ratio); - final DividerSnapAlgorithm.SnapTarget snapTarget = - mDividerSnapAlgorithm.calculateNonDismissingSnapTarget(position); + public void setDivideRatio(@SnapPosition int snapPosition) { + final DividerSnapAlgorithm.SnapTarget snapTarget = mDividerSnapAlgorithm.findSnapTarget( + snapPosition); + + if (snapTarget == null) { + throw new IllegalArgumentException("No SnapTarget for position " + snapPosition); + } + setDividePosition(snapTarget.position, false /* applyLayoutChange */); } /** Resets divider position. */ public void resetDividerPosition() { - mDividePosition = mDividerSnapAlgorithm.getMiddleTarget().position; - updateBounds(mDividePosition); + mDividerPosition = mDividerSnapAlgorithm.getMiddleTarget().position; + updateBounds(mDividerPosition); mWinToken1 = null; mWinToken2 = null; mWinBounds1.setEmpty(); @@ -510,7 +521,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange * target indicates dismissing split. */ public void snapToTarget(int currentPosition, DividerSnapAlgorithm.SnapTarget snapTarget) { - switch (snapTarget.snapTo) { + switch (snapTarget.snapPosition) { case SNAP_TO_START_AND_DISMISS: flingDividePosition(currentPosition, snapTarget.position, FLING_RESIZE_DURATION, () -> mSplitLayoutHandler.onSnappedToDismiss(false /* bottomOrRight */, @@ -668,8 +679,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange @Override public void onAnimationEnd(Animator animation) { - mDividePosition = dividerPos; - updateBounds(mDividePosition); + mDividerPosition = dividerPos; + updateBounds(mDividerPosition); finishCallback.accept(insets); InteractionJankMonitorUtils.endTracing(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java index c111ce623c1a..953efa78326c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java @@ -22,10 +22,13 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.TaskInfo; import android.app.TaskInfo.CameraCompatControlState; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.hardware.display.DisplayManager; +import android.net.Uri; +import android.os.UserHandle; import android.provider.Settings; import android.util.ArraySet; import android.util.Log; @@ -173,6 +176,18 @@ public class CompatUIController implements OnDisplaysChangedListener, // be shown. private boolean mKeyguardShowing; + /** + * The id of the task for the application we're currently attempting to show the user aspect + * ratio settings button for, or have most recently shown the button for. + */ + private int mTopActivityTaskId; + + /** + * Whether the user aspect ratio settings button has been shown for the current application + * associated with the task id stored in {@link CompatUIController#mTopActivityTaskId}. + */ + private boolean mHasShownUserAspectRatioSettingsButton = false; + public CompatUIController(@NonNull Context context, @NonNull ShellInit shellInit, @NonNull ShellController shellController, @@ -227,6 +242,11 @@ public class CompatUIController implements OnDisplaysChangedListener, if (taskInfo != null && !taskInfo.topActivityInSizeCompat) { mSetOfTaskIdsShowingRestartDialog.remove(taskInfo.taskId); } + + if (taskInfo != null && taskListener != null) { + updateActiveTaskInfo(taskInfo); + } + if (taskInfo.configuration == null || taskListener == null) { // Null token means the current foreground activity is not in compatibility mode. removeLayouts(taskInfo.taskId); @@ -319,6 +339,46 @@ public class CompatUIController implements OnDisplaysChangedListener, forAllLayouts(layout -> layout.updateVisibility(showOnDisplay(layout.getDisplayId()))); } + /** + * Invoked when a new task is created or the info of an existing task has changed. Updates the + * shown status of the user aspect ratio settings button and the task id it relates to. + */ + void updateActiveTaskInfo(@NonNull TaskInfo taskInfo) { + // If the activity belongs to the task we are currently tracking, don't update any variables + // as they are still relevant. Else, if the activity is visible and focused (the one the + // user can see and is using), the user aspect ratio button can potentially be displayed so + // start tracking the buttons visibility for this task. + if (mTopActivityTaskId != taskInfo.taskId && !taskInfo.isTopActivityTransparent + && taskInfo.isVisible && taskInfo.isFocused) { + mTopActivityTaskId = taskInfo.taskId; + setHasShownUserAspectRatioSettingsButton(false); + } + } + + /** + * Informs the system that the user aspect ratio button has been displayed for the application + * associated with the task id in {@link CompatUIController#mTopActivityTaskId}. + */ + void setHasShownUserAspectRatioSettingsButton(boolean state) { + mHasShownUserAspectRatioSettingsButton = state; + } + + /** + * Returns whether the user aspect ratio settings button has been show for the application + * associated with the task id in {@link CompatUIController#mTopActivityTaskId}. + */ + boolean hasShownUserAspectRatioSettingsButton() { + return mHasShownUserAspectRatioSettingsButton; + } + + /** + * Returns the task id of the application we are currently attempting to show, of have most + * recently shown, the user aspect ratio settings button for. + */ + int getTopActivityTaskId() { + return mTopActivityTaskId; + } + private boolean showOnDisplay(int displayId) { return !mKeyguardShowing && !isImeShowingOnDisplay(displayId); } @@ -569,7 +629,8 @@ public class CompatUIController implements OnDisplaysChangedListener, return new UserAspectRatioSettingsWindowManager(context, taskInfo, mSyncQueue, taskListener, mDisplayController.getDisplayLayout(taskInfo.displayId), mCompatUIHintsState, this::launchUserAspectRatioSettings, mMainExecutor, - mDisappearTimeSupplier); + mDisappearTimeSupplier, this::hasShownUserAspectRatioSettingsButton, + this::setHasShownUserAspectRatioSettingsButton); } private void launchUserAspectRatioSettings( @@ -577,7 +638,13 @@ public class CompatUIController implements OnDisplaysChangedListener, final Intent intent = new Intent(Settings.ACTION_MANAGE_USER_ASPECT_RATIO_SETTINGS); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); - mContext.startActivity(intent); + final ComponentName appComponent = taskInfo.topActivity; + if (appComponent != null) { + final Uri packageUri = Uri.parse("package:" + appComponent.getPackageName()); + intent.setData(packageUri); + } + final UserHandle userHandle = UserHandle.of(taskInfo.userId); + mContext.startActivityAsUser(intent, userHandle); } private void removeLayouts(int taskId) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java index 77aefc8f7e4a..c2dec623416b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java @@ -37,7 +37,9 @@ import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.compatui.CompatUIController.CompatUIHintsState; import java.util.function.BiConsumer; +import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; /** * Window manager for the user aspect ratio settings button which allows users to go to @@ -55,6 +57,12 @@ class UserAspectRatioSettingsWindowManager extends CompatUIWindowManagerAbstract private final ShellExecutor mShellExecutor; + @NonNull + private final Supplier<Boolean> mUserAspectRatioButtonShownChecker; + + @NonNull + private final Consumer<Boolean> mUserAspectRatioButtonStateConsumer; + @VisibleForTesting @NonNull final CompatUIHintsState mCompatUIHintsState; @@ -72,9 +80,13 @@ class UserAspectRatioSettingsWindowManager extends CompatUIWindowManagerAbstract @NonNull DisplayLayout displayLayout, @NonNull CompatUIHintsState compatUIHintsState, @NonNull BiConsumer<TaskInfo, ShellTaskOrganizer.TaskListener> onButtonClicked, @NonNull ShellExecutor shellExecutor, - @NonNull Function<Integer, Integer> disappearTimeSupplier) { + @NonNull Function<Integer, Integer> disappearTimeSupplier, + @NonNull Supplier<Boolean> userAspectRatioButtonStateChecker, + @NonNull Consumer<Boolean> userAspectRatioButtonShownConsumer) { super(context, taskInfo, syncQueue, taskListener, displayLayout); mShellExecutor = shellExecutor; + mUserAspectRatioButtonShownChecker = userAspectRatioButtonStateChecker; + mUserAspectRatioButtonStateConsumer = userAspectRatioButtonShownConsumer; mHasUserAspectRatioSettingsButton = getHasUserAspectRatioSettingsButton(taskInfo); mCompatUIHintsState = compatUIHintsState; mOnButtonClicked = onButtonClicked; @@ -180,11 +192,18 @@ class UserAspectRatioSettingsWindowManager extends CompatUIWindowManagerAbstract } } + @VisibleForTesting + boolean isShowingButton() { + return (mUserAspectRatioButtonShownChecker.get() + && !isHideDelayReached(mNextButtonHideTimeMs)); + } + private void showUserAspectRatioButton() { if (mLayout == null) { return; } mLayout.setUserAspectRatioButtonVisibility(true); + mUserAspectRatioButtonStateConsumer.accept(true); // Only show by default for the first time. if (!mCompatUIHintsState.mHasShownUserAspectRatioSettingsButtonHint) { mLayout.setUserAspectRatioSettingsHintVisibility(/* show= */ true); @@ -210,7 +229,8 @@ class UserAspectRatioSettingsWindowManager extends CompatUIWindowManagerAbstract private boolean getHasUserAspectRatioSettingsButton(@NonNull TaskInfo taskInfo) { return taskInfo.topActivityEligibleForUserAspectRatioButton && (taskInfo.topActivityBoundsLetterboxed - || taskInfo.isUserFullscreenOverrideEnabled); + || taskInfo.isUserFullscreenOverrideEnabled) + && (!mUserAspectRatioButtonShownChecker.get() || isShowingButton()); } private long getDisappearTimeMs() { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl index 14304a3c0aac..253acc49071a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl @@ -91,42 +91,42 @@ interface ISplitScreen { * Starts tasks simultaneously in one transition. */ oneway void startTasks(int taskId1, in Bundle options1, int taskId2, in Bundle options2, - int splitPosition, float splitRatio, in RemoteTransition remoteTransition, + int splitPosition, int snapPosition, in RemoteTransition remoteTransition, in InstanceId instanceId) = 10; /** * Starts a pair of intent and task in one transition. */ oneway void startIntentAndTask(in PendingIntent pendingIntent, int userId1, in Bundle options1, - int taskId, in Bundle options2, int sidePosition, float splitRatio, + int taskId, in Bundle options2, int sidePosition, int snapPosition, in RemoteTransition remoteTransition, in InstanceId instanceId) = 16; /** * Starts a pair of shortcut and task in one transition. */ oneway void startShortcutAndTask(in ShortcutInfo shortcutInfo, in Bundle options1, int taskId, - in Bundle options2, int splitPosition, float splitRatio, + in Bundle options2, int splitPosition, int snapPosition, in RemoteTransition remoteTransition, in InstanceId instanceId) = 17; /** * Version of startTasks using legacy transition system. */ oneway void startTasksWithLegacyTransition(int taskId1, in Bundle options1, int taskId2, - in Bundle options2, int splitPosition, float splitRatio, + in Bundle options2, int splitPosition, int snapPosition, in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 11; /** * Starts a pair of intent and task using legacy transition system. */ oneway void startIntentAndTaskWithLegacyTransition(in PendingIntent pendingIntent, int userId1, - in Bundle options1, int taskId, in Bundle options2, int splitPosition, float splitRatio, + in Bundle options1, int taskId, in Bundle options2, int splitPosition, int snapPosition, in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 12; /** * Starts a pair of shortcut and task using legacy transition system. */ oneway void startShortcutAndTaskWithLegacyTransition(in ShortcutInfo shortcutInfo, - in Bundle options1, int taskId, in Bundle options2, int splitPosition, float splitRatio, + in Bundle options1, int taskId, in Bundle options2, int splitPosition, int snapPosition, in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 15; /** @@ -135,7 +135,7 @@ interface ISplitScreen { oneway void startIntentsWithLegacyTransition(in PendingIntent pendingIntent1, int userId1, in ShortcutInfo shortcutInfo1, in Bundle options1, in PendingIntent pendingIntent2, int userId2, in ShortcutInfo shortcutInfo2, in Bundle options2, int splitPosition, - float splitRatio, in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 18; + int snapPosition, in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 18; /** * Start a pair of intents in one transition. @@ -143,7 +143,7 @@ interface ISplitScreen { oneway void startIntents(in PendingIntent pendingIntent1, int userId1, in ShortcutInfo shortcutInfo1, in Bundle options1, in PendingIntent pendingIntent2, int userId2, in ShortcutInfo shortcutInfo2, in Bundle options2, int splitPosition, - float splitRatio, in RemoteTransition remoteTransition, in InstanceId instanceId) = 19; + int snapPosition, in RemoteTransition remoteTransition, in InstanceId instanceId) = 19; /** * Blocking call that notifies and gets additional split-screen targets when entering diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java index f70b0fc5af48..ccffa02a22c1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java @@ -85,6 +85,7 @@ import com.android.wm.shell.common.SingleInstanceRemoteListener; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.common.annotations.ExternalThread; +import com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition; import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition; import com.android.wm.shell.common.split.SplitScreenUtils; import com.android.wm.shell.desktopmode.DesktopTasksController; @@ -600,8 +601,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, void startShortcutAndTaskWithLegacyTransition(ShortcutInfo shortcutInfo, @Nullable Bundle options1, int taskId, @Nullable Bundle options2, - @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter, - InstanceId instanceId) { + @SplitPosition int splitPosition, @SnapPosition int snapPosition, + RemoteAnimationAdapter adapter, InstanceId instanceId) { if (options1 == null) options1 = new Bundle(); final ActivityOptions activityOptions = ActivityOptions.fromBundle(options1); @@ -625,13 +626,14 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, } mStageCoordinator.startShortcutAndTaskWithLegacyTransition(shortcutInfo, - activityOptions.toBundle(), taskId, options2, splitPosition, splitRatio, adapter, + activityOptions.toBundle(), taskId, options2, splitPosition, snapPosition, adapter, instanceId); } void startShortcutAndTask(ShortcutInfo shortcutInfo, @Nullable Bundle options1, int taskId, @Nullable Bundle options2, @SplitPosition int splitPosition, - float splitRatio, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { + @SnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition, + InstanceId instanceId) { if (options1 == null) options1 = new Bundle(); final ActivityOptions activityOptions = ActivityOptions.fromBundle(options1); final String packageName1 = shortcutInfo.getPackage(); @@ -658,7 +660,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, } } mStageCoordinator.startShortcutAndTask(shortcutInfo, activityOptions.toBundle(), taskId, - options2, splitPosition, splitRatio, remoteTransition, instanceId); + options2, splitPosition, snapPosition, remoteTransition, instanceId); } /** @@ -673,8 +675,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, private void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, int userId1, @Nullable Bundle options1, int taskId, @Nullable Bundle options2, - @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter, - InstanceId instanceId) { + @SplitPosition int splitPosition, @SnapPosition int snapPosition, + RemoteAnimationAdapter adapter, InstanceId instanceId) { Intent fillInIntent = null; final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent); final String packageName2 = SplitScreenUtils.getPackageName(taskId, mTaskOrganizer); @@ -695,12 +697,12 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, } } mStageCoordinator.startIntentAndTaskWithLegacyTransition(pendingIntent, fillInIntent, - options1, taskId, options2, splitPosition, splitRatio, adapter, instanceId); + options1, taskId, options2, splitPosition, snapPosition, adapter, instanceId); } private void startIntentAndTask(PendingIntent pendingIntent, int userId1, @Nullable Bundle options1, int taskId, @Nullable Bundle options2, - @SplitPosition int splitPosition, float splitRatio, + @SplitPosition int splitPosition, @SnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { Intent fillInIntent = null; final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent); @@ -727,14 +729,14 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, } } mStageCoordinator.startIntentAndTask(pendingIntent, fillInIntent, options1, taskId, - options2, splitPosition, splitRatio, remoteTransition, instanceId); + options2, splitPosition, snapPosition, remoteTransition, instanceId); } private void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, int userId1, @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1, PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2, - @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio, - RemoteAnimationAdapter adapter, InstanceId instanceId) { + @Nullable Bundle options2, @SplitPosition int splitPosition, + @SnapPosition int snapPosition, RemoteAnimationAdapter adapter, InstanceId instanceId) { Intent fillInIntent1 = null; Intent fillInIntent2 = null; final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent1); @@ -758,14 +760,15 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, } mStageCoordinator.startIntentsWithLegacyTransition(pendingIntent1, fillInIntent1, shortcutInfo1, options1, pendingIntent2, fillInIntent2, shortcutInfo2, options2, - splitPosition, splitRatio, adapter, instanceId); + splitPosition, snapPosition, adapter, instanceId); } private void startIntents(PendingIntent pendingIntent1, int userId1, @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1, PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2, - @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio, - @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { + @Nullable Bundle options2, @SplitPosition int splitPosition, + @SnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition, + InstanceId instanceId) { Intent fillInIntent1 = null; Intent fillInIntent2 = null; final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent1); @@ -800,7 +803,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, } mStageCoordinator.startIntents(pendingIntent1, fillInIntent1, shortcutInfo1, activityOptions1.toBundle(), pendingIntent2, fillInIntent2, shortcutInfo2, - activityOptions2.toBundle(), splitPosition, splitRatio, remoteTransition, + activityOptions2.toBundle(), splitPosition, snapPosition, remoteTransition, instanceId); } @@ -1222,78 +1225,82 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, @Override public void startTasksWithLegacyTransition(int taskId1, @Nullable Bundle options1, int taskId2, @Nullable Bundle options2, @SplitPosition int splitPosition, - float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) { + @SnapPosition int snapPosition, RemoteAnimationAdapter adapter, + InstanceId instanceId) { executeRemoteCallWithTaskPermission(mController, "startTasks", (controller) -> controller.mStageCoordinator.startTasksWithLegacyTransition( - taskId1, options1, taskId2, options2, splitPosition, - splitRatio, adapter, instanceId)); + taskId1, options1, taskId2, options2, splitPosition, snapPosition, + adapter, instanceId)); } @Override public void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, int userId1, - Bundle options1, int taskId, Bundle options2, int splitPosition, float splitRatio, - RemoteAnimationAdapter adapter, InstanceId instanceId) { + Bundle options1, int taskId, Bundle options2, int splitPosition, + @SnapPosition int snapPosition, RemoteAnimationAdapter adapter, + InstanceId instanceId) { executeRemoteCallWithTaskPermission(mController, "startIntentAndTaskWithLegacyTransition", (controller) -> controller.startIntentAndTaskWithLegacyTransition(pendingIntent, - userId1, options1, taskId, options2, splitPosition, splitRatio, - adapter, instanceId)); + userId1, options1, taskId, options2, splitPosition, + snapPosition, adapter, instanceId)); } @Override public void startShortcutAndTaskWithLegacyTransition(ShortcutInfo shortcutInfo, @Nullable Bundle options1, int taskId, @Nullable Bundle options2, - @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter, - InstanceId instanceId) { + @SplitPosition int splitPosition, @SnapPosition int snapPosition, + RemoteAnimationAdapter adapter, InstanceId instanceId) { executeRemoteCallWithTaskPermission(mController, "startShortcutAndTaskWithLegacyTransition", (controller) -> controller.startShortcutAndTaskWithLegacyTransition( shortcutInfo, options1, taskId, options2, splitPosition, - splitRatio, adapter, instanceId)); + snapPosition, adapter, instanceId)); } @Override public void startTasks(int taskId1, @Nullable Bundle options1, int taskId2, - @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio, - @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { + @Nullable Bundle options2, @SplitPosition int splitPosition, + @SnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition, + InstanceId instanceId) { executeRemoteCallWithTaskPermission(mController, "startTasks", (controller) -> controller.mStageCoordinator.startTasks(taskId1, options1, - taskId2, options2, splitPosition, splitRatio, remoteTransition, + taskId2, options2, splitPosition, snapPosition, remoteTransition, instanceId)); } @Override public void startIntentAndTask(PendingIntent pendingIntent, int userId1, @Nullable Bundle options1, int taskId, @Nullable Bundle options2, - @SplitPosition int splitPosition, float splitRatio, + @SplitPosition int splitPosition, @SnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { executeRemoteCallWithTaskPermission(mController, "startIntentAndTask", (controller) -> controller.startIntentAndTask(pendingIntent, userId1, options1, - taskId, options2, splitPosition, splitRatio, remoteTransition, + taskId, options2, splitPosition, snapPosition, remoteTransition, instanceId)); } @Override public void startShortcutAndTask(ShortcutInfo shortcutInfo, @Nullable Bundle options1, int taskId, @Nullable Bundle options2, @SplitPosition int splitPosition, - float splitRatio, @Nullable RemoteTransition remoteTransition, + @SnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { executeRemoteCallWithTaskPermission(mController, "startShortcutAndTask", (controller) -> controller.startShortcutAndTask(shortcutInfo, options1, taskId, - options2, splitPosition, splitRatio, remoteTransition, instanceId)); + options2, splitPosition, snapPosition, remoteTransition, instanceId)); } @Override public void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, int userId1, @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1, PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2, - @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio, - RemoteAnimationAdapter adapter, InstanceId instanceId) { + @Nullable Bundle options2, @SplitPosition int splitPosition, + @SnapPosition int snapPosition, RemoteAnimationAdapter adapter, + InstanceId instanceId) { executeRemoteCallWithTaskPermission(mController, "startIntentsWithLegacyTransition", (controller) -> controller.startIntentsWithLegacyTransition(pendingIntent1, userId1, shortcutInfo1, options1, pendingIntent2, userId2, shortcutInfo2, - options2, splitPosition, splitRatio, adapter, instanceId) + options2, splitPosition, snapPosition, adapter, instanceId) ); } @@ -1301,13 +1308,14 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, public void startIntents(PendingIntent pendingIntent1, int userId1, @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1, PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2, - @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio, - @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { + @Nullable Bundle options2, @SplitPosition int splitPosition, + @SnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition, + InstanceId instanceId) { executeRemoteCallWithTaskPermission(mController, "startIntents", (controller) -> controller.startIntents(pendingIntent1, userId1, shortcutInfo1, options1, pendingIntent2, userId2, shortcutInfo2, options2, - splitPosition, splitRatio, remoteTransition, instanceId) + splitPosition, snapPosition, remoteTransition, instanceId) ); } 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 94fa485efd5c..3d825f072a6a 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 @@ -128,6 +128,7 @@ import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.common.split.SplitLayout; +import com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition; import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition; import com.android.wm.shell.common.split.SplitScreenUtils; import com.android.wm.shell.common.split.SplitWindowManager; @@ -631,8 +632,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } /** Starts 2 tasks in one transition. */ - void startTasks(int taskId1, @Nullable Bundle options1, int taskId2, - @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio, + void startTasks(int taskId1, @Nullable Bundle options1, int taskId2, @Nullable Bundle options2, + @SplitPosition int splitPosition, @SnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { final WindowContainerTransaction wct = new WindowContainerTransaction(); if (taskId2 == INVALID_TASK_ID) { @@ -654,13 +655,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, addActivityOptions(options1, mSideStage); wct.startTask(taskId1, options1); - startWithTask(wct, taskId2, options2, splitRatio, remoteTransition, instanceId); + startWithTask(wct, taskId2, options2, snapPosition, remoteTransition, instanceId); } /** Start an intent and a task to a split pair in one transition. */ void startIntentAndTask(PendingIntent pendingIntent, Intent fillInIntent, @Nullable Bundle options1, int taskId, @Nullable Bundle options2, - @SplitPosition int splitPosition, float splitRatio, + @SplitPosition int splitPosition, @SnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { final WindowContainerTransaction wct = new WindowContainerTransaction(); if (taskId == INVALID_TASK_ID) { @@ -676,13 +677,14 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, addActivityOptions(options1, mSideStage); wct.sendPendingIntent(pendingIntent, fillInIntent, options1); - startWithTask(wct, taskId, options2, splitRatio, remoteTransition, instanceId); + startWithTask(wct, taskId, options2, snapPosition, remoteTransition, instanceId); } /** Starts a shortcut and a task to a split pair in one transition. */ void startShortcutAndTask(ShortcutInfo shortcutInfo, @Nullable Bundle options1, int taskId, @Nullable Bundle options2, @SplitPosition int splitPosition, - float splitRatio, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { + @SnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition, + InstanceId instanceId) { final WindowContainerTransaction wct = new WindowContainerTransaction(); if (taskId == INVALID_TASK_ID) { options1 = options1 != null ? options1 : new Bundle(); @@ -697,7 +699,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, addActivityOptions(options1, mSideStage); wct.startShortcut(mContext.getPackageName(), shortcutInfo, options1); - startWithTask(wct, taskId, options2, splitRatio, remoteTransition, instanceId); + startWithTask(wct, taskId, options2, snapPosition, remoteTransition, instanceId); } /** @@ -708,14 +710,14 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, * {@link SplitscreenEventLogger#logEnter(float, int, int, int, int, boolean)} */ private void startWithTask(WindowContainerTransaction wct, int mainTaskId, - @Nullable Bundle mainOptions, float splitRatio, + @Nullable Bundle mainOptions, @SnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { if (!mMainStage.isActive()) { // Build a request WCT that will launch both apps such that task 0 is on the main stage // while task 1 is on the side stage. mMainStage.activate(wct, false /* reparent */); } - mSplitLayout.setDivideRatio(splitRatio); + mSplitLayout.setDivideRatio(snapPosition); updateWindowBounds(mSplitLayout, wct); wct.reorder(mRootTaskInfo.token, true); setRootForceTranslucent(false, wct); @@ -740,7 +742,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1, PendingIntent pendingIntent2, Intent fillInIntent2, @Nullable ShortcutInfo shortcutInfo2, @Nullable Bundle options2, - @SplitPosition int splitPosition, float splitRatio, + @SplitPosition int splitPosition, @SnapPosition int snapPosition, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) { final WindowContainerTransaction wct = new WindowContainerTransaction(); if (pendingIntent2 == null) { @@ -762,7 +764,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } setSideStagePosition(splitPosition, wct); - mSplitLayout.setDivideRatio(splitRatio); + mSplitLayout.setDivideRatio(snapPosition); updateWindowBounds(mSplitLayout, wct); wct.reorder(mRootTaskInfo.token, true); setRootForceTranslucent(false, wct); @@ -790,7 +792,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, /** Starts a pair of tasks using legacy transition. */ void startTasksWithLegacyTransition(int taskId1, @Nullable Bundle options1, int taskId2, @Nullable Bundle options2, @SplitPosition int splitPosition, - float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) { + @SnapPosition int snapPosition, RemoteAnimationAdapter adapter, InstanceId instanceId) { final WindowContainerTransaction wct = new WindowContainerTransaction(); if (options1 == null) options1 = new Bundle(); if (taskId2 == INVALID_TASK_ID) { @@ -811,7 +813,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, addActivityOptions(options1, mSideStage); wct.startTask(taskId1, options1); mSplitRequest = new SplitRequest(taskId1, taskId2, splitPosition); - startWithLegacyTransition(wct, taskId2, options2, splitPosition, splitRatio, adapter, + startWithLegacyTransition(wct, taskId2, options2, splitPosition, snapPosition, adapter, instanceId); } @@ -820,8 +822,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1, @Nullable PendingIntent pendingIntent2, Intent fillInIntent2, @Nullable ShortcutInfo shortcutInfo2, @Nullable Bundle options2, - @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter, - InstanceId instanceId) { + @SplitPosition int splitPosition, @SnapPosition int snapPosition, + RemoteAnimationAdapter adapter, InstanceId instanceId) { final WindowContainerTransaction wct = new WindowContainerTransaction(); if (options1 == null) options1 = new Bundle(); if (pendingIntent2 == null) { @@ -840,13 +842,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, pendingIntent2 != null ? pendingIntent2.getIntent() : null, splitPosition); } startWithLegacyTransition(wct, pendingIntent2, fillInIntent2, shortcutInfo2, options2, - splitPosition, splitRatio, adapter, instanceId); + splitPosition, snapPosition, adapter, instanceId); } void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, Intent fillInIntent, @Nullable Bundle options1, int taskId, @Nullable Bundle options2, - @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter, - InstanceId instanceId) { + @SplitPosition int splitPosition, @SnapPosition int snapPosition, + RemoteAnimationAdapter adapter, InstanceId instanceId) { final WindowContainerTransaction wct = new WindowContainerTransaction(); if (options1 == null) options1 = new Bundle(); if (taskId == INVALID_TASK_ID) { @@ -859,15 +861,15 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, addActivityOptions(options1, mSideStage); wct.sendPendingIntent(pendingIntent, fillInIntent, options1); mSplitRequest = new SplitRequest(taskId, pendingIntent.getIntent(), splitPosition); - startWithLegacyTransition(wct, taskId, options2, splitPosition, splitRatio, adapter, + startWithLegacyTransition(wct, taskId, options2, splitPosition, snapPosition, adapter, instanceId); } /** Starts a pair of shortcut and task using legacy transition. */ void startShortcutAndTaskWithLegacyTransition(ShortcutInfo shortcutInfo, @Nullable Bundle options1, int taskId, @Nullable Bundle options2, - @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter, - InstanceId instanceId) { + @SplitPosition int splitPosition, @SnapPosition int snapPosition, + RemoteAnimationAdapter adapter, InstanceId instanceId) { final WindowContainerTransaction wct = new WindowContainerTransaction(); if (options1 == null) options1 = new Bundle(); if (taskId == INVALID_TASK_ID) { @@ -878,7 +880,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, addActivityOptions(options1, mSideStage); wct.startShortcut(mContext.getPackageName(), shortcutInfo, options1); - startWithLegacyTransition(wct, taskId, options2, splitPosition, splitRatio, adapter, + startWithLegacyTransition(wct, taskId, options2, splitPosition, snapPosition, adapter, instanceId); } @@ -928,18 +930,19 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, private void startWithLegacyTransition(WindowContainerTransaction wct, @Nullable PendingIntent mainPendingIntent, @Nullable Intent mainFillInIntent, @Nullable ShortcutInfo mainShortcutInfo, @Nullable Bundle mainOptions, - @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter, - InstanceId instanceId) { + @SplitPosition int sidePosition, @SnapPosition int snapPosition, + RemoteAnimationAdapter adapter, InstanceId instanceId) { startWithLegacyTransition(wct, INVALID_TASK_ID, mainPendingIntent, mainFillInIntent, - mainShortcutInfo, mainOptions, sidePosition, splitRatio, adapter, instanceId); + mainShortcutInfo, mainOptions, sidePosition, snapPosition, adapter, instanceId); } private void startWithLegacyTransition(WindowContainerTransaction wct, int mainTaskId, - @Nullable Bundle mainOptions, @SplitPosition int sidePosition, float splitRatio, - RemoteAnimationAdapter adapter, InstanceId instanceId) { + @Nullable Bundle mainOptions, @SplitPosition int sidePosition, + @SnapPosition int snapPosition, RemoteAnimationAdapter adapter, + InstanceId instanceId) { startWithLegacyTransition(wct, mainTaskId, null /* mainPendingIntent */, null /* mainFillInIntent */, null /* mainShortcutInfo */, mainOptions, sidePosition, - splitRatio, adapter, instanceId); + snapPosition, adapter, instanceId); } /** @@ -950,15 +953,15 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, private void startWithLegacyTransition(WindowContainerTransaction wct, int mainTaskId, @Nullable PendingIntent mainPendingIntent, @Nullable Intent mainFillInIntent, @Nullable ShortcutInfo mainShortcutInfo, @Nullable Bundle options, - @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter, - InstanceId instanceId) { + @SplitPosition int sidePosition, @SnapPosition int snapPosition, + RemoteAnimationAdapter adapter, InstanceId instanceId) { if (!isSplitScreenVisible()) { exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RECREATE_SPLIT); } // Init divider first to make divider leash for remote animation target. mSplitLayout.init(); - mSplitLayout.setDivideRatio(splitRatio); + mSplitLayout.setDivideRatio(snapPosition); // Apply surface bounds before animation start. SurfaceControl.Transaction startT = mTransactionPool.acquire(); @@ -1551,6 +1554,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition, boolean resizeAnim) { onSplitScreenEnter(); + // Preemptively reset the reparenting behavior if we know that we are entering, as starting + // split tasks with activity trampolines can inadvertently trigger the task to be + // reparented out of the split root mid-launch + wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token, + false /* setReparentLeafTaskIfRelaunch */); if (isSplitActive()) { prepareBringSplit(wct, taskInfo, startPosition, resizeAnim); } else { @@ -1761,7 +1769,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, rightBottomTaskId = sideStageTopTaskId; } SplitBounds splitBounds = new SplitBounds(topLeftBounds, bottomRightBounds, - leftTopTaskId, rightBottomTaskId); + leftTopTaskId, rightBottomTaskId, mSplitLayout.calculateCurrentSnapPosition()); if (mainStageTopTaskId != INVALID_TASK_ID && sideStageTopTaskId != INVALID_TASK_ID) { // Update the pair for the top tasks recentTasks.addSplitPair(mainStageTopTaskId, sideStageTopTaskId, splitBounds); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/SplitBounds.java b/libs/WindowManager/Shell/src/com/android/wm/shell/util/SplitBounds.java index 0edcff45f648..a68b41d6563a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/util/SplitBounds.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/util/SplitBounds.java @@ -19,6 +19,8 @@ import android.graphics.Rect; import android.os.Parcel; import android.os.Parcelable; +import com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition; + import java.util.Objects; /** @@ -37,6 +39,7 @@ public class SplitBounds implements Parcelable { public final float leftTaskPercent; public final float dividerWidthPercent; public final float dividerHeightPercent; + public final @SnapPosition int snapPosition; /** * If {@code true}, that means at the time of creation of this object, the * split-screened apps were vertically stacked. This is useful in scenarios like @@ -47,12 +50,13 @@ public class SplitBounds implements Parcelable { public final int leftTopTaskId; public final int rightBottomTaskId; - public SplitBounds(Rect leftTopBounds, Rect rightBottomBounds, - int leftTopTaskId, int rightBottomTaskId) { + public SplitBounds(Rect leftTopBounds, Rect rightBottomBounds, int leftTopTaskId, + int rightBottomTaskId, @SnapPosition int snapPosition) { this.leftTopBounds = leftTopBounds; this.rightBottomBounds = rightBottomBounds; this.leftTopTaskId = leftTopTaskId; this.rightBottomTaskId = rightBottomTaskId; + this.snapPosition = snapPosition; if (rightBottomBounds.top > leftTopBounds.top) { // vertical apps, horizontal divider @@ -83,8 +87,9 @@ public class SplitBounds implements Parcelable { appsStackedVertically = parcel.readBoolean(); leftTopTaskId = parcel.readInt(); rightBottomTaskId = parcel.readInt(); - dividerWidthPercent = parcel.readInt(); - dividerHeightPercent = parcel.readInt(); + dividerWidthPercent = parcel.readFloat(); + dividerHeightPercent = parcel.readFloat(); + snapPosition = parcel.readInt(); } @Override @@ -99,6 +104,7 @@ public class SplitBounds implements Parcelable { parcel.writeInt(rightBottomTaskId); parcel.writeFloat(dividerWidthPercent); parcel.writeFloat(dividerHeightPercent); + parcel.writeInt(snapPosition); } @Override @@ -129,7 +135,8 @@ public class SplitBounds implements Parcelable { return "LeftTop: " + leftTopBounds + ", taskId: " + leftTopTaskId + "\n" + "RightBottom: " + rightBottomBounds + ", taskId: " + rightBottomTaskId + "\n" + "Divider: " + visualDividerBounds + "\n" - + "AppsVertical? " + appsStackedVertically; + + "AppsVertical? " + appsStackedVertically + "\n" + + "snapPosition: " + snapPosition; } public static final Creator<SplitBounds> CREATOR = new Creator<SplitBounds>() { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java index 1ec8a1749b55..f82b212c344c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java @@ -26,7 +26,10 @@ import android.annotation.Nullable; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.content.res.ColorStateList; +import android.content.res.Configuration; import android.content.res.Resources; +import android.content.res.TypedArray; +import android.graphics.Color; import android.graphics.PointF; import android.graphics.drawable.Drawable; import android.view.MotionEvent; @@ -167,10 +170,9 @@ class HandleMenu { desktopBtn.setOnClickListener(mOnClickListener); // The button corresponding to the windowing mode that the task is currently in uses a // different color than the others. - final ColorStateList activeColorStateList = ColorStateList.valueOf( - mContext.getColor(R.color.desktop_mode_caption_menu_buttons_color_active)); - final ColorStateList inActiveColorStateList = ColorStateList.valueOf( - mContext.getColor(R.color.desktop_mode_caption_menu_buttons_color_inactive)); + final int[] iconColors = getWindowingIconColor(); + final ColorStateList inActiveColorStateList = ColorStateList.valueOf(iconColors[0]); + final ColorStateList activeColorStateList = ColorStateList.valueOf(iconColors[1]); fullscreenBtn.setImageTintList( mTaskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN ? activeColorStateList : inActiveColorStateList); @@ -197,6 +199,23 @@ class HandleMenu { } /** + * Returns array of windowing icon color based on current UI theme. First element of the + * array is for inactive icons and the second is for active icons. + */ + private int[] getWindowingIconColor() { + final int mode = mContext.getResources().getConfiguration().uiMode + & Configuration.UI_MODE_NIGHT_MASK; + final boolean isNightMode = (mode == Configuration.UI_MODE_NIGHT_YES); + final TypedArray typedArray = mContext.obtainStyledAttributes(new int[]{ + com.android.internal.R.attr.materialColorOnSurface, + com.android.internal.R.attr.materialColorPrimary}); + final int inActiveColor = typedArray.getColor(0, isNightMode ? Color.WHITE : Color.BLACK); + final int activeColor = typedArray.getColor(1, isNightMode ? Color.WHITE : Color.BLACK); + typedArray.recycle(); + return new int[] {inActiveColor, activeColor}; + } + + /** * Updates the handle menu pills' position variables to reflect their next positions */ private void updateHandleMenuPillPositions() { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java index 3c853f188e3a..07fee4316c08 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java @@ -195,13 +195,16 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> rootView = null; // Clear it just in case we use it accidentally final int oldDensityDpi = mWindowDecorConfig.densityDpi; + final int oldNightMode = mWindowDecorConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK; mWindowDecorConfig = params.mWindowDecorConfig != null ? params.mWindowDecorConfig : mTaskInfo.getConfiguration(); final int newDensityDpi = mWindowDecorConfig.densityDpi; + final int newNightMode = mWindowDecorConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK; if (oldDensityDpi != newDensityDpi || mDisplay == null || mDisplay.getDisplayId() != mTaskInfo.displayId - || oldLayoutResId != mLayoutResId) { + || oldLayoutResId != mLayoutResId + || oldNightMode != newNightMode) { releaseViews(); if (!obtainDisplayOrRegisterListener()) { @@ -209,6 +212,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> return; } mDecorWindowContext = mContext.createConfigurationContext(mWindowDecorConfig); + mDecorWindowContext.setTheme(mContext.getThemeResId()); if (params.mLayoutResId != 0) { outResult.mRootView = (T) LayoutInflater.from(mDecorWindowContext) .inflate(params.mLayoutResId, null); diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt index 77f14f1b66a3..adf92d8854ff 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt @@ -50,7 +50,7 @@ abstract class BaseAppCompat(flicker: LegacyFlickerTest) : BaseTest(flicker) { } @Before - fun before() { + fun setUp() { Assume.assumeTrue(tapl.isTablet && letterboxRule.isIgnoreOrientationRequest) } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RotateImmersiveAppInFullscreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RotateImmersiveAppInFullscreenTest.kt new file mode 100644 index 000000000000..ba2b3e7e2781 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RotateImmersiveAppInFullscreenTest.kt @@ -0,0 +1,199 @@ +/* + * 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.appcompat + +import android.os.Build +import android.tools.common.datatypes.Rect +import android.platform.test.annotations.Postsubmit +import android.system.helpers.CommandsHelper +import android.tools.common.NavBar +import android.tools.common.Rotation +import android.tools.common.flicker.assertions.FlickerTest +import android.tools.common.traces.component.ComponentNameMatcher +import android.tools.device.flicker.junit.FlickerParametersRunnerFactory +import android.tools.device.flicker.legacy.FlickerBuilder +import android.tools.device.flicker.legacy.LegacyFlickerTest +import android.tools.device.flicker.legacy.LegacyFlickerTestFactory +import android.tools.device.helpers.FIND_TIMEOUT +import android.tools.device.traces.parsers.toFlickerComponent +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.Until +import com.android.server.wm.flicker.helpers.LetterboxAppHelper +import com.android.server.wm.flicker.testapp.ActivityOptions +import org.junit.Assume +import org.junit.Before +import org.junit.Ignore +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.Parameterized + +/** + * Test rotating an immersive app in fullscreen. + * + * To run this test: `atest WMShellFlickerTestsOther:RotateImmersiveAppInFullscreenTest` + * + * Actions: + * ``` + * Rotate the device by 90 degrees to trigger a rotation through sensors + * Verify that the button exists + * ``` + * + * Notes: + * ``` + * Some default assertions that are inherited from + * the `BaseTest` are ignored due to the nature of the immersive apps. + * + * This test only works with Cuttlefish devices. + * ``` + */ +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +class RotateImmersiveAppInFullscreenTest(flicker: LegacyFlickerTest) : BaseAppCompat(flicker) { + + private val immersiveApp = LetterboxAppHelper(instrumentation, + launcherName = ActivityOptions.PortraitImmersiveActivity.LABEL, + component = + ActivityOptions.PortraitImmersiveActivity.COMPONENT.toFlickerComponent()) + + private val cmdHelper: CommandsHelper = CommandsHelper.getInstance(instrumentation) + private val execAdb: (String) -> String = { cmd -> cmdHelper.executeShellCommand(cmd) } + + protected val uiDevice: UiDevice = UiDevice.getInstance(instrumentation) + + private val isCuttlefishDevice: Boolean = Build.MODEL.contains("Cuttlefish") + + /** {@inheritDoc} */ + override val transition: FlickerBuilder.() -> Unit + get() = { + setup { + setStartRotation() + immersiveApp.launchViaIntent(wmHelper) + startDisplayBounds = + wmHelper.currentState.layerState.physicalDisplayBounds + ?: error("Display not found") + } + transitions { + if (isCuttlefishDevice) { + // Simulates a device rotation through sensors because the rotation button + // only appears in a rotation event through sensors + execAdb("/vendor/bin/cuttlefish_sensor_injection rotate 0") + // verify rotation button existence + val rotationButtonSelector = By.res(LAUNCHER_PACKAGE, "rotate_suggestion") + uiDevice.wait(Until.hasObject(rotationButtonSelector), FIND_TIMEOUT) + uiDevice.findObject(rotationButtonSelector) + ?: error("rotation button not found") + } + } + teardown { + immersiveApp.exit(wmHelper) + } + } + + @Before + fun setUpForImmersiveAppTests() { + Assume.assumeTrue(isCuttlefishDevice) + } + + /** {@inheritDoc} */ + @Test + @Ignore("Not applicable to this CUJ. App is in immersive mode.") + override fun taskBarLayerIsVisibleAtStartAndEnd() { + } + + /** {@inheritDoc} */ + @Test + @Ignore("Not applicable to this CUJ. App is in immersive mode.") + override fun navBarLayerIsVisibleAtStartAndEnd() { + } + + /** {@inheritDoc} */ + @Test + @Ignore("Not applicable to this CUJ. App is in immersive mode.") + override fun statusBarLayerIsVisibleAtStartAndEnd() { + } + + /** {@inheritDoc} */ + @Test + @Ignore("Not applicable to this CUJ. App is in immersive mode.") + override fun taskBarWindowIsAlwaysVisible() { + } + + /** {@inheritDoc} */ + @Test + @Ignore("Not applicable to this CUJ. App is in immersive mode.") + override fun navBarWindowIsAlwaysVisible() { + } + + /** {@inheritDoc} */ + @Test + @Ignore("Not applicable to this CUJ. App is in immersive mode.") + override fun statusBarWindowIsAlwaysVisible() { + } + + @Test + @Ignore("Not applicable to this CUJ. App is in immersive mode.") + override fun statusBarLayerPositionAtStartAndEnd() { + } + + @Test + @Ignore("Not applicable to this CUJ. App is in immersive mode.") + override fun visibleWindowsShownMoreThanOneConsecutiveEntry() { + } + + /** Test that app is fullscreen by checking status bar and task bar visibility. */ + @Postsubmit + @Test + fun appWindowFullScreen() { + flicker.assertWmEnd { + this.isAppWindowInvisible(ComponentNameMatcher.STATUS_BAR) + .isAppWindowInvisible(ComponentNameMatcher.TASK_BAR) + .visibleRegion(immersiveApp).coversExactly(startDisplayBounds) + } + } + + /** Test that app is in the original rotation we have set up. */ + @Postsubmit + @Test + fun appInOriginalRotation() { + flicker.assertWmEnd { + this.hasRotation(Rotation.ROTATION_90) + } + } + + companion object { + private var startDisplayBounds = Rect.EMPTY + const val LAUNCHER_PACKAGE = "com.google.android.apps.nexuslauncher" + + /** + * Creates the test configurations. + * + * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and + * navigation modes. + */ + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): Collection<FlickerTest> { + return LegacyFlickerTestFactory.nonRotationTests( + supportedRotations = listOf(Rotation.ROTATION_90), + // TODO(b/292403378): 3 button mode not added as rotation button is hidden in taskbar + supportedNavigationModes = listOf(NavBar.MODE_GESTURAL) + + ) + } + } +} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipFromSplitScreenOnGoToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipFromSplitScreenOnGoToHomeTest.kt index 03c438f1be86..213d596a6131 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipFromSplitScreenOnGoToHomeTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipFromSplitScreenOnGoToHomeTest.kt @@ -135,7 +135,7 @@ class AutoEnterPipFromSplitScreenOnGoToHomeTest(flicker: LegacyFlickerTest) : if (flicker.scenario.isLandscapeOrSeascapeAtStart) { flicker.assertWmVisibleRegion(pipApp) { // first check against landscape bounds then against portrait bounds - (coversAtMost(displayBounds).then() as RegionTraceSubject).coversAtMost( + coversAtMost(displayBounds).then().coversAtMost( portraitDisplayBounds ) } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt new file mode 100644 index 000000000000..f58332198696 --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt @@ -0,0 +1,201 @@ +/* + * 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.bubbles + +import android.content.pm.LauncherApps +import android.content.pm.ShortcutInfo +import android.content.res.Resources +import android.graphics.Color +import android.os.Handler +import android.os.UserManager +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper.RunWithLooper +import android.view.IWindowManager +import android.view.WindowManager +import androidx.test.filters.SmallTest +import com.android.internal.R +import com.android.internal.statusbar.IStatusBarService +import com.android.launcher3.icons.BubbleIconFactory +import com.android.wm.shell.ShellTaskOrganizer +import com.android.wm.shell.ShellTestCase +import com.android.wm.shell.TestShellExecutor +import com.android.wm.shell.WindowManagerShellWrapper +import com.android.wm.shell.bubbles.bar.BubbleBarLayerView +import com.android.wm.shell.bubbles.properties.BubbleProperties +import com.android.wm.shell.common.DisplayController +import com.android.wm.shell.common.FloatingContentCoordinator +import com.android.wm.shell.common.ShellExecutor +import com.android.wm.shell.common.SyncTransactionQueue +import com.android.wm.shell.common.TaskStackListenerImpl +import com.android.wm.shell.sysui.ShellCommandHandler +import com.android.wm.shell.sysui.ShellController +import com.android.wm.shell.sysui.ShellInit +import com.android.wm.shell.taskview.TaskViewTransitions +import com.android.wm.shell.transition.Transitions +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.kotlin.any +import org.mockito.kotlin.doThrow +import org.mockito.kotlin.eq +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +/** + * Tests for loading / inflating views & icons for a bubble. + */ +@SmallTest +@RunWith(AndroidTestingRunner::class) +@RunWithLooper(setAsMainLooper = true) +class BubbleViewInfoTest : ShellTestCase() { + + private lateinit var metadataFlagListener: Bubbles.BubbleMetadataFlagListener + private lateinit var iconFactory: BubbleIconFactory + private lateinit var bubble: Bubble + + private lateinit var bubbleController: BubbleController + private lateinit var mainExecutor: ShellExecutor + private lateinit var bubbleStackView: BubbleStackView + private lateinit var bubbleBarLayerView: BubbleBarLayerView + + @Before + fun setup() { + metadataFlagListener = Bubbles.BubbleMetadataFlagListener {} + iconFactory = BubbleIconFactory(context, + 60, + 30, + Color.RED, + mContext.resources.getDimensionPixelSize( + R.dimen.importance_ring_stroke_width)) + + mainExecutor = TestShellExecutor() + val windowManager = context.getSystemService(WindowManager::class.java) + val shellInit = ShellInit(mainExecutor) + val shellCommandHandler = ShellCommandHandler() + val shellController = ShellController(context, shellInit, shellCommandHandler, + mainExecutor) + val bubblePositioner = BubblePositioner(context, windowManager) + val bubbleData = BubbleData(context, mock<BubbleLogger>(), bubblePositioner, + BubbleEducationController(context), mainExecutor) + val surfaceSynchronizer = { obj: Runnable -> obj.run() } + + bubbleController = BubbleController( + context, + shellInit, + shellCommandHandler, + shellController, + bubbleData, + surfaceSynchronizer, + FloatingContentCoordinator(), + mock<BubbleDataRepository>(), + mock<IStatusBarService>(), + windowManager, + WindowManagerShellWrapper(mainExecutor), + mock<UserManager>(), + mock<LauncherApps>(), + mock<BubbleLogger>(), + mock<TaskStackListenerImpl>(), + ShellTaskOrganizer(mainExecutor), + bubblePositioner, + mock<DisplayController>(), + null, + null, + mainExecutor, + mock<Handler>(), + mock<ShellExecutor>(), + mock<TaskViewTransitions>(), + mock<Transitions>(), + mock<SyncTransactionQueue>(), + mock<IWindowManager>(), + mock<BubbleProperties>()) + + bubbleStackView = BubbleStackView(context, bubbleController, bubbleData, + surfaceSynchronizer, FloatingContentCoordinator(), mainExecutor) + bubbleBarLayerView = BubbleBarLayerView(context, bubbleController) + } + + @Test + fun testPopulate() { + bubble = createBubbleWithShortcut() + val info = BubbleViewInfoTask.BubbleViewInfo.populate(context, + bubbleController, bubbleStackView, iconFactory, bubble, false /* skipInflation */) + assertThat(info!!).isNotNull() + + assertThat(info.imageView).isNotNull() + assertThat(info.expandedView).isNotNull() + assertThat(info.bubbleBarExpandedView).isNull() + + assertThat(info.shortcutInfo).isNotNull() + assertThat(info.appName).isNotEmpty() + assertThat(info.rawBadgeBitmap).isNotNull() + assertThat(info.dotPath).isNotNull() + assertThat(info.bubbleBitmap).isNotNull() + assertThat(info.badgeBitmap).isNotNull() + } + + @Test + fun testPopulateForBubbleBar() { + bubble = createBubbleWithShortcut() + val info = BubbleViewInfoTask.BubbleViewInfo.populateForBubbleBar(context, + bubbleController, bubbleBarLayerView, iconFactory, bubble, + false /* skipInflation */) + assertThat(info!!).isNotNull() + + assertThat(info.imageView).isNull() + assertThat(info.expandedView).isNull() + assertThat(info.bubbleBarExpandedView).isNotNull() + + assertThat(info.shortcutInfo).isNotNull() + assertThat(info.appName).isNotEmpty() + assertThat(info.rawBadgeBitmap).isNotNull() + assertThat(info.dotPath).isNotNull() + assertThat(info.bubbleBitmap).isNotNull() + assertThat(info.badgeBitmap).isNotNull() + } + + @Test + fun testPopulate_invalidShortcutIcon() { + bubble = createBubbleWithShortcut() + + // This eventually calls down to load the shortcut icon from the app, simulate an + // exception here if the app has an issue loading the shortcut icon; we default to + // the app icon in that case / none of the icons will be null. + val mockIconFactory = mock<BubbleIconFactory>() + whenever(mockIconFactory.getBubbleDrawable(eq(context), eq(bubble.shortcutInfo), + any())).doThrow(RuntimeException()) + + val info = BubbleViewInfoTask.BubbleViewInfo.populateForBubbleBar(context, + bubbleController, bubbleBarLayerView, iconFactory, bubble, + true /* skipInflation */) + assertThat(info).isNotNull() + + assertThat(info?.shortcutInfo).isNotNull() + assertThat(info?.appName).isNotEmpty() + assertThat(info?.rawBadgeBitmap).isNotNull() + assertThat(info?.dotPath).isNotNull() + assertThat(info?.bubbleBitmap).isNotNull() + assertThat(info?.badgeBitmap).isNotNull() + } + + private fun createBubbleWithShortcut(): Bubble { + val shortcutInfo = ShortcutInfo.Builder(mContext, "mockShortcutId").build() + return Bubble("mockKey", shortcutInfo, 1000, Resources.ID_NULL, + "mockTitle", 0 /* taskId */, "mockLocus", true /* isDismissible */, + mainExecutor, metadataFlagListener) + } +}
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java index ad84c7fb6128..56d0f8e13f08 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java @@ -18,9 +18,13 @@ package com.android.wm.shell.common.split; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; + +import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_END_AND_DISMISS; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_START_AND_DISMISS; + import static com.google.common.truth.Truth.assertThat; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; @@ -130,7 +134,7 @@ public class SplitLayoutTests extends ShellTestCase { @Test public void testSetDivideRatio() { mSplitLayout.setDividePosition(200, false /* applyLayoutChange */); - mSplitLayout.setDivideRatio(0.5f); + mSplitLayout.setDivideRatio(SNAP_TO_50_50); assertThat(mSplitLayout.getDividePosition()).isEqualTo( mSplitLayout.mDividerSnapAlgorithm.getMiddleTarget().position); } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java index 9b9600e4a51e..f85d707d55f9 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java @@ -61,6 +61,7 @@ import com.android.wm.shell.transition.Transitions; import dagger.Lazy; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -523,13 +524,175 @@ public class CompatUIControllerTest extends ShellTestCase { .createLayout(anyBoolean()); } + @Test + public void testUpdateActiveTaskInfo_newTask_visibleAndFocused_updated() { + // Simulate user aspect ratio button being shown for previous task + mController.setHasShownUserAspectRatioSettingsButton(true); + Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton()); + + // Create new task + final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, + /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ true, + /* isFocused */ true); + + // Simulate new task being shown + mController.updateActiveTaskInfo(taskInfo); + + // Check topActivityTaskId is updated to the taskId of the new task and + // hasShownUserAspectRatioSettingsButton has been reset to false + Assert.assertEquals(TASK_ID, mController.getTopActivityTaskId()); + Assert.assertFalse(mController.hasShownUserAspectRatioSettingsButton()); + } + + @Test + public void testUpdateActiveTaskInfo_newTask_notVisibleOrFocused_notUpdated() { + // Create new task + final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, + /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ true, + /* isFocused */ true); + + // Simulate task being shown + mController.updateActiveTaskInfo(taskInfo); + + // Check topActivityTaskId is updated to the taskId of the new task and + // hasShownUserAspectRatioSettingsButton has been reset to false + Assert.assertEquals(TASK_ID, mController.getTopActivityTaskId()); + Assert.assertFalse(mController.hasShownUserAspectRatioSettingsButton()); + + // Simulate user aspect ratio button being shown + mController.setHasShownUserAspectRatioSettingsButton(true); + Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton()); + + final int newTaskId = TASK_ID + 1; + + // Create visible but NOT focused task + final TaskInfo taskInfo1 = createTaskInfo(DISPLAY_ID, newTaskId, + /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ true, + /* isFocused */ false); + + // Simulate new task being shown + mController.updateActiveTaskInfo(taskInfo1); + + // Check topActivityTaskId is NOT updated and hasShownUserAspectRatioSettingsButton + // remains true + Assert.assertEquals(TASK_ID, mController.getTopActivityTaskId()); + Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton()); + + // Create focused but NOT visible task + final TaskInfo taskInfo2 = createTaskInfo(DISPLAY_ID, newTaskId, + /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ false, + /* isFocused */ true); + + // Simulate new task being shown + mController.updateActiveTaskInfo(taskInfo2); + + // Check topActivityTaskId is NOT updated and hasShownUserAspectRatioSettingsButton + // remains true + Assert.assertEquals(TASK_ID, mController.getTopActivityTaskId()); + Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton()); + + // Create NOT focused but NOT visible task + final TaskInfo taskInfo3 = createTaskInfo(DISPLAY_ID, newTaskId, + /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ false, + /* isFocused */ false); + + // Simulate new task being shown + mController.updateActiveTaskInfo(taskInfo3); + + // Check topActivityTaskId is NOT updated and hasShownUserAspectRatioSettingsButton + // remains true + Assert.assertEquals(TASK_ID, mController.getTopActivityTaskId()); + Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton()); + } + + @Test + public void testUpdateActiveTaskInfo_sameTask_notUpdated() { + // Create new task + final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, + /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ true, + /* isFocused */ true); + + // Simulate new task being shown + mController.updateActiveTaskInfo(taskInfo); + + // Check topActivityTaskId is updated to the taskId of the new task and + // hasShownUserAspectRatioSettingsButton has been reset to false + Assert.assertEquals(TASK_ID, mController.getTopActivityTaskId()); + Assert.assertFalse(mController.hasShownUserAspectRatioSettingsButton()); + + // Simulate user aspect ratio button being shown + mController.setHasShownUserAspectRatioSettingsButton(true); + Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton()); + + // Simulate same task being re-shown + mController.updateActiveTaskInfo(taskInfo); + + // Check topActivityTaskId is NOT updated and hasShownUserAspectRatioSettingsButton + // remains true + Assert.assertEquals(TASK_ID, mController.getTopActivityTaskId()); + Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton()); + } + + @Test + public void testUpdateActiveTaskInfo_transparentTask_notUpdated() { + // Create new task + final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, + /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ true, + /* isFocused */ true); + + // Simulate new task being shown + mController.updateActiveTaskInfo(taskInfo); + + // Check topActivityTaskId is updated to the taskId of the new task and + // hasShownUserAspectRatioSettingsButton has been reset to false + Assert.assertEquals(TASK_ID, mController.getTopActivityTaskId()); + Assert.assertFalse(mController.hasShownUserAspectRatioSettingsButton()); + + // Simulate user aspect ratio button being shown + mController.setHasShownUserAspectRatioSettingsButton(true); + Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton()); + + final int newTaskId = TASK_ID + 1; + + // Create transparent task + final TaskInfo taskInfo1 = createTaskInfo(DISPLAY_ID, newTaskId, + /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN, /* isVisible */ true, + /* isFocused */ true, /* isTopActivityTransparent */ true); + + // Simulate new task being shown + mController.updateActiveTaskInfo(taskInfo1); + + // Check topActivityTaskId is NOT updated and hasShownUserAspectRatioSettingsButton + // remains true + Assert.assertEquals(TASK_ID, mController.getTopActivityTaskId()); + Assert.assertTrue(mController.hasShownUserAspectRatioSettingsButton()); + } + private static TaskInfo createTaskInfo(int displayId, int taskId, boolean hasSizeCompat, @CameraCompatControlState int cameraCompatControlState) { + return createTaskInfo(displayId, taskId, hasSizeCompat, cameraCompatControlState, + /* isVisible */ false, /* isFocused */ false, + /* isTopActivityTransparent */ false); + } + + private static TaskInfo createTaskInfo(int displayId, int taskId, boolean hasSizeCompat, + @CameraCompatControlState int cameraCompatControlState, boolean isVisible, + boolean isFocused) { + return createTaskInfo(displayId, taskId, hasSizeCompat, cameraCompatControlState, + isVisible, isFocused, /* isTopActivityTransparent */ false); + } + + private static TaskInfo createTaskInfo(int displayId, int taskId, boolean hasSizeCompat, + @CameraCompatControlState int cameraCompatControlState, boolean isVisible, + boolean isFocused, boolean isTopActivityTransparent) { RunningTaskInfo taskInfo = new RunningTaskInfo(); taskInfo.taskId = taskId; taskInfo.displayId = displayId; taskInfo.topActivityInSizeCompat = hasSizeCompat; taskInfo.cameraCompatControlState = cameraCompatControlState; + taskInfo.isVisible = isVisible; + taskInfo.isFocused = isFocused; + taskInfo.isTopActivityTransparent = isTopActivityTransparent; return taskInfo; } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java index ce1290b38830..f460d1b09e34 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java @@ -93,7 +93,8 @@ public class UserAspectRatioSettingsLayoutTest extends ShellTestCase { mWindowManager = new UserAspectRatioSettingsWindowManager(mContext, mTaskInfo, mSyncTransactionQueue, mTaskListener, new DisplayLayout(), new CompatUIController.CompatUIHintsState(), - mOnUserAspectRatioSettingsButtonClicked, new TestShellExecutor(), flags -> 0); + mOnUserAspectRatioSettingsButtonClicked, new TestShellExecutor(), flags -> 0, + () -> false, s -> {}); mLayout = (UserAspectRatioSettingsLayout) LayoutInflater.from(mContext).inflate( R.layout.user_aspect_ratio_settings_layout, null); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java index 08cc2f763135..5a4d6c812c17 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java @@ -36,6 +36,7 @@ import android.content.ComponentName; import android.content.res.Configuration; import android.graphics.Rect; import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper.RunWithLooper; import android.util.Pair; import android.view.DisplayInfo; import android.view.InsetsSource; @@ -66,6 +67,7 @@ import org.mockito.MockitoAnnotations; import java.util.HashSet; import java.util.Set; import java.util.function.BiConsumer; +import java.util.function.Supplier; /** * Tests for {@link UserAspectRatioSettingsWindowManager}. @@ -74,6 +76,7 @@ import java.util.function.BiConsumer; * atest WMShellUnitTests:UserAspectRatioSettingsWindowManagerTest */ @RunWith(AndroidTestingRunner.class) +@RunWithLooper @SmallTest public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase { @@ -81,6 +84,8 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase { @Mock private SyncTransactionQueue mSyncTransactionQueue; @Mock + private Supplier<Boolean> mUserAspectRatioButtonShownChecker; + @Mock private BiConsumer<TaskInfo, ShellTaskOrganizer.TaskListener> mOnUserAspectRatioSettingsButtonClicked; @Mock private ShellTaskOrganizer.TaskListener mTaskListener; @@ -106,10 +111,12 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase { false, /* topActivityBoundsLetterboxed */ true); mWindowManager = new UserAspectRatioSettingsWindowManager(mContext, mTaskInfo, mSyncTransactionQueue, mTaskListener, new DisplayLayout(), new CompatUIHintsState(), - mOnUserAspectRatioSettingsButtonClicked, mExecutor, flags -> 0); + mOnUserAspectRatioSettingsButtonClicked, mExecutor, flags -> 0, + mUserAspectRatioButtonShownChecker, s -> {}); spyOn(mWindowManager); doReturn(mLayout).when(mWindowManager).inflateLayout(); doReturn(mViewHost).when(mWindowManager).createSurfaceViewHost(); + doReturn(false).when(mUserAspectRatioButtonShownChecker).get(); } @Test @@ -293,6 +300,39 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase { } @Test + public void testLayoutHasUserAspectRatioSettingsButton() { + clearInvocations(mWindowManager); + spyOn(mWindowManager); + TaskInfo taskInfo = createTaskInfo(/* eligibleForUserAspectRatioButton= */ + true, /* topActivityBoundsLetterboxed */ true); + + // User aspect ratio settings button has not yet been shown. + doReturn(false).when(mUserAspectRatioButtonShownChecker).get(); + + // Check the layout has the user aspect ratio settings button. + mWindowManager.updateCompatInfo(taskInfo, mTaskListener, /* canShow= */ true); + assertTrue(mWindowManager.mHasUserAspectRatioSettingsButton); + + // User aspect ratio settings button has been shown and is still visible. + spyOn(mWindowManager); + doReturn(true).when(mWindowManager).isShowingButton(); + doReturn(true).when(mUserAspectRatioButtonShownChecker).get(); + + // Check the layout still has the user aspect ratio settings button. + mWindowManager.updateCompatInfo(taskInfo, mTaskListener, /* canShow= */ true); + assertTrue(mWindowManager.mHasUserAspectRatioSettingsButton); + + // User aspect ratio settings button has been shown and has timed out so is no longer + // visible. + doReturn(false).when(mWindowManager).isShowingButton(); + doReturn(true).when(mUserAspectRatioButtonShownChecker).get(); + + // Check the layout no longer has the user aspect ratio button. + mWindowManager.updateCompatInfo(taskInfo, mTaskListener, /* canShow= */ true); + assertFalse(mWindowManager.mHasUserAspectRatioSettingsButton); + } + + @Test public void testAttachToParentSurface() { final SurfaceControl.Builder b = new SurfaceControl.Builder(); mWindowManager.attachToParentSurface(b); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedRecentTaskInfoTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedRecentTaskInfoTest.kt index baa06f2f0c45..bbd65be9abda 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedRecentTaskInfoTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedRecentTaskInfoTest.kt @@ -24,6 +24,7 @@ import android.window.IWindowContainerToken import android.window.WindowContainerToken import androidx.test.filters.SmallTest import com.android.wm.shell.ShellTestCase +import com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50 import com.android.wm.shell.util.GroupedRecentTaskInfo import com.android.wm.shell.util.GroupedRecentTaskInfo.CREATOR import com.android.wm.shell.util.GroupedRecentTaskInfo.TYPE_FREEFORM @@ -123,6 +124,7 @@ class GroupedRecentTaskInfoTest : ShellTestCase() { assertThat(recentTaskInfoParcel.taskInfo2).isNotNull() assertThat(recentTaskInfoParcel.taskInfo2!!.taskId).isEqualTo(2) assertThat(recentTaskInfoParcel.splitBounds).isNotNull() + assertThat(recentTaskInfoParcel.splitBounds!!.snapPosition).isEqualTo(SNAP_TO_50_50) } @Test @@ -156,7 +158,7 @@ class GroupedRecentTaskInfoTest : ShellTestCase() { private fun splitTasksGroupInfo(): GroupedRecentTaskInfo { val task1 = createTaskInfo(id = 1) val task2 = createTaskInfo(id = 2) - val splitBounds = SplitBounds(Rect(), Rect(), 1, 2) + val splitBounds = SplitBounds(Rect(), Rect(), 1, 2, SNAP_TO_50_50) return GroupedRecentTaskInfo.forSplitTasks(task1, task2, splitBounds) } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java index 40ce7859cc7f..10e9e11e9004 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java @@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; +import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -173,10 +174,10 @@ public class RecentTasksControllerTest extends ShellTestCase { // Verify only one update if the split info is the same SplitBounds bounds1 = new SplitBounds(new Rect(0, 0, 50, 50), - new Rect(50, 50, 100, 100), t1.taskId, t2.taskId); + new Rect(50, 50, 100, 100), t1.taskId, t2.taskId, SNAP_TO_50_50); mRecentTasksController.addSplitPair(t1.taskId, t2.taskId, bounds1); SplitBounds bounds2 = new SplitBounds(new Rect(0, 0, 50, 50), - new Rect(50, 50, 100, 100), t1.taskId, t2.taskId); + new Rect(50, 50, 100, 100), t1.taskId, t2.taskId, SNAP_TO_50_50); mRecentTasksController.addSplitPair(t1.taskId, t2.taskId, bounds2); verify(mRecentTasksController, times(1)).notifyRecentTasksChanged(); } @@ -207,8 +208,10 @@ public class RecentTasksControllerTest extends ShellTestCase { setRawList(t1, t2, t3, t4, t5, t6); // Mark a couple pairs [t2, t4], [t3, t5] - SplitBounds pair1Bounds = new SplitBounds(new Rect(), new Rect(), 2, 4); - SplitBounds pair2Bounds = new SplitBounds(new Rect(), new Rect(), 3, 5); + SplitBounds pair1Bounds = + new SplitBounds(new Rect(), new Rect(), 2, 4, SNAP_TO_50_50); + SplitBounds pair2Bounds = + new SplitBounds(new Rect(), new Rect(), 3, 5, SNAP_TO_50_50); mRecentTasksController.addSplitPair(t2.taskId, t4.taskId, pair1Bounds); mRecentTasksController.addSplitPair(t3.taskId, t5.taskId, pair2Bounds); @@ -236,8 +239,10 @@ public class RecentTasksControllerTest extends ShellTestCase { setRawList(t1, t2, t3, t4, t5, t6); // Mark a couple pairs [t2, t4], [t3, t5] - SplitBounds pair1Bounds = new SplitBounds(new Rect(), new Rect(), 2, 4); - SplitBounds pair2Bounds = new SplitBounds(new Rect(), new Rect(), 3, 5); + SplitBounds pair1Bounds = + new SplitBounds(new Rect(), new Rect(), 2, 4, SNAP_TO_50_50); + SplitBounds pair2Bounds = + new SplitBounds(new Rect(), new Rect(), 3, 5, SNAP_TO_50_50); mRecentTasksController.addSplitPair(t2.taskId, t4.taskId, pair1Bounds); mRecentTasksController.addSplitPair(t3.taskId, t5.taskId, pair2Bounds); @@ -334,7 +339,8 @@ public class RecentTasksControllerTest extends ShellTestCase { setRawList(t1, t2, t3); // Add a pair - SplitBounds pair1Bounds = new SplitBounds(new Rect(), new Rect(), 2, 3); + SplitBounds pair1Bounds = + new SplitBounds(new Rect(), new Rect(), 2, 3, SNAP_TO_50_50); mRecentTasksController.addSplitPair(t2.taskId, t3.taskId, pair1Bounds); reset(mRecentTasksController); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/SplitBoundsTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/SplitBoundsTest.java index 50d02ae0dccd..b790aee6fb0e 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/SplitBoundsTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/SplitBoundsTest.java @@ -1,5 +1,7 @@ package com.android.wm.shell.recents; +import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -44,21 +46,21 @@ public class SplitBoundsTest extends ShellTestCase { @Test public void testVerticalStacked() { SplitBounds ssb = new SplitBounds(mTopRect, mBottomRect, - TASK_ID_1, TASK_ID_2); + TASK_ID_1, TASK_ID_2, SNAP_TO_50_50); assertTrue(ssb.appsStackedVertically); } @Test public void testHorizontalStacked() { SplitBounds ssb = new SplitBounds(mLeftRect, mRightRect, - TASK_ID_1, TASK_ID_2); + TASK_ID_1, TASK_ID_2, SNAP_TO_50_50); assertFalse(ssb.appsStackedVertically); } @Test public void testHorizontalDividerBounds() { SplitBounds ssb = new SplitBounds(mTopRect, mBottomRect, - TASK_ID_1, TASK_ID_2); + TASK_ID_1, TASK_ID_2, SNAP_TO_50_50); Rect dividerBounds = ssb.visualDividerBounds; assertEquals(0, dividerBounds.left); assertEquals(DEVICE_LENGTH / 2 - DIVIDER_SIZE / 2, dividerBounds.top); @@ -69,7 +71,7 @@ public class SplitBoundsTest extends ShellTestCase { @Test public void testVerticalDividerBounds() { SplitBounds ssb = new SplitBounds(mLeftRect, mRightRect, - TASK_ID_1, TASK_ID_2); + TASK_ID_1, TASK_ID_2, SNAP_TO_50_50); Rect dividerBounds = ssb.visualDividerBounds; assertEquals(DEVICE_WIDTH / 2 - DIVIDER_SIZE / 2, dividerBounds.left); assertEquals(0, dividerBounds.top); @@ -80,7 +82,7 @@ public class SplitBoundsTest extends ShellTestCase { @Test public void testEqualVerticalTaskPercent() { SplitBounds ssb = new SplitBounds(mTopRect, mBottomRect, - TASK_ID_1, TASK_ID_2); + TASK_ID_1, TASK_ID_2, SNAP_TO_50_50); float topPercentSpaceTaken = (float) (DEVICE_LENGTH / 2 - DIVIDER_SIZE / 2) / DEVICE_LENGTH; assertEquals(topPercentSpaceTaken, ssb.topTaskPercent, 0.01); } @@ -88,7 +90,7 @@ public class SplitBoundsTest extends ShellTestCase { @Test public void testEqualHorizontalTaskPercent() { SplitBounds ssb = new SplitBounds(mLeftRect, mRightRect, - TASK_ID_1, TASK_ID_2); + TASK_ID_1, TASK_ID_2, SNAP_TO_50_50); float leftPercentSpaceTaken = (float) (DEVICE_WIDTH / 2 - DIVIDER_SIZE / 2) / DEVICE_WIDTH; assertEquals(leftPercentSpaceTaken, ssb.leftTaskPercent, 0.01); } diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index 502ff874ea69..e1dd145edcfa 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -36,11 +36,6 @@ aconfig_declarations { ], } -java_aconfig_library { - name: "hwui_flags_java_lib", - aconfig_declarations: "hwui_flags", -} - cc_aconfig_library { name: "hwui_flags_cc_lib", aconfig_declarations: "hwui_flags", diff --git a/libs/hwui/aconfig/hwui_flags.aconfig b/libs/hwui/aconfig/hwui_flags.aconfig index d074a90d1adf..d0d3c5e7ece1 100644 --- a/libs/hwui/aconfig/hwui_flags.aconfig +++ b/libs/hwui/aconfig/hwui_flags.aconfig @@ -5,4 +5,18 @@ flag { namespace: "core_graphics" description: "API to enable apps to restrict the amount of HDR headroom that is used" bug: "234181960" -}
\ No newline at end of file +} + +flag { + name: "hdr_10bit_plus" + namespace: "core_graphics" + description: "Use 10101010 and FP16 formats for HDR-UI when available" + bug: "284159488" +} + +flag { + name: "gainmap_animations" + namespace: "core_graphics" + description: "APIs to help enable animations involving gainmaps" + bug: "296482289" +} diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index d54c5f57c95c..b00fc699e515 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -123,7 +123,7 @@ CanvasContext::CanvasContext(RenderThread& thread, bool translucent, RenderNode* , mProfiler(mJankTracker.frames(), thread.timeLord().frameIntervalNanos()) , mContentDrawBounds(0, 0, 0, 0) , mRenderPipeline(std::move(renderPipeline)) - , mHintSessionWrapper(uiThreadId, renderThreadId) { + , mHintSessionWrapper(std::make_shared<HintSessionWrapper>(uiThreadId, renderThreadId)) { mRenderThread.cacheManager().registerCanvasContext(this); mRenderThread.renderState().registerContextCallback(this); rootRenderNode->makeRoot(); @@ -162,6 +162,7 @@ void CanvasContext::destroy() { destroyHardwareResources(); mAnimationContext->destroy(); mRenderThread.cacheManager().onContextStopped(this); + mHintSessionWrapper->delayedDestroy(mRenderThread, 2_s, mHintSessionWrapper); } static void setBufferCount(ANativeWindow* window) { @@ -766,7 +767,7 @@ void CanvasContext::draw(bool solelyTextureViewUpdates) { int64_t frameDeadline = mCurrentFrameInfo->get(FrameInfoIndex::FrameDeadline); int64_t dequeueBufferDuration = mCurrentFrameInfo->get(FrameInfoIndex::DequeueBufferDuration); - mHintSessionWrapper.updateTargetWorkDuration(frameDeadline - intendedVsync); + mHintSessionWrapper->updateTargetWorkDuration(frameDeadline - intendedVsync); if (didDraw) { int64_t frameStartTime = mCurrentFrameInfo->get(FrameInfoIndex::FrameStartTime); @@ -774,7 +775,7 @@ void CanvasContext::draw(bool solelyTextureViewUpdates) { int64_t actualDuration = frameDuration - (std::min(syncDelayDuration, mLastDequeueBufferDuration)) - dequeueBufferDuration - idleDuration; - mHintSessionWrapper.reportActualWorkDuration(actualDuration); + mHintSessionWrapper->reportActualWorkDuration(actualDuration); } mLastDequeueBufferDuration = dequeueBufferDuration; @@ -917,10 +918,10 @@ const SkM44& CanvasContext::getPixelSnapMatrix() const { } void CanvasContext::prepareAndDraw(RenderNode* node) { - ATRACE_CALL(); + int64_t vsyncId = mRenderThread.timeLord().lastVsyncId(); + ATRACE_FORMAT("%s %" PRId64, __func__, vsyncId); nsecs_t vsync = mRenderThread.timeLord().computeFrameTimeNanos(); - int64_t vsyncId = mRenderThread.timeLord().lastVsyncId(); int64_t frameDeadline = mRenderThread.timeLord().lastFrameDeadline(); int64_t frameInterval = mRenderThread.timeLord().frameIntervalNanos(); int64_t frameInfo[UI_THREAD_FRAME_INFO_SIZE]; @@ -1112,11 +1113,11 @@ void CanvasContext::prepareSurfaceControlForWebview() { } void CanvasContext::sendLoadResetHint() { - mHintSessionWrapper.sendLoadResetHint(); + mHintSessionWrapper->sendLoadResetHint(); } void CanvasContext::sendLoadIncreaseHint() { - mHintSessionWrapper.sendLoadIncreaseHint(); + mHintSessionWrapper->sendLoadIncreaseHint(); } void CanvasContext::setSyncDelayDuration(nsecs_t duration) { @@ -1124,7 +1125,7 @@ void CanvasContext::setSyncDelayDuration(nsecs_t duration) { } void CanvasContext::startHintSession() { - mHintSessionWrapper.init(); + mHintSessionWrapper->init(); } bool CanvasContext::shouldDither() { diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 241f8dd879d9..37e4f7ecca54 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -363,7 +363,7 @@ private: std::function<bool(int64_t, int64_t, int64_t)> mASurfaceTransactionCallback; std::function<void()> mPrepareSurfaceControlForWebviewCallback; - HintSessionWrapper mHintSessionWrapper; + std::shared_ptr<HintSessionWrapper> mHintSessionWrapper; nsecs_t mLastDequeueBufferDuration = 0; nsecs_t mSyncDelayDuration = 0; nsecs_t mIdleDuration = 0; diff --git a/libs/hwui/renderthread/HintSessionWrapper.cpp b/libs/hwui/renderthread/HintSessionWrapper.cpp index b34da5153a72..d1ebe6d9f576 100644 --- a/libs/hwui/renderthread/HintSessionWrapper.cpp +++ b/libs/hwui/renderthread/HintSessionWrapper.cpp @@ -24,6 +24,7 @@ #include <vector> #include "../Properties.h" +#include "RenderThread.h" #include "thread/CommonPool.h" using namespace std::chrono_literals; @@ -62,8 +63,9 @@ HintSessionWrapper::~HintSessionWrapper() { } void HintSessionWrapper::destroy() { - if (mHintSessionFuture.valid()) { - mHintSession = mHintSessionFuture.get(); + if (mHintSessionFuture.has_value()) { + mHintSession = mHintSessionFuture->get(); + mHintSessionFuture = std::nullopt; } if (mHintSession) { mBinding->closeSession(mHintSession); @@ -74,12 +76,12 @@ void HintSessionWrapper::destroy() { bool HintSessionWrapper::init() { if (mHintSession != nullptr) return true; - // If we're waiting for the session - if (mHintSessionFuture.valid()) { + if (mHintSessionFuture.has_value()) { // If the session is here - if (mHintSessionFuture.wait_for(0s) == std::future_status::ready) { - mHintSession = mHintSessionFuture.get(); + if (mHintSessionFuture->wait_for(0s) == std::future_status::ready) { + mHintSession = mHintSessionFuture->get(); + mHintSessionFuture = std::nullopt; if (mHintSession != nullptr) { mSessionValid = true; return true; @@ -136,6 +138,7 @@ void HintSessionWrapper::reportActualWorkDuration(long actualDurationNanos) { actualDurationNanos < kSanityCheckUpperBound) { mBinding->reportActualWorkDuration(mHintSession, actualDurationNanos); } + mLastFrameNotification = systemTime(); } void HintSessionWrapper::sendLoadResetHint() { @@ -153,6 +156,28 @@ void HintSessionWrapper::sendLoadResetHint() { void HintSessionWrapper::sendLoadIncreaseHint() { if (!init()) return; mBinding->sendHint(mHintSession, static_cast<int32_t>(SessionHint::CPU_LOAD_UP)); + mLastFrameNotification = systemTime(); +} + +bool HintSessionWrapper::alive() { + return mHintSession != nullptr; +} + +nsecs_t HintSessionWrapper::getLastUpdate() { + return mLastFrameNotification; +} + +// Requires passing in its shared_ptr since it shouldn't own a shared_ptr to itself +void HintSessionWrapper::delayedDestroy(RenderThread& rt, nsecs_t delay, + std::shared_ptr<HintSessionWrapper> wrapperPtr) { + nsecs_t lastUpdate = wrapperPtr->getLastUpdate(); + rt.queue().postDelayed(delay, [lastUpdate = lastUpdate, wrapper = wrapperPtr]() mutable { + if (wrapper->getLastUpdate() == lastUpdate) { + wrapper->destroy(); + } + // Ensure the shared_ptr is killed at the end of the method + wrapper = nullptr; + }); } } /* namespace renderthread */ diff --git a/libs/hwui/renderthread/HintSessionWrapper.h b/libs/hwui/renderthread/HintSessionWrapper.h index f8b876e28d51..36e91ea33c75 100644 --- a/libs/hwui/renderthread/HintSessionWrapper.h +++ b/libs/hwui/renderthread/HintSessionWrapper.h @@ -19,6 +19,7 @@ #include <android/performance_hint.h> #include <future> +#include <optional> #include "utils/TimeUtils.h" @@ -27,6 +28,8 @@ namespace uirenderer { namespace renderthread { +class RenderThread; + class HintSessionWrapper { public: friend class HintSessionWrapperTests; @@ -40,10 +43,15 @@ public: void sendLoadIncreaseHint(); bool init(); void destroy(); + bool alive(); + nsecs_t getLastUpdate(); + void delayedDestroy(renderthread::RenderThread& rt, nsecs_t delay, + std::shared_ptr<HintSessionWrapper> wrapperPtr); private: APerformanceHintSession* mHintSession = nullptr; - std::future<APerformanceHintSession*> mHintSessionFuture; + // This needs to work concurrently for testing + std::optional<std::shared_future<APerformanceHintSession*>> mHintSessionFuture; int mResetsSinceLastReport = 0; nsecs_t mLastFrameNotification = 0; diff --git a/libs/hwui/tests/unit/HintSessionWrapperTests.cpp b/libs/hwui/tests/unit/HintSessionWrapperTests.cpp index 623be1e3f3f3..a14ae1cc46ec 100644 --- a/libs/hwui/tests/unit/HintSessionWrapperTests.cpp +++ b/libs/hwui/tests/unit/HintSessionWrapperTests.cpp @@ -23,9 +23,11 @@ #include <chrono> #include "Properties.h" +#include "tests/common/TestUtils.h" using namespace testing; using namespace std::chrono_literals; +using namespace android::uirenderer::renderthread; APerformanceHintManager* managerPtr = reinterpret_cast<APerformanceHintManager*>(123); APerformanceHintSession* sessionPtr = reinterpret_cast<APerformanceHintSession*>(456); @@ -42,6 +44,9 @@ public: protected: std::shared_ptr<HintSessionWrapper> mWrapper; + std::promise<int> blockDestroyCallUntil; + std::promise<int> waitForDestroyFinished; + class MockHintSessionBinding : public HintSessionWrapper::HintSessionBinding { public: void init() override; @@ -53,11 +58,17 @@ protected: MOCK_METHOD(void, fakeUpdateTargetWorkDuration, (APerformanceHintSession*, int64_t)); MOCK_METHOD(void, fakeReportActualWorkDuration, (APerformanceHintSession*, int64_t)); MOCK_METHOD(void, fakeSendHint, (APerformanceHintSession*, int32_t)); + // Needs to be on the binding so it can be accessed from static methods + std::promise<int> allowCreationToFinish; }; // Must be static so it can have function pointers we can point to with static methods static std::shared_ptr<MockHintSessionBinding> sMockBinding; + static void allowCreationToFinish() { sMockBinding->allowCreationToFinish.set_value(1); } + void allowDelayedDestructionToStart() { blockDestroyCallUntil.set_value(1); } + void waitForDelayedDestructionToFinish() { waitForDestroyFinished.get_future().wait(); } + // Must be static so we can point to them as normal fn pointers with HintSessionBinding static APerformanceHintManager* stubGetManager() { return sMockBinding->fakeGetManager(); }; static APerformanceHintSession* stubCreateSession(APerformanceHintManager* manager, @@ -65,6 +76,12 @@ protected: int64_t initialTarget) { return sMockBinding->fakeCreateSession(manager, ids, idsSize, initialTarget); } + static APerformanceHintSession* stubManagedCreateSession(APerformanceHintManager* manager, + const int32_t* ids, size_t idsSize, + int64_t initialTarget) { + sMockBinding->allowCreationToFinish.get_future().wait(); + return sMockBinding->fakeCreateSession(manager, ids, idsSize, initialTarget); + } static APerformanceHintSession* stubSlowCreateSession(APerformanceHintManager* manager, const int32_t* ids, size_t idsSize, int64_t initialTarget) { @@ -85,7 +102,21 @@ protected: static void stubSendHint(APerformanceHintSession* session, int32_t hintId) { sMockBinding->fakeSendHint(session, hintId); }; - void waitForWrapperReady() { mWrapper->mHintSessionFuture.wait(); } + void waitForWrapperReady() { + if (mWrapper->mHintSessionFuture.has_value()) { + mWrapper->mHintSessionFuture->wait(); + } + } + void scheduleDelayedDestroyManaged() { + TestUtils::runOnRenderThread([&](renderthread::RenderThread& rt) { + // Guaranteed to be scheduled first, allows destruction to start + rt.queue().postDelayed(0_ms, [&] { blockDestroyCallUntil.get_future().wait(); }); + // Guaranteed to be scheduled second, destroys the session + mWrapper->delayedDestroy(rt, 1_ms, mWrapper); + // This is guaranteed to be queued after the destroy, signals that destruction is done + rt.queue().postDelayed(1_ms, [&] { waitForDestroyFinished.set_value(1); }); + }); + } }; std::shared_ptr<HintSessionWrapperTests::MockHintSessionBinding> @@ -113,6 +144,7 @@ void HintSessionWrapperTests::MockHintSessionBinding::init() { } void HintSessionWrapperTests::TearDown() { + // Ensure that anything running on RT is completely finished mWrapper = nullptr; sMockBinding = nullptr; } @@ -122,6 +154,7 @@ TEST_F(HintSessionWrapperTests, destructorClosesBackgroundSession) { sMockBinding->createSession = stubSlowCreateSession; mWrapper->init(); mWrapper = nullptr; + Mock::VerifyAndClearExpectations(sMockBinding.get()); } TEST_F(HintSessionWrapperTests, sessionInitializesCorrectly) { @@ -148,4 +181,107 @@ TEST_F(HintSessionWrapperTests, loadResetHintsSendCorrectly) { mWrapper->sendLoadResetHint(); } +TEST_F(HintSessionWrapperTests, delayedDeletionWorksCorrectlyAndOnlyClosesOnce) { + EXPECT_CALL(*sMockBinding, fakeCloseSession(sessionPtr)).Times(1); + mWrapper->init(); + waitForWrapperReady(); + // Init a second time just to ensure the wrapper grabs the promise value + mWrapper->init(); + + EXPECT_EQ(mWrapper->alive(), true); + + // Schedule delayed destruction, allow it to run, and check when it's done + scheduleDelayedDestroyManaged(); + allowDelayedDestructionToStart(); + waitForDelayedDestructionToFinish(); + + // Ensure it closed within the timeframe of the test + Mock::VerifyAndClearExpectations(sMockBinding.get()); + EXPECT_EQ(mWrapper->alive(), false); + // If we then delete the wrapper, it shouldn't close the session again + EXPECT_CALL(*sMockBinding, fakeCloseSession(_)).Times(0); + mWrapper = nullptr; +} + +TEST_F(HintSessionWrapperTests, delayedDeletionResolvesBeforeAsyncCreationFinishes) { + // Here we test whether queueing delayedDestroy works while creation is still happening, if + // creation happens after + EXPECT_CALL(*sMockBinding, fakeCloseSession(sessionPtr)).Times(1); + sMockBinding->createSession = &stubManagedCreateSession; + + // Start creating the session and destroying it at the same time + mWrapper->init(); + scheduleDelayedDestroyManaged(); + + // Allow destruction to happen first + allowDelayedDestructionToStart(); + + // Make sure destruction has had time to happen + std::this_thread::sleep_for(50ms); + + // Then, allow creation to finish after delayed destroy runs + allowCreationToFinish(); + + // Wait for destruction to finish + waitForDelayedDestructionToFinish(); + + // Ensure it closed within the timeframe of the test + Mock::VerifyAndClearExpectations(sMockBinding.get()); + EXPECT_EQ(mWrapper->alive(), false); +} + +TEST_F(HintSessionWrapperTests, delayedDeletionResolvesAfterAsyncCreationFinishes) { + // Here we test whether queueing delayedDestroy works while creation is still happening, if + // creation happens before + EXPECT_CALL(*sMockBinding, fakeCloseSession(sessionPtr)).Times(1); + sMockBinding->createSession = &stubManagedCreateSession; + + // Start creating the session and destroying it at the same time + mWrapper->init(); + scheduleDelayedDestroyManaged(); + + // Allow creation to happen first + allowCreationToFinish(); + + // Make sure creation has had time to happen + waitForWrapperReady(); + + // Then allow destruction to happen after creation is done + allowDelayedDestructionToStart(); + + // Wait for it to finish + waitForDelayedDestructionToFinish(); + + // Ensure it closed within the timeframe of the test + Mock::VerifyAndClearExpectations(sMockBinding.get()); + EXPECT_EQ(mWrapper->alive(), false); +} + +TEST_F(HintSessionWrapperTests, delayedDeletionDoesNotKillReusedSession) { + EXPECT_CALL(*sMockBinding, fakeCloseSession(sessionPtr)).Times(0); + EXPECT_CALL(*sMockBinding, + fakeSendHint(sessionPtr, static_cast<int32_t>(SessionHint::CPU_LOAD_UP))) + .Times(1); + + mWrapper->init(); + waitForWrapperReady(); + // Init a second time just to grab the wrapper from the promise + mWrapper->init(); + EXPECT_EQ(mWrapper->alive(), true); + + // First schedule the deletion + scheduleDelayedDestroyManaged(); + + // Then, send a hint to update the timestamp + mWrapper->sendLoadIncreaseHint(); + + // Then, run the delayed deletion after sending the update + allowDelayedDestructionToStart(); + waitForDelayedDestructionToFinish(); + + // Ensure it didn't close within the timeframe of the test + Mock::VerifyAndClearExpectations(sMockBinding.get()); + EXPECT_EQ(mWrapper->alive(), true); +} + } // namespace android::uirenderer::renderthread
\ No newline at end of file diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 842542f4f43b..adc0e16448ee 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -941,27 +941,15 @@ public class AudioManager { } /** - * Sends a simulated key event for a media button. - * To simulate a key press, you must first send a KeyEvent built with a - * {@link KeyEvent#ACTION_DOWN} action, then another event with the {@link KeyEvent#ACTION_UP} - * action. + * Sends a simulated key event for a media button. To simulate a key press, you must first send + * a KeyEvent built with a {@link KeyEvent#ACTION_DOWN} action, then another event with the + * {@link KeyEvent#ACTION_UP} action. + * * <p>The key event will be sent to the current media key event consumer which registered with * {@link AudioManager#registerMediaButtonEventReceiver(PendingIntent)}. - * @param keyEvent a {@link KeyEvent} instance whose key code is one of - * {@link KeyEvent#KEYCODE_MUTE}, - * {@link KeyEvent#KEYCODE_HEADSETHOOK}, - * {@link KeyEvent#KEYCODE_MEDIA_PLAY}, - * {@link KeyEvent#KEYCODE_MEDIA_PAUSE}, - * {@link KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE}, - * {@link KeyEvent#KEYCODE_MEDIA_STOP}, - * {@link KeyEvent#KEYCODE_MEDIA_NEXT}, - * {@link KeyEvent#KEYCODE_MEDIA_PREVIOUS}, - * {@link KeyEvent#KEYCODE_MEDIA_REWIND}, - * {@link KeyEvent#KEYCODE_MEDIA_RECORD}, - * {@link KeyEvent#KEYCODE_MEDIA_FAST_FORWARD}, - * {@link KeyEvent#KEYCODE_MEDIA_CLOSE}, - * {@link KeyEvent#KEYCODE_MEDIA_EJECT}, - * or {@link KeyEvent#KEYCODE_MEDIA_AUDIO_TRACK}. + * + * @param keyEvent a media session {@link KeyEvent}, as defined by {@link + * KeyEvent#isMediaSessionKey}. */ public void dispatchMediaKeyEvent(KeyEvent keyEvent) { MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(getContext()); diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java index a6e8fa0644df..aaaf25f008c7 100644 --- a/media/java/android/media/RemoteController.java +++ b/media/java/android/media/RemoteController.java @@ -220,33 +220,21 @@ import java.util.List; return -1; } - /** - * Send a simulated key event for a media button to be received by the current client. - * To simulate a key press, you must first send a KeyEvent built with - * a {@link KeyEvent#ACTION_DOWN} action, then another event with the {@link KeyEvent#ACTION_UP} - * action. - * <p>The key event will be sent to the registered receiver - * (see {@link AudioManager#registerMediaButtonEventReceiver(PendingIntent)}) whose associated - * {@link RemoteControlClient}'s metadata and playback state is published (there may be - * none under some circumstances). - * @param keyEvent a {@link KeyEvent} instance whose key code is one of - * {@link KeyEvent#KEYCODE_MUTE}, - * {@link KeyEvent#KEYCODE_HEADSETHOOK}, - * {@link KeyEvent#KEYCODE_MEDIA_PLAY}, - * {@link KeyEvent#KEYCODE_MEDIA_PAUSE}, - * {@link KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE}, - * {@link KeyEvent#KEYCODE_MEDIA_STOP}, - * {@link KeyEvent#KEYCODE_MEDIA_NEXT}, - * {@link KeyEvent#KEYCODE_MEDIA_PREVIOUS}, - * {@link KeyEvent#KEYCODE_MEDIA_REWIND}, - * {@link KeyEvent#KEYCODE_MEDIA_RECORD}, - * {@link KeyEvent#KEYCODE_MEDIA_FAST_FORWARD}, - * {@link KeyEvent#KEYCODE_MEDIA_CLOSE}, - * {@link KeyEvent#KEYCODE_MEDIA_EJECT}, - * or {@link KeyEvent#KEYCODE_MEDIA_AUDIO_TRACK}. + * Send a simulated key event for a media button to be received by the current client. To + * simulate a key press, you must first send a KeyEvent built with a {@link + * KeyEvent#ACTION_DOWN} action, then another event with the {@link KeyEvent#ACTION_UP} action. + * + * <p>The key event will be sent to the registered receiver (see {@link + * AudioManager#registerMediaButtonEventReceiver(PendingIntent)}) whose associated {@link + * RemoteControlClient}'s metadata and playback state is published (there may be none under some + * circumstances). + * + * @param keyEvent a media session {@link KeyEvent}, as defined by {@link + * KeyEvent#isMediaSessionKey}. * @return true if the event was successfully sent, false otherwise. - * @throws IllegalArgumentException + * @throws IllegalArgumentException If the provided {@link KeyEvent} is not a media session key, + * as defined by {@link KeyEvent#isMediaSessionKey}. */ public boolean sendMediaKeyEvent(KeyEvent keyEvent) throws IllegalArgumentException { if (!KeyEvent.isMediaSessionKey(keyEvent.getKeyCode())) { diff --git a/media/java/android/media/RouteDiscoveryPreference.java b/media/java/android/media/RouteDiscoveryPreference.java index 71d8261b09bf..161fd2fb7f96 100644 --- a/media/java/android/media/RouteDiscoveryPreference.java +++ b/media/java/android/media/RouteDiscoveryPreference.java @@ -194,6 +194,7 @@ public final class RouteDiscoveryPreference implements Parcelable { String indent = prefix + " "; + pw.println(indent + "mShouldPerformActiveScan=" + mShouldPerformActiveScan); pw.println(indent + "mPreferredFeatures=" + mPreferredFeatures); pw.println(indent + "mPackageOrder=" + mPackageOrder); pw.println(indent + "mAllowedPackages=" + mAllowedPackages); diff --git a/omapi/java/android/se/omapi/SeFrameworkInitializer.java b/omapi/java/android/se/omapi/SeFrameworkInitializer.java new file mode 100644 index 000000000000..d09a35d85009 --- /dev/null +++ b/omapi/java/android/se/omapi/SeFrameworkInitializer.java @@ -0,0 +1,70 @@ +/* + * Copyright 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.se.omapi; + +import android.annotation.FlaggedApi; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.nfc.Flags; + +/** + * Class for performing registration for SE service. + * + * @hide + */ +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) +@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) +public class SeFrameworkInitializer { + private SeFrameworkInitializer() {} + + private static volatile SeServiceManager sSeServiceManager; + + /** + * Sets an instance of {@link SeServiceManager} that allows + * the se mainline module to register/obtain se binder services. This is called + * by the platform during the system initialization. + * + * @param seServiceManager instance of {@link SeServiceManager} that allows + * the se/nfc mainline module to register/obtain se binder services. + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public static void setSeServiceManager( + @NonNull SeServiceManager seServiceManager) { + if (sSeServiceManager != null) { + throw new IllegalStateException("setSeServiceManager called twice!"); + } + + if (seServiceManager == null) { + throw new IllegalArgumentException("seServiceManager must not be null"); + } + + sSeServiceManager = seServiceManager; + } + + /** + * Gets an instance of {@link SeServiceManager} that allows + * the se mainline module to register/obtain se binder services. + * + * @return instance of {@link SeServiceManager} that allows + * the se/nfc mainline module to register/obtain se binder services. + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @Nullable + public static SeServiceManager getSeServiceManager() { + return sSeServiceManager; + } +} diff --git a/omapi/java/android/se/omapi/SeServiceManager.java b/omapi/java/android/se/omapi/SeServiceManager.java new file mode 100644 index 000000000000..791073706752 --- /dev/null +++ b/omapi/java/android/se/omapi/SeServiceManager.java @@ -0,0 +1,140 @@ +/* + * Copyright 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. + */ + + +/********************************************************************** + * This file is not a part of the SE mainline module * + * *******************************************************************/ + +package android.se.omapi; + +import android.annotation.FlaggedApi; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.annotation.SystemApi.Client; +import android.content.Context; +import android.nfc.Flags; +import android.os.IBinder; +import android.os.ServiceManager; + +/** + * Provides a way to register and obtain the system service binder objects managed by the + * SecureElement service. + * + * @hide + */ +@SystemApi(client = Client.MODULE_LIBRARIES) +@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) +public class SeServiceManager { + + /** + * @hide + */ + public SeServiceManager() { + } + + /** + * A class that exposes the methods to register and obtain each system service. + * @hide + */ + @SystemApi(client = Client.MODULE_LIBRARIES) + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public static final class ServiceRegisterer { + private final String mServiceName; + + /** + * @hide + */ + public ServiceRegisterer(String serviceName) { + mServiceName = serviceName; + } + + /** + * Register a system server binding object for a service. + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public void register(@NonNull IBinder service) { + ServiceManager.addService(mServiceName, service); + } + + /** + * Get the system server binding object for a service. + * + * <p>This blocks until the service instance is ready, + * or a timeout happens, in which case it returns null. + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @Nullable + public IBinder get() { + return ServiceManager.getService(mServiceName); + } + + /** + * Get the system server binding object for a service. + * + * <p>This blocks until the service instance is ready, + * or a timeout happens, in which case it throws {@link ServiceNotFoundException}. + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull + public IBinder getOrThrow() throws ServiceNotFoundException { + try { + return ServiceManager.getServiceOrThrow(mServiceName); + } catch (ServiceManager.ServiceNotFoundException e) { + throw new ServiceNotFoundException(mServiceName); + } + } + + /** + * Get the system server binding object for a service. If the specified service is + * not available, it returns null. + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @Nullable + public IBinder tryGet() { + return ServiceManager.checkService(mServiceName); + } + } + + /** + * See {@link ServiceRegisterer#getOrThrow}. + * @hide + */ + @SystemApi(client = Client.MODULE_LIBRARIES) + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public static class ServiceNotFoundException extends ServiceManager.ServiceNotFoundException { + /** + * Constructor. + * + * @param name the name of the binder service that cannot be found. + * + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + public ServiceNotFoundException(@NonNull String name) { + super(name); + } + } + + /** + * Returns {@link ServiceRegisterer} for the "secure_element" service. + */ + @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) + @NonNull + public ServiceRegisterer getSeManagerServiceRegisterer() { + return new ServiceRegisterer(Context.SECURE_ELEMENT_SERVICE); + } +} diff --git a/packages/CredentialManager/horologist/Android.bp b/packages/CredentialManager/horologist/Android.bp index bb324bb8350d..bb255bdb1306 100644 --- a/packages/CredentialManager/horologist/Android.bp +++ b/packages/CredentialManager/horologist/Android.bp @@ -16,6 +16,7 @@ android_library { "androidx.compose.foundation_foundation", "androidx.compose.runtime_runtime", "androidx.compose.ui_ui", + "androidx.compose.ui_ui-tooling", "androidx.navigation_navigation-compose", "androidx.lifecycle_lifecycle-extensions", "androidx.lifecycle_lifecycle-runtime-ktx", diff --git a/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/layout/BelowTimeTextPreview.kt b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/layout/BelowTimeTextPreview.kt new file mode 100644 index 000000000000..e6025fc0911f --- /dev/null +++ b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/layout/BelowTimeTextPreview.kt @@ -0,0 +1,26 @@ +/* + * Copyright 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 + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.horologist.compose.layout + +import androidx.compose.runtime.Composable +import com.google.android.horologist.annotations.ExperimentalHorologistApi + +@OptIn(ExperimentalHorologistApi::class) +@Composable +public fun belowTimeTextPreview(): ScalingLazyColumnState { + return ScalingLazyColumnDefaults.belowTimeText().create() +} diff --git a/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Button.kt b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Button.kt new file mode 100644 index 000000000000..57e0c106b5f0 --- /dev/null +++ b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Button.kt @@ -0,0 +1,143 @@ +/* + * Copyright 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 + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.horologist.compose.material + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.unit.Dp +import androidx.wear.compose.material.Button +import androidx.wear.compose.material.ButtonColors +import androidx.wear.compose.material.ButtonDefaults +import androidx.wear.compose.material.ButtonDefaults.DefaultButtonSize +import androidx.wear.compose.material.ButtonDefaults.DefaultIconSize +import androidx.wear.compose.material.ButtonDefaults.LargeButtonSize +import androidx.wear.compose.material.ButtonDefaults.LargeIconSize +import androidx.wear.compose.material.ButtonDefaults.SmallButtonSize +import androidx.wear.compose.material.ButtonDefaults.SmallIconSize +import com.google.android.horologist.annotations.ExperimentalHorologistApi + +/** + * This component is an alternative to [Button], providing the following: + * - a convenient way of providing an icon and choosing its size from a range of sizes recommended + * by the Wear guidelines; + */ +@ExperimentalHorologistApi +@Composable +public fun Button( + imageVector: ImageVector, + contentDescription: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, + colors: ButtonColors = ButtonDefaults.primaryButtonColors(), + buttonSize: ButtonSize = ButtonSize.Default, + iconRtlMode: IconRtlMode = IconRtlMode.Default, + enabled: Boolean = true, +) { + Button( + icon = imageVector, + contentDescription = contentDescription, + onClick = onClick, + modifier = modifier, + colors = colors, + buttonSize = buttonSize, + iconRtlMode = iconRtlMode, + enabled = enabled, + ) +} + +/** + * This component is an alternative to [Button], providing the following: + * - a convenient way of providing an icon and choosing its size from a range of sizes recommended + * by the Wear guidelines; + */ +@ExperimentalHorologistApi +@Composable +public fun Button( + @DrawableRes id: Int, + contentDescription: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, + colors: ButtonColors = ButtonDefaults.primaryButtonColors(), + buttonSize: ButtonSize = ButtonSize.Default, + iconRtlMode: IconRtlMode = IconRtlMode.Default, + enabled: Boolean = true, +) { + Button( + icon = id, + contentDescription = contentDescription, + onClick = onClick, + modifier = modifier, + colors = colors, + buttonSize = buttonSize, + iconRtlMode = iconRtlMode, + enabled = enabled, + ) +} + +@OptIn(ExperimentalHorologistApi::class) +@Composable +internal fun Button( + icon: Any, + contentDescription: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, + colors: ButtonColors = ButtonDefaults.primaryButtonColors(), + buttonSize: ButtonSize = ButtonSize.Default, + iconRtlMode: IconRtlMode = IconRtlMode.Default, + enabled: Boolean = true, +) { + Button( + onClick = onClick, + modifier = modifier.size(buttonSize.tapTargetSize), + enabled = enabled, + colors = colors, + ) { + val iconModifier = Modifier + .size(buttonSize.iconSize) + .align(Alignment.Center) + + Icon( + icon = icon, + contentDescription = contentDescription, + modifier = iconModifier, + rtlMode = iconRtlMode, + ) + } +} + +@ExperimentalHorologistApi +public sealed class ButtonSize( + public val iconSize: Dp, + public val tapTargetSize: Dp, +) { + public object Default : + ButtonSize(iconSize = DefaultIconSize, tapTargetSize = DefaultButtonSize) + + public object Large : ButtonSize(iconSize = LargeIconSize, tapTargetSize = LargeButtonSize) + public object Small : ButtonSize(iconSize = SmallIconSize, tapTargetSize = SmallButtonSize) + + /** + * Custom sizes should follow the [accessibility principles and guidance for touch targets](https://developer.android.com/training/wearables/accessibility#set-minimum). + */ + public data class Custom(val customIconSize: Dp, val customTapTargetSize: Dp) : + ButtonSize(iconSize = customIconSize, tapTargetSize = customTapTargetSize) +} + diff --git a/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Icon.kt b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Icon.kt new file mode 100644 index 000000000000..74e54c0ba479 --- /dev/null +++ b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Icon.kt @@ -0,0 +1,129 @@ +/* + * Copyright 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 + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.horologist.compose.material + +import androidx.annotation.DrawableRes +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.scale +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalLayoutDirection +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.LayoutDirection +import androidx.wear.compose.material.Icon +import androidx.wear.compose.material.LocalContentAlpha +import androidx.wear.compose.material.LocalContentColor +import com.google.android.horologist.annotations.ExperimentalHorologistApi + +/** + * This component is an alternative to [Icon], providing the following: + * - a convenient way of setting the icon to be mirrored in RTL mode; + */ +@ExperimentalHorologistApi +@Composable +public fun Icon( + imageVector: ImageVector, + contentDescription: String?, + modifier: Modifier = Modifier, + tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current), + rtlMode: IconRtlMode = IconRtlMode.Default, +) { + val shouldMirror = + rtlMode == IconRtlMode.Mirrored && LocalLayoutDirection.current == LayoutDirection.Rtl + Icon( + modifier = modifier.scale( + scaleX = if (shouldMirror) -1f else 1f, + scaleY = 1f, + ), + imageVector = imageVector, + contentDescription = contentDescription, + tint = tint, + ) +} + +/** + * This component is an alternative to [Icon], providing the following: + * - a convenient way of setting the icon to be mirrored in RTL mode; + */ +@ExperimentalHorologistApi +@Composable +public fun Icon( + @DrawableRes id: Int, + contentDescription: String?, + modifier: Modifier = Modifier, + tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current), + rtlMode: IconRtlMode = IconRtlMode.Default, +) { + val shouldMirror = + rtlMode == IconRtlMode.Mirrored && LocalLayoutDirection.current == LayoutDirection.Rtl + + Icon( + painter = painterResource(id = id), + contentDescription = contentDescription, + modifier = modifier.scale( + scaleX = if (shouldMirror) -1f else 1f, + scaleY = 1f, + ), + tint = tint, + ) +} + +@OptIn(ExperimentalHorologistApi::class) +@Composable +internal fun Icon( + icon: Any, + contentDescription: String?, + modifier: Modifier = Modifier, + tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current), + rtlMode: IconRtlMode = IconRtlMode.Default, +) { + val shouldMirror = + rtlMode == IconRtlMode.Mirrored && LocalLayoutDirection.current == LayoutDirection.Rtl + + val iconModifier = modifier.scale( + scaleX = if (shouldMirror) -1f else 1f, + scaleY = 1f, + ) + when (icon) { + is ImageVector -> { + Icon( + imageVector = icon, + modifier = iconModifier, + contentDescription = contentDescription, + tint = tint, + ) + } + + is Int -> { + Icon( + painter = painterResource(id = icon), + contentDescription = contentDescription, + modifier = iconModifier, + tint = tint, + ) + } + + else -> throw IllegalArgumentException("Type not supported.") + } +} + +@ExperimentalHorologistApi +public enum class IconRtlMode { + Default, + Mirrored, +} diff --git a/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/util/A11y.kt b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/util/A11y.kt new file mode 100644 index 000000000000..39de2e142edc --- /dev/null +++ b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/util/A11y.kt @@ -0,0 +1,28 @@ +/* + * Copyright 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 + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.horologist.compose.material.util + +import com.google.android.horologist.annotations.ExperimentalHorologistApi + +/** + * Make explicit that a conscious decision was made to mark an element as decorative, so it does not + * have associated actions or state. + * + * https://developer.android.com/jetpack/compose/accessibility#describe-visual + */ +@ExperimentalHorologistApi +public val DECORATIVE_ELEMENT_CONTENT_DESCRIPTION: String? = null diff --git a/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/tools/WearPreview.kt b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/tools/WearPreview.kt new file mode 100644 index 000000000000..0bfceeea916c --- /dev/null +++ b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/tools/WearPreview.kt @@ -0,0 +1,25 @@ +/* + * Copyright 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 + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.horologist.compose.tools + +import androidx.compose.ui.tooling.preview.Preview + +@Preview( + backgroundColor = 0xff000000, + showBackground = true, +) +public annotation class WearPreview diff --git a/packages/CredentialManager/shared/Android.bp b/packages/CredentialManager/shared/Android.bp new file mode 100644 index 000000000000..38d98a9d47f7 --- /dev/null +++ b/packages/CredentialManager/shared/Android.bp @@ -0,0 +1,19 @@ +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_library { + name: "CredentialManagerShared", + manifest: "AndroidManifest.xml", + srcs: ["src/**/*.kt"], + static_libs: [ + "androidx.core_core-ktx", + "androidx.credentials_credentials", + "guava", + ], +} diff --git a/packages/CredentialManager/shared/AndroidManifest.xml b/packages/CredentialManager/shared/AndroidManifest.xml new file mode 100644 index 000000000000..a46088783024 --- /dev/null +++ b/packages/CredentialManager/shared/AndroidManifest.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* + * Copyright (c) 2023 Google Inc. + * + * 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="com.android.credentialmanager"> + +</manifest> diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt new file mode 100644 index 000000000000..defba8dacb7b --- /dev/null +++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt @@ -0,0 +1,42 @@ +/* + * 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.0N + * + * 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 + +import android.content.Intent +import android.credentials.ui.RequestInfo +import com.android.credentialmanager.ktx.requestInfo +import com.android.credentialmanager.mapper.toGet +import com.android.credentialmanager.mapper.toRequestCancel +import com.android.credentialmanager.model.Request + +fun Intent.parse(): Request { + this.toRequestCancel()?.let { return it } + + return when (requestInfo?.type) { + RequestInfo.TYPE_CREATE -> { + Request.Create + } + + RequestInfo.TYPE_GET -> { + this.toGet() + } + + else -> { + throw IllegalStateException("Unrecognized request type: ${requestInfo?.type}") + } + } +} diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/LogConstants.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/LogConstants.kt new file mode 100644 index 000000000000..44d33ff7084a --- /dev/null +++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/LogConstants.kt @@ -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.0N + * + * 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 + +const val TAG = "CredentialSelector" diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/factory/CredentialEntryFactory.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/factory/CredentialEntryFactory.kt new file mode 100644 index 000000000000..a2c1f0388807 --- /dev/null +++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/factory/CredentialEntryFactory.kt @@ -0,0 +1,25 @@ +package com.android.credentialmanager.factory + +import android.app.slice.Slice +import android.credentials.Credential +import androidx.credentials.PublicKeyCredential +import androidx.credentials.provider.CredentialEntry +import androidx.credentials.provider.CustomCredentialEntry +import androidx.credentials.provider.PasswordCredentialEntry +import androidx.credentials.provider.PublicKeyCredentialEntry + +fun fromSlice(slice: Slice): CredentialEntry? = + try { + when (slice.spec?.type) { + Credential.TYPE_PASSWORD_CREDENTIAL -> PasswordCredentialEntry.fromSlice(slice)!! + + PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL -> + PublicKeyCredentialEntry.fromSlice(slice)!! + + else -> CustomCredentialEntry.fromSlice(slice)!! + } + } catch (e: Exception) { + // Try CustomCredentialEntry.fromSlice one last time in case the cause was a failed + // password / passkey parsing attempt. + CustomCredentialEntry.fromSlice(slice) + }
\ No newline at end of file diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/IntentKtx.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/IntentKtx.kt new file mode 100644 index 000000000000..a4c20bfabb35 --- /dev/null +++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/IntentKtx.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.0N + * + * 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.ktx + +import android.content.Intent +import android.credentials.ui.CancelUiRequest +import android.credentials.ui.CreateCredentialProviderData +import android.credentials.ui.GetCredentialProviderData +import android.credentials.ui.ProviderData +import android.credentials.ui.RequestInfo + +val Intent.cancelUiRequest: CancelUiRequest? + get() = this.extras?.getParcelable( + CancelUiRequest.EXTRA_CANCEL_UI_REQUEST, + CancelUiRequest::class.java + ) + +val Intent.requestInfo: RequestInfo? + get() = this.extras?.getParcelable( + RequestInfo.EXTRA_REQUEST_INFO, + RequestInfo::class.java + ) + +val Intent.getCredentialProviderDataList: List<ProviderData> + get() = this.extras?.getParcelableArrayList( + ProviderData.EXTRA_ENABLED_PROVIDER_DATA_LIST, + GetCredentialProviderData::class.java + ) ?: emptyList() + +val Intent.createCredentialProviderDataList: List<ProviderData> + get() = this.extras?.getParcelableArrayList( + ProviderData.EXTRA_ENABLED_PROVIDER_DATA_LIST, + CreateCredentialProviderData::class.java + ) ?: emptyList() diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/PackageManagerKtx.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/PackageManagerKtx.kt new file mode 100644 index 000000000000..5f4f298241a1 --- /dev/null +++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/PackageManagerKtx.kt @@ -0,0 +1,35 @@ +/* + * 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.0N + * + * 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.ktx + +import android.content.pm.PackageManager +import android.text.TextUtils +import android.util.Log +import com.android.credentialmanager.TAG + +fun PackageManager.appLabel(appPackageName: String): String? = + try { + val pkgInfo = this.getPackageInfo(appPackageName, PackageManager.PackageInfoFlags.of(0)) + val applicationInfo = checkNotNull(pkgInfo.applicationInfo) + applicationInfo.loadSafeLabel( + this, 0f, + TextUtils.SAFE_STRING_FLAG_FIRST_LINE or TextUtils.SAFE_STRING_FLAG_TRIM + ).toString() + } catch (e: Exception) { + Log.e(TAG, "Caller app not found", e) + null + } diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestCancelMapper.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestCancelMapper.kt new file mode 100644 index 000000000000..86a6d23a76a9 --- /dev/null +++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestCancelMapper.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.0N + * + * 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.mapper + +import android.content.Intent +import com.android.credentialmanager.ktx.cancelUiRequest +import com.android.credentialmanager.model.Request + +fun Intent.toRequestCancel(): Request.Cancel? = + this.cancelUiRequest?.let { cancelUiRequest -> + Request.Cancel( + showCancellationUi = cancelUiRequest.shouldShowCancellationUi(), + appPackageName = cancelUiRequest.appPackageName + ) + } diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestGetMapper.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestGetMapper.kt new file mode 100644 index 000000000000..ed9d56344853 --- /dev/null +++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestGetMapper.kt @@ -0,0 +1,22 @@ +package com.android.credentialmanager.mapper + +import android.content.Intent +import android.credentials.ui.GetCredentialProviderData +import com.android.credentialmanager.ktx.getCredentialProviderDataList +import com.android.credentialmanager.model.Request +import com.google.common.collect.ImmutableList +import com.google.common.collect.ImmutableMap + +fun Intent.toGet() = Request.Get( + providers = ImmutableMap.copyOf( + getCredentialProviderDataList.associateBy { it.providerFlattenedComponentName } + ), + entries = ImmutableList.copyOf( + getCredentialProviderDataList.map { providerData -> + check(providerData is GetCredentialProviderData) { + "Invalid provider data type for GetCredentialRequest" + } + providerData + }.flatMap { it.credentialEntries } + ) +)
\ No newline at end of file diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt new file mode 100644 index 000000000000..bc073105efe1 --- /dev/null +++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt @@ -0,0 +1,39 @@ +/* + * 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.0N + * + * 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.model + +import android.credentials.ui.Entry +import android.credentials.ui.ProviderData +import com.google.common.collect.ImmutableList +import com.google.common.collect.ImmutableMap + +/** + * Represents the request made by the CredentialManager API. + */ +sealed class Request { + data class Cancel( + val showCancellationUi: Boolean, + val appPackageName: String? + ) : Request() + + data class Get( + val providers: ImmutableMap<String, ProviderData>, + val entries: ImmutableList<Entry>, + ) : Request() + + data object Create : Request() +} diff --git a/packages/CredentialManager/wear/Android.bp b/packages/CredentialManager/wear/Android.bp index 639e8d18b306..c0dff168969d 100644 --- a/packages/CredentialManager/wear/Android.bp +++ b/packages/CredentialManager/wear/Android.bp @@ -21,6 +21,7 @@ android_app { }, static_libs: [ + "CredentialManagerShared", "Horologist", "PlatformComposeCore", "androidx.activity_activity-compose", @@ -31,6 +32,7 @@ android_app { "androidx.compose.material_material-icons-extended", "androidx.compose.runtime_runtime", "androidx.compose.ui_ui", + "androidx.compose.ui_ui-tooling", "androidx.core_core-ktx", "androidx.lifecycle_lifecycle-extensions", "androidx.lifecycle_lifecycle-livedata", diff --git a/packages/CredentialManager/wear/res/drawable/passkey_icon.xml b/packages/CredentialManager/wear/res/drawable/passkey_icon.xml new file mode 100644 index 000000000000..be366bf2a255 --- /dev/null +++ b/packages/CredentialManager/wear/res/drawable/passkey_icon.xml @@ -0,0 +1,21 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:pathData="M23,10.5H17V13.5H23V10.5Z" + android:fillColor="#188038"/> + <path + android:pathData="M6.5,17.5C3.5,17.5 1,15 1,12C1,9 3.5,6.5 6.5,6.5C9.5,6.5 12,9 12,12C12,15 9.5,17.5 6.5,17.5ZM6.5,9.5C5.1,9.5 4,10.6 4,12C4,13.4 5.1,14.5 6.5,14.5C7.9,14.5 9,13.4 9,12C9,10.6 7.9,9.5 6.5,9.5Z" + android:fillColor="#4285F4"/> + <path + android:pathData="M21,13.5H19H17V16.5H19V15.5C19,14.9 19.4,14.5 20,14.5C20.6,14.5 21,14.9 21,15.5V16.5H23V13.5H21Z" + android:fillColor="#34A853"/> + <path + android:pathData="M11.8,10.5H8.5C8.8,10.9 9,11.4 9,12C9,12.6 8.8,13.1 8.5,13.5H11.8C11.9,13 12,12.5 12,12C12,11.5 11.9,11 11.8,10.5Z" + android:fillColor="#EA4335"/> + <path + android:pathData="M17,10.5H11.8C11.9,11 12,11.5 12,12C12,12.5 11.9,13 11.8,13.5H17V10.5Z" + android:fillColor="#FBBC04"/> +</vector> diff --git a/packages/CredentialManager/wear/res/values/strings.xml b/packages/CredentialManager/wear/res/values/strings.xml index 10ea9186ca85..109644f46b10 100644 --- a/packages/CredentialManager/wear/res/values/strings.xml +++ b/packages/CredentialManager/wear/res/values/strings.xml @@ -18,4 +18,14 @@ <!-- The name of this application. Credential Manager is a service that centralizes and provides access to a user's credentials used to sign in to various apps. [CHAR LIMIT=80] --> <string name="app_name">Credential Manager</string> + <!-- Title of a screen prompting if the user would like to use their saved passkey. + [CHAR LIMIT=80] --> + <string name="use_passkey_title">Use passkey?</string> + <!-- Title of a screen prompting if the user would like to use their saved password. + [CHAR LIMIT=80] --> + <string name="use_password_title">Use password?</string> + <!-- Content description for the cancel button of a screen. [CHAR LIMIT=NONE] --> + <string name="dialog_cancel_button_cd">Cancel</string> + <!-- Content description for the OK button of a screen. [CHAR LIMIT=NONE] --> + <string name="dialog_ok_button_cd">OK</string> </resources>
\ No newline at end of file diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorActivity.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorActivity.kt index 77fffaa1e04c..53122ba7ccdc 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorActivity.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorActivity.kt @@ -16,28 +16,72 @@ package com.android.credentialmanager.ui +import android.content.Intent import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.navigation.NavHostController +import androidx.activity.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import androidx.wear.compose.material.MaterialTheme -import androidx.wear.compose.navigation.rememberSwipeDismissableNavController +import kotlinx.coroutines.launch class CredentialSelectorActivity : ComponentActivity() { - lateinit var navController: NavHostController + private val viewModel: CredentialSelectorViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setTheme(android.R.style.Theme_DeviceDefault) - setContent { - navController = rememberSwipeDismissableNavController() + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.uiState.collect { uiState -> + when (uiState) { + CredentialSelectorUiState.Idle -> { + // Don't display anything, assuming that there should be minimal latency + // to parse the Credential Manager intent and define the state of the + // app. If latency is big, then a "loading" screen should be displayed + // to the user. + } - MaterialTheme { - WearApp(navController = navController) + is CredentialSelectorUiState.Get -> { + setContent { + MaterialTheme { + WearApp() + } + } + } + + CredentialSelectorUiState.Create -> { + // TODO: b/301206624 - Implement create flow + finish() + } + + is CredentialSelectorUiState.Cancel -> { + // TODO: b/300422310 - Implement cancel with message flow + finish() + } + + CredentialSelectorUiState.Finish -> { + finish() + } + } + } } } + + viewModel.onNewIntent(intent) + } + + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + + val previousIntent = getIntent() + setIntent(intent) + + viewModel.onNewIntent(intent, previousIntent) } } diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorViewModel.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorViewModel.kt new file mode 100644 index 000000000000..d22d5d1a28a3 --- /dev/null +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/CredentialSelectorViewModel.kt @@ -0,0 +1,123 @@ +/* + * 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.0N + * + * 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.ui + +import android.app.Application +import android.content.Intent +import android.util.Log +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.viewModelScope +import com.android.credentialmanager.TAG +import com.android.credentialmanager.parse +import com.android.credentialmanager.ktx.appLabel +import com.android.credentialmanager.ktx.requestInfo +import com.android.credentialmanager.mapper.toGet +import com.android.credentialmanager.ui.model.PasskeyUiModel +import com.android.credentialmanager.ui.model.PasswordUiModel +import com.android.credentialmanager.model.Request +import com.android.credentialmanager.ui.mapper.toGet +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch + +class CredentialSelectorViewModel( + private val application: Application +) : AndroidViewModel(application = application) { + + private val _uiState = + MutableStateFlow<CredentialSelectorUiState>(CredentialSelectorUiState.Idle) + val uiState: StateFlow<CredentialSelectorUiState> = _uiState + + fun onNewIntent(intent: Intent, previousIntent: Intent? = null) { + viewModelScope.launch { + val request = intent.parse() + if (shouldFinishActivity(request = request, previousIntent = previousIntent)) { + _uiState.value = CredentialSelectorUiState.Finish + } else { + when (request) { + is Request.Cancel -> { + request.appPackageName?.let { appPackageName -> + application.packageManager.appLabel(appPackageName)?.let { appLabel -> + _uiState.value = CredentialSelectorUiState.Cancel(appLabel) + } ?: run { + Log.d(TAG, + "Received UI cancel request with an invalid package name.") + _uiState.value = CredentialSelectorUiState.Finish + } + } ?: run { + Log.d(TAG, "Received UI cancel request with an invalid package name.") + _uiState.value = CredentialSelectorUiState.Finish + } + } + + Request.Create -> { + _uiState.value = CredentialSelectorUiState.Create + } + + is Request.Get -> { + _uiState.value = request.toGet() + } + } + } + } + } + + /** + * Check if backend requested the UI activity to be cancelled. Different from the other + * finishing flows, this one does not report anything back to the Credential Manager service + * backend. + */ + private fun shouldFinishActivity(request: Request, previousIntent: Intent? = null): Boolean { + if (request !is Request.Cancel) { + return false + } else { + Log.d( + TAG, "Received UI cancellation intent. Should show cancellation" + + " ui = ${request.showCancellationUi}") + + previousIntent?.let { + val previousUiRequest = previousIntent.parse() + + if (previousUiRequest is Request.Cancel) { + val previousToken = previousIntent.requestInfo?.token + val currentToken = previousIntent.requestInfo?.token + + if (previousToken != currentToken) { + // Cancellation was for a different request, don't cancel the current UI. + return false + } + } + } + + return !request.showCancellationUi + } + } +} + +sealed class CredentialSelectorUiState { + data object Idle : CredentialSelectorUiState() + sealed class Get : CredentialSelectorUiState() { + data class SingleProviderSinglePasskey(val passkeyUiModel: PasskeyUiModel) : Get() + data class SingleProviderSinglePassword(val passwordUiModel: PasswordUiModel) : Get() + + // TODO: b/301206470 add the remaining states + } + + data object Create : CredentialSelectorUiState() + data class Cancel(val appName: String) : CredentialSelectorUiState() + data object Finish : CredentialSelectorUiState() +} diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/Screen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/Screen.kt index ee6ea5e57c19..7d1a49b07718 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/Screen.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/Screen.kt @@ -19,5 +19,5 @@ package com.android.credentialmanager.ui sealed class Screen( val route: String, ) { - object Main : Screen("main") + data object Main : Screen("main") } diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt index 5ec0c8cd9292..19ea9ede9d98 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt @@ -19,8 +19,8 @@ package com.android.credentialmanager.ui import androidx.compose.runtime.Composable -import androidx.navigation.NavHostController import androidx.wear.compose.foundation.rememberSwipeToDismissBoxState +import androidx.wear.compose.navigation.rememberSwipeDismissableNavController import androidx.wear.compose.navigation.rememberSwipeDismissableNavHostState import com.android.credentialmanager.ui.screens.MainScreen import com.google.android.horologist.annotations.ExperimentalHorologistApi @@ -28,9 +28,8 @@ import com.google.android.horologist.compose.navscaffold.WearNavScaffold import com.google.android.horologist.compose.navscaffold.composable @Composable -fun WearApp( - navController: NavHostController -) { +fun WearApp() { + val navController = rememberSwipeDismissableNavController() val swipeToDismissBoxState = rememberSwipeToDismissBoxState() val navHostState = rememberSwipeDismissableNavHostState(swipeToDismissBoxState = swipeToDismissBoxState) diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/AccountRow.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/AccountRow.kt new file mode 100644 index 000000000000..c20ee0c22ad6 --- /dev/null +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/AccountRow.kt @@ -0,0 +1,63 @@ +/* + * Copyright 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 + * + * https://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.ui.components + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.wear.compose.material.MaterialTheme +import androidx.wear.compose.material.Text +import com.google.android.horologist.compose.tools.WearPreview + +@Composable +fun AccountRow( + name: String, + email: String, + modifier: Modifier = Modifier, +) { + Column(modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) { + Text( + text = name, + color = Color(0xFFE6FF7B), + overflow = TextOverflow.Ellipsis, + maxLines = 1, + style = MaterialTheme.typography.title2 + ) + Text( + text = email, + modifier = Modifier.padding(top = 7.dp), + color = Color(0xFFCAC5BC), + overflow = TextOverflow.Ellipsis, + maxLines = 2, + style = MaterialTheme.typography.body1, + ) + } +} + +@WearPreview +@Composable +fun AccountRowPreview() { + AccountRow( + name = "Elisa Beckett", + email = "beckett_bakery@gmail.com", + ) +} diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/DialogButtonsRow.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/DialogButtonsRow.kt new file mode 100644 index 000000000000..5cb3c1590dfd --- /dev/null +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/DialogButtonsRow.kt @@ -0,0 +1,71 @@ +/* + * Copyright 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 + * + * https://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.ui.components + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Check +import androidx.compose.material.icons.filled.Close +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.wear.compose.material.ButtonDefaults +import com.google.android.horologist.compose.material.Button +import com.google.android.horologist.compose.tools.WearPreview +import com.android.credentialmanager.R +import com.google.android.horologist.annotations.ExperimentalHorologistApi + +@OptIn(ExperimentalHorologistApi::class) +@Composable +fun DialogButtonsRow( + onCancelClick: () -> Unit, + onOKClick: () -> Unit, + modifier: Modifier = Modifier, + cancelButtonIcon: ImageVector = Icons.Default.Close, + okButtonIcon: ImageVector = Icons.Default.Check, + cancelButtonContentDescription: String = stringResource(R.string.dialog_cancel_button_cd), + okButtonContentDescription: String = stringResource(R.string.dialog_ok_button_cd), +) { + Row( + modifier = modifier, + horizontalArrangement = Arrangement.Center, + ) { + Button( + imageVector = cancelButtonIcon, + contentDescription = cancelButtonContentDescription, + onClick = onCancelClick, + colors = ButtonDefaults.secondaryButtonColors(), + ) + Button( + imageVector = okButtonIcon, + contentDescription = okButtonContentDescription, + onClick = onOKClick, + modifier = Modifier.padding(start = 20.dp) + ) + } +} + +@WearPreview +@Composable +fun DialogButtonsRowPreview() { + DialogButtonsRow(onCancelClick = {}, onOKClick = {}) +} + diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/PasswordRow.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/PasswordRow.kt new file mode 100644 index 000000000000..97900b723bc3 --- /dev/null +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/PasswordRow.kt @@ -0,0 +1,62 @@ +/* + * Copyright 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 + * + * https://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.ui.components + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.wear.compose.material.MaterialTheme +import androidx.wear.compose.material.Text +import com.google.android.horologist.compose.tools.WearPreview + +@Composable +fun PasswordRow( + email: String, + modifier: Modifier = Modifier, +) { + Column(modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) { + Text( + text = email, + color = Color(0xFFE6FF7B), + overflow = TextOverflow.Ellipsis, + maxLines = 2, + style = MaterialTheme.typography.title2 + ) + Text( + text = "••••••••••••••", + modifier = Modifier.padding(top = 7.dp), + color = Color(0xFFCAC5BC), + overflow = TextOverflow.Ellipsis, + maxLines = 1, + style = MaterialTheme.typography.body1, + ) + } +} + +@WearPreview +@Composable +fun PasswordRowPreview() { + PasswordRow( + email = "beckett_bakery@gmail.com", + ) +} + diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/SignInHeader.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/SignInHeader.kt new file mode 100644 index 000000000000..956c56b2c7b1 --- /dev/null +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/SignInHeader.kt @@ -0,0 +1,83 @@ +/* + * Copyright 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 + * + * https://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.ui.components + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.wear.compose.material.MaterialTheme +import androidx.wear.compose.material.Text +import com.android.credentialmanager.R +import com.google.android.horologist.annotations.ExperimentalHorologistApi +import com.google.android.horologist.compose.material.Icon +import com.google.android.horologist.compose.material.util.DECORATIVE_ELEMENT_CONTENT_DESCRIPTION +import com.google.android.horologist.compose.tools.WearPreview + +@OptIn(ExperimentalHorologistApi::class) +@Composable +fun SignInHeader( + @DrawableRes icon: Int, + title: String, + modifier: Modifier = Modifier, +) { + SignInHeader( + iconContent = { + Icon( + id = icon, + contentDescription = DECORATIVE_ELEMENT_CONTENT_DESCRIPTION + ) + }, + title = title, + modifier = modifier, + ) +} + +@Composable +fun SignInHeader( + iconContent: @Composable ColumnScope.() -> Unit, + title: String, + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier, + horizontalAlignment = Alignment.CenterHorizontally + ) { + iconContent() + Text( + text = title, + modifier = Modifier + .padding(top = 6.dp) + .padding(horizontal = 10.dp), + style = MaterialTheme.typography.title3 + ) + } +} + +@WearPreview +@Composable +fun SignInHeaderPreview() { + SignInHeader( + icon = R.drawable.passkey_icon, + title = stringResource(R.string.use_passkey_title) + ) +} diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mapper/CredentialSelectorUiStateGetMapper.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mapper/CredentialSelectorUiStateGetMapper.kt new file mode 100644 index 000000000000..5ceec1783c84 --- /dev/null +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mapper/CredentialSelectorUiStateGetMapper.kt @@ -0,0 +1,51 @@ +package com.android.credentialmanager.ui.mapper + +import androidx.credentials.provider.CustomCredentialEntry +import androidx.credentials.provider.PasswordCredentialEntry +import androidx.credentials.provider.PublicKeyCredentialEntry +import com.android.credentialmanager.ui.CredentialSelectorUiState +import com.android.credentialmanager.factory.fromSlice +import com.android.credentialmanager.ui.model.PasswordUiModel +import com.android.credentialmanager.model.Request + +fun Request.Get.toGet(): CredentialSelectorUiState.Get { + if (this.providers.isEmpty()) { + throw IllegalStateException("Invalid GetCredential request with empty list of providers.") + } + + if (this.entries.isEmpty()) { + throw IllegalStateException("Invalid GetCredential request with empty list of entries.") + } + + if (this.providers.size == 1) { + if (this.entries.size == 1) { + val slice = this.entries.first().slice + when (val credentialEntry = fromSlice(slice)) { + is PasswordCredentialEntry -> { + return CredentialSelectorUiState.Get.SingleProviderSinglePassword( + PasswordUiModel(credentialEntry.displayName.toString()) + ) + } + + is PublicKeyCredentialEntry -> { + TODO("b/301206470 - to be implemented") + } + + is CustomCredentialEntry -> { + TODO("b/301206470 - to be implemented") + } + + else -> { + throw IllegalStateException( + "Encountered unrecognized credential entry (${slice.spec?.type}) for " + + "GetCredential request with single account" + ) + } + } + } else { + TODO("b/301206470 - to be implemented") + } + } else { + TODO("b/301206470 - to be implemented") + } +}
\ No newline at end of file diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasskeyUiModel.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasskeyUiModel.kt new file mode 100644 index 000000000000..a368de27867a --- /dev/null +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasskeyUiModel.kt @@ -0,0 +1,22 @@ +/* + * 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.0N + * + * 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.ui.model + +data class PasskeyUiModel( + val name: String, + val email: String, +) diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasswordUiModel.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasswordUiModel.kt new file mode 100644 index 000000000000..52bbfaa818ed --- /dev/null +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/model/PasswordUiModel.kt @@ -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.0N + * + * 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.ui.model + +data class PasswordUiModel(val email: String) diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/MainScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/MainScreen.kt index 662d7108ab90..94a671efc393 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/MainScreen.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/MainScreen.kt @@ -23,7 +23,9 @@ import androidx.compose.ui.Modifier import androidx.wear.compose.material.Text @Composable -fun MainScreen(modifier: Modifier = Modifier) { +fun MainScreen( + modifier: Modifier = Modifier +) { Box(modifier = modifier, contentAlignment = Alignment.Center) { Text("This is a placeholder for the main screen.") } diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SingleAccountScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SingleAccountScreen.kt new file mode 100644 index 000000000000..f344ad0bd22d --- /dev/null +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SingleAccountScreen.kt @@ -0,0 +1,83 @@ +/* + * Copyright 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 + * + * https://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. + */ + +@file:OptIn(ExperimentalHorologistApi::class) + +package com.android.credentialmanager.ui.screens + +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.wear.compose.foundation.lazy.ScalingLazyListScope +import com.android.credentialmanager.R +import com.android.credentialmanager.ui.components.AccountRow +import com.android.credentialmanager.ui.components.DialogButtonsRow +import com.android.credentialmanager.ui.components.SignInHeader +import com.google.android.horologist.annotations.ExperimentalHorologistApi +import com.google.android.horologist.compose.layout.ScalingLazyColumn +import com.google.android.horologist.compose.layout.ScalingLazyColumnState +import com.google.android.horologist.compose.layout.belowTimeTextPreview +import com.google.android.horologist.compose.tools.WearPreview + +@Composable +fun SingleAccountScreen( + headerContent: @Composable () -> Unit, + accountContent: @Composable () -> Unit, + columnState: ScalingLazyColumnState, + modifier: Modifier = Modifier, + content: ScalingLazyListScope.() -> Unit, +) { + ScalingLazyColumn( + columnState = columnState, + modifier = modifier.fillMaxSize(), + ) { + item { headerContent() } + item { accountContent() } + content() + } +} + +@WearPreview +@Composable +fun SingleAccountScreenPreview() { + SingleAccountScreen( + headerContent = { + SignInHeader( + icon = R.drawable.passkey_icon, + title = stringResource(R.string.use_passkey_title), + ) + }, + accountContent = { + AccountRow( + name = "Elisa Beckett", + email = "beckett_bakery@gmail.com", + modifier = Modifier.padding(top = 10.dp) + ) + }, + columnState = belowTimeTextPreview(), + ) { + item { + DialogButtonsRow( + onCancelClick = {}, + onOKClick = {}, + modifier = Modifier.padding(top = 10.dp) + ) + } + } +} diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SinglePasskeyScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SinglePasskeyScreen.kt new file mode 100644 index 000000000000..c8f871e46c83 --- /dev/null +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SinglePasskeyScreen.kt @@ -0,0 +1,82 @@ +/* + * Copyright 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 + * + * https://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. + */ + +@file:OptIn(ExperimentalHorologistApi::class) + +package com.android.credentialmanager.ui.screens + +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import com.android.credentialmanager.R +import com.android.credentialmanager.ui.components.AccountRow +import com.android.credentialmanager.ui.components.DialogButtonsRow +import com.android.credentialmanager.ui.components.SignInHeader +import com.google.android.horologist.annotations.ExperimentalHorologistApi +import com.google.android.horologist.compose.layout.ScalingLazyColumnState +import com.google.android.horologist.compose.layout.belowTimeTextPreview +import com.google.android.horologist.compose.tools.WearPreview + +@Composable +fun SinglePasskeyScreen( + name: String, + email: String, + onCancelClick: () -> Unit, + onOKClick: () -> Unit, + columnState: ScalingLazyColumnState, + modifier: Modifier = Modifier, +) { + SingleAccountScreen( + headerContent = { + SignInHeader( + icon = R.drawable.passkey_icon, + title = stringResource(R.string.use_passkey_title), + ) + }, + accountContent = { + AccountRow( + name = name, + email = email, + modifier = Modifier.padding(top = 10.dp), + ) + }, + columnState = columnState, + modifier = modifier.padding(horizontal = 10.dp) + ) { + item { + DialogButtonsRow( + onCancelClick = onCancelClick, + onOKClick = onOKClick, + modifier = Modifier.padding(top = 10.dp) + ) + } + } +} + +@WearPreview +@Composable +fun SinglePasskeyScreenPreview() { + SinglePasskeyScreen( + name = "Elisa Beckett", + email = "beckett_bakery@gmail.com", + onCancelClick = {}, + onOKClick = {}, + columnState = belowTimeTextPreview(), + ) +} + diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SinglePasswordScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SinglePasswordScreen.kt new file mode 100644 index 000000000000..d863d3c68ceb --- /dev/null +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/SinglePasswordScreen.kt @@ -0,0 +1,79 @@ +/* + * Copyright 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 + * + * https://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. + */ + +@file:OptIn(ExperimentalHorologistApi::class) + +package com.android.credentialmanager.ui.screens + +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import com.android.credentialmanager.R +import com.android.credentialmanager.ui.components.DialogButtonsRow +import com.android.credentialmanager.ui.components.PasswordRow +import com.android.credentialmanager.ui.components.SignInHeader +import com.google.android.horologist.annotations.ExperimentalHorologistApi +import com.google.android.horologist.compose.layout.ScalingLazyColumnState +import com.google.android.horologist.compose.layout.belowTimeTextPreview +import com.google.android.horologist.compose.tools.WearPreview + +@Composable +fun SinglePasswordScreen( + email: String, + onCancelClick: () -> Unit, + onOKClick: () -> Unit, + columnState: ScalingLazyColumnState, + modifier: Modifier = Modifier, +) { + SingleAccountScreen( + headerContent = { + SignInHeader( + icon = R.drawable.passkey_icon, + title = stringResource(R.string.use_password_title), + ) + }, + accountContent = { + PasswordRow( + email = email, + modifier = Modifier.padding(top = 10.dp), + ) + }, + columnState = columnState, + modifier = modifier.padding(horizontal = 10.dp) + ) { + item { + DialogButtonsRow( + onCancelClick = onCancelClick, + onOKClick = onOKClick, + modifier = Modifier.padding(top = 10.dp) + ) + } + } +} + +@WearPreview +@Composable +fun SinglePasswordScreenPreview() { + SinglePasswordScreen( + email = "beckett_bakery@gmail.com", + onCancelClick = {}, + onOKClick = {}, + columnState = belowTimeTextPreview(), + ) +} + diff --git a/packages/SettingsLib/ActionBarShadow/Android.bp b/packages/SettingsLib/ActionBarShadow/Android.bp index bf4c8587722a..6f9445874fce 100644 --- a/packages/SettingsLib/ActionBarShadow/Android.bp +++ b/packages/SettingsLib/ActionBarShadow/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibActionBarShadow", + use_resource_processor: true, srcs: ["src/**/*.java"], diff --git a/packages/SettingsLib/ActionBarShadow/AndroidManifest.xml b/packages/SettingsLib/ActionBarShadow/AndroidManifest.xml index 98c4cb4b2766..4ec6870e6c87 100644 --- a/packages/SettingsLib/ActionBarShadow/AndroidManifest.xml +++ b/packages/SettingsLib/ActionBarShadow/AndroidManifest.xml @@ -16,6 +16,6 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.actionbarshadow"> </manifest> diff --git a/packages/SettingsLib/ActionButtonsPreference/Android.bp b/packages/SettingsLib/ActionButtonsPreference/Android.bp index b6e167717023..122855561751 100644 --- a/packages/SettingsLib/ActionButtonsPreference/Android.bp +++ b/packages/SettingsLib/ActionButtonsPreference/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibActionButtonsPreference", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/ActionButtonsPreference/AndroidManifest.xml b/packages/SettingsLib/ActionButtonsPreference/AndroidManifest.xml index 4b9f1ab8d6cc..01ad59814cc8 100644 --- a/packages/SettingsLib/ActionButtonsPreference/AndroidManifest.xml +++ b/packages/SettingsLib/ActionButtonsPreference/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.preference.actionbuttons"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java b/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java index 4d3ca945f7e1..3e65d94e3323 100644 --- a/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java +++ b/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java @@ -32,10 +32,11 @@ import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; import com.android.settingslib.utils.BuildCompatUtils; - import java.util.ArrayList; import java.util.List; +import com.android.settingslib.widget.preference.actionbuttons.R; + /** * This preference provides a four buttons layout with Settings style. * It looks like below diff --git a/packages/SettingsLib/ActivityEmbedding/Android.bp b/packages/SettingsLib/ActivityEmbedding/Android.bp index 0cd9fe387a22..41de29a93e51 100644 --- a/packages/SettingsLib/ActivityEmbedding/Android.bp +++ b/packages/SettingsLib/ActivityEmbedding/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibActivityEmbedding", + use_resource_processor: true, srcs: ["src/**/*.java"], diff --git a/packages/SettingsLib/ActivityEmbedding/AndroidManifest.xml b/packages/SettingsLib/ActivityEmbedding/AndroidManifest.xml index 0949e1defc2f..c67f51c0d7e7 100644 --- a/packages/SettingsLib/ActivityEmbedding/AndroidManifest.xml +++ b/packages/SettingsLib/ActivityEmbedding/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.activityembedding"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/AdaptiveIcon/Android.bp b/packages/SettingsLib/AdaptiveIcon/Android.bp index 934aacfddfb9..df72a921544d 100644 --- a/packages/SettingsLib/AdaptiveIcon/Android.bp +++ b/packages/SettingsLib/AdaptiveIcon/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibAdaptiveIcon", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/AdaptiveIcon/AndroidManifest.xml b/packages/SettingsLib/AdaptiveIcon/AndroidManifest.xml index 256b8f3ea477..7709ad3cba4d 100644 --- a/packages/SettingsLib/AdaptiveIcon/AndroidManifest.xml +++ b/packages/SettingsLib/AdaptiveIcon/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.adaptiveicon"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java index 723caf2ce0a1..fc41c93587c4 100644 --- a/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java +++ b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java @@ -32,6 +32,7 @@ import android.util.Log; import androidx.annotation.VisibleForTesting; import com.android.settingslib.drawer.Tile; +import com.android.settingslib.widget.adaptiveicon.R; /** * Adaptive icon that can set background color diff --git a/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java index e82997431290..12c234ecd739 100644 --- a/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java +++ b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java @@ -34,6 +34,8 @@ import android.view.WindowManagerGlobal; import androidx.annotation.IntDef; import androidx.annotation.VisibleForTesting; +import com.android.settingslib.widget.adaptiveicon.R; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/packages/SettingsLib/AppPreference/Android.bp b/packages/SettingsLib/AppPreference/Android.bp index 0ba47a8156e3..69b9d44fe16f 100644 --- a/packages/SettingsLib/AppPreference/Android.bp +++ b/packages/SettingsLib/AppPreference/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibAppPreference", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/AppPreference/AndroidManifest.xml b/packages/SettingsLib/AppPreference/AndroidManifest.xml index 4b9f1ab8d6cc..9d014977da8f 100644 --- a/packages/SettingsLib/AppPreference/AndroidManifest.xml +++ b/packages/SettingsLib/AppPreference/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.preference.app"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppHeaderPreference.java b/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppHeaderPreference.java index 60d00da29755..b1d311080b86 100644 --- a/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppHeaderPreference.java +++ b/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppHeaderPreference.java @@ -28,6 +28,8 @@ import androidx.annotation.StringRes; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.widget.preference.app.R; + /** * The Preference for the pages need to show big apps icon and name in the header of the page. */ diff --git a/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppPreference.java b/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppPreference.java index cfe701353787..f1d162e116b5 100644 --- a/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppPreference.java +++ b/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppPreference.java @@ -24,6 +24,8 @@ import android.widget.ProgressBar; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.widget.preference.app.R; + /** * The Preference for the pages need to show apps icon. */ diff --git a/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppSwitchPreference.java b/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppSwitchPreference.java index 781bfcdbc75e..87bfc8111a4b 100644 --- a/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppSwitchPreference.java +++ b/packages/SettingsLib/AppPreference/src/com/android/settingslib/widget/AppSwitchPreference.java @@ -22,7 +22,7 @@ import android.view.View; import androidx.preference.PreferenceViewHolder; import androidx.preference.SwitchPreference; - +import com.android.settingslib.widget.preference.app.R; /** * The SwitchPreference for the pages need to show apps icon. */ diff --git a/packages/SettingsLib/BannerMessagePreference/Android.bp b/packages/SettingsLib/BannerMessagePreference/Android.bp index 0f7a451e7c8b..da91344242a1 100644 --- a/packages/SettingsLib/BannerMessagePreference/Android.bp +++ b/packages/SettingsLib/BannerMessagePreference/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibBannerMessagePreference", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/BannerMessagePreference/AndroidManifest.xml b/packages/SettingsLib/BannerMessagePreference/AndroidManifest.xml index dd51ea38a1fe..a93a1fec8135 100644 --- a/packages/SettingsLib/BannerMessagePreference/AndroidManifest.xml +++ b/packages/SettingsLib/BannerMessagePreference/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.preference.banner"> <uses-sdk android:minSdkVersion="28"/> diff --git a/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java b/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java index afeb24ad3b61..33775a64aa82 100644 --- a/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java +++ b/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java @@ -39,7 +39,7 @@ import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; import com.android.settingslib.utils.BuildCompatUtils; - +import com.android.settingslib.widget.preference.banner.R; /** * Banner message is a banner displaying important information (permission request, page error etc), * and provide actions for user to address. It requires a user action to be dismissed. diff --git a/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessageView.java b/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessageView.java index 5ca6fb64db2d..ff4e79ddaaa1 100644 --- a/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessageView.java +++ b/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessageView.java @@ -25,6 +25,8 @@ import android.widget.LinearLayout; import androidx.annotation.Nullable; +import com.android.settingslib.widget.preference.banner.R; + /** * The view providing {@link BannerMessagePreference}. * @@ -75,7 +77,7 @@ public class BannerMessageView extends LinearLayout { int minimum = getResources() - .getDimensionPixelSize(R.dimen.settingslib_preferred_minimum_touch_target); + .getDimensionPixelSize(com.android.settingslib.widget.theme.R.dimen.settingslib_preferred_minimum_touch_target); int width = dismissButton.getWidth(); int height = dismissButton.getHeight(); int widthIncrease = width < minimum ? minimum - width : 0; diff --git a/packages/SettingsLib/BarChartPreference/Android.bp b/packages/SettingsLib/BarChartPreference/Android.bp index 5c5da9827e61..be1e0cf8ab4f 100644 --- a/packages/SettingsLib/BarChartPreference/Android.bp +++ b/packages/SettingsLib/BarChartPreference/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibBarChartPreference", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/BarChartPreference/AndroidManifest.xml b/packages/SettingsLib/BarChartPreference/AndroidManifest.xml index 4b9f1ab8d6cc..fda4e1d2e232 100644 --- a/packages/SettingsLib/BarChartPreference/AndroidManifest.xml +++ b/packages/SettingsLib/BarChartPreference/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.preference.barchart"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartInfo.java b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartInfo.java index eeaf2737a2fd..a32a24d825ba 100644 --- a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartInfo.java +++ b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartInfo.java @@ -24,7 +24,7 @@ import androidx.annotation.StringRes; import java.util.ArrayList; import java.util.List; - +import com.android.settingslib.widget.preference.barchart.R; /** * BarChartInfo is responsible for storing information about {@link BarChartPreference}. */ diff --git a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java index 20e0a3b20b8c..d63fc3c34728 100644 --- a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java +++ b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarChartPreference.java @@ -28,7 +28,7 @@ import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; import java.util.Arrays; - +import com.android.settingslib.widget.preference.barchart.R; /** * This BarChartPreference shows up to four bar views in this preference at most. * diff --git a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java index 93a34c03bf92..7c749716942d 100644 --- a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java +++ b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java @@ -29,7 +29,7 @@ import android.widget.TextView; import androidx.annotation.ColorInt; import androidx.annotation.VisibleForTesting; - +import com.android.settingslib.widget.preference.barchart.R; /** * {@link View} for a single vertical bar with icon and summary. */ diff --git a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java index 922337a92f18..4b6ca4ad48ca 100644 --- a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java +++ b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java @@ -23,7 +23,7 @@ import androidx.annotation.IntRange; import androidx.annotation.Nullable; import java.util.Comparator; - +import com.android.settingslib.widget.preference.barchart.R; /** * A class responsible for saving bar view information. */ diff --git a/packages/SettingsLib/ButtonPreference/Android.bp b/packages/SettingsLib/ButtonPreference/Android.bp index 39f804fa9ae5..35572fad55a2 100644 --- a/packages/SettingsLib/ButtonPreference/Android.bp +++ b/packages/SettingsLib/ButtonPreference/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibButtonPreference", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/ButtonPreference/AndroidManifest.xml b/packages/SettingsLib/ButtonPreference/AndroidManifest.xml index 2d35c331cd82..f867707e8e08 100644 --- a/packages/SettingsLib/ButtonPreference/AndroidManifest.xml +++ b/packages/SettingsLib/ButtonPreference/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.preference.button"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/ButtonPreference/src/com/android/settingslib/widget/ButtonPreference.java b/packages/SettingsLib/ButtonPreference/src/com/android/settingslib/widget/ButtonPreference.java index 5364783b4c68..16ba96265751 100644 --- a/packages/SettingsLib/ButtonPreference/src/com/android/settingslib/widget/ButtonPreference.java +++ b/packages/SettingsLib/ButtonPreference/src/com/android/settingslib/widget/ButtonPreference.java @@ -30,6 +30,8 @@ import androidx.annotation.GravityInt; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.widget.preference.button.R; + /** * A preference handled a button */ diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp index df43863fdd84..70f7554d5e53 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibCollapsingToolbarBaseActivity", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/AndroidManifest.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/AndroidManifest.xml index 51fc7ed64660..dabba6832134 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/AndroidManifest.xml +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.collapsingtoolbar"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/BasePreferencesFragment.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/BasePreferencesFragment.java index 3582897014ff..8ebbac39d1d0 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/BasePreferencesFragment.java +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/BasePreferencesFragment.java @@ -20,7 +20,6 @@ import androidx.fragment.app.FragmentActivity; import androidx.preference.PreferenceFragmentCompat; import com.android.settingslib.utils.BuildCompatUtils; -import com.android.settingslib.widget.R; import com.google.android.material.appbar.AppBarLayout; diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java index dcc6e5a37246..04c44e6d11be 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java @@ -27,7 +27,6 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import com.android.settingslib.utils.BuildCompatUtils; -import com.android.settingslib.widget.R; import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.CollapsingToolbarLayout; @@ -70,7 +69,7 @@ public class CollapsingToolbarAppCompatActivity extends AppCompatActivity { if (BuildCompatUtils.isAtLeastS()) { DynamicColors.applyToActivityIfAvailable(this); } - setTheme(R.style.Theme_SubSettingsBase); + setTheme(com.android.settingslib.widget.theme.R.style.Theme_SubSettingsBase); if (mCustomizeLayoutResId > 0 && !BuildCompatUtils.isAtLeastS()) { super.setContentView(mCustomizeLayoutResId); diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java index 19b7e8546805..143101f76977 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java @@ -28,7 +28,6 @@ import androidx.annotation.Nullable; import androidx.fragment.app.FragmentActivity; import com.android.settingslib.utils.BuildCompatUtils; -import com.android.settingslib.widget.R; import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.CollapsingToolbarLayout; diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarDelegate.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarDelegate.java index 1c2288acd358..155cfbbc6677 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarDelegate.java +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarDelegate.java @@ -35,8 +35,6 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.coordinatorlayout.widget.CoordinatorLayout; -import com.android.settingslib.widget.R; - import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.CollapsingToolbarLayout; diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayout.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayout.java index e4e34f8cae1e..f70add9cc62d 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayout.java +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayout.java @@ -38,7 +38,7 @@ import androidx.annotation.RequiresApi; import androidx.appcompat.app.AppCompatActivity; import androidx.coordinatorlayout.widget.CoordinatorLayout; -import com.android.settingslib.widget.R; +import com.android.settingslib.collapsingtoolbar.R; import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.CollapsingToolbarLayout; diff --git a/packages/SettingsLib/DeviceStateRotationLock/Android.bp b/packages/SettingsLib/DeviceStateRotationLock/Android.bp index 103309a43bb8..72df6cd58af5 100644 --- a/packages/SettingsLib/DeviceStateRotationLock/Android.bp +++ b/packages/SettingsLib/DeviceStateRotationLock/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibDeviceStateRotationLock", + use_resource_processor: true, srcs: [ "src/**/*.java", diff --git a/packages/SettingsLib/DisplayUtils/Android.bp b/packages/SettingsLib/DisplayUtils/Android.bp index 136f883ca70d..eab35a11d7d6 100644 --- a/packages/SettingsLib/DisplayUtils/Android.bp +++ b/packages/SettingsLib/DisplayUtils/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibDisplayUtils", + use_resource_processor: true, srcs: ["src/**/*.java"], diff --git a/packages/SettingsLib/EmergencyNumber/Android.bp b/packages/SettingsLib/EmergencyNumber/Android.bp index 25b4905c438f..986baf70fa44 100644 --- a/packages/SettingsLib/EmergencyNumber/Android.bp +++ b/packages/SettingsLib/EmergencyNumber/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibEmergencyNumber", + use_resource_processor: true, srcs: ["src/**/*.java"], static_libs: [ diff --git a/packages/SettingsLib/EntityHeaderWidgets/Android.bp b/packages/SettingsLib/EntityHeaderWidgets/Android.bp index bd83cdce0078..17b662c60227 100644 --- a/packages/SettingsLib/EntityHeaderWidgets/Android.bp +++ b/packages/SettingsLib/EntityHeaderWidgets/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibEntityHeaderWidgets", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/EntityHeaderWidgets/AndroidManifest.xml b/packages/SettingsLib/EntityHeaderWidgets/AndroidManifest.xml index 4b9f1ab8d6cc..ad4d22d0e276 100644 --- a/packages/SettingsLib/EntityHeaderWidgets/AndroidManifest.xml +++ b/packages/SettingsLib/EntityHeaderWidgets/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.entityheader"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/EntityHeaderWidgets/src/com/android/settingslib/widget/AppEntitiesHeaderController.java b/packages/SettingsLib/EntityHeaderWidgets/src/com/android/settingslib/widget/AppEntitiesHeaderController.java index 6e95a0ed106a..d802e5b7a145 100644 --- a/packages/SettingsLib/EntityHeaderWidgets/src/com/android/settingslib/widget/AppEntitiesHeaderController.java +++ b/packages/SettingsLib/EntityHeaderWidgets/src/com/android/settingslib/widget/AppEntitiesHeaderController.java @@ -30,6 +30,8 @@ import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.annotation.VisibleForTesting; +import com.android.settingslib.widget.entityheader.R; + /** * This class is used to initialize view which was inflated * from {@link R.xml.app_entities_header.xml}. diff --git a/packages/SettingsLib/EntityHeaderWidgets/src/com/android/settingslib/widget/AppEntityInfo.java b/packages/SettingsLib/EntityHeaderWidgets/src/com/android/settingslib/widget/AppEntityInfo.java index 1e55f2e99bfc..0439ff5dab96 100644 --- a/packages/SettingsLib/EntityHeaderWidgets/src/com/android/settingslib/widget/AppEntityInfo.java +++ b/packages/SettingsLib/EntityHeaderWidgets/src/com/android/settingslib/widget/AppEntityInfo.java @@ -22,6 +22,8 @@ import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.settingslib.widget.entityheader.R; + /** * AppEntityInfo is responsible for storing app information shown in {@link R.xml.app_view.xml}. */ diff --git a/packages/SettingsLib/FooterPreference/Android.bp b/packages/SettingsLib/FooterPreference/Android.bp index 8b976bbb2c56..b45cd65467d2 100644 --- a/packages/SettingsLib/FooterPreference/Android.bp +++ b/packages/SettingsLib/FooterPreference/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibFooterPreference", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/FooterPreference/AndroidManifest.xml b/packages/SettingsLib/FooterPreference/AndroidManifest.xml index 96d9e518663f..9046b109bb75 100644 --- a/packages/SettingsLib/FooterPreference/AndroidManifest.xml +++ b/packages/SettingsLib/FooterPreference/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.preference.footer"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java b/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java index bf24c86b8d8b..5b2fa1d2a1bb 100644 --- a/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java +++ b/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java @@ -30,6 +30,8 @@ import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.widget.preference.footer.R; + /** * A custom preference acting as "footer" of a page. It has a field for icon and text. It is added * to screen as the last preference. @@ -47,7 +49,7 @@ public class FooterPreference extends Preference { private FooterLearnMoreSpan mLearnMoreSpan; public FooterPreference(Context context, AttributeSet attrs) { - super(context, attrs, R.attr.footerPreferenceStyle); + super(context, attrs, com.android.settingslib.widget.theme.R.attr.footerPreferenceStyle); init(); } diff --git a/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/LinkTextView.java b/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/LinkTextView.java index 868feadf6b35..16d4475aaa07 100644 --- a/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/LinkTextView.java +++ b/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/LinkTextView.java @@ -22,6 +22,8 @@ import android.text.style.ClickableSpan; import android.util.AttributeSet; import android.widget.TextView; +import com.android.settingslib.widget.preference.footer.R; + /** * Copied from setup wizard. This TextView performed two functions. The first is to make it so the * link behaves properly and becomes clickable. The second was that it made the link visible to diff --git a/packages/SettingsLib/HelpUtils/Android.bp b/packages/SettingsLib/HelpUtils/Android.bp index 13fcf8c7cbe3..041fce254b72 100644 --- a/packages/SettingsLib/HelpUtils/Android.bp +++ b/packages/SettingsLib/HelpUtils/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibHelpUtils", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/HelpUtils/AndroidManifest.xml b/packages/SettingsLib/HelpUtils/AndroidManifest.xml index ccad6e49ff8c..35c7515b60a0 100644 --- a/packages/SettingsLib/HelpUtils/AndroidManifest.xml +++ b/packages/SettingsLib/HelpUtils/AndroidManifest.xml @@ -16,6 +16,6 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.help"> </manifest> diff --git a/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java b/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java index 70c8658a7f55..2c13695eb892 100644 --- a/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java +++ b/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java @@ -36,7 +36,7 @@ import android.view.MenuItem.OnMenuItemClickListener; import androidx.annotation.RequiresApi; import androidx.annotation.VisibleForTesting; -import com.android.settingslib.widget.R; +import com.android.settingslib.widget.help.R; import java.net.URISyntaxException; import java.util.Locale; diff --git a/packages/SettingsLib/IllustrationPreference/Android.bp b/packages/SettingsLib/IllustrationPreference/Android.bp index 24ccab235fa1..4d4759b99f15 100644 --- a/packages/SettingsLib/IllustrationPreference/Android.bp +++ b/packages/SettingsLib/IllustrationPreference/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibIllustrationPreference", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/IllustrationPreference/AndroidManifest.xml b/packages/SettingsLib/IllustrationPreference/AndroidManifest.xml index 73163fca5362..a0d10c383445 100644 --- a/packages/SettingsLib/IllustrationPreference/AndroidManifest.xml +++ b/packages/SettingsLib/IllustrationPreference/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.preference.illustration"> <uses-sdk android:minSdkVersion="28" /> diff --git a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java index 37ae2d45e614..f4d4dbadb37f 100644 --- a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java +++ b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java @@ -42,6 +42,7 @@ import com.airbnb.lottie.LottieDrawable; import java.io.FileNotFoundException; import java.io.InputStream; +import com.android.settingslib.widget.preference.illustration.R; /** * IllustrationPreference is a preference that can play lottie format animation @@ -427,10 +428,10 @@ public class IllustrationPreference extends Preference { mIsAutoScale = false; if (attrs != null) { TypedArray a = context.obtainStyledAttributes(attrs, - R.styleable.LottieAnimationView, 0 /*defStyleAttr*/, 0 /*defStyleRes*/); - mImageResId = a.getResourceId(R.styleable.LottieAnimationView_lottie_rawRes, 0); + com.airbnb.lottie.R.styleable.LottieAnimationView, 0 /*defStyleAttr*/, 0 /*defStyleRes*/); + mImageResId = a.getResourceId(com.airbnb.lottie.R.styleable.LottieAnimationView_lottie_rawRes, 0); mCacheComposition = a.getBoolean( - R.styleable.LottieAnimationView_lottie_cacheComposition, true); + com.airbnb.lottie.R.styleable.LottieAnimationView_lottie_cacheComposition, true); a = context.obtainStyledAttributes(attrs, R.styleable.IllustrationPreference, 0 /*defStyleAttr*/, 0 /*defStyleRes*/); diff --git a/packages/SettingsLib/LayoutPreference/Android.bp b/packages/SettingsLib/LayoutPreference/Android.bp index c29e1f789fd3..53ded2385634 100644 --- a/packages/SettingsLib/LayoutPreference/Android.bp +++ b/packages/SettingsLib/LayoutPreference/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibLayoutPreference", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/LayoutPreference/AndroidManifest.xml b/packages/SettingsLib/LayoutPreference/AndroidManifest.xml index 4b9f1ab8d6cc..a8427a1cbfb1 100644 --- a/packages/SettingsLib/LayoutPreference/AndroidManifest.xml +++ b/packages/SettingsLib/LayoutPreference/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.preference.layout"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/LayoutPreference/src/com/android/settingslib/widget/LayoutPreference.java b/packages/SettingsLib/LayoutPreference/src/com/android/settingslib/widget/LayoutPreference.java index 2a635b0996e6..49f045f4423c 100644 --- a/packages/SettingsLib/LayoutPreference/src/com/android/settingslib/widget/LayoutPreference.java +++ b/packages/SettingsLib/LayoutPreference/src/com/android/settingslib/widget/LayoutPreference.java @@ -102,16 +102,16 @@ public class LayoutPreference extends Preference { } private void init(Context context, AttributeSet attrs, int defStyleAttr) { - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Preference); - mAllowDividerAbove = TypedArrayUtils.getBoolean(a, R.styleable.Preference_allowDividerAbove, - R.styleable.Preference_allowDividerAbove, false); - mAllowDividerBelow = TypedArrayUtils.getBoolean(a, R.styleable.Preference_allowDividerBelow, - R.styleable.Preference_allowDividerBelow, false); + TypedArray a = context.obtainStyledAttributes(attrs, androidx.preference.R.styleable.Preference); + mAllowDividerAbove = TypedArrayUtils.getBoolean(a, androidx.preference.R.styleable.Preference_allowDividerAbove, + androidx.preference.R.styleable.Preference_allowDividerAbove, false); + mAllowDividerBelow = TypedArrayUtils.getBoolean(a, androidx.preference.R.styleable.Preference_allowDividerBelow, + androidx.preference.R.styleable.Preference_allowDividerBelow, false); a.recycle(); a = context.obtainStyledAttributes( - attrs, R.styleable.Preference, defStyleAttr, 0); - int layoutResource = a.getResourceId(R.styleable.Preference_android_layout, 0); + attrs, androidx.preference.R.styleable.Preference, defStyleAttr, 0); + int layoutResource = a.getResourceId(androidx.preference.R.styleable.Preference_android_layout, 0); if (layoutResource == 0) { throw new IllegalArgumentException("LayoutPreference requires a layout to be defined"); } @@ -124,7 +124,7 @@ public class LayoutPreference extends Preference { } private void setView(View view) { - setLayoutResource(R.layout.layout_preference_frame); + setLayoutResource(com.android.settingslib.widget.preference.layout.R.layout.layout_preference_frame); mRootView = view; setShouldDisableView(false); } diff --git a/packages/SettingsLib/MainSwitchPreference/AndroidManifest.xml b/packages/SettingsLib/MainSwitchPreference/AndroidManifest.xml index 6e0d82768148..4b3acbf2c394 100644 --- a/packages/SettingsLib/MainSwitchPreference/AndroidManifest.xml +++ b/packages/SettingsLib/MainSwitchPreference/AndroidManifest.xml @@ -16,6 +16,6 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.mainswitch"> </manifest> diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java index d1703c31627d..56b3eacf6c1f 100644 --- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java +++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java @@ -35,6 +35,8 @@ import com.android.settingslib.utils.BuildCompatUtils; import java.util.ArrayList; import java.util.List; +import com.android.settingslib.widget.mainswitch.R; + /** * MainSwitchBar is a View with a customized Switch. * This component is used as the main switch of the page diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java index 53cc268851e7..11a680466ecf 100644 --- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java +++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java @@ -27,6 +27,8 @@ import androidx.preference.TwoStatePreference; import java.util.ArrayList; import java.util.List; +import com.android.settingslib.widget.mainswitch.R; + /** * MainSwitchPreference is a Preference with a customized Switch. * This component is used as the main switch of the page diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/OnMainSwitchChangeListener.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/OnMainSwitchChangeListener.java index 1c610d9995f6..03868f99663d 100644 --- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/OnMainSwitchChangeListener.java +++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/OnMainSwitchChangeListener.java @@ -18,6 +18,8 @@ package com.android.settingslib.widget; import android.widget.Switch; +import com.android.settingslib.widget.mainswitch.R; + /** * Called when the checked state of the Switch has changed. */ diff --git a/packages/SettingsLib/ProfileSelector/Android.bp b/packages/SettingsLib/ProfileSelector/Android.bp index 250cd755a6a6..155ed2e091f8 100644 --- a/packages/SettingsLib/ProfileSelector/Android.bp +++ b/packages/SettingsLib/ProfileSelector/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibProfileSelector", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/ProfileSelector/AndroidManifest.xml b/packages/SettingsLib/ProfileSelector/AndroidManifest.xml index a57469e39eb6..80f6b7683269 100644 --- a/packages/SettingsLib/ProfileSelector/AndroidManifest.xml +++ b/packages/SettingsLib/ProfileSelector/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.profileselector"> <uses-sdk android:minSdkVersion="23" /> </manifest> diff --git a/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileSelectFragment.java b/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileSelectFragment.java index ac426ed8b5d4..be5753beea4e 100644 --- a/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileSelectFragment.java +++ b/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileSelectFragment.java @@ -27,6 +27,7 @@ import androidx.viewpager2.widget.ViewPager2; import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayoutMediator; +import com.android.settingslib.widget.profileselector.R; /** * Base fragment class for profile settings. diff --git a/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileViewPagerAdapter.java b/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileViewPagerAdapter.java index daf2564a674e..f5ab64742992 100644 --- a/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileViewPagerAdapter.java +++ b/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileViewPagerAdapter.java @@ -18,6 +18,7 @@ package com.android.settingslib.widget; import androidx.fragment.app.Fragment; import androidx.viewpager2.adapter.FragmentStateAdapter; +import com.android.settingslib.widget.profileselector.R; /** * ViewPager Adapter to handle between TabLayout and ViewPager2 diff --git a/packages/SettingsLib/ProgressBar/Android.bp b/packages/SettingsLib/ProgressBar/Android.bp index fb3c4e6efd90..d876573a7728 100644 --- a/packages/SettingsLib/ProgressBar/Android.bp +++ b/packages/SettingsLib/ProgressBar/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibProgressBar", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/ProgressBar/AndroidManifest.xml b/packages/SettingsLib/ProgressBar/AndroidManifest.xml index 256b8f3ea477..fbd6eb00feb6 100644 --- a/packages/SettingsLib/ProgressBar/AndroidManifest.xml +++ b/packages/SettingsLib/ProgressBar/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.progressbar"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/RadioButtonPreference/Android.bp b/packages/SettingsLib/RadioButtonPreference/Android.bp index 1387daa959be..505ba05c5f59 100644 --- a/packages/SettingsLib/RadioButtonPreference/Android.bp +++ b/packages/SettingsLib/RadioButtonPreference/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibRadioButtonPreference", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/RadioButtonPreference/AndroidManifest.xml b/packages/SettingsLib/RadioButtonPreference/AndroidManifest.xml index fda7fde29404..8b5c3b1b5652 100644 --- a/packages/SettingsLib/RadioButtonPreference/AndroidManifest.xml +++ b/packages/SettingsLib/RadioButtonPreference/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.preference.radio"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/RadioButtonPreference/src/com/android/settingslib/widget/RadioButtonPreference.java b/packages/SettingsLib/RadioButtonPreference/src/com/android/settingslib/widget/RadioButtonPreference.java index 02d3c06dcea2..fc4b71430c5f 100644 --- a/packages/SettingsLib/RadioButtonPreference/src/com/android/settingslib/widget/RadioButtonPreference.java +++ b/packages/SettingsLib/RadioButtonPreference/src/com/android/settingslib/widget/RadioButtonPreference.java @@ -25,6 +25,8 @@ import android.widget.ImageView; import androidx.preference.CheckBoxPreference; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.widget.preference.radio.R; + /** * DEPRECATED. Please use SelectorWithWidgetPreference instead. * diff --git a/packages/SettingsLib/RestrictedLockUtils/Android.bp b/packages/SettingsLib/RestrictedLockUtils/Android.bp index 6a8fef36a969..028489d22bdb 100644 --- a/packages/SettingsLib/RestrictedLockUtils/Android.bp +++ b/packages/SettingsLib/RestrictedLockUtils/Android.bp @@ -15,6 +15,7 @@ filegroup { android_library { name: "SettingsLibRestrictedLockUtils", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/RestrictedLockUtils/AndroidManifest.xml b/packages/SettingsLib/RestrictedLockUtils/AndroidManifest.xml index 09756400b736..50a55a79fb3e 100644 --- a/packages/SettingsLib/RestrictedLockUtils/AndroidManifest.xml +++ b/packages/SettingsLib/RestrictedLockUtils/AndroidManifest.xml @@ -16,6 +16,6 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.restricted"> </manifest>
\ No newline at end of file diff --git a/packages/SettingsLib/SchedulesProvider/Android.bp b/packages/SettingsLib/SchedulesProvider/Android.bp index c4373bb2dc1f..2d93e4e3a925 100644 --- a/packages/SettingsLib/SchedulesProvider/Android.bp +++ b/packages/SettingsLib/SchedulesProvider/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibSchedulesProvider", + use_resource_processor: true, srcs: ["src/**/*.java"], diff --git a/packages/SettingsLib/SearchProvider/Android.bp b/packages/SettingsLib/SearchProvider/Android.bp index f96011ad5d09..c07a802f3ed5 100644 --- a/packages/SettingsLib/SearchProvider/Android.bp +++ b/packages/SettingsLib/SearchProvider/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibSearchProvider", + use_resource_processor: true, srcs: ["src/**/*.java"], diff --git a/packages/SettingsLib/SearchProvider/AndroidManifest.xml b/packages/SettingsLib/SearchProvider/AndroidManifest.xml index 2c06673a56ad..7e2c47f420bd 100644 --- a/packages/SettingsLib/SearchProvider/AndroidManifest.xml +++ b/packages/SettingsLib/SearchProvider/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.search"> + package="com.android.settingslib.search.provider"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/SearchWidget/Android.bp b/packages/SettingsLib/SearchWidget/Android.bp index 5aaee2afc069..ad9e16738e18 100644 --- a/packages/SettingsLib/SearchWidget/Android.bp +++ b/packages/SettingsLib/SearchWidget/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibSearchWidget", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/SearchWidget/AndroidManifest.xml b/packages/SettingsLib/SearchWidget/AndroidManifest.xml index 5798801fe5fa..5982b02902cc 100644 --- a/packages/SettingsLib/SearchWidget/AndroidManifest.xml +++ b/packages/SettingsLib/SearchWidget/AndroidManifest.xml @@ -16,6 +16,6 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.search"> + package="com.android.settingslib.search.widget"> </manifest> diff --git a/packages/SettingsLib/SelectorWithWidgetPreference/Android.bp b/packages/SettingsLib/SelectorWithWidgetPreference/Android.bp index b5a21bdae606..702387ecadab 100644 --- a/packages/SettingsLib/SelectorWithWidgetPreference/Android.bp +++ b/packages/SettingsLib/SelectorWithWidgetPreference/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibSelectorWithWidgetPreference", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/SelectorWithWidgetPreference/AndroidManifest.xml b/packages/SettingsLib/SelectorWithWidgetPreference/AndroidManifest.xml index 51fc7ed64660..919d1a934ca0 100644 --- a/packages/SettingsLib/SelectorWithWidgetPreference/AndroidManifest.xml +++ b/packages/SettingsLib/SelectorWithWidgetPreference/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.preference.selector"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java b/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java index 1d1316a48fd3..f2ce8a965dfa 100644 --- a/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java +++ b/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java @@ -25,6 +25,8 @@ import android.widget.ImageView; import androidx.preference.CheckBoxPreference; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.widget.preference.selector.R; + /** * Selector preference (checkbox or radio button) with an optional additional widget. * diff --git a/packages/SettingsLib/SettingsSpinner/Android.bp b/packages/SettingsLib/SettingsSpinner/Android.bp index cbb570ece8b0..0eec50563a75 100644 --- a/packages/SettingsLib/SettingsSpinner/Android.bp +++ b/packages/SettingsLib/SettingsSpinner/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibSettingsSpinner", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/SettingsSpinner/AndroidManifest.xml b/packages/SettingsLib/SettingsSpinner/AndroidManifest.xml index 4b9f1ab8d6cc..123175c91cbc 100644 --- a/packages/SettingsLib/SettingsSpinner/AndroidManifest.xml +++ b/packages/SettingsLib/SettingsSpinner/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.spinner"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerAdapter.java b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerAdapter.java index 7288494beb21..f33cacd36c6d 100644 --- a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerAdapter.java +++ b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerAdapter.java @@ -22,7 +22,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; - +import com.android.settingslib.widget.spinner.R; /** * An ArrayAdapter which was used by Spinner with settings style. * @param <T> the data type to be loaded. diff --git a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerPreference.java b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerPreference.java index 69528757c0e3..63fe1b509751 100644 --- a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerPreference.java +++ b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/SettingsSpinnerPreference.java @@ -25,6 +25,7 @@ import android.widget.Spinner; import androidx.preference.Preference; import androidx.preference.Preference.OnPreferenceClickListener; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.widget.spinner.R; /** * This preference uses Spinner & SettingsSpinnerAdapter which provide default layouts for diff --git a/packages/SettingsLib/SettingsTheme/Android.bp b/packages/SettingsLib/SettingsTheme/Android.bp index e6fb720ba27f..996477cf7960 100644 --- a/packages/SettingsLib/SettingsTheme/Android.bp +++ b/packages/SettingsLib/SettingsTheme/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibSettingsTheme", + use_resource_processor: true, resource_dirs: ["res"], static_libs: ["androidx.preference_preference"], sdk_version: "system_current", diff --git a/packages/SettingsLib/SettingsTheme/AndroidManifest.xml b/packages/SettingsLib/SettingsTheme/AndroidManifest.xml index fda7fde29404..56d137a8927a 100644 --- a/packages/SettingsLib/SettingsTheme/AndroidManifest.xml +++ b/packages/SettingsLib/SettingsTheme/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.theme"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/SettingsTransition/Android.bp b/packages/SettingsLib/SettingsTransition/Android.bp index 48cc75d41285..06493c056203 100644 --- a/packages/SettingsLib/SettingsTransition/Android.bp +++ b/packages/SettingsLib/SettingsTransition/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibSettingsTransition", + use_resource_processor: true, srcs: ["src/**/*.java"], diff --git a/packages/SettingsLib/SettingsTransition/AndroidManifest.xml b/packages/SettingsLib/SettingsTransition/AndroidManifest.xml index 244b367423a4..3e64d560c96c 100644 --- a/packages/SettingsLib/SettingsTransition/AndroidManifest.xml +++ b/packages/SettingsLib/SettingsTransition/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.transition"> <uses-sdk android:minSdkVersion="29" /> diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/editor/SettingsExposedDropdownMenuCheckBoxProvider.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/editor/SettingsExposedDropdownMenuCheckBoxProvider.kt index 37c8eef8a90d..d28964676bdd 100644 --- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/editor/SettingsExposedDropdownMenuCheckBoxProvider.kt +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/editor/SettingsExposedDropdownMenuCheckBoxProvider.kt @@ -37,7 +37,7 @@ object SettingsExposedDropdownMenuCheckBoxProvider : SettingsPageProvider { override val name = "SettingsExposedDropdownMenuCheckBox" private const val exposedDropdownMenuCheckBoxLabel = "ExposedDropdownMenuCheckBoxLabel" private val options = listOf("item1", "item2", "item3") - private val selectedOptionsState1 = mutableStateListOf("item1", "item2") + private val selectedOptionsState1 = mutableStateListOf(0, 1) override fun getTitle(arguments: Bundle?): String { return TITLE diff --git a/packages/SettingsLib/Spa/screenshot/Android.bp b/packages/SettingsLib/Spa/screenshot/Android.bp index 4e6b646da819..bd508cbb9e2f 100644 --- a/packages/SettingsLib/Spa/screenshot/Android.bp +++ b/packages/SettingsLib/Spa/screenshot/Android.bp @@ -20,6 +20,7 @@ package { android_test { name: "SpaScreenshotTests", + use_resource_processor: true, test_suites: ["device-tests"], asset_dirs: ["assets"], diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBox.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBox.kt index a25818553c05..5d248e192c7a 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBox.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBox.kt @@ -51,7 +51,8 @@ import com.android.settingslib.spa.framework.theme.SettingsTheme fun SettingsExposedDropdownMenuCheckBox( label: String, options: List<String>, - selectedOptionsState: SnapshotStateList<String>, + selectedOptionsState: SnapshotStateList<Int>, + emptyVal: String = "", enabled: Boolean, onSelectedOptionStateChange: () -> Unit, ) { @@ -70,7 +71,8 @@ fun SettingsExposedDropdownMenuCheckBox( modifier = Modifier .menuAnchor() .fillMaxWidth(), - value = selectedOptionsState.joinToString(", "), + value = if (selectedOptionsState.size == 0) emptyVal + else selectedOptionsState.joinToString { options[it] }, onValueChange = {}, label = { Text(text = label) }, trailingIcon = { @@ -89,19 +91,19 @@ fun SettingsExposedDropdownMenuCheckBox( .width(with(LocalDensity.current) { dropDownWidth.toDp() }), onDismissRequest = { expanded = false }, ) { - options.forEach { option -> + options.forEachIndexed { index, option -> TextButton( modifier = Modifier .fillMaxHeight() .fillMaxWidth(), onClick = { - if (selectedOptionsState.contains(option)) { + if (selectedOptionsState.contains(index)) { selectedOptionsState.remove( - option + index ) } else { selectedOptionsState.add( - option + index ) } onSelectedOptionStateChange() @@ -114,7 +116,7 @@ fun SettingsExposedDropdownMenuCheckBox( verticalAlignment = Alignment.CenterVertically ) { Checkbox( - checked = selectedOptionsState.contains(option), + checked = selectedOptionsState.contains(index), onCheckedChange = null, ) Text(text = option) @@ -130,7 +132,7 @@ fun SettingsExposedDropdownMenuCheckBox( @Composable private fun ActionButtonsPreview() { val options = listOf("item1", "item2", "item3") - val selectedOptionsState = remember { mutableStateListOf("item1", "item2") } + val selectedOptionsState = remember { mutableStateListOf(0, 1) } SettingsTheme { SettingsExposedDropdownMenuCheckBox( label = "label", diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBoxTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBoxTest.kt index b0271ae1d98c..2b78ed7d6fa2 100644 --- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBoxTest.kt +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/editor/SettingsExposedDropdownMenuCheckBoxTest.kt @@ -39,7 +39,7 @@ class SettingsExposedDropdownMenuCheckBoxTest { private val item2 = "item2" private val item3 = "item3" private val options = listOf(item1, item2, item3) - private val selectedOptionsState1 = mutableStateListOf(item1, item2) + private val selectedOptionsState1 = mutableStateListOf(0, 1) private val exposedDropdownMenuCheckBoxLabel = "ExposedDropdownMenuCheckBoxLabel" @Test diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt index a370ebfe21d5..f54de1514fcf 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt @@ -26,10 +26,10 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.settingslib.RestrictedLockUtils import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin import com.android.settingslib.RestrictedLockUtilsInternal -import com.android.settingslib.widget.R import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOn +import com.android.settingslib.widget.restricted.R data class Restrictions( val userId: Int, diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt index ea83e1d0d3d1..fc10a27cfa5b 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt @@ -72,7 +72,7 @@ class AppInfoProvider(private val packageInfo: PackageInfo) { private fun InstallType(app: ApplicationInfo) { if (!app.isInstantApp) return Spacer(modifier = Modifier.height(4.dp)) - SettingsBody(stringResource(com.android.settingslib.widget.R.string.install_type_instant)) + SettingsBody(stringResource(com.android.settingslib.widget.preference.app.R.string.install_type_instant)) } @Composable diff --git a/packages/SettingsLib/Tile/Android.bp b/packages/SettingsLib/Tile/Android.bp index cc570ccbb506..eb9e329b6a59 100644 --- a/packages/SettingsLib/Tile/Android.bp +++ b/packages/SettingsLib/Tile/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibTile", + use_resource_processor: true, srcs: ["src/**/*.java"], diff --git a/packages/SettingsLib/TopIntroPreference/Android.bp b/packages/SettingsLib/TopIntroPreference/Android.bp index 5d09a1a926d8..77b7ac1246bd 100644 --- a/packages/SettingsLib/TopIntroPreference/Android.bp +++ b/packages/SettingsLib/TopIntroPreference/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibTopIntroPreference", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/TopIntroPreference/AndroidManifest.xml b/packages/SettingsLib/TopIntroPreference/AndroidManifest.xml index 96d9e518663f..6cf643f7c708 100644 --- a/packages/SettingsLib/TopIntroPreference/AndroidManifest.xml +++ b/packages/SettingsLib/TopIntroPreference/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.preference.topintro"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/TopIntroPreference/src/com/android/settingslib/widget/TopIntroPreference.java b/packages/SettingsLib/TopIntroPreference/src/com/android/settingslib/widget/TopIntroPreference.java index 5a5a9b8ffada..1bbd76d86b7f 100644 --- a/packages/SettingsLib/TopIntroPreference/src/com/android/settingslib/widget/TopIntroPreference.java +++ b/packages/SettingsLib/TopIntroPreference/src/com/android/settingslib/widget/TopIntroPreference.java @@ -22,6 +22,8 @@ import android.util.AttributeSet; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.widget.preference.topintro.R; + /** * The TopIntroPreference shows a text which describe a feature. Gernerally, we expect this * preference always shows on the top of screen. diff --git a/packages/SettingsLib/TwoTargetPreference/Android.bp b/packages/SettingsLib/TwoTargetPreference/Android.bp index a3e50a92c0af..5aa906ec0ab3 100644 --- a/packages/SettingsLib/TwoTargetPreference/Android.bp +++ b/packages/SettingsLib/TwoTargetPreference/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibTwoTargetPreference", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/TwoTargetPreference/AndroidManifest.xml b/packages/SettingsLib/TwoTargetPreference/AndroidManifest.xml index 120b0859a70a..15e9368b52cd 100644 --- a/packages/SettingsLib/TwoTargetPreference/AndroidManifest.xml +++ b/packages/SettingsLib/TwoTargetPreference/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.preference.twotarget"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/TwoTargetPreference/src/com/android/settingslib/widget/TwoTargetPreference.java b/packages/SettingsLib/TwoTargetPreference/src/com/android/settingslib/widget/TwoTargetPreference.java index 9130662021d5..b125f716fe52 100644 --- a/packages/SettingsLib/TwoTargetPreference/src/com/android/settingslib/widget/TwoTargetPreference.java +++ b/packages/SettingsLib/TwoTargetPreference/src/com/android/settingslib/widget/TwoTargetPreference.java @@ -26,6 +26,8 @@ import androidx.annotation.IntDef; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.widget.preference.twotarget.R; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/packages/SettingsLib/UsageProgressBarPreference/Android.bp b/packages/SettingsLib/UsageProgressBarPreference/Android.bp index ad6e7ab9f564..4cc90ccbfe80 100644 --- a/packages/SettingsLib/UsageProgressBarPreference/Android.bp +++ b/packages/SettingsLib/UsageProgressBarPreference/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibUsageProgressBarPreference", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/UsageProgressBarPreference/AndroidManifest.xml b/packages/SettingsLib/UsageProgressBarPreference/AndroidManifest.xml index 51fc7ed64660..1e9df9c3e303 100644 --- a/packages/SettingsLib/UsageProgressBarPreference/AndroidManifest.xml +++ b/packages/SettingsLib/UsageProgressBarPreference/AndroidManifest.xml @@ -16,7 +16,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.widget"> + package="com.android.settingslib.widget.preference.usage"> <uses-sdk android:minSdkVersion="21" /> diff --git a/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java b/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java index 4eedab2f417c..712f6f03a441 100644 --- a/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java +++ b/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java @@ -31,6 +31,8 @@ import android.widget.TextView; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.widget.preference.usage.R; + import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/packages/SettingsLib/Utils/Android.bp b/packages/SettingsLib/Utils/Android.bp index dc2b52d24462..c7ad24c6148c 100644 --- a/packages/SettingsLib/Utils/Android.bp +++ b/packages/SettingsLib/Utils/Android.bp @@ -9,6 +9,7 @@ package { android_library { name: "SettingsLibUtils", + use_resource_processor: true, srcs: ["src/**/*.java"], resource_dirs: ["res"], diff --git a/packages/SettingsLib/search/Android.bp b/packages/SettingsLib/search/Android.bp index 918d696fa481..202e7fe219de 100644 --- a/packages/SettingsLib/search/Android.bp +++ b/packages/SettingsLib/search/Android.bp @@ -16,6 +16,7 @@ java_library { android_library { name: "SettingsLib-search", + use_resource_processor: true, static_libs: [ "SettingsLib-search-interface", ], diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java index b1d1ea5eda42..758f090118ad 100644 --- a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java +++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java @@ -126,10 +126,10 @@ public class RestrictedSwitchPreference extends SwitchPreference { switchSummary = isChecked() ? getUpdatableEnterpriseString( getContext(), ENABLED_BY_ADMIN_SWITCH_SUMMARY, - com.android.settingslib.widget.R.string.enabled_by_admin) + com.android.settingslib.widget.restricted.R.string.enabled_by_admin) : getUpdatableEnterpriseString( getContext(), DISABLED_BY_ADMIN_SWITCH_SUMMARY, - com.android.settingslib.widget.R.string.disabled_by_admin); + com.android.settingslib.widget.restricted.R.string.disabled_by_admin); } else { switchSummary = mRestrictedSwitchSummary; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BroadcastDialog.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BroadcastDialog.java index f5257b070392..8c0dc41f18af 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BroadcastDialog.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BroadcastDialog.java @@ -47,7 +47,7 @@ public class BroadcastDialog extends AlertDialog { final Window window = getWindow(); window.setContentView(layout); window.setWindowAnimations( - com.android.settingslib.widget.R.style.Theme_AlertDialog_SettingsLib); + com.android.settingslib.widget.theme.R.style.Theme_AlertDialog_SettingsLib); TextView title = layout.findViewById(R.id.dialog_title); TextView subTitle = layout.findViewById(R.id.dialog_subtitle); diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java index d53c3a7aafa6..2999c838a866 100644 --- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java +++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java @@ -153,7 +153,7 @@ public class InputMethodPreference extends PrimarySwitchPreference } final ImageView icon = holder.itemView.findViewById(android.R.id.icon); final int iconSize = getContext().getResources().getDimensionPixelSize( - com.android.settingslib.widget.R.dimen.secondary_app_icon_size); + com.android.settingslib.widget.theme.R.dimen.secondary_app_icon_size); if (icon != null && iconSize > 0) { ViewGroup.LayoutParams params = icon.getLayoutParams(); params.height = iconSize; diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java index 2d6f0587fbf7..98272cc1dabd 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java @@ -167,8 +167,8 @@ public class AccessPointPreference extends Preference { ImageView frictionImageView = (ImageView) view.findViewById(R.id.friction_icon); bindFrictionImage(frictionImageView); - final View divider = - view.findViewById(com.android.settingslib.widget.R.id.two_target_divider); + final View divider = view.findViewById( + com.android.settingslib.widget.preference.twotarget.R.id.two_target_divider); divider.setVisibility(shouldShowDivider() ? View.VISIBLE : View.INVISIBLE); } diff --git a/packages/SettingsLib/tests/integ/Android.bp b/packages/SettingsLib/tests/integ/Android.bp index 8970debb3e2f..b03c43cbdee5 100644 --- a/packages/SettingsLib/tests/integ/Android.bp +++ b/packages/SettingsLib/tests/integ/Android.bp @@ -23,6 +23,7 @@ package { android_test { name: "SettingsLibTests", + use_resource_processor: true, defaults: [ "SettingsLibDefaults", "framework-wifi-test-defaults", diff --git a/packages/SettingsLib/tests/integ/AndroidManifest.xml b/packages/SettingsLib/tests/integ/AndroidManifest.xml index 2a4dfdd84c63..a95da3033eae 100644 --- a/packages/SettingsLib/tests/integ/AndroidManifest.xml +++ b/packages/SettingsLib/tests/integ/AndroidManifest.xml @@ -15,7 +15,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib"> + package="com.android.settingslib.tests.integ"> <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> <uses-permission android:name="android.permission.MANAGE_USERS" /> diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/SettingsSpinnerPreferenceTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/SettingsSpinnerPreferenceTest.java index b81d13d985e4..c8b20c1753b9 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/SettingsSpinnerPreferenceTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/SettingsSpinnerPreferenceTest.java @@ -28,6 +28,8 @@ import androidx.preference.PreferenceViewHolder; import androidx.test.core.app.ApplicationProvider; import androidx.test.runner.AndroidJUnit4; +import com.android.settingslib.widget.spinner.R; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/UsageProgressBarPreferenceTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/UsageProgressBarPreferenceTest.java index a9ad00d90ab8..a66d3fbee77c 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/UsageProgressBarPreferenceTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/UsageProgressBarPreferenceTest.java @@ -35,6 +35,8 @@ import androidx.preference.PreferenceViewHolder; import androidx.test.core.app.ApplicationProvider; import androidx.test.runner.AndroidJUnit4; +import com.android.settingslib.widget.preference.usage.R; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/packages/SettingsLib/tests/robotests/Android.bp b/packages/SettingsLib/tests/robotests/Android.bp index c037c400948f..dd9cb9cf7abe 100644 --- a/packages/SettingsLib/tests/robotests/Android.bp +++ b/packages/SettingsLib/tests/robotests/Android.bp @@ -27,6 +27,7 @@ package { android_app { name: "SettingsLibShell", + use_resource_processor: true, defaults: ["SettingsLibDefaults"], platform_apis: true, diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java index 4811d9507c8d..e1577e03ab5f 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java @@ -182,14 +182,14 @@ public class HelpUtilsTest { final Menu item = mock(Menu.class); when(item.findItem(MENU_HELP)).thenReturn(null); when(item.add(0, MENU_HELP, 0, - com.android.settingslib.widget.R.string.help_feedback_label)).thenReturn( + com.android.settingslib.widget.help.R.string.help_feedback_label)).thenReturn( mock(MenuItem.class)); HelpUtils.prepareHelpMenuItem(mActivity, item, TEST_HELP_URL, "backup_url"); HelpUtils.prepareHelpMenuItem(mActivity, item, 0, "backup_url"); verify(item, times(2)).add(0, MENU_HELP, 0, - com.android.settingslib.widget.R.string.help_feedback_label); + com.android.settingslib.widget.help.R.string.help_feedback_label); } @Test @@ -197,13 +197,13 @@ public class HelpUtilsTest { final Menu item = mock(Menu.class); when(item.findItem(MENU_HELP)).thenReturn(mock(MenuItem.class)); when(item.add(0, MENU_HELP, 0, - com.android.settingslib.widget.R.string.help_feedback_label)).thenReturn( + com.android.settingslib.widget.help.R.string.help_feedback_label)).thenReturn( mock(MenuItem.class)); HelpUtils.prepareHelpMenuItem(mActivity, item, TEST_HELP_URL, "backup_url"); HelpUtils.prepareHelpMenuItem(mActivity, item, 0, "backup_url"); verify(item, never()).add(0, MENU_HELP, 0, - com.android.settingslib.widget.R.string.help_feedback_label); + com.android.settingslib.widget.help.R.string.help_feedback_label); } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/PrimarySwitchPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/PrimarySwitchPreferenceTest.java index 32a16716d9f9..d9cf9f285164 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/PrimarySwitchPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/PrimarySwitchPreferenceTest.java @@ -54,7 +54,8 @@ public class PrimarySwitchPreferenceTest { mPreference = new PrimarySwitchPreference(mContext); LayoutInflater inflater = LayoutInflater.from(mContext); mHolder = PreferenceViewHolder.createInstanceForTests(inflater.inflate( - com.android.settingslib.widget.R.layout.preference_two_target, null)); + com.android.settingslib.widget.preference.twotarget.R.layout.preference_two_target, + null)); mWidgetView = mHolder.itemView.findViewById(android.R.id.widget_frame); inflater.inflate(R.layout.preference_widget_primary_switch, mWidgetView, true); } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayoutTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayoutTest.java index ff84dc92037f..2b1e8080d389 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayoutTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayoutTest.java @@ -24,7 +24,7 @@ import android.widget.TextView; import androidx.annotation.Nullable; -import com.android.settingslib.R; +import com.android.settingslib.collapsingtoolbar.R; import org.junit.Before; import org.junit.Test; @@ -58,7 +58,7 @@ public class CollapsingCoordinatorLayoutTest { View contentFrameView = layout.findViewById(com.android.settingslib.widget.R.id.content_frame); - TextView textView = contentFrameView.findViewById(R.id.text_hello_world); + TextView textView = contentFrameView.findViewById(com.android.settingslib.robotests.R.id.text_hello_world); assertThat(textView).isNotNull(); assertThat(textView.getText().toString()).isEqualTo(TEXT_HELLO_WORLD); @@ -80,8 +80,8 @@ public class CollapsingCoordinatorLayoutTest { protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTheme(android.R.style.Theme_Light_NoTitleBar); - setContentView(R.layout.collapsing_test_layout); - mCollapsingCoordinatorLayout = findViewById(R.id.id_collapsing_test); + setContentView(com.android.settingslib.robotests.R.layout.collapsing_test_layout); + mCollapsingCoordinatorLayout = findViewById(com.android.settingslib.robotests.R.id.id_collapsing_test); } public CollapsingCoordinatorLayout getCollapsingCoordinatorLayout() { diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java index 9f31ceff7230..6d9261d81cd6 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ActionButtonsPreferenceTest.java @@ -31,6 +31,8 @@ import android.widget.Button; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.widget.preference.actionbuttons.R; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -55,10 +57,10 @@ public class ActionButtonsPreferenceTest { @Test public void onBindViewHolder_setTitle_shouldShowButtonByDefault() { - mPref.setButton1Text(R.string.install_other_apps); - mPref.setButton2Text(R.string.install_other_apps); - mPref.setButton3Text(R.string.install_other_apps); - mPref.setButton4Text(R.string.install_other_apps); + mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps); + mPref.setButton2Text(com.android.settingslib.R.string.install_other_apps); + mPref.setButton3Text(com.android.settingslib.R.string.install_other_apps); + mPref.setButton4Text(com.android.settingslib.R.string.install_other_apps); mPref.onBindViewHolder(mHolder); @@ -107,10 +109,10 @@ public class ActionButtonsPreferenceTest { @Test public void onBindViewHolder_setVisibleIsGoneAndSetTitle_shouldNotShowButton() { - mPref.setButton1Text(R.string.install_other_apps).setButton1Visible(false); - mPref.setButton2Text(R.string.install_other_apps).setButton2Visible(false); - mPref.setButton3Text(R.string.install_other_apps).setButton3Visible(false); - mPref.setButton4Text(R.string.install_other_apps).setButton4Visible(false); + mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps).setButton1Visible(false); + mPref.setButton2Text(com.android.settingslib.R.string.install_other_apps).setButton2Visible(false); + mPref.setButton3Text(com.android.settingslib.R.string.install_other_apps).setButton3Visible(false); + mPref.setButton4Text(com.android.settingslib.R.string.install_other_apps).setButton4Visible(false); mPref.onBindViewHolder(mHolder); @@ -145,10 +147,10 @@ public class ActionButtonsPreferenceTest { @Test public void onBindViewHolder_setVisibility_shouldUpdateButtonVisibility() { - mPref.setButton1Text(R.string.install_other_apps).setButton1Visible(false); - mPref.setButton2Text(R.string.install_other_apps).setButton2Visible(false); - mPref.setButton3Text(R.string.install_other_apps).setButton3Visible(false); - mPref.setButton4Text(R.string.install_other_apps).setButton4Visible(false); + mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps).setButton1Visible(false); + mPref.setButton2Text(com.android.settingslib.R.string.install_other_apps).setButton2Visible(false); + mPref.setButton3Text(com.android.settingslib.R.string.install_other_apps).setButton3Visible(false); + mPref.setButton4Text(com.android.settingslib.R.string.install_other_apps).setButton4Visible(false); mPref.onBindViewHolder(mHolder); @@ -195,26 +197,26 @@ public class ActionButtonsPreferenceTest { @Test public void onBindViewHolder_setText_shouldShowSameText() { - mPref.setButton1Text(R.string.install_other_apps); - mPref.setButton2Text(R.string.install_other_apps); - mPref.setButton3Text(R.string.install_other_apps); - mPref.setButton4Text(R.string.install_other_apps); + mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps); + mPref.setButton2Text(com.android.settingslib.R.string.install_other_apps); + mPref.setButton3Text(com.android.settingslib.R.string.install_other_apps); + mPref.setButton4Text(com.android.settingslib.R.string.install_other_apps); mPref.onBindViewHolder(mHolder); assertThat(((Button) mRootView.findViewById(R.id.button1)).getText()) - .isEqualTo(mContext.getText(R.string.install_other_apps)); + .isEqualTo(mContext.getText(com.android.settingslib.R.string.install_other_apps)); assertThat(((Button) mRootView.findViewById(R.id.button2)).getText()) - .isEqualTo(mContext.getText(R.string.install_other_apps)); + .isEqualTo(mContext.getText(com.android.settingslib.R.string.install_other_apps)); assertThat(((Button) mRootView.findViewById(R.id.button3)).getText()) - .isEqualTo(mContext.getText(R.string.install_other_apps)); + .isEqualTo(mContext.getText(com.android.settingslib.R.string.install_other_apps)); assertThat(((Button) mRootView.findViewById(R.id.button4)).getText()) - .isEqualTo(mContext.getText(R.string.install_other_apps)); + .isEqualTo(mContext.getText(com.android.settingslib.R.string.install_other_apps)); } @Test public void onBindViewHolder_setButtonIcon_iconMustDisplayAboveText() { - mPref.setButton1Text(R.string.install_other_apps); + mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps); mPref.setButton1Icon(com.android.internal.R.drawable.ic_plus); mPref.onBindViewHolder(mHolder); @@ -227,7 +229,7 @@ public class ActionButtonsPreferenceTest { @Test public void setButtonIcon_iconResourceIdIsZero_shouldNotDisplayIcon() { - mPref.setButton1Text(R.string.install_other_apps); + mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps); mPref.setButton1Icon(0); mPref.onBindViewHolder(mHolder); @@ -240,7 +242,7 @@ public class ActionButtonsPreferenceTest { @Test public void setButtonIcon_iconResourceIdNotExisting_shouldNotDisplayIconAndCrash() { - mPref.setButton1Text(R.string.install_other_apps); + mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps); mPref.setButton1Icon(999999999 /* not existing id */); // Should not crash here mPref.onBindViewHolder(mHolder); @@ -253,10 +255,10 @@ public class ActionButtonsPreferenceTest { @Test public void onBindViewHolder_setAllButton_shouldShowAllDivider() { - mPref.setButton1Text(R.string.install_other_apps); - mPref.setButton2Text(R.string.install_other_apps); - mPref.setButton3Text(R.string.install_other_apps); - mPref.setButton4Text(R.string.install_other_apps); + mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps); + mPref.setButton2Text(com.android.settingslib.R.string.install_other_apps); + mPref.setButton3Text(com.android.settingslib.R.string.install_other_apps); + mPref.setButton4Text(com.android.settingslib.R.string.install_other_apps); mPref.onBindViewHolder(mHolder); @@ -270,9 +272,9 @@ public class ActionButtonsPreferenceTest { @Test public void onBindViewHolder_setAllButtonWithoutButton2_shouldHideDivider1() { - mPref.setButton1Text(R.string.install_other_apps); - mPref.setButton3Text(R.string.install_other_apps); - mPref.setButton4Text(R.string.install_other_apps); + mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps); + mPref.setButton3Text(com.android.settingslib.R.string.install_other_apps); + mPref.setButton4Text(com.android.settingslib.R.string.install_other_apps); mPref.onBindViewHolder(mHolder); @@ -286,9 +288,9 @@ public class ActionButtonsPreferenceTest { @Test public void onBindViewHolder_setAllButtonWithoutButton3_shouldHideDivider2() { - mPref.setButton1Text(R.string.install_other_apps); - mPref.setButton2Text(R.string.install_other_apps); - mPref.setButton4Text(R.string.install_other_apps); + mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps); + mPref.setButton2Text(com.android.settingslib.R.string.install_other_apps); + mPref.setButton4Text(com.android.settingslib.R.string.install_other_apps); mPref.onBindViewHolder(mHolder); @@ -302,8 +304,8 @@ public class ActionButtonsPreferenceTest { @Test public void onBindViewHolder_setButton1And4_shouldShowDivider3Only() { - mPref.setButton1Text(R.string.install_other_apps); - mPref.setButton4Text(R.string.install_other_apps); + mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps); + mPref.setButton4Text(com.android.settingslib.R.string.install_other_apps); mPref.onBindViewHolder(mHolder); @@ -317,7 +319,7 @@ public class ActionButtonsPreferenceTest { @Test public void onBindViewHolder_setOneButtonOnly_noDivider() { - mPref.setButton4Text(R.string.install_other_apps); + mPref.setButton4Text(com.android.settingslib.R.string.install_other_apps); mPref.onBindViewHolder(mHolder); @@ -331,8 +333,8 @@ public class ActionButtonsPreferenceTest { @Test public void onBindViewHolder_setButton1And2_shouldShowDivider1Only() { - mPref.setButton1Text(R.string.install_other_apps); - mPref.setButton2Text(R.string.install_other_apps); + mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps); + mPref.setButton2Text(com.android.settingslib.R.string.install_other_apps); mPref.onBindViewHolder(mHolder); @@ -346,8 +348,8 @@ public class ActionButtonsPreferenceTest { @Test public void onBindViewHolder_setButton1And3_shouldShowDivider2Only() { - mPref.setButton1Text(R.string.install_other_apps); - mPref.setButton3Text(R.string.install_other_apps); + mPref.setButton1Text(com.android.settingslib.R.string.install_other_apps); + mPref.setButton3Text(com.android.settingslib.R.string.install_other_apps); mPref.onBindViewHolder(mHolder); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java index 10862403ae70..6195d754f8f0 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java @@ -36,7 +36,7 @@ import android.graphics.drawable.Icon; import android.graphics.drawable.ShapeDrawable; import android.os.Bundle; -import com.android.settingslib.R; +import com.android.settingslib.widget.adaptiveicon.R; import com.android.settingslib.drawer.ActivityTile; import com.android.settingslib.drawer.CategoryKey; import com.android.settingslib.drawer.Tile; @@ -87,7 +87,7 @@ public class AdaptiveIconTest { public void setBackgroundColor_externalTileWithBackgroundColorRawValue_shouldUpdateIcon() { final Tile tile = spy(new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE)); mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, 0xff0000); - doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update)) + doReturn(Icon.createWithResource(mContext, com.android.settingslib.R.drawable.ic_system_update)) .when(tile).getIcon(mContext); final AdaptiveIcon icon = new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)); @@ -99,7 +99,7 @@ public class AdaptiveIconTest { @Test public void setBackgroundColor_tileWithoutBackgroundColor_shouldSetDefaultBackgroundColor() { final Tile tile = spy(new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE)); - doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update)) + doReturn(Icon.createWithResource(mContext, com.android.settingslib.R.drawable.ic_system_update)) .when(tile).getIcon(mContext); final AdaptiveIcon icon = new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)); @@ -114,7 +114,7 @@ public class AdaptiveIconTest { final Tile tile = spy(new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE)); mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT, com.android.settingslib.widget.R.color.bt_outline_color); - doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update)) + doReturn(Icon.createWithResource(mContext, com.android.settingslib.R.drawable.ic_system_update)) .when(tile).getIcon(mContext); final AdaptiveIcon icon = diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveOutlineDrawableTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveOutlineDrawableTest.java index b2bc53dda1fa..943b9944af40 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveOutlineDrawableTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveOutlineDrawableTest.java @@ -21,6 +21,8 @@ import static com.google.common.truth.Truth.assertThat; import android.content.res.Resources; import android.graphics.Paint; +import com.android.settingslib.widget.adaptiveicon.R; + import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppEntitiesHeaderControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppEntitiesHeaderControllerTest.java index c9b066a5768e..172c1785c01b 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppEntitiesHeaderControllerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppEntitiesHeaderControllerTest.java @@ -24,6 +24,8 @@ import android.view.View; import android.widget.ImageView; import android.widget.TextView; +import com.android.settingslib.widget.entityheader.R; + import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -69,18 +71,18 @@ public class AppEntitiesHeaderControllerTest { @Test public void setHeaderTitleRes_setTextRes_shouldSetToTitleView() { - mController.setHeaderTitleRes(R.string.expand_button_title).apply(); + mController.setHeaderTitleRes(androidx.preference.R.string.expand_button_title).apply(); final TextView view = mAppEntitiesHeaderView.findViewById(R.id.header_title); - assertThat(view.getText()).isEqualTo(mContext.getText(R.string.expand_button_title)); + assertThat(view.getText()).isEqualTo(mContext.getText(androidx.preference.R.string.expand_button_title)); } @Test public void setHeaderDetailsRes_setTextRes_shouldSetToDetailsView() { - mController.setHeaderDetailsRes(R.string.expand_button_title).apply(); + mController.setHeaderDetailsRes(androidx.preference.R.string.expand_button_title).apply(); final TextView view = mAppEntitiesHeaderView.findViewById(R.id.header_details); - assertThat(view.getText()).isEqualTo(mContext.getText(R.string.expand_button_title)); + assertThat(view.getText()).isEqualTo(mContext.getText(androidx.preference.R.string.expand_button_title)); } @Test @@ -93,7 +95,7 @@ public class AppEntitiesHeaderControllerTest { @Test public void setHeaderDetails_detailsTextAndResBothSet_shouldSetTextToDetailsView() { - mController.setHeaderDetailsRes(R.string.expand_button_title); + mController.setHeaderDetailsRes(androidx.preference.R.string.expand_button_title); mController.setHeaderDetails(TITLE).apply(); final TextView view = mAppEntitiesHeaderView.findViewById(R.id.header_details); @@ -206,7 +208,7 @@ public class AppEntitiesHeaderControllerTest { @Test public void apply_noAppEntitySet_shouldOnlyShowTitleAndEmptyView() { - mController.setHeaderTitleRes(R.string.expand_button_title) + mController.setHeaderTitleRes(androidx.preference.R.string.expand_button_title) .setAppEntity(0, mAppEntityInfo) .setAppEntity(1, mAppEntityInfo) .setAppEntity(2, mAppEntityInfo).apply(); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppHeaderPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppHeaderPreferenceTest.java index e2b242c97e0e..9112f6bc69a5 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppHeaderPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppHeaderPreferenceTest.java @@ -24,7 +24,7 @@ import android.widget.TextView; import androidx.preference.PreferenceViewHolder; - +import com.android.settingslib.widget.preference.app.R; import org.junit.Before; import org.junit.Test; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppPreferenceTest.java index 9e265a45a8f2..6c8fd50d1896 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AppPreferenceTest.java @@ -23,6 +23,8 @@ import android.view.View; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.widget.preference.app.R; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -56,7 +58,7 @@ public class AppPreferenceTest { @Test public void foobar_testName() { - float iconSize = mContext.getResources().getDimension(R.dimen.secondary_app_icon_size); + float iconSize = mContext.getResources().getDimension(com.android.settingslib.widget.theme.R.dimen.secondary_app_icon_size); assertThat(Float.floatToIntBits(iconSize)).isEqualTo(Float.floatToIntBits(32)); } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java index 0d889139e8b4..721e69d2eb8d 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java @@ -39,7 +39,7 @@ import android.widget.TextView; import androidx.annotation.ColorRes; import androidx.preference.PreferenceViewHolder; -import androidx.preference.R; +import com.android.settingslib.widget.preference.banner.R; import com.android.settingslib.testutils.OverpoweredReflectionHelper; @@ -65,7 +65,7 @@ public class BannerMessagePreferenceTest { private final View.OnClickListener mClickListener = v -> mClickListenerCalled = true; private final int mMinimumTargetSize = RuntimeEnvironment.application.getResources() - .getDimensionPixelSize(R.dimen.settingslib_preferred_minimum_touch_target); + .getDimensionPixelSize(com.android.settingslib.widget.theme.R.dimen.settingslib_preferred_minimum_touch_target); private static final int TEST_STRING_RES_ID = R.string.accessibility_banner_message_dismiss; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java index 567d90fa8916..ae6573e599ce 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java @@ -26,6 +26,8 @@ import android.widget.TextView; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.widget.preference.barchart.R; + import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -71,9 +73,9 @@ public class BarChartPreferenceTest { mDetailsView = mBarChartView.findViewById(R.id.bar_chart_details); mBarChartInfo = new BarChartInfo.Builder() - .setTitle(R.string.debug_app) - .setDetails(R.string.debug_app) - .setEmptyText(R.string.debug_app) + .setTitle(com.android.settingslib.R.string.debug_app) + .setDetails(com.android.settingslib.R.string.debug_app) + .setEmptyText(com.android.settingslib.R.string.debug_app) .setDetailsOnClickListener(v -> { }) .build(); @@ -82,21 +84,21 @@ public class BarChartPreferenceTest { @Test public void initializeBarChart_titleSet_shouldSetTitleInChartView() { final BarChartInfo barChartInfo = new BarChartInfo.Builder() - .setTitle(R.string.debug_app) + .setTitle(com.android.settingslib.R.string.debug_app) .build(); mPreference.initializeBarChart(barChartInfo); mPreference.onBindViewHolder(mHolder); assertThat(mTitleView.getVisibility()).isEqualTo(View.VISIBLE); - assertThat(mTitleView.getText()).isEqualTo(mContext.getText(R.string.debug_app)); + assertThat(mTitleView.getText()).isEqualTo(mContext.getText(com.android.settingslib.R.string.debug_app)); } @Test public void initializeBarChart_noBarViewSet_shouldShowTitleAndEmptyView() { final BarChartInfo barChartInfo = new BarChartInfo.Builder() - .setTitle(R.string.debug_app) - .setEmptyText(R.string.debug_app) + .setTitle(com.android.settingslib.R.string.debug_app) + .setEmptyText(com.android.settingslib.R.string.debug_app) .build(); mPreference.initializeBarChart(barChartInfo); @@ -113,11 +115,11 @@ public class BarChartPreferenceTest { @Test public void initializeBarChart_detailsSet_shouldShowBarChartDetailsView() { final BarChartInfo barChartInfo = new BarChartInfo.Builder() - .setTitle(R.string.debug_app) - .setDetails(R.string.debug_app) + .setTitle(com.android.settingslib.R.string.debug_app) + .setDetails(com.android.settingslib.R.string.debug_app) .addBarViewInfo( new BarViewInfo(mIcon, 10, null /* title */, - mContext.getText(R.string.debug_app) /* summary */, + mContext.getText(com.android.settingslib.R.string.debug_app) /* summary */, null /* contentDescription */)) .build(); @@ -125,17 +127,17 @@ public class BarChartPreferenceTest { mPreference.onBindViewHolder(mHolder); assertThat(mDetailsView.getVisibility()).isEqualTo(View.VISIBLE); - assertThat(mDetailsView.getText()).isEqualTo(mContext.getText(R.string.debug_app)); + assertThat(mDetailsView.getText()).isEqualTo(mContext.getText(com.android.settingslib.R.string.debug_app)); } @Test public void initializeBarChart_detailsNotSet_shouldHideBarChartDetailsView() { // We don't call BarChartInfo.Builder#setDetails yet. final BarChartInfo barChartInfo = new BarChartInfo.Builder() - .setTitle(R.string.debug_app) + .setTitle(com.android.settingslib.R.string.debug_app) .addBarViewInfo( new BarViewInfo(mIcon, 10, null /* title */, - mContext.getText(R.string.debug_app) /* summary */, + mContext.getText(com.android.settingslib.R.string.debug_app) /* summary */, null /* contentDescription */)) .build(); @@ -148,13 +150,13 @@ public class BarChartPreferenceTest { @Test public void initializeBarChart_clickListenerSet_shouldSetClickListenerOnDetailsView() { final BarChartInfo barChartInfo = new BarChartInfo.Builder() - .setTitle(R.string.debug_app) - .setDetails(R.string.debug_app) + .setTitle(com.android.settingslib.R.string.debug_app) + .setDetails(com.android.settingslib.R.string.debug_app) .setDetailsOnClickListener(v -> { }) .addBarViewInfo( new BarViewInfo(mIcon, 10, null /* title */, - mContext.getText(R.string.debug_app) /* summary */, + mContext.getText(com.android.settingslib.R.string.debug_app) /* summary */, null /* contentDescription */)) .build(); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ButtonPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ButtonPreferenceTest.java index d78f8e7e4e9b..f3fe5172b46a 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ButtonPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/ButtonPreferenceTest.java @@ -68,14 +68,14 @@ public class ButtonPreferenceTest { @Test public void onBindViewHolder_whenIconSet_shouldSetIcon() { - mPreference.setIcon(R.drawable.settingslib_ic_cross); + mPreference.setIcon(com.android.settingslib.widget.preference.banner.R.drawable.settingslib_ic_cross); mPreference.onBindViewHolder(mHolder); final Button button = mPreference.getButton(); final Drawable icon = button.getCompoundDrawablesRelative()[0]; final ShadowDrawable shadowDrawable = shadowOf(icon); - assertThat(shadowDrawable.getCreatedFromResId()).isEqualTo(R.drawable.settingslib_ic_cross); + assertThat(shadowDrawable.getCreatedFromResId()).isEqualTo(com.android.settingslib.widget.preference.banner.R.drawable.settingslib_ic_cross); } @Test diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java index a26f200ec603..ccbe4f03e80c 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java @@ -28,7 +28,7 @@ import android.widget.TextView; import androidx.preference.PreferenceViewHolder; -import com.android.settingslib.R; +import com.android.settingslib.widget.preference.footer.R; import org.junit.Before; import org.junit.Test; @@ -96,7 +96,7 @@ public class FooterPreferenceTest { public void onBindViewHolder_whenTitleIsNull_shouldNotRaiseNpe() { PreferenceViewHolder viewHolder = spy(PreferenceViewHolder.createInstanceForTests( LayoutInflater.from(mContext) - .inflate(com.android.settingslib.widget.R.layout.preference_footer, null))); + .inflate(R.layout.preference_footer, null))); when(viewHolder.findViewById(androidx.core.R.id.title)).thenReturn(null); Throwable actualThrowable = null; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java index 21e119a48f7b..6590bbdcdae6 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java @@ -39,6 +39,8 @@ import android.widget.ImageView; import androidx.preference.PreferenceViewHolder; import androidx.test.core.app.ApplicationProvider; +import com.android.settingslib.widget.preference.illustration.R; + import com.airbnb.lottie.LottieAnimationView; import org.junit.Before; @@ -49,6 +51,7 @@ import org.mockito.MockitoAnnotations; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; + @RunWith(RobolectricTestRunner.class) public class IllustrationPreferenceTest { diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/LayoutPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/LayoutPreferenceTest.java index 99261a38f73b..58817fbd272a 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/LayoutPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/LayoutPreferenceTest.java @@ -27,6 +27,8 @@ import android.view.LayoutInflater; import androidx.preference.Preference.OnPreferenceClickListener; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.widget.preference.layout.R; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchBarTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchBarTest.java index 24037caf4e6c..942e91525f02 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchBarTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchBarTest.java @@ -26,6 +26,8 @@ import android.view.View; import android.widget.Switch; import android.widget.TextView; +import com.android.settingslib.widget.mainswitch.R; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java index e58c04a3b435..c2e81bd7d54c 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/MainSwitchPreferenceTest.java @@ -24,6 +24,8 @@ import android.widget.TextView; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.widget.mainswitch.R; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/RadioButtonPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/RadioButtonPreferenceTest.java index a5028ff30d73..0f708cdb9992 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/RadioButtonPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/RadioButtonPreferenceTest.java @@ -28,6 +28,8 @@ import android.view.View; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.widget.preference.radio.R; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/SelectorWithWidgetPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/SelectorWithWidgetPreferenceTest.java index 34efe82f2527..60885f1079d3 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/SelectorWithWidgetPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/SelectorWithWidgetPreferenceTest.java @@ -28,6 +28,8 @@ import android.view.View; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.widget.preference.selector.R; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/TwoTargetPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/TwoTargetPreferenceTest.java index 23b4c2aec80f..3befddab2db5 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/TwoTargetPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/TwoTargetPreferenceTest.java @@ -32,6 +32,8 @@ import android.widget.LinearLayout; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.widget.preference.twotarget.R; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/packages/SettingsLib/tests/unit/Android.bp b/packages/SettingsLib/tests/unit/Android.bp index a4558f1bd40b..19ab1c69e98c 100644 --- a/packages/SettingsLib/tests/unit/Android.bp +++ b/packages/SettingsLib/tests/unit/Android.bp @@ -20,6 +20,7 @@ package { android_test { name: "SettingsLibUnitTests", + use_resource_processor: true, test_suites: ["device-tests"], srcs: [ diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java index 0a98032e26d8..e9533e598336 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java @@ -137,6 +137,13 @@ final class SettingsState { private static final String ATTR_VALUE_BASE64 = "valueBase64"; private static final String ATTR_DEFAULT_VALUE_BASE64 = "defaultValueBase64"; + /** + * In the config table, there are special flags of the form {@code staged/namespace*flagName}. + * On boot, when the XML file is initially parsed, these transform into + * {@code namespace/flagName}, and the special staged flags are deleted. + */ + private static final String CONFIG_STAGED_PREFIX = "staged/"; + // This was used in version 120 and before. private static final String NULL_VALUE_OLD_STYLE = "null"; @@ -1191,6 +1198,42 @@ final class SettingsState { } } + /** + * Transforms a staged flag name to its real flag name. + * + * Staged flags take the form {@code staged/namespace*flagName}. If + * {@code stagedFlagName} takes the proper form, returns + * {@code namespace/flagName}. Otherwise, returns {@code stagedFlagName} + * unmodified, and logs an error message. + * + */ + @VisibleForTesting + public static String createRealFlagName(String stagedFlagName) { + int slashIndex = stagedFlagName.indexOf("/"); + if (slashIndex == -1 || slashIndex == stagedFlagName.length() - 1 + || slashIndex == 0) { + Slog.w(LOG_TAG, "invalid staged flag, not applying: " + stagedFlagName); + return stagedFlagName; + } + + String namespaceAndFlag = + stagedFlagName.substring(slashIndex + 1); + + int starIndex = namespaceAndFlag.indexOf("*"); + if (starIndex == -1 || starIndex == namespaceAndFlag.length() - 1 + || starIndex == 0) { + Slog.w(LOG_TAG, "invalid staged flag, not applying: " + stagedFlagName); + return stagedFlagName; + } + + String namespace = + namespaceAndFlag.substring(0, starIndex); + String flagName = + namespaceAndFlag.substring(starIndex + 1); + + return namespace + "/" + flagName; + } + @GuardedBy("mLock") private void parseSettingsLocked(TypedXmlPullParser parser) throws IOException, XmlPullParserException { @@ -1199,6 +1242,7 @@ final class SettingsState { final int outerDepth = parser.getDepth(); int type; + HashSet<String> flagsWithStagedValueApplied = new HashSet<String>(); while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { @@ -1221,6 +1265,18 @@ final class SettingsState { fromSystem = parser.getAttributeBoolean(null, ATTR_DEFAULT_SYS_SET, false); tag = getValueAttribute(parser, ATTR_TAG, ATTR_TAG_BASE64); } + + if (isConfigSettingsKey(mKey)) { + if (flagsWithStagedValueApplied.contains(name)) { + continue; + } + + if (name.startsWith(CONFIG_STAGED_PREFIX)) { + name = createRealFlagName(name); + flagsWithStagedValueApplied.add(name); + } + } + mSettings.put(name, new Setting(name, value, defaultValue, packageName, tag, fromSystem, id, isPreservedInRestore)); @@ -1229,6 +1285,16 @@ final class SettingsState { } } } + + if (isConfigSettingsKey(mKey) && !flagsWithStagedValueApplied.isEmpty()) { + // On boot, the config table XML file includes special staged flags. On the initial + // boot XML -> HashMap parse, these staged flags get transformed into real flags. + // After this, the HashMap contains no special staged flags (only the transformed + // real flags), but the XML still does. We then have no need for the special staged + // flags in the XML, so we overwrite the XML with the latest contents of the + // HashMap. + writeStateAsyncLocked(); + } } @GuardedBy("mLock") diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java index 26cac37f8b35..df4d2a1ed89f 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java @@ -51,6 +51,21 @@ public class SettingsStateTest extends AndroidTestCase { private static final String SYSTEM_PACKAGE = "android"; private static final String SETTING_NAME = "test_setting"; + private static final String FLAG_NAME_1 = "namespace123/flag456"; + private static final String FLAG_NAME_1_STAGED = "staged/namespace123*flag456"; + private static final String FLAG_NAME_2 = "not_staged/flag101"; + + private static final String INVALID_STAGED_FLAG_1 = "stagednamespace*flagName"; + private static final String INVALID_STAGED_FLAG_2 = "staged/"; + private static final String INVALID_STAGED_FLAG_3 = "staged/namespace*"; + private static final String INVALID_STAGED_FLAG_4 = "staged/*flagName"; + + private static final String VALID_STAGED_FLAG_1 = "staged/namespace*flagName"; + private static final String VALID_STAGED_FLAG_1_TRANSFORMED = "namespace/flagName"; + + private static final String VALUE1 = "5"; + private static final String VALUE2 = "6"; + private final Object mLock = new Object(); private File mSettingsFile; @@ -454,4 +469,68 @@ public class SettingsStateTest extends AndroidTestCase { } } } + + public void testApplyStagedConfigValues() { + int configKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_CONFIG, 0); + Object lock = new Object(); + SettingsState settingsState = new SettingsState( + getContext(), lock, mSettingsFile, configKey, + SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper()); + + synchronized (lock) { + settingsState.insertSettingLocked( + FLAG_NAME_1_STAGED, VALUE1, null, false, TEST_PACKAGE); + settingsState.insertSettingLocked(FLAG_NAME_2, VALUE2, null, false, TEST_PACKAGE); + settingsState.persistSyncLocked(); + + assertEquals(VALUE1, settingsState.getSettingLocked(FLAG_NAME_1_STAGED).getValue()); + assertEquals(VALUE2, settingsState.getSettingLocked(FLAG_NAME_2).getValue()); + } + + settingsState = new SettingsState(getContext(), lock, mSettingsFile, configKey, + SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper()); + + synchronized (lock) { + assertEquals(VALUE1, settingsState.getSettingLocked(FLAG_NAME_1).getValue()); + assertEquals(VALUE2, settingsState.getSettingLocked(FLAG_NAME_2).getValue()); + + assertEquals(null, settingsState.getSettingLocked(FLAG_NAME_1_STAGED).getValue()); + } + } + + public void testStagingTransformation() { + assertEquals(INVALID_STAGED_FLAG_1, + SettingsState.createRealFlagName(INVALID_STAGED_FLAG_1)); + assertEquals(INVALID_STAGED_FLAG_2, + SettingsState.createRealFlagName(INVALID_STAGED_FLAG_2)); + assertEquals(INVALID_STAGED_FLAG_3, + SettingsState.createRealFlagName(INVALID_STAGED_FLAG_3)); + assertEquals(INVALID_STAGED_FLAG_4, + SettingsState.createRealFlagName(INVALID_STAGED_FLAG_4)); + + assertEquals(VALID_STAGED_FLAG_1_TRANSFORMED, + SettingsState.createRealFlagName(VALID_STAGED_FLAG_1)); + } + + public void testInvalidStagedFlagsUnaffectedByReboot() { + int configKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_CONFIG, 0); + Object lock = new Object(); + SettingsState settingsState = new SettingsState( + getContext(), lock, mSettingsFile, configKey, + SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper()); + + synchronized (lock) { + settingsState.insertSettingLocked(INVALID_STAGED_FLAG_1, + VALUE2, null, false, TEST_PACKAGE); + settingsState.persistSyncLocked(); + assertEquals(VALUE2, settingsState.getSettingLocked(INVALID_STAGED_FLAG_1).getValue()); + } + + settingsState = new SettingsState(getContext(), lock, mSettingsFile, configKey, + SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper()); + + synchronized (lock) { + assertEquals(VALUE2, settingsState.getSettingLocked(INVALID_STAGED_FLAG_1).getValue()); + } + } } diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 15620b7023e2..11ae9c35898b 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -206,6 +206,7 @@ <uses-permission android:name="android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY" /> <uses-permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS" /> <uses-permission android:name="android.permission.REVOKE_RUNTIME_PERMISSIONS" /> + <uses-permission android:name="android.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS" /> <uses-permission android:name="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS" /> <uses-permission android:name="android.permission.WHITELIST_RESTRICTED_PERMISSIONS" /> <!-- Permission required for processes that don't own the focused window to switch diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index 608010156fcf..5e7e044947fd 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -116,6 +116,7 @@ filegroup { //Create a library to expose SystemUI's resources to other modules. android_library { name: "SystemUI-res", + use_resource_processor: true, resource_dirs: [ "res-product", "res-keyguard", @@ -149,13 +150,9 @@ android_library { exclude_srcs: [":ReleaseJavaFiles"], }, }, - resource_dirs: [ - "res-product", - "res-keyguard", - "res", - ], use_resource_processor: true, static_libs: [ + "SystemUI-res", "WifiTrackerLib", "WindowManager-Shell", "SystemUIAnimationLib", @@ -380,14 +377,13 @@ java_library { android_library { name: "SystemUI-tests-base", + use_resource_processor: true, manifest: "tests/AndroidManifest-base.xml", resource_dirs: [ "tests/res", - "res-product", - "res-keyguard", - "res", ], static_libs: [ + "SystemUI-res", "WifiTrackerLib", "SystemUIAnimationLib", "SystemUIPluginLib", @@ -442,6 +438,7 @@ android_library { android_library { name: "SystemUI-tests", + use_resource_processor: true, defaults: [ "SystemUI_compose_defaults", ], @@ -485,6 +482,7 @@ android_library { android_app { name: "SystemUIRobo-stub", + use_resource_processor: true, defaults: [ "platform_app_defaults", "SystemUI_optimized_defaults", diff --git a/packages/SystemUI/accessibility/accessibilitymenu/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/Android.bp index ff723e34d6bc..8b12f3c738cc 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/Android.bp +++ b/packages/SystemUI/accessibility/accessibilitymenu/Android.bp @@ -29,6 +29,7 @@ filegroup { android_app { name: "AccessibilityMenu", + use_resource_processor: true, static_libs: [ "androidx.coordinatorlayout_coordinatorlayout", diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp index 1757dda84eef..538ecb3d438d 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp +++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp @@ -20,6 +20,7 @@ package { android_test { name: "AccessibilityMenuServiceTests", + use_resource_processor: true, certificate: "platform", libs: [ "android.test.runner", diff --git a/packages/SystemUI/aconfig/OWNERS b/packages/SystemUI/aconfig/OWNERS new file mode 100644 index 000000000000..e1a7a0f84ad0 --- /dev/null +++ b/packages/SystemUI/aconfig/OWNERS @@ -0,0 +1 @@ +per-file accessibility.aconfig = file:/core/java/android/view/accessibility/OWNERS diff --git a/packages/SystemUI/animation/Android.bp b/packages/SystemUI/animation/Android.bp index 6f53b42371c6..8438051e3430 100644 --- a/packages/SystemUI/animation/Android.bp +++ b/packages/SystemUI/animation/Android.bp @@ -24,6 +24,7 @@ package { android_library { name: "SystemUIAnimationLib", + use_resource_processor: true, srcs: [ "src/**/*.java", @@ -52,6 +53,7 @@ android_library { android_library { name: "SystemUIShaderLib", + use_resource_processor: true, srcs: [ "src/com/android/systemui/surfaceeffects/**/*.java", 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 1b56d4a201d9..0f2e4bace46d 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt @@ -25,6 +25,7 @@ import android.graphics.Path import android.graphics.Rect import android.graphics.RectF import android.os.Build +import android.os.Handler import android.os.Looper import android.os.RemoteException import android.util.Log @@ -58,7 +59,14 @@ class ActivityLaunchAnimator( /** The animator used when animating a Dialog into an app. */ // TODO(b/218989950): Remove this animator and instead set the duration of the dim fade out to // TIMINGS.contentBeforeFadeOutDuration. - private val dialogToAppAnimator: LaunchAnimator = DEFAULT_DIALOG_TO_APP_ANIMATOR + private val dialogToAppAnimator: LaunchAnimator = DEFAULT_DIALOG_TO_APP_ANIMATOR, + + /** + * Whether we should disable the WindowManager timeout. This should be set to true in tests + * only. + */ + // TODO(b/301385865): Remove this flag. + private val disableWmTimeout: Boolean = false, ) { companion object { /** The timings when animating a View into an app. */ @@ -252,7 +260,7 @@ class ActivityLaunchAnimator( Log.d( TAG, "Calling controller.onIntentStarted(willAnimate=$willAnimate) " + - "[controller=$this]" + "[controller=$this]" ) } this.onIntentStarted(willAnimate) @@ -431,7 +439,8 @@ class ActivityLaunchAnimator( internal val delegate: AnimationDelegate init { - delegate = AnimationDelegate(controller, callback, listener, launchAnimator) + delegate = + AnimationDelegate(controller, callback, listener, launchAnimator, disableWmTimeout) } @BinderThread @@ -461,13 +470,26 @@ class ActivityLaunchAnimator( /** Listener for animation lifecycle events. */ private val listener: Listener? = null, /** The animator to use to animate the window launch. */ - private val launchAnimator: LaunchAnimator = DEFAULT_LAUNCH_ANIMATOR + private val launchAnimator: LaunchAnimator = DEFAULT_LAUNCH_ANIMATOR, + + /** + * Whether we should disable the WindowManager timeout. This should be set to true in tests + * only. + */ + // TODO(b/301385865): Remove this flag. + disableWmTimeout: Boolean = false, ) : RemoteAnimationDelegate<IRemoteAnimationFinishedCallback> { private val launchContainer = controller.launchContainer private val context = launchContainer.context private val transactionApplierView = controller.openingWindowSyncView ?: controller.launchContainer private val transactionApplier = SyncRtSurfaceTransactionApplier(transactionApplierView) + private val timeoutHandler = + if (!disableWmTimeout) { + Handler(Looper.getMainLooper()) + } else { + null + } private val matrix = Matrix() private val invertMatrix = Matrix() @@ -487,11 +509,11 @@ class ActivityLaunchAnimator( @UiThread internal fun postTimeout() { - launchContainer.postDelayed(onTimeout, LAUNCH_TIMEOUT) + timeoutHandler?.postDelayed(onTimeout, LAUNCH_TIMEOUT) } private fun removeTimeout() { - launchContainer.removeCallbacks(onTimeout) + timeoutHandler?.removeCallbacks(onTimeout) } @UiThread diff --git a/packages/SystemUI/common/Android.bp b/packages/SystemUI/common/Android.bp index e36ada89b207..482776a37327 100644 --- a/packages/SystemUI/common/Android.bp +++ b/packages/SystemUI/common/Android.bp @@ -24,6 +24,7 @@ package { android_library { name: "SystemUICommon", + use_resource_processor: true, srcs: [ "src/**/*.java", diff --git a/packages/SystemUI/compose/core/Android.bp b/packages/SystemUI/compose/core/Android.bp index ab3efb886182..510fa1e1fa80 100644 --- a/packages/SystemUI/compose/core/Android.bp +++ b/packages/SystemUI/compose/core/Android.bp @@ -38,4 +38,5 @@ android_library { ], kotlincflags: ["-Xjvm-default=all"], + use_resource_processor: true, } diff --git a/packages/SystemUI/compose/core/tests/Android.bp b/packages/SystemUI/compose/core/tests/Android.bp index 5a8a374b4b7f..52c63854f62f 100644 --- a/packages/SystemUI/compose/core/tests/Android.bp +++ b/packages/SystemUI/compose/core/tests/Android.bp @@ -47,4 +47,5 @@ android_test { ], kotlincflags: ["-Xjvm-default=all"], + use_resource_processor: true, } diff --git a/packages/SystemUI/compose/features/Android.bp b/packages/SystemUI/compose/features/Android.bp index c6438c9ef955..e4426fe97859 100644 --- a/packages/SystemUI/compose/features/Android.bp +++ b/packages/SystemUI/compose/features/Android.bp @@ -23,6 +23,7 @@ package { android_library { name: "SystemUIComposeFeatures", + use_resource_processor: true, manifest: "AndroidManifest.xml", srcs: [ diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt index 5505eaf8fd7e..46a9d42d0606 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt @@ -48,7 +48,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.SceneScope -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.bouncer.ui.viewmodel.AuthMethodBouncerViewModel import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt index 8a8557aa1f43..df22a7023ebf 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt @@ -17,8 +17,11 @@ package com.android.systemui.bouncer.ui.composable import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.imeAnimationTarget import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.LocalTextStyle @@ -29,6 +32,7 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawBehind @@ -44,6 +48,7 @@ import androidx.compose.ui.unit.dp import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel /** UI for the input part of a password-requiring version of the bouncer. */ +@OptIn(ExperimentalLayoutApi::class) @Composable internal fun PasswordBouncer( viewModel: PasswordBouncerViewModel, @@ -54,6 +59,10 @@ internal fun PasswordBouncer( val isInputEnabled: Boolean by viewModel.isInputEnabled.collectAsState() val animateFailure: Boolean by viewModel.animateFailure.collectAsState() + val density = LocalDensity.current + val isImeVisible by rememberUpdatedState(WindowInsets.imeAnimationTarget.getBottom(density) > 0) + LaunchedEffect(isImeVisible) { viewModel.onImeVisibilityChanged(isImeVisible) } + LaunchedEffect(Unit) { // When the UI comes up, request focus on the TextField to bring up the software keyboard. focusRequester.requestFocus() diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt index e5c69777503c..6491b70db99b 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt @@ -55,7 +55,7 @@ import androidx.compose.ui.unit.dp import com.android.compose.animation.Easings import com.android.compose.grid.VerticalGrid import com.android.compose.modifiers.thenIf -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.bouncer.ui.viewmodel.ActionButtonAppearance import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel import com.android.systemui.common.shared.model.ContentDescription diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinInputDisplay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinInputDisplay.kt index 77065cfdeb76..055ece328fc3 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinInputDisplay.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinInputDisplay.kt @@ -51,7 +51,7 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.android.compose.animation.Easings import com.android.keyguard.PinShapeAdapter -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.bouncer.ui.viewmodel.EntryToken.Digit import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel import com.android.systemui.bouncer.ui.viewmodel.PinInputViewModel diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt index 77daebb9b8a0..c3a3752db374 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt @@ -36,7 +36,7 @@ import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.viewinterop.AndroidView import androidx.core.view.isVisible import com.android.compose.animation.scene.SceneScope -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.qualifiers.KeyguardRootView diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt index 68f010e1c50d..e12b7eae96e7 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt @@ -47,7 +47,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.android.compose.theme.LocalAndroidColorScheme -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.people.ui.viewmodel.PeopleTileViewModel import com.android.systemui.people.ui.viewmodel.PeopleViewModel diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt index 1e6f4a2f5b23..26cc9b952e27 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt @@ -42,7 +42,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.android.compose.theme.LocalAndroidColorScheme -import com.android.systemui.R +import com.android.systemui.res.R @Composable internal fun PeopleScreenEmpty( diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt index 482220013e32..689a0a2815c5 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt @@ -69,7 +69,7 @@ import com.android.compose.animation.Expandable import com.android.compose.modifiers.background import com.android.compose.theme.LocalAndroidColorScheme import com.android.compose.theme.colorAttr -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.ui.compose.Icon diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt index 272e507d5d4a..8e3400872a9a 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt @@ -47,7 +47,7 @@ import com.android.compose.animation.scene.SceneScope import com.android.compose.animation.scene.ValueKey import com.android.compose.animation.scene.animateSharedFloatAsState import com.android.settingslib.Utils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.battery.BatteryMeterView import com.android.systemui.battery.BatteryMeterViewController import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel diff --git a/packages/SystemUI/compose/features/tests/Android.bp b/packages/SystemUI/compose/features/tests/Android.bp index c7c9140b53ed..c85cd7bae41b 100644 --- a/packages/SystemUI/compose/features/tests/Android.bp +++ b/packages/SystemUI/compose/features/tests/Android.bp @@ -24,6 +24,7 @@ package { // TODO(b/230606318): Make those host tests instead of device tests. android_test { name: "SystemUIComposeFeaturesTests", + use_resource_processor: true, manifest: "AndroidManifest.xml", test_suites: ["device-tests"], sdk_version: "current", diff --git a/packages/SystemUI/customization/Android.bp b/packages/SystemUI/customization/Android.bp index fc37b355494f..927fd8ea6279 100644 --- a/packages/SystemUI/customization/Android.bp +++ b/packages/SystemUI/customization/Android.bp @@ -23,6 +23,7 @@ package { android_library { name: "SystemUICustomizationLib", + use_resource_processor: true, srcs: [ "src/**/*.java", "src/**/*.kt", diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt index 054f9ec1dbbc..c41dc53fdc6b 100644 --- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt +++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt @@ -148,7 +148,7 @@ open class ClockRegistry( override fun onPluginAttached( manager: PluginLifecycleManager<ClockProviderPlugin> ): Boolean { - manager.isDebug = true + manager.isDebug = !keepAllLoaded if (keepAllLoaded) { // Always load new plugins if requested @@ -511,6 +511,12 @@ open class ClockRegistry( fun verifyLoadedProviders() { val shouldSchedule = isVerifying.compareAndSet(false, true) if (!shouldSchedule) { + logger.tryLog( + TAG, + LogLevel.VERBOSE, + {}, + { "verifyLoadedProviders: shouldSchedule=false" } + ) return } @@ -670,6 +676,7 @@ open class ClockRegistry( { str1 = clockId }, { "Clock $str1 not loaded; using default" } ) + verifyLoadedProviders() } else { logger.tryLog( TAG, diff --git a/packages/SystemUI/log/Android.bp b/packages/SystemUI/log/Android.bp index 627ac4b7c381..2be22a65676b 100644 --- a/packages/SystemUI/log/Android.bp +++ b/packages/SystemUI/log/Android.bp @@ -23,6 +23,7 @@ package { android_library { name: "SystemUILogLib", + use_resource_processor: true, srcs: [ "src/**/*.java", "src/**/*.kt", diff --git a/packages/SystemUI/plugin/Android.bp b/packages/SystemUI/plugin/Android.bp index bb47a2f4726e..c42895282440 100644 --- a/packages/SystemUI/plugin/Android.bp +++ b/packages/SystemUI/plugin/Android.bp @@ -50,6 +50,7 @@ android_app { // Dummy to generate .toc files. name: "PluginDummyLib", + use_resource_processor: true, platform_apis: true, srcs: ["src/**/*.java"], diff --git a/packages/SystemUI/plugin/ExamplePlugin/Android.bp b/packages/SystemUI/plugin/ExamplePlugin/Android.bp index 3f0fdedb57da..66951b5d9640 100644 --- a/packages/SystemUI/plugin/ExamplePlugin/Android.bp +++ b/packages/SystemUI/plugin/ExamplePlugin/Android.bp @@ -10,6 +10,7 @@ package { android_app { name: "ExamplePlugin", + use_resource_processor: true, libs: ["SystemUIPluginLib"], diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml index 8c817330953c..d1067a9960bf 100644 --- a/packages/SystemUI/res-keyguard/values/dimens.xml +++ b/packages/SystemUI/res-keyguard/values/dimens.xml @@ -105,6 +105,13 @@ screen. --> <item name="half_opened_bouncer_height_ratio" type="dimen" format="float">0.0</item> + <!-- Proportion of the screen height to use to set the maximum height of the bouncer to when + the device is in the DEVICE_POSTURE_HALF_OPENED posture. + + This value is only used when motion layout bouncer is used - when flag + landscape.enable_lockscreen (b/293252410) is on --> + <item name="motion_layout_half_fold_bouncer_height_ratio" type="dimen" format="float">0.55</item> + <!-- The actual amount of translation that is applied to the security when it animates from one side of the screen to the other in one-handed or user switcher mode. Note that it will always translate from the side of the screen to the other (it will "jump" closer to the diff --git a/packages/SystemUI/res-keyguard/xml/keyguard_pattern_scene.xml b/packages/SystemUI/res-keyguard/xml/keyguard_pattern_scene.xml index 6112411402c4..751d6d8d04e7 100644 --- a/packages/SystemUI/res-keyguard/xml/keyguard_pattern_scene.xml +++ b/packages/SystemUI/res-keyguard/xml/keyguard_pattern_scene.xml @@ -10,9 +10,34 @@ motion:duration="0" motion:autoTransition="none"/> + <Transition + motion:constraintSetStart="@id/single_constraints" + motion:constraintSetEnd="@+id/half_folded_single_constraints" + motion:duration="@integer/material_motion_duration_short_1" + motion:autoTransition="none"/> + <!-- No changes to default layout --> <ConstraintSet android:id="@+id/single_constraints"/> + <ConstraintSet android:id="@+id/half_folded_single_constraints"> + + <Constraint + android:id="@+id/pattern_top_guideline" + androidprv:layout_constraintGuide_percent= + "@dimen/motion_layout_half_fold_bouncer_height_ratio"/> + + <Constraint + android:id="@+id/keyguard_selector_fade_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="0dp" + android:layout_marginTop="@dimen/keyguard_eca_top_margin" + android:orientation="vertical" + androidprv:layout_constraintBottom_toBottomOf="parent" + androidprv:layout_constraintTop_toBottomOf="@+id/flow1"/> + + </ConstraintSet> + <ConstraintSet android:id="@+id/split_constraints"> <Constraint diff --git a/packages/SystemUI/res-keyguard/xml/keyguard_pin_scene.xml b/packages/SystemUI/res-keyguard/xml/keyguard_pin_scene.xml index 2a1270c80b75..cc498f4a7ab3 100644 --- a/packages/SystemUI/res-keyguard/xml/keyguard_pin_scene.xml +++ b/packages/SystemUI/res-keyguard/xml/keyguard_pin_scene.xml @@ -26,11 +26,35 @@ motion:constraintSetStart="@id/single_constraints" motion:constraintSetEnd="@+id/split_constraints" motion:duration="0" - motion:autoTransition="none"/> + motion:autoTransition="none" /> + + <Transition + motion:constraintSetStart="@id/single_constraints" + motion:constraintSetEnd="@+id/half_folded_single_constraints" + motion:duration="@integer/material_motion_duration_short_1" /> <!-- No changes to default layout --> <ConstraintSet android:id="@+id/single_constraints"/> + <ConstraintSet android:id="@+id/half_folded_single_constraints"> + + <Constraint + android:id="@+id/pin_pad_top_guideline" + androidprv:layout_constraintGuide_percent= + "@dimen/motion_layout_half_fold_bouncer_height_ratio"/> + + <Constraint + android:id="@+id/keyguard_selector_fade_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="0dp" + android:layout_marginTop="@dimen/keyguard_eca_top_margin" + android:orientation="vertical" + androidprv:layout_constraintBottom_toBottomOf="parent" + androidprv:layout_constraintTop_toBottomOf="@+id/flow1"/> + + </ConstraintSet> + <ConstraintSet android:id="@+id/split_constraints"> <Constraint @@ -68,4 +92,5 @@ android:layout_marginTop="@dimen/keyguard_eca_top_margin" /> </ConstraintSet> + </MotionScene>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/bluetooth_device_item.xml b/packages/SystemUI/res/layout/bluetooth_device_item.xml new file mode 100644 index 000000000000..4265c4b14ee9 --- /dev/null +++ b/packages/SystemUI/res/layout/bluetooth_device_item.xml @@ -0,0 +1,68 @@ +<?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" + android:id="@+id/bluetooth_device_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:layout_marginBottom="4dp"> + + <LinearLayout + android:id="@+id/bluetooth_device" + style="@style/BluetoothTileDialog.Device" + android:layout_height="@dimen/bluetooth_dialog_device_height" + android:paddingEnd="24dp" + android:paddingStart="20dp" + android:baselineAligned="false"> + + <FrameLayout + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_gravity="center_vertical|start" + android:clickable="false"> + + <ImageView + android:id="@+id/bluetooth_device_icon" + android:contentDescription="@string/accessibility_bluetooth_device_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" /> + </FrameLayout> + + <LinearLayout + android:layout_width="0dp" + android:layout_height="@dimen/bluetooth_dialog_device_height" + android:paddingStart="20dp" + android:paddingEnd="24dp" + android:layout_marginEnd="30dp" + android:layout_weight="1" + android:clickable="false" + android:gravity="start|center_vertical" + android:orientation="vertical"> + + <TextView + android:id="@+id/bluetooth_device_name" + style="@style/BluetoothTileDialog.DeviceName" + android:textSize="14sp" /> + + <TextView + android:id="@+id/bluetooth_device_summary" + style="@style/BluetoothTileDialog.DeviceSummary" /> + </LinearLayout> + </LinearLayout> + +</LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml b/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml new file mode 100644 index 000000000000..9d14d0f36048 --- /dev/null +++ b/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml @@ -0,0 +1,168 @@ +<?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" + android:id="@+id/root" + android:layout_width="@dimen/large_dialog_width" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <LinearLayout + style="@style/Widget.SliceView.Panel" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/bluetooth_dialog_layout_margin" + android:layout_marginTop="24dp" + android:gravity="center_vertical|center_horizontal" + android:orientation="vertical"> + + <TextView + android:id="@+id/bluetooth_tile_dialog_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:ellipsize="end" + android:gravity="center_vertical|center_horizontal" + android:text="@string/quick_settings_bluetooth_label" + android:textAppearance="@style/TextAppearance.Dialog.Title" + android:textSize="24sp" /> + + <TextView + android:id="@+id/bluetooth_tile_dialog_subtitle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:ellipsize="end" + android:gravity="center_vertical|center_horizontal" + android:maxLines="1" + android:text="@string/quick_settings_bluetooth_tile_subtitle" + android:textAppearance="@style/TextAppearance.Dialog.Body.Message" /> + </LinearLayout> + + <LinearLayout + android:id="@+id/turn_on_bluetooth_layout" + style="@style/BluetoothTileDialog.Device" + android:layout_height="@dimen/bluetooth_dialog_device_height" + android:gravity="center" + android:clickable="false" + android:focusable="false" + android:baselineAligned="false"> + + <LinearLayout + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:gravity="start|center_vertical" + android:orientation="vertical" + android:clickable="false"> + <TextView + android:id="@+id/bluetooth_toggle_title" + android:text="@string/turn_on_bluetooth" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="start|center_vertical" + android:textAppearance="@style/TextAppearance.Dialog.Body.Message" + android:textSize="16sp"/> + </LinearLayout> + + <FrameLayout + android:layout_width="@dimen/settingslib_switch_track_width" + android:layout_height="48dp" + android:layout_marginTop="10dp" + android:layout_marginBottom="10dp"> + <Switch + android:id="@+id/bluetooth_toggle" + android:contentDescription="@string/turn_on_bluetooth" + android:switchMinWidth="@dimen/settingslib_switch_track_width" + android:layout_gravity="center" + android:layout_width="@dimen/settingslib_switch_track_width" + android:layout_height="match_parent" + android:track="@drawable/settingslib_track_selector" + android:thumb="@drawable/settingslib_thumb_selector" + android:theme="@style/MainSwitch.Settingslib"/> + </FrameLayout> + + </LinearLayout> + + <LinearLayout + android:id="@+id/body_layout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/device_list" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:nestedScrollingEnabled="false" + android:overScrollMode="never" + android:scrollbars="vertical" /> + + <LinearLayout + android:id="@+id/see_all_layout" + style="@style/BluetoothTileDialog.Device" + android:layout_height="64dp" + android:paddingStart="20dp" + android:visibility="gone"> + + <FrameLayout + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_gravity="center_vertical|start" + android:clickable="false"> + + <ImageView + android:id="@+id/arrow_forward" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:src="@drawable/ic_arrow_forward" + android:importantForAccessibility="no" /> + </FrameLayout> + + <FrameLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_marginStart="@dimen/bluetooth_dialog_layout_margin" + android:clickable="false" + android:orientation="vertical"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:gravity="start|center_vertical" + android:text="@string/see_all_bluetooth_devices" + android:textAppearance="@style/TextAppearance.Dialog.Body.Message" + android:textSize="14sp" /> + </FrameLayout> + </LinearLayout> + + <Button + android:id="@+id/done_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginStart="@dimen/dialog_side_padding" + android:layout_marginEnd="@dimen/dialog_side_padding" + android:layout_marginBottom="@dimen/dialog_bottom_padding" + android:text="@string/inline_done_button" + android:layout_gravity="end|center_vertical" + style="@style/Widget.Dialog.Button" + android:maxLines="1" + android:ellipsize="end" + android:clickable="true" + android:focusable="true"/> + </LinearLayout> +</LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/values-land/bools.xml b/packages/SystemUI/res/values-land/bools.xml index e24792dc7dd7..c112edcf22bf 100644 --- a/packages/SystemUI/res/values-land/bools.xml +++ b/packages/SystemUI/res/values-land/bools.xml @@ -19,4 +19,7 @@ <!-- Only use small clock on lockscreen. True here because only small clock used on small devices in landscape --> <bool name="force_small_clock_on_lockscreen">true</bool> + + <!-- True when small screen (<sw600dp) is landscape. --> + <bool name="is_small_screen_landscape">true</bool> </resources> diff --git a/packages/SystemUI/res/values-sw600dp-land/bools.xml b/packages/SystemUI/res/values-sw600dp-land/bools.xml index c4d77e894141..36926a2b4813 100644 --- a/packages/SystemUI/res/values-sw600dp-land/bools.xml +++ b/packages/SystemUI/res/values-sw600dp-land/bools.xml @@ -19,4 +19,7 @@ <!-- Only use small clock on lockscreen. False here because large clock is allowed on large devices in landscape --> <bool name="force_small_clock_on_lockscreen">false</bool> + + <!-- True when small screen (<sw600dp) is landscape. --> + <bool name="is_small_screen_landscape">false</bool> </resources> diff --git a/packages/SystemUI/res/values/bools.xml b/packages/SystemUI/res/values/bools.xml index 39566622a5f4..234c6df69d0b 100644 --- a/packages/SystemUI/res/values/bools.xml +++ b/packages/SystemUI/res/values/bools.xml @@ -63,4 +63,7 @@ <!-- Only use small clock on lockscreen. False here because large clock used by default, unless otherwise specified --> <bool name="force_small_clock_on_lockscreen">false</bool> + + <!-- True when small screen (<sw600dp) is landscape. --> + <bool name="is_small_screen_landscape">false</bool> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 7e9d3f59369b..88726af39c25 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1643,6 +1643,11 @@ <!-- Radius of switch track --> <dimen name="settingslib_switch_track_radius">35dp</dimen> + <!-- Bluetooth dialog related dimensions --> + <dimen name="bluetooth_dialog_layout_margin">16dp</dimen> + <!-- The height of the bluetooth device in bluetooth dialog. --> + <dimen name="bluetooth_dialog_device_height">72dp</dimen> + <!-- Height percentage of the parent container occupied by the communal view --> <item name="communal_source_height_percentage" format="float" type="dimen">0.80</item> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 29c9767866e9..5f3ddda0e8bf 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -459,6 +459,9 @@ <!-- Content description of the bluetooth icon when connected for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_bluetooth_connected">Bluetooth connected.</string> + + <!-- Content description of the bluetooth device icon. [CHAR LIMIT=NONE] --> + <string name="accessibility_bluetooth_device_icon">Bluetooth device icon</string> <!-- Content description of the bluetooth icon when connecting for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> <!-- Content description of the battery when battery state is unknown for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> @@ -621,6 +624,17 @@ <!-- QuickSettings: Bluetooth (Off) [CHAR LIMIT=NONE] --> <!-- QuickSettings: Bluetooth detail panel, text when there are no items [CHAR LIMIT=NONE] --> <string name="quick_settings_bluetooth_detail_empty_text">No paired devices available</string> + <!-- QuickSettings: Bluetooth dialog subtitle [CHAR LIMIT=NONE]--> + <string name="quick_settings_bluetooth_tile_subtitle">Tap to connect or disconnect</string> + <!-- QuickSettings: Bluetooth dialog see all devices [CHAR LIMIT=NONE]--> + <string name="see_all_bluetooth_devices">See all</string> + <!-- QuickSettings: Bluetooth dialog turn on Bluetooth [CHAR LIMIT=NONE]--> + <string name="turn_on_bluetooth">Use Bluetooth</string> + <!-- QuickSettings: Bluetooth dialog device connected default summary [CHAR LIMIT=NONE]--> + <string name="quick_settings_bluetooth_device_connected">Connected</string> + <!-- QuickSettings: Bluetooth dialog device saved default summary [CHAR LIMIT=NONE]--> + <string name="quick_settings_bluetooth_device_saved">Saved</string> + <!-- QuickSettings: Bluetooth secondary label for the battery level of a connected device [CHAR LIMIT=20]--> <string name="quick_settings_bluetooth_secondary_label_battery_level"><xliff:g id="battery_level_as_percentage">%s</xliff:g> battery</string> <!-- QuickSettings: Bluetooth secondary label for an audio device being connected [CHAR LIMIT=20]--> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 6991b964c504..3bd6ab0b32bc 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -15,7 +15,7 @@ --> <resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"> + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"> <style name="TextAppearance.StatusBar.Clock" parent="@*android:style/TextAppearance.StatusBar.Icon"> <item name="android:textSize">@dimen/status_bar_clock_size</item> @@ -54,10 +54,10 @@ </style> <style name="TextAppearance.StatusBar.Expanded.EmergencyCallsOnly" - parent="TextAppearance.StatusBar.Expanded.AboveDateTime" /> + parent="TextAppearance.StatusBar.Expanded.AboveDateTime" /> <style name="TextAppearance.StatusBar.Expanded.ChargingInfo" - parent="TextAppearance.StatusBar.Expanded.AboveDateTime" /> + parent="TextAppearance.StatusBar.Expanded.AboveDateTime" /> <style name="TextAppearance.StatusBar.Expanded.UserSwitcher"> <item name="android:textSize">@dimen/kg_user_switcher_text_size</item> @@ -645,7 +645,7 @@ </style> <style name="TextAppearance.HeadsUpStatusBarText" - parent="@*android:style/TextAppearance.DeviceDefault.Notification.Info"> + parent="@*android:style/TextAppearance.DeviceDefault.Notification.Info"> </style> <style name="TextAppearance.QSEdit" > @@ -699,7 +699,7 @@ </style> <style name="MediaPlayer.SessionAction" - parent="@android:style/Widget.Material.Button.Borderless.Small"> + parent="@android:style/Widget.Material.Button.Borderless.Small"> <item name="android:background">@drawable/qs_media_light_source</item> <item name="android:tint">?android:attr/textColorPrimary</item> <item name="android:paddingTop">12dp</item> @@ -929,12 +929,13 @@ <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item> </style> - <style name="Theme.SystemUI.Dialog.Control.DetailPanel" parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar"> - <item name="android:windowFullscreen">false</item> - <item name="android:windowIsFloating">false</item> - <item name="android:windowBackground">@color/controls_task_view_bg</item> - <item name="android:backgroundDimEnabled">false</item> - <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item> + <style name="Theme.SystemUI.Dialog.Control.DetailPanel" + parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar"> + <item name="android:windowFullscreen">false</item> + <item name="android:windowIsFloating">false</item> + <item name="android:windowBackground">@color/controls_task_view_bg</item> + <item name="android:backgroundDimEnabled">false</item> + <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item> </style> <style name="Control" /> @@ -1034,17 +1035,17 @@ <style name="Wallet" /> <style name="Wallet.TextAppearance"> - <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item> - <item name="android:textColor">?android:attr/textColorPrimary</item> - <item name="android:singleLine">true</item> - <item name="android:textSize">14sp</item> + <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item> + <item name="android:textColor">?android:attr/textColorPrimary</item> + <item name="android:singleLine">true</item> + <item name="android:textSize">14sp</item> </style> <style name="Wallet.Theme" parent="@android:style/Theme.DeviceDefault"> - <item name="android:colorBackground">@color/material_dynamic_neutral10</item> - <item name="android:itemBackground">@color/material_dynamic_neutral20</item> - <!-- Setting a placeholder will avoid using the SystemUI icon on the splash screen. --> - <item name="android:windowSplashScreenAnimatedIcon">@drawable/ic_blank</item> + <item name="android:colorBackground">@color/material_dynamic_neutral10</item> + <item name="android:itemBackground">@color/material_dynamic_neutral20</item> + <!-- Setting a placeholder will avoid using the SystemUI icon on the splash screen. --> + <item name="android:windowSplashScreenAnimatedIcon">@drawable/ic_blank</item> </style> <style name="Animation.InternetDialog" parent="@android:style/Animation.InputMethod"> @@ -1169,7 +1170,7 @@ </style> <style name="TrimmedHorizontalProgressBar" - parent="android:Widget.Material.ProgressBar.Horizontal"> + parent="android:Widget.Material.ProgressBar.Horizontal"> <item name="android:indeterminateDrawable"> @drawable/progress_indeterminate_horizontal_material_trimmed </item> @@ -1254,6 +1255,37 @@ <item name="android:textColor">?android:attr/textColorSecondary</item> </style> + <style name="BluetoothTileDialog"> + <item name="android:layout_width">wrap_content</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_gravity">center_vertical|start</item> + </style> + + <style name="BluetoothTileDialog.Device"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">88dp</item> + <item name="android:layout_gravity">center_vertical|start</item> + <item name="android:layout_marginStart">@dimen/bluetooth_dialog_layout_margin</item> + <item name="android:layout_marginEnd">@dimen/bluetooth_dialog_layout_margin</item> + <item name="android:paddingStart">22dp</item> + <item name="android:paddingEnd">22dp</item> + <item name="android:orientation">horizontal</item> + <item name="android:focusable">true</item> + <item name="android:clickable">true</item> + </style> + + <style name="BluetoothTileDialog.DeviceName"> + <item name="android:textSize">14sp</item> + <item name="android:textAppearance">@style/TextAppearance.Dialog.Title</item> + </style> + + <style name="BluetoothTileDialog.DeviceSummary"> + <item name="android:layout_marginEnd">7dp</item> + <item name="android:ellipsize">end</item> + <item name="android:maxLines">2</item> + <item name="android:textAppearance">@style/TextAppearance.Dialog.Body.Message</item> + </style> + <style name="BroadcastDialog"> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> @@ -1397,7 +1429,7 @@ </style> <style name="PermissionGrantButtonTop" - parent="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"> + parent="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"> <item name="android:layout_width">332dp</item> <item name="android:layout_height">56dp</item> <item name="android:layout_marginTop">2dp</item> @@ -1406,7 +1438,7 @@ </style> <style name="PermissionGrantButtonBottom" - parent="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"> + parent="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"> <item name="android:layout_width">332dp</item> <item name="android:layout_height">56dp</item> <item name="android:layout_marginTop">2dp</item> @@ -1465,14 +1497,14 @@ </style> <style name="TextAppearance.PrivacyDialog.Item.Title" - parent="@android:style/TextAppearance.DeviceDefault.Medium"> + parent="@android:style/TextAppearance.DeviceDefault.Medium"> <item name="android:textSize">14sp</item> <item name="android:lineHeight">20sp</item> <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item> </style> <style name="TextAppearance.PrivacyDialog.Item.Summary" - parent="@android:style/TextAppearance.DeviceDefault.Small"> + parent="@android:style/TextAppearance.DeviceDefault.Small"> <item name="android:textSize">14sp</item> <item name="android:lineHeight">20sp</item> <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item> @@ -1481,4 +1513,4 @@ <style name="Theme.PrivacyDialog" parent="@style/Theme.SystemUI.Dialog"> <item name="android:colorBackground">?androidprv:attr/materialColorSurfaceContainer</item> </style> -</resources> +</resources>
\ No newline at end of file diff --git a/packages/SystemUI/shared/Android.bp b/packages/SystemUI/shared/Android.bp index 0415341c16b6..9c368eb0a978 100644 --- a/packages/SystemUI/shared/Android.bp +++ b/packages/SystemUI/shared/Android.bp @@ -38,6 +38,7 @@ java_library { android_library { name: "SystemUISharedLib", + use_resource_processor: true, srcs: [ "src/**/*.java", "src/**/*.kt", diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java index 7719e95b9416..f9f2c63c0469 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java @@ -73,7 +73,7 @@ public class PluginInstance<T extends Plugin> implements PluginLifecycleManager mComponentName = componentName; mPluginFactory = pluginFactory; mPlugin = plugin; - mTag = TAG + mComponentName.toShortString() + mTag = TAG + "[" + mComponentName.getShortClassName() + "]" + '@' + Integer.toHexString(hashCode()); if (mPlugin != null) { diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierText.java b/packages/SystemUI/src/com/android/keyguard/CarrierText.java index 87a9b0f17a1c..ae282c7e14bd 100644 --- a/packages/SystemUI/src/com/android/keyguard/CarrierText.java +++ b/packages/SystemUI/src/com/android/keyguard/CarrierText.java @@ -24,7 +24,7 @@ import android.util.AttributeSet; import android.view.View; import android.widget.TextView; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.Locale; diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java index b52ee01bfa61..873c3d9105db 100644 --- a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java +++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java @@ -39,7 +39,7 @@ import androidx.annotation.VisibleForTesting; import com.android.keyguard.logging.CarrierTextManagerLogger; import com.android.settingslib.WirelessUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.keyguard.WakefulnessLifecycle; diff --git a/packages/SystemUI/src/com/android/keyguard/ConnectedDisplayKeyguardPresentation.kt b/packages/SystemUI/src/com/android/keyguard/ConnectedDisplayKeyguardPresentation.kt index 006974c9fa92..d677a15862de 100644 --- a/packages/SystemUI/src/com/android/keyguard/ConnectedDisplayKeyguardPresentation.kt +++ b/packages/SystemUI/src/com/android/keyguard/ConnectedDisplayKeyguardPresentation.kt @@ -25,7 +25,7 @@ import android.view.LayoutInflater import android.view.View import android.view.WindowManager import com.android.keyguard.dagger.KeyguardStatusViewComponent -import com.android.systemui.R +import com.android.systemui.res.R import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java b/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java index 225bebe57128..b2ffccc5616d 100644 --- a/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java +++ b/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java @@ -21,7 +21,7 @@ import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; -import com.android.systemui.R; +import com.android.systemui.res.R; public class EmergencyCarrierArea extends AlphaOptimizedLinearLayout { diff --git a/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt b/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt index 788a66dcf281..6a170a506fc4 100644 --- a/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt +++ b/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt @@ -20,10 +20,11 @@ import android.content.res.Resources import android.os.Build import android.os.PowerManager import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager +import com.android.systemui.keyguard.shared.model.WakeSleepReason import com.android.systemui.util.settings.GlobalSettings import java.io.PrintWriter import java.util.stream.Collectors @@ -38,6 +39,7 @@ constructor(@Main resources: Resources, globalSettings: GlobalSettings, dumpMana private val defaultTriggerFaceAuthOnWakeUpFrom: Set<Int> = resources.getIntArray(R.array.config_face_auth_wake_up_triggers).toSet() private val triggerFaceAuthOnWakeUpFrom: Set<Int> + private val wakeSleepReasonsToTriggerFaceAuth: Set<WakeSleepReason> init { triggerFaceAuthOnWakeUpFrom = @@ -52,6 +54,14 @@ constructor(@Main resources: Resources, globalSettings: GlobalSettings, dumpMana } else { defaultTriggerFaceAuthOnWakeUpFrom } + wakeSleepReasonsToTriggerFaceAuth = + triggerFaceAuthOnWakeUpFrom + .map { + val enumVal = WakeSleepReason.fromPowerManagerWakeReason(it) + assert(enumVal != WakeSleepReason.OTHER) + enumVal + } + .toSet() dumpManager.registerDumpable(this) } @@ -59,6 +69,9 @@ constructor(@Main resources: Resources, globalSettings: GlobalSettings, dumpMana return triggerFaceAuthOnWakeUpFrom.contains(pmWakeReason) } + fun shouldTriggerFaceAuthOnWakeUpFrom(wakeReason: WakeSleepReason): Boolean = + wakeSleepReasonsToTriggerFaceAuth.contains(wakeReason) + override fun dump(pw: PrintWriter, args: Array<out String>) { pw.println("FaceWakeUpTriggers:") for (pmWakeReason in triggerFaceAuthOnWakeUpFrom) { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java index c6d147108611..dfeb1f318081 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java @@ -25,7 +25,7 @@ import android.view.View; import androidx.annotation.CallSuper; import com.android.internal.widget.LockscreenCredential; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Base class for PIN and password unlock screens. diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java index e3f9de11bf98..167bd59d4e8d 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java @@ -34,7 +34,7 @@ import com.android.internal.widget.LockscreenCredential; import com.android.keyguard.EmergencyButtonController.EmergencyButtonCallback; import com.android.keyguard.KeyguardAbsKeyInputView.KeyDownListener; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.classifier.FalsingClassifier; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.flags.FeatureFlags; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java index a78c293a65ac..f7db48aefdaf 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java @@ -23,7 +23,7 @@ import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.TextView; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Replaces fancy colons with regular colons. Only works on TextViews. diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java index 1703b3034775..ba8e42752586 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java @@ -22,7 +22,7 @@ import androidx.core.content.res.ResourcesCompat; import com.android.app.animation.Interpolators; import com.android.keyguard.dagger.KeyguardStatusViewScope; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.log.LogBuffer; import com.android.systemui.log.core.LogLevel; import com.android.systemui.plugins.ClockController; @@ -112,6 +112,8 @@ public class KeyguardClockSwitch extends RelativeLayout { private int mWeatherClockSmartspaceTranslateY = 0; private int mDrawAlpha = 255; + private int mStatusBarHeight = 0; + /** * Maintain state so that a newly connected plugin can be initialized. */ @@ -154,6 +156,8 @@ public class KeyguardClockSwitch extends RelativeLayout { R.dimen.weather_clock_smartspace_translateX); mWeatherClockSmartspaceTranslateY = mContext.getResources().getDimensionPixelSize( R.dimen.weather_clock_smartspace_translateY); + mStatusBarHeight = mContext.getResources().getDimensionPixelSize( + R.dimen.status_bar_height); updateStatusArea(/* animate= */false); } @@ -299,6 +303,8 @@ public class KeyguardClockSwitch extends RelativeLayout { mStatusAreaAnim = null; View in, out; + // statusAreaYTranslation uses for the translation for both mStatusArea and mSmallClockFrame + // statusAreaClockTranslateY only uses for mStatusArea float statusAreaYTranslation, statusAreaClockScale = 1f; float statusAreaClockTranslateX = 0f, statusAreaClockTranslateY = 0f; float clockInYTranslation, clockOutYTranslation; @@ -313,10 +319,21 @@ public class KeyguardClockSwitch extends RelativeLayout { && mClock.getLargeClock().getConfig().getHasCustomWeatherDataDisplay()) { statusAreaClockScale = mWeatherClockSmartspaceScaling; statusAreaClockTranslateX = mWeatherClockSmartspaceTranslateX; - statusAreaClockTranslateY = mWeatherClockSmartspaceTranslateY - mSmartspaceTop; if (mSplitShadeCentered) { statusAreaClockTranslateX *= SMARTSPACE_TRANSLATION_CENTER_MULTIPLIER; } + + // On large weather clock, + // top padding for time is status bar height from top of the screen. + // On small one, + // it's screenOffsetYPadding (translationY for KeyguardStatusView), + // Cause smartspace is positioned according to the smallClockFrame + // we need to translate the difference between bottom of large clock and small clock + // Also, we need to counter offset the empty date weather view, mSmartspaceTop + // mWeatherClockSmartspaceTranslateY is only for Felix + statusAreaClockTranslateY = mStatusBarHeight - 0.6F * mSmallClockFrame.getHeight() + - mSmartspaceTop - screenOffsetYPadding + - statusAreaYTranslation + mWeatherClockSmartspaceTranslateY; } clockInYTranslation = 0; clockOutYTranslation = 0; // Small clock translation is handled with statusArea diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java index 11f95895338a..29414ea7f4c0 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java @@ -37,7 +37,7 @@ import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; @@ -527,7 +527,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS if (!mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) { NotificationIconContainer nic = (NotificationIconContainer) mView.findViewById( - com.android.systemui.R.id.left_aligned_notification_icon_container); + com.android.systemui.res.R.id.left_aligned_notification_icon_container); mNotificationIconAreaController.setupAodIcons(nic); } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java index 1c5a5758c2a4..9c015fea5cf7 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java @@ -39,7 +39,7 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.dagger.KeyguardStatusViewComponent; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.UiBackground; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java b/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java index ccbb0c5057cc..fc4e122d235b 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java @@ -32,7 +32,7 @@ import android.view.View; import android.view.WindowManager; import android.widget.Button; -import com.android.systemui.R; +import com.android.systemui.res.R; /*** * This button is used by the device with embedded SIM card to disable current carrier to unlock diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardInputView.java index 98f082f78a38..38c84954a76d 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputView.java @@ -28,7 +28,7 @@ import androidx.annotation.CallSuper; import androidx.annotation.Nullable; import com.android.internal.jank.InteractionJankMonitor; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * A Base class for all Keyguard password/pattern/pin related inputs. diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java index abd1563ecc43..29ce18c60833 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java @@ -29,7 +29,7 @@ import android.view.inputmethod.InputMethodManager; import com.android.internal.util.LatencyTracker; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor; import com.android.systemui.bouncer.ui.BouncerMessageView; import com.android.systemui.bouncer.ui.binder.BouncerMessageViewBinder; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java index fc66527998b9..7e44866f9473 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java @@ -27,7 +27,7 @@ import android.widget.TextView; import androidx.annotation.Nullable; import com.android.internal.policy.SystemBarUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; /*** * Manages a number of views inside of the given layout. See below for a list of widgets. diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java index 72b4ae568397..622b67f25da3 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java @@ -17,6 +17,7 @@ package com.android.keyguard; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; +import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_PIN_APPEAR; import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_PIN_DISAPPEAR; @@ -40,7 +41,7 @@ import androidx.constraintlayout.widget.ConstraintSet; import com.android.app.animation.Interpolators; import com.android.settingslib.animation.DisappearAnimationUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.policy.DevicePostureController.DevicePostureInt; /** @@ -52,6 +53,8 @@ public class KeyguardPINView extends KeyguardPinBasedInputView { private final DisappearAnimationUtils mDisappearAnimationUtils; private final DisappearAnimationUtils mDisappearAnimationUtilsLocked; @Nullable private MotionLayout mContainerMotionLayout; + // TODO (b/293252410) - usage of mContainerConstraintLayout should be removed + // when the flag is enabled/removed @Nullable private ConstraintLayout mContainerConstraintLayout; private int mDisappearYTranslation; private View[][] mViews; @@ -59,7 +62,7 @@ public class KeyguardPINView extends KeyguardPinBasedInputView { private int mYTransOffset; private View mBouncerMessageArea; private boolean mAlreadyUsingSplitBouncer = false; - private boolean mIsLockScreenLandscapeEnabled = false; + private boolean mIsSmallLockScreenLandscapeEnabled = false; @DevicePostureInt private int mLastDevicePosture = DEVICE_POSTURE_UNKNOWN; public static final long ANIMATION_DURATION = 650; @@ -87,12 +90,12 @@ public class KeyguardPINView extends KeyguardPinBasedInputView { /** Use motion layout (new bouncer implementation) if LOCKSCREEN_ENABLE_LANDSCAPE flag is * enabled, instead of constraint layout (old bouncer implementation) */ public void setIsLockScreenLandscapeEnabled(boolean isLockScreenLandscapeEnabled) { - mIsLockScreenLandscapeEnabled = isLockScreenLandscapeEnabled; + mIsSmallLockScreenLandscapeEnabled = isLockScreenLandscapeEnabled; findContainerLayout(); } private void findContainerLayout() { - if (mIsLockScreenLandscapeEnabled) { + if (mIsSmallLockScreenLandscapeEnabled) { mContainerMotionLayout = findViewById(R.id.pin_container); } else { mContainerConstraintLayout = findViewById(R.id.pin_container); @@ -109,7 +112,7 @@ public class KeyguardPINView extends KeyguardPinBasedInputView { if (mLastDevicePosture == posture) return; mLastDevicePosture = posture; - if (mIsLockScreenLandscapeEnabled) { + if (mIsSmallLockScreenLandscapeEnabled) { boolean useSplitBouncerAfterFold = mLastDevicePosture == DEVICE_POSTURE_CLOSED && getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE @@ -166,21 +169,45 @@ public class KeyguardPINView extends KeyguardPinBasedInputView { } } + if (mIsSmallLockScreenLandscapeEnabled) { + updateHalfFoldedConstraints(); + } else { + updateHalfFoldedGuideline(); + } + } + + private void updateHalfFoldedConstraints() { + // Update the constraints based on the device posture... + if (mAlreadyUsingSplitBouncer) return; + + boolean shouldCollapsePin = + mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED + && mContext.getResources().getConfiguration().orientation + == ORIENTATION_PORTRAIT; + + int expectedMotionLayoutState = shouldCollapsePin + ? R.id.half_folded_single_constraints + : R.id.single_constraints; + + transitionToMotionLayoutState(expectedMotionLayoutState); + } + + // TODO (b/293252410) - this method can be removed when the flag is enabled/removed + private void updateHalfFoldedGuideline() { // Update the guideline based on the device posture... float halfOpenPercentage = mContext.getResources().getFloat(R.dimen.half_opened_bouncer_height_ratio); - if (mIsLockScreenLandscapeEnabled) { - ConstraintSet cs = mContainerMotionLayout.getConstraintSet(R.id.single_constraints); - cs.setGuidelinePercent(R.id.pin_pad_top_guideline, - mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED ? halfOpenPercentage : 0.0f); - cs.applyTo(mContainerMotionLayout); - } else { - ConstraintSet cs = new ConstraintSet(); - cs.clone(mContainerConstraintLayout); - cs.setGuidelinePercent(R.id.pin_pad_top_guideline, - mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED ? halfOpenPercentage : 0.0f); - cs.applyTo(mContainerConstraintLayout); + ConstraintSet cs = new ConstraintSet(); + cs.clone(mContainerConstraintLayout); + cs.setGuidelinePercent(R.id.pin_pad_top_guideline, + mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED ? halfOpenPercentage : 0.0f); + cs.applyTo(mContainerConstraintLayout); + } + + private void transitionToMotionLayoutState(int state) { + if (mContainerMotionLayout.getCurrentState() != state) { + mContainerMotionLayout.transitionToState(state); } } @@ -189,12 +216,24 @@ public class KeyguardPINView extends KeyguardPinBasedInputView { * Only called when flag LANDSCAPE_ENABLE_LOCKSCREEN is enabled. */ @Override protected void updateConstraints(boolean useSplitBouncer) { + if (!mIsSmallLockScreenLandscapeEnabled) return; + mAlreadyUsingSplitBouncer = useSplitBouncer; + if (useSplitBouncer) { mContainerMotionLayout.jumpToState(R.id.split_constraints); mContainerMotionLayout.setMaxWidth(Integer.MAX_VALUE); } else { - mContainerMotionLayout.jumpToState(R.id.single_constraints); + boolean useHalfFoldedConstraints = + mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED + && mContext.getResources().getConfiguration().orientation + == ORIENTATION_PORTRAIT; + + if (useHalfFoldedConstraints) { + mContainerMotionLayout.jumpToState(R.id.half_folded_single_constraints); + } else { + mContainerMotionLayout.jumpToState(R.id.single_constraints); + } mContainerMotionLayout.setMaxWidth(getResources() .getDimensionPixelSize(R.dimen.keyguard_security_width)); } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java index 8d5fc0467e3b..51c0676876b9 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java @@ -56,7 +56,7 @@ import com.android.app.animation.Interpolators; import com.android.internal.widget.LockscreenCredential; import com.android.internal.widget.TextViewInputDisabler; import com.android.systemui.DejankUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.policy.DevicePostureController; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java index ab8cd531c307..959cf6fb8565 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java @@ -39,7 +39,7 @@ import android.widget.TextView.OnEditorActionListener; import com.android.internal.util.LatencyTracker; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.flags.FeatureFlags; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java index 56706b5a7135..5c206e95966b 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java @@ -16,6 +16,7 @@ package com.android.keyguard; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; +import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_CLOSED; import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_HALF_OPENED; @@ -42,7 +43,7 @@ import com.android.internal.widget.LockPatternView; import com.android.settingslib.animation.AppearAnimationCreator; import com.android.settingslib.animation.AppearAnimationUtils; import com.android.settingslib.animation.DisappearAnimationUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.policy.DevicePostureController.DevicePostureInt; public class KeyguardPatternView extends KeyguardInputView @@ -81,9 +82,11 @@ public class KeyguardPatternView extends KeyguardInputView BouncerKeyguardMessageArea mSecurityMessageDisplay; private View mEcaView; @Nullable private MotionLayout mContainerMotionLayout; + // TODO (b/293252410) - usage of mContainerConstraintLayout should be removed + // when the flag is enabled/removed @Nullable private ConstraintLayout mContainerConstraintLayout; private boolean mAlreadyUsingSplitBouncer = false; - private boolean mIsLockScreenLandscapeEnabled = false; + private boolean mIsSmallLockScreenLandscapeEnabled = false; @DevicePostureInt private int mLastDevicePosture = DEVICE_POSTURE_UNKNOWN; public KeyguardPatternView(Context context) { @@ -111,12 +114,12 @@ public class KeyguardPatternView extends KeyguardInputView * enabled, instead of constraint layout (old bouncer implementation) */ public void setIsLockScreenLandscapeEnabled(boolean isLockScreenLandscapeEnabled) { - mIsLockScreenLandscapeEnabled = isLockScreenLandscapeEnabled; + mIsSmallLockScreenLandscapeEnabled = isLockScreenLandscapeEnabled; findContainerLayout(); } private void findContainerLayout() { - if (mIsLockScreenLandscapeEnabled) { + if (mIsSmallLockScreenLandscapeEnabled) { mContainerMotionLayout = findViewById(R.id.pattern_container); } else { mContainerConstraintLayout = findViewById(R.id.pattern_container); @@ -132,7 +135,7 @@ public class KeyguardPatternView extends KeyguardInputView if (mLastDevicePosture == posture) return; mLastDevicePosture = posture; - if (mIsLockScreenLandscapeEnabled) { + if (mIsSmallLockScreenLandscapeEnabled) { boolean useSplitBouncerAfterFold = mLastDevicePosture == DEVICE_POSTURE_CLOSED && getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE @@ -147,21 +150,45 @@ public class KeyguardPatternView extends KeyguardInputView } private void updateMargins() { + if (mIsSmallLockScreenLandscapeEnabled) { + updateHalfFoldedConstraints(); + } else { + updateHalfFoldedGuideline(); + } + } + + private void updateHalfFoldedConstraints() { + // Update the constraints based on the device posture... + if (mAlreadyUsingSplitBouncer) return; + + boolean shouldCollapsePattern = + mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED + && mContext.getResources().getConfiguration().orientation + == ORIENTATION_PORTRAIT; + + int expectedMotionLayoutState = shouldCollapsePattern + ? R.id.half_folded_single_constraints + : R.id.single_constraints; + + transitionToMotionLayoutState(expectedMotionLayoutState); + } + + // TODO (b/293252410) - this method can be removed when the flag is enabled/removed + private void updateHalfFoldedGuideline() { // Update the guideline based on the device posture... float halfOpenPercentage = mContext.getResources().getFloat(R.dimen.half_opened_bouncer_height_ratio); - if (mIsLockScreenLandscapeEnabled) { - ConstraintSet cs = mContainerMotionLayout.getConstraintSet(R.id.single_constraints); - cs.setGuidelinePercent(R.id.pattern_top_guideline, - mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED ? halfOpenPercentage : 0.0f); - cs.applyTo(mContainerMotionLayout); - } else { - ConstraintSet cs = new ConstraintSet(); - cs.clone(mContainerConstraintLayout); - cs.setGuidelinePercent(R.id.pattern_top_guideline, - mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED ? halfOpenPercentage : 0.0f); - cs.applyTo(mContainerConstraintLayout); + ConstraintSet cs = new ConstraintSet(); + cs.clone(mContainerConstraintLayout); + cs.setGuidelinePercent(R.id.pattern_top_guideline, + mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED ? halfOpenPercentage : 0.0f); + cs.applyTo(mContainerConstraintLayout); + } + + private void transitionToMotionLayoutState(int state) { + if (mContainerMotionLayout.getCurrentState() != state) { + mContainerMotionLayout.transitionToState(state); } } @@ -172,12 +199,24 @@ public class KeyguardPatternView extends KeyguardInputView */ @Override protected void updateConstraints(boolean useSplitBouncer) { + if (!mIsSmallLockScreenLandscapeEnabled) return; + mAlreadyUsingSplitBouncer = useSplitBouncer; + if (useSplitBouncer) { mContainerMotionLayout.jumpToState(R.id.split_constraints); mContainerMotionLayout.setMaxWidth(Integer.MAX_VALUE); } else { - mContainerMotionLayout.jumpToState(R.id.single_constraints); + boolean useHalfFoldedConstraints = + mLastDevicePosture == DEVICE_POSTURE_HALF_OPENED + && mContext.getResources().getConfiguration().orientation + == ORIENTATION_PORTRAIT; + + if (useHalfFoldedConstraints) { + mContainerMotionLayout.jumpToState(R.id.half_folded_single_constraints); + } else { + mContainerMotionLayout.jumpToState(R.id.single_constraints); + } mContainerMotionLayout.setMaxWidth(getResources() .getDimensionPixelSize(R.dimen.biometric_auth_pattern_view_max_size)); } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java index 98312b11e9d6..714ba81fc664 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java @@ -36,7 +36,7 @@ import com.android.internal.widget.LockPatternView.Cell; import com.android.internal.widget.LockscreenCredential; import com.android.keyguard.EmergencyButtonController.EmergencyButtonCallback; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.classifier.FalsingClassifier; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.flags.FeatureFlags; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java index 38e5dc57d316..9d6d0332b96b 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java @@ -39,7 +39,7 @@ import androidx.annotation.CallSuper; import com.android.app.animation.Interpolators; import com.android.internal.widget.LockscreenCredential; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.ArrayList; import java.util.List; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java index 31cbdde3452d..aacf8662b2b8 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java @@ -25,7 +25,7 @@ import android.view.View.OnTouchListener; import com.android.internal.util.LatencyTracker; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.flags.FeatureFlags; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java index 0af803fc84fe..9a788688c9d1 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java @@ -23,7 +23,7 @@ import android.view.View; import com.android.internal.util.LatencyTracker; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index 3f3efe9c5ab1..f7a4d47be800 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -97,7 +97,7 @@ import com.android.keyguard.KeyguardSecurityModel.SecurityMode; import com.android.settingslib.Utils; import com.android.settingslib.drawable.CircleFramedDrawable; import com.android.systemui.Gefingerpoken; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.classifier.FalsingA11yDelegate; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.shade.TouchLogger; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java index e9dd08c67b99..625c1de0134d 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java @@ -68,7 +68,7 @@ import com.android.keyguard.KeyguardSecurityModel.SecurityMode; import com.android.keyguard.dagger.KeyguardBouncerScope; import com.android.settingslib.utils.ThreadUtils; import com.android.systemui.Gefingerpoken; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor; import com.android.systemui.biometrics.FaceAuthAccessibilityDelegate; import com.android.systemui.biometrics.SideFpsController; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java index 74f90063096e..44db01e3c99e 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java @@ -30,7 +30,7 @@ import android.view.ViewHierarchyEncoder; import android.widget.FrameLayout; import android.widget.ViewFlipper; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Subclass of the current view flipper that allows us to overload dispatchTouchEvent() so diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java index f18504c28609..ec2999ffcfe1 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java @@ -30,7 +30,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.KeyguardInputViewController.Factory; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; import com.android.keyguard.dagger.KeyguardBouncerScope; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.util.ViewController; @@ -139,12 +139,12 @@ public class KeyguardSecurityViewFlipperController onViewInflatedListener.onViewInflated(childController); // Single bouncer constrains are default - if (mFeatureFlags.isEnabled(LOCKSCREEN_ENABLE_LANDSCAPE) - && - getResources().getBoolean(R.bool.update_bouncer_constraints)) { + if (mFeatureFlags.isEnabled(LOCKSCREEN_ENABLE_LANDSCAPE)) { boolean useSplitBouncer = - getResources().getConfiguration().orientation + getResources().getBoolean(R.bool.update_bouncer_constraints) + && getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE; + updateConstraints(useSplitBouncer); } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewTransition.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewTransition.kt index e1c060f0e8cb..db191c6cb8f3 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewTransition.kt +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewTransition.kt @@ -28,7 +28,7 @@ import android.view.ViewGroup import android.view.animation.AnimationUtils import com.android.app.animation.Interpolators import com.android.internal.R.interpolator.fast_out_extra_slow_in -import com.android.systemui.R +import com.android.systemui.res.R /** Animates constraint layout changes for the security view. */ class KeyguardSecurityViewTransition : Transition() { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt index 7c8d91fdaba8..392abf2aa82c 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt @@ -21,7 +21,7 @@ import android.util.AttributeSet import android.widget.ImageView import androidx.core.graphics.drawable.DrawableCompat import com.android.settingslib.Utils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.EMERGENCY_BUTTON abstract class KeyguardSimInputView(context: Context, attrs: AttributeSet) : diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java index 9d170150a709..bacd0c2d1e34 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java @@ -20,7 +20,7 @@ import android.content.Context; import android.content.res.Configuration; import android.util.AttributeSet; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Displays a PIN pad for unlocking. diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java index 1fc88ab16e83..8717a532b43d 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java @@ -39,7 +39,7 @@ import android.widget.ImageView; import com.android.internal.util.LatencyTracker; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.flags.FeatureFlags; @@ -144,7 +144,7 @@ public class KeyguardSimPinViewController mView.resetPasswordText(true /* animate */, true /* announce */); getKeyguardSecurityCallback().userActivity(); mMessageAreaController.setMessage( - com.android.systemui.R.string.kg_invalid_sim_pin_hint); + com.android.systemui.res.R.string.kg_invalid_sim_pin_hint); return; } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java index 5f45fe31a779..151ca8ade506 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java @@ -22,7 +22,7 @@ import android.content.Context; import android.util.AttributeSet; import android.util.Log; -import com.android.systemui.R; +import com.android.systemui.res.R; /** diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java index 49d786fdddd8..248b7afd7535 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java @@ -36,7 +36,7 @@ import android.widget.ImageView; import com.android.internal.util.LatencyTracker; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.flags.FeatureFlags; @@ -139,25 +139,25 @@ public class KeyguardSimPukViewController if (mState == ENTER_PUK) { if (checkPuk()) { mState = ENTER_PIN; - msg = com.android.systemui.R.string.kg_puk_enter_pin_hint; + msg = com.android.systemui.res.R.string.kg_puk_enter_pin_hint; } else { - msg = com.android.systemui.R.string.kg_invalid_sim_puk_hint; + msg = com.android.systemui.res.R.string.kg_invalid_sim_puk_hint; } } else if (mState == ENTER_PIN) { if (checkPin()) { mState = CONFIRM_PIN; - msg = com.android.systemui.R.string.kg_enter_confirm_pin_hint; + msg = com.android.systemui.res.R.string.kg_enter_confirm_pin_hint; } else { - msg = com.android.systemui.R.string.kg_invalid_sim_pin_hint; + msg = com.android.systemui.res.R.string.kg_invalid_sim_pin_hint; } } else if (mState == CONFIRM_PIN) { if (confirmPin()) { mState = DONE; - msg = com.android.systemui.R.string.keyguard_sim_unlock_progress_dialog_message; + msg = com.android.systemui.res.R.string.keyguard_sim_unlock_progress_dialog_message; updateSim(); } else { mState = ENTER_PIN; // try again? - msg = com.android.systemui.R.string.kg_invalid_confirm_pin_hint; + msg = com.android.systemui.res.R.string.kg_invalid_confirm_pin_hint; } } mView.resetPasswordText(true /* animate */, true /* announce */); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java index b4f124aa598a..7b5325d4eaa6 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java @@ -48,7 +48,7 @@ import com.android.app.animation.Interpolators; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.ColorUtils; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.util.wakelock.KeepAwakeAnimationListener; import java.io.PrintWriter; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusAreaView.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusAreaView.kt index e7da2b977379..11b1a7d00056 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusAreaView.kt +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusAreaView.kt @@ -4,7 +4,7 @@ import android.content.Context import android.util.AttributeSet import android.util.FloatProperty import android.widget.LinearLayout -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.statusbar.notification.AnimatableProperty class KeyguardStatusAreaView( diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java index 5774e42d2425..d8486029a903 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java @@ -29,7 +29,7 @@ import android.view.ViewGroup; import android.view.ViewPropertyAnimator; import android.widget.GridLayout; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.shade.TouchLogger; import com.android.systemui.statusbar.CrossFadeHelper; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java index c314586e4a21..8d0d299e56c2 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java @@ -49,7 +49,7 @@ import com.android.internal.jank.InteractionJankMonitor; import com.android.keyguard.KeyguardClockSwitch.ClockSize; import com.android.keyguard.logging.KeyguardLogger; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt index ca64ae059093..7170be6124d2 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt @@ -18,7 +18,7 @@ package com.android.keyguard import android.content.Context import android.view.ViewGroup -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.StatusBarState.KEYGUARD import com.android.systemui.shared.animation.UnfoldConstantTranslateAnimator diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index abab5e682478..51308b86a532 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -153,7 +153,7 @@ import com.android.settingslib.Utils; import com.android.settingslib.WirelessUtils; import com.android.settingslib.fuelgauge.BatteryStatus; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.biometrics.AuthController; import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider; import com.android.systemui.broadcast.BroadcastDispatcher; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherAnchor.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherAnchor.kt index 5f3ba72d445b..04e8a970c50b 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherAnchor.kt +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherAnchor.kt @@ -20,7 +20,7 @@ import android.util.AttributeSet import android.view.accessibility.AccessibilityNodeInfo import android.widget.LinearLayout import androidx.core.view.accessibility.AccessibilityNodeInfoCompat -import com.android.systemui.R +import com.android.systemui.res.R /** * Custom View for the multi-user switcher pull-down menu anchor diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherPopupMenu.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherPopupMenu.java index b793fd22aed1..f746459bf8dd 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherPopupMenu.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherPopupMenu.java @@ -25,7 +25,7 @@ import android.view.View; import android.widget.ListPopupWindow; import android.widget.ListView; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.FalsingManager; /** diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconView.java b/packages/SystemUI/src/com/android/keyguard/LockIconView.java index c52288190a7c..1d2d77f16b75 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconView.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconView.java @@ -37,7 +37,7 @@ import androidx.annotation.NonNull; import com.android.internal.graphics.ColorUtils; import com.android.settingslib.Utils; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.io.PrintWriter; diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java index 214b1228b87a..165c4bb018d3 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java @@ -56,7 +56,7 @@ import androidx.annotation.VisibleForTesting; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.biometrics.AuthController; import com.android.systemui.biometrics.AuthRippleController; import com.android.systemui.biometrics.UdfpsController; diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java index 5c2f3b368f96..76f93e18dda4 100644 --- a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java +++ b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java @@ -30,7 +30,7 @@ import android.view.MotionEvent; import androidx.annotation.Nullable; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Similar to the {@link NumPadKey}, but displays an image. diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java index 466d15474679..871d57da9b0d 100644 --- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java +++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java @@ -36,7 +36,7 @@ import android.widget.TextView; import androidx.annotation.Nullable; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Viewgroup for the bouncer numpad button, specifically for digits. diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java index 9a2ffe0ec68c..85f8b4824c99 100644 --- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java +++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java @@ -37,7 +37,7 @@ import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.ArrayList; diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeAdapter.kt b/packages/SystemUI/src/com/android/keyguard/PinShapeAdapter.kt index 4496dc311e92..8d1bbb29267b 100644 --- a/packages/SystemUI/src/com/android/keyguard/PinShapeAdapter.kt +++ b/packages/SystemUI/src/com/android/keyguard/PinShapeAdapter.kt @@ -17,7 +17,7 @@ package com.android.keyguard import android.content.Context -import com.android.systemui.R +import com.android.systemui.res.R import kotlin.random.Random class PinShapeAdapter { diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java b/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java index 7c129b4c8905..5e9eed98f97b 100644 --- a/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java +++ b/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java @@ -29,7 +29,7 @@ import android.widget.LinearLayout; import androidx.core.graphics.drawable.DrawableCompat; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * This class contains implementation for methods that will be used when user has set a diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java index 5f33ef91ed9c..8c987e3c3143 100644 --- a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java +++ b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java @@ -40,7 +40,7 @@ import androidx.core.graphics.drawable.DrawableCompat; import com.android.app.animation.Interpolators; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * This class contains implementation for methods that will be used when user has set a diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java index 83fc2789dc91..9716d98cf5e0 100644 --- a/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java +++ b/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java @@ -20,7 +20,7 @@ import android.content.Context; import android.content.res.Resources; import android.view.LayoutInflater; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Application; import com.android.systemui.dagger.qualifiers.Background; diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java index 893239ba7ecb..afea224f31eb 100644 --- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java +++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java @@ -25,7 +25,7 @@ import android.view.ViewGroup; import com.android.keyguard.KeyguardSecurityContainer; import com.android.keyguard.KeyguardSecurityViewFlipper; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.biometrics.SideFpsController; import com.android.systemui.dagger.qualifiers.RootView; import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor; diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java index 87627698597f..37600da3a4de 100644 --- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java +++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java @@ -17,7 +17,7 @@ package com.android.keyguard.dagger; import com.android.keyguard.CarrierText; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.battery.BatteryMeterView; import com.android.systemui.statusbar.phone.KeyguardStatusBarView; import com.android.systemui.statusbar.phone.StatusBarLocation; diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewModule.java index b8841eda1de4..7575f0e80d1c 100644 --- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewModule.java +++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewModule.java @@ -19,7 +19,7 @@ package com.android.keyguard.dagger; import com.android.keyguard.KeyguardClockSwitch; import com.android.keyguard.KeyguardSliceView; import com.android.keyguard.KeyguardStatusView; -import com.android.systemui.R; +import com.android.systemui.res.R; import dagger.Module; import dagger.Provides; diff --git a/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java b/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java index 4c16d41c8672..72fa2b0bcacb 100644 --- a/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java +++ b/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java @@ -24,6 +24,8 @@ import android.view.LayoutInflater; import android.view.View; import android.widget.FrameLayout; +import com.android.systemui.res.R; + import java.util.ArrayList; import java.util.List; import java.util.Set; diff --git a/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt b/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt index eee705dea277..2d2ebe99d651 100644 --- a/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt +++ b/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt @@ -22,8 +22,8 @@ import android.graphics.Rect import android.graphics.RectF import android.hardware.camera2.CameraManager import android.util.PathParser +import com.android.systemui.res.R import java.util.concurrent.Executor - import kotlin.math.roundToInt /** diff --git a/packages/SystemUI/src/com/android/systemui/DessertCaseView.java b/packages/SystemUI/src/com/android/systemui/DessertCaseView.java index 5e963798b9a2..2010a706fad2 100644 --- a/packages/SystemUI/src/com/android/systemui/DessertCaseView.java +++ b/packages/SystemUI/src/com/android/systemui/DessertCaseView.java @@ -43,6 +43,8 @@ import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; import android.widget.ImageView; +import com.android.systemui.res.R; + import java.util.HashSet; import java.util.Set; diff --git a/packages/SystemUI/src/com/android/systemui/DualToneHandler.kt b/packages/SystemUI/src/com/android/systemui/DualToneHandler.kt index 2b8d3e046ffa..22d0bc9e4b5c 100644 --- a/packages/SystemUI/src/com/android/systemui/DualToneHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/DualToneHandler.kt @@ -20,6 +20,7 @@ import android.animation.ArgbEvaluator import android.content.Context import android.view.ContextThemeWrapper import com.android.settingslib.Utils +import com.android.systemui.res.R /** * A color blender for `Theme.SystemUI` and other themes. diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java index 7c377d2841e3..086713f49508 100644 --- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java +++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java @@ -36,6 +36,8 @@ import androidx.core.animation.Animator; import androidx.core.animation.AnimatorListenerAdapter; import androidx.core.animation.ObjectAnimator; +import com.android.systemui.res.R; + import com.android.internal.annotations.VisibleForTesting; import com.android.internal.jank.InteractionJankMonitor; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java b/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java index e6d5719e6fbd..ab431d03760e 100644 --- a/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java +++ b/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java @@ -37,6 +37,7 @@ import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; +import com.android.systemui.res.R; import com.android.internal.app.AlertActivity; import com.android.internal.app.AlertController; import com.android.internal.logging.MetricsLogger; diff --git a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java index 104b71f29219..4541384aaa37 100644 --- a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java +++ b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java @@ -24,6 +24,7 @@ import android.os.UserHandle; import androidx.annotation.NonNull; +import com.android.systemui.res.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.UiEventLogger; import com.android.systemui.broadcast.BroadcastDispatcher; diff --git a/packages/SystemUI/src/com/android/systemui/GuestSessionNotification.java b/packages/SystemUI/src/com/android/systemui/GuestSessionNotification.java index 7a6b1c372a24..161cb43e95ba 100644 --- a/packages/SystemUI/src/com/android/systemui/GuestSessionNotification.java +++ b/packages/SystemUI/src/com/android/systemui/GuestSessionNotification.java @@ -26,6 +26,7 @@ import android.os.Bundle; import android.os.UserHandle; import android.provider.Settings; +import com.android.systemui.res.R; import com.android.internal.messages.nano.SystemMessageProto; import com.android.systemui.util.NotificationChannels; diff --git a/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java b/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java index d631cf3551d9..0643d0243517 100644 --- a/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java @@ -23,6 +23,7 @@ import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; +import com.android.systemui.res.R; import com.android.settingslib.Utils; public class HardwareBgDrawable extends LayerDrawable { diff --git a/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java b/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java index 1bb03291996d..b9e412c5d00e 100644 --- a/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java +++ b/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java @@ -20,6 +20,7 @@ import android.util.AttributeSet; import android.util.Log; import android.view.View; +import com.android.systemui.res.R; import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.PluginManager; import com.android.systemui.plugins.ViewProvider; diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index ff395da54d18..4af2c740ddc9 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -84,6 +84,7 @@ import com.android.systemui.decor.RoundedCornerResDelegateImpl; import com.android.systemui.decor.ScreenDecorCommand; import com.android.systemui.log.ScreenDecorationsLogger; import com.android.systemui.qs.SettingObserver; +import com.android.systemui.res.R; import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.commandline.CommandRegistry; @@ -334,7 +335,7 @@ public class ScreenDecorations implements CoreStartable, Dumpable { mThreadFactory = threadFactory; mDotFactory = dotFactory; mFaceScanningFactory = faceScanningFactory; - mFaceScanningViewId = com.android.systemui.R.id.face_scanning_anim; + mFaceScanningViewId = com.android.systemui.res.R.id.face_scanning_anim; mLogger = logger; mAuthController = authController; } @@ -1195,7 +1196,7 @@ public class ScreenDecorations implements CoreStartable, Dumpable { if (faceScanningOverlay != null) { faceScanningOverlay.setFaceScanningAnimColor( Utils.getColorAttrDefaultColor(faceScanningOverlay.getContext(), - com.android.systemui.R.attr.wallpaperTextColorAccent)); + com.android.systemui.res.R.attr.wallpaperTextColorAccent)); } } diff --git a/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java b/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java index 6f99a24b7312..67012cb0584f 100644 --- a/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java +++ b/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java @@ -35,6 +35,8 @@ import android.util.Log; import android.widget.CheckBox; import android.widget.TextView; +import com.android.systemui.res.R; + public class SlicePermissionActivity extends Activity implements OnClickListener, OnDismissListener { diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java index 3ca74acf2d66..954129ef78c8 100644 --- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java @@ -51,6 +51,7 @@ import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.wm.shell.animation.FlingAnimationUtils; import com.android.wm.shell.animation.PhysicsAnimator; diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index 38298cfac49a..bf445177f3f8 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -37,6 +37,7 @@ import android.view.SurfaceControl; import android.view.ThreadedRenderer; import android.view.View; +import com.android.systemui.res.R; import com.android.internal.protolog.common.ProtoLog; import com.android.systemui.dagger.GlobalRootComponent; import com.android.systemui.dagger.SysUIComponent; diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java b/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java index 2b468cf7c16b..872b00518d62 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java @@ -22,6 +22,7 @@ import android.os.Handler; import android.os.HandlerThread; import android.util.Log; +import com.android.systemui.res.R; import com.android.systemui.dagger.GlobalRootComponent; import com.android.systemui.dagger.SysUIComponent; import com.android.systemui.dagger.WMComponent; diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java index 6cf9eff1da2f..76c228252484 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java @@ -33,6 +33,7 @@ import com.android.systemui.dump.DumpHandler; import com.android.systemui.dump.LogBufferEulogizer; import com.android.systemui.dump.LogBufferFreezer; import com.android.systemui.dump.SystemUIAuxiliaryDumpService; +import com.android.systemui.res.R; import com.android.systemui.shared.system.UncaughtExceptionPreHandlerManager; import com.android.systemui.statusbar.policy.BatteryStateNotifier; diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java index f817c3cb90a7..84f1395051eb 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java @@ -46,7 +46,7 @@ import android.widget.ImageView; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.Collections; diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java index 859e183d39fe..ee7781d8af20 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java @@ -73,7 +73,7 @@ public class MagnificationSettingsController implements ComponentCallbacks { context.getDisplay(), WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, null); - mContext.setTheme(com.android.systemui.R.style.Theme_SystemUI); + mContext.setTheme(com.android.systemui.res.R.style.Theme_SystemUI); mDisplayId = mContext.getDisplayId(); mConfiguration = new Configuration(mContext.getResources().getConfiguration()); mSettingsControllerCallback = settingsControllerCallback; diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MirrorWindowControl.java b/packages/SystemUI/src/com/android/systemui/accessibility/MirrorWindowControl.java index 6de3e930cfa3..443441f1ef48 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/MirrorWindowControl.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/MirrorWindowControl.java @@ -31,7 +31,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Contains a movable control UI to manipulate mirrored window's position, size and scale. The diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SimpleMirrorWindowControl.java b/packages/SystemUI/src/com/android/systemui/accessibility/SimpleMirrorWindowControl.java index ed6fbecd19fe..bc469eed7359 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/SimpleMirrorWindowControl.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/SimpleMirrorWindowControl.java @@ -28,7 +28,7 @@ import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * A basic control to move the mirror window. diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java index 69041d32f04a..59b85d112753 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java @@ -102,7 +102,7 @@ public class WindowMagnification implements CoreStartable, CommandQueue.Callback protected WindowMagnificationController createInstance(Display display) { final Context windowContext = mContext.createWindowContext(display, TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, /* options */ null); - windowContext.setTheme(com.android.systemui.R.style.Theme_SystemUI); + windowContext.setTheme(com.android.systemui.res.R.style.Theme_SystemUI); return new WindowMagnificationController( windowContext, mHandler, @@ -141,7 +141,7 @@ public class WindowMagnification implements CoreStartable, CommandQueue.Callback protected MagnificationSettingsController createInstance(Display display) { final Context windowContext = mContext.createWindowContext(display, TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, /* options */ null); - windowContext.setTheme(com.android.systemui.R.style.Theme_SystemUI); + windowContext.setTheme(com.android.systemui.res.R.style.Theme_SystemUI); return new MagnificationSettingsController( windowContext, new SfVsyncFrameCallbackProvider(), diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java index d061c8ef6e12..9dd1454d2528 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java @@ -30,7 +30,7 @@ import android.view.accessibility.IRemoteMagnificationAnimationCallback; import android.view.animation.AccelerateInterpolator; import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java index 773241ec57e3..c095aa8349b3 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java @@ -80,7 +80,7 @@ import androidx.core.math.MathUtils; import com.android.internal.accessibility.common.MagnificationConstants; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.model.SysUiState; import com.android.systemui.util.settings.SecureSettings; diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java index 7c11311373ab..c03e403b754b 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java @@ -59,7 +59,7 @@ import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView; import com.android.systemui.util.settings.SecureSettings; diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java index ecfe4caa5984..83ad3c23fda3 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java @@ -29,7 +29,7 @@ import androidx.recyclerview.widget.RecyclerView.Adapter; import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType; import com.android.internal.accessibility.dialog.AccessibilityTarget; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.accessibility.floatingmenu.AccessibilityTargetAdapter.ViewHolder; import java.lang.annotation.Retention; diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipView.java index 5ec024ebc917..1ff9eb4ef503 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipView.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipView.java @@ -41,7 +41,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.recents.TriangleShape; /** diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegate.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegate.java index 14517ba5bdb4..9c22a7738ad6 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegate.java @@ -27,7 +27,7 @@ import androidx.annotation.NonNull; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * An accessibility item delegate for the individual items of the list view in the diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuMessageView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuMessageView.java index 3e2b06b39bad..bf121fb8c752 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuMessageView.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuMessageView.java @@ -37,7 +37,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearance.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearance.java index df2c05d9f53c..89ce06514e1c 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearance.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearance.java @@ -35,7 +35,7 @@ import android.view.WindowMetrics; import androidx.annotation.DimenRes; import com.android.systemui.Flags; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java index 6ba40d6944e3..b6e8997c31e7 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java @@ -59,7 +59,7 @@ import androidx.lifecycle.Observer; import com.android.internal.accessibility.dialog.AccessibilityTarget; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.util.settings.SecureSettings; import com.android.wm.shell.bubbles.DismissViewUtils; import com.android.wm.shell.common.bubbles.DismissView; diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt b/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt index 0ef256d41157..2d2f29564263 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt @@ -29,7 +29,7 @@ import android.widget.SeekBar import android.widget.TextView import androidx.annotation.MainThread import androidx.annotation.WorkerThread -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView.OnSeekBarWithIconButtonsChangeListener import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView.OnSeekBarWithIconButtonsChangeListener.ControlUnitType diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java index d49197557dc4..a5c5beccefd9 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java @@ -33,7 +33,7 @@ import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; import com.android.app.animation.Interpolators; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Visually discloses that contextual data was provided to an assistant. diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java index f26404cad02b..0e339dd68b4f 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java @@ -29,7 +29,7 @@ import com.android.internal.app.IVoiceInteractionSessionListener; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.assist.ui.DefaultUiController; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; @@ -309,8 +309,14 @@ public class AssistManager { } int invocationType = args.getInt(INVOCATION_TYPE_KEY); - return mAssistOverrideInvocationTypes != null && Arrays.stream( - mAssistOverrideInvocationTypes).anyMatch(override -> override == invocationType); + return shouldOverrideAssist(invocationType); + } + + /** @return true if the invocation type should be handled by OverviewProxy instead of SysUI. */ + public boolean shouldOverrideAssist(int invocationType) { + return mAssistOverrideInvocationTypes != null + && Arrays.stream(mAssistOverrideInvocationTypes).anyMatch( + override -> override == invocationType); } /** diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java index 1c980993f32a..1ee06cc8d757 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java +++ b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java @@ -35,7 +35,7 @@ import android.widget.FrameLayout; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.assist.AssistLogger; import com.android.systemui.assist.AssistManager; import com.android.systemui.assist.AssistantSessionEvent; diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java b/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java index 9b441ad1d75c..5765f3a57c14 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java +++ b/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java @@ -21,7 +21,7 @@ import android.util.DisplayMetrics; import android.view.Display; import android.view.Surface; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Utility class for determining screen and corner dimensions. diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java index ac39ed501811..4d89231f0b15 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java +++ b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java @@ -32,7 +32,7 @@ import android.view.View; import com.android.settingslib.Utils; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.navigationbar.NavigationBarController; import com.android.systemui.navigationbar.NavigationBar; import com.android.systemui.navigationbar.NavigationBarTransitions; diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java b/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java index 523378e97c94..fa9676b04f84 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java +++ b/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java @@ -23,7 +23,7 @@ import android.graphics.RectF; import android.util.Log; import android.util.PathParser; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Parses a path describing rounded corners from a string. diff --git a/packages/SystemUI/src/com/android/systemui/battery/AccessorizedBatteryDrawable.kt b/packages/SystemUI/src/com/android/systemui/battery/AccessorizedBatteryDrawable.kt index b81d7fced5e4..b8de117fcbe9 100644 --- a/packages/SystemUI/src/com/android/systemui/battery/AccessorizedBatteryDrawable.kt +++ b/packages/SystemUI/src/com/android/systemui/battery/AccessorizedBatteryDrawable.kt @@ -28,7 +28,7 @@ import android.graphics.Rect import android.graphics.drawable.DrawableWrapper import android.util.PathParser import com.android.settingslib.graph.ThemedBatteryDrawable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.battery.BatterySpecs.BATTERY_HEIGHT import com.android.systemui.battery.BatterySpecs.BATTERY_HEIGHT_WITH_SHIELD import com.android.systemui.battery.BatterySpecs.BATTERY_WIDTH diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java index 6ca1c3de0b63..f25f994bf8f3 100644 --- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java +++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java @@ -47,7 +47,7 @@ import androidx.annotation.VisibleForTesting; import com.android.app.animation.Interpolators; import com.android.systemui.DualToneHandler; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.policy.BatteryController; diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java index b6f47e9c907e..5b840b52bde6 100644 --- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java +++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java @@ -30,7 +30,7 @@ import android.view.View; import androidx.annotation.NonNull; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.flags.FeatureFlags; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceIconController.kt index ea8f5d376ba7..3f2da5e144c5 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceIconController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceIconController.kt @@ -19,7 +19,7 @@ import android.content.Context import android.graphics.drawable.Drawable import android.util.Log import com.airbnb.lottie.LottieAnimationView -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.ui.binder.Spaghetti.BiometricState private const val TAG = "AuthBiometricFaceIconController" diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt index fb22c6b07db4..09eabf2aa430 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt @@ -19,7 +19,7 @@ package com.android.systemui.biometrics import android.annotation.RawRes import android.content.Context import com.airbnb.lottie.LottieAnimationView -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.ui.binder.Spaghetti.BiometricState import com.android.systemui.biometrics.ui.binder.Spaghetti.BiometricState.STATE_AUTHENTICATED import com.android.systemui.biometrics.ui.binder.Spaghetti.BiometricState.STATE_ERROR diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt index 683541bd1b5b..0ad3848299f9 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt @@ -26,7 +26,7 @@ import android.view.View import androidx.annotation.VisibleForTesting import com.airbnb.lottie.LottieAnimationView import com.android.settingslib.widget.LottieColorUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.ui.binder.Spaghetti.BiometricState import com.android.systemui.biometrics.ui.binder.Spaghetti.BiometricState.STATE_AUTHENTICATED import com.android.systemui.biometrics.ui.binder.Spaghetti.BiometricState.STATE_AUTHENTICATING diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java index c7d7fe32be31..85122baa3fec 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java @@ -63,7 +63,7 @@ import com.android.app.animation.Interpolators; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.widget.LockPatternUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.biometrics.AuthController.ScaleFactorProvider; import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor; import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java index b752c3b80cae..a64e862000fc 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java @@ -627,7 +627,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks, int xFpLocation = mCachedDisplayInfo.getNaturalWidth() / 2; try { xFpLocation = mContext.getResources().getDimensionPixelSize( - com.android.systemui.R.dimen + com.android.systemui.res.R.dimen .physical_fingerprint_sensor_center_screen_location_x); } catch (Resources.NotFoundException e) { } @@ -635,7 +635,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks, return new Point( (int) (xFpLocation * mScaleFactor), (int) (mContext.getResources().getDimensionPixelSize( - com.android.systemui.R.dimen + com.android.systemui.res.R.dimen .physical_fingerprint_sensor_center_screen_location_y) * mScaleFactor) ); @@ -815,7 +815,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks, mFaceProps = mFaceManager != null ? mFaceManager.getSensorPropertiesInternal() : null; int[] faceAuthLocation = context.getResources().getIntArray( - com.android.systemui.R.array.config_face_auth_props); + com.android.systemui.res.R.array.config_face_auth_props); if (faceAuthLocation == null || faceAuthLocation.length < 2) { mFaceSensorLocationDefault = null; } else { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java index 167067e7d7e9..bc0c8c892be8 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java @@ -27,7 +27,7 @@ import android.view.View; import android.view.ViewOutlineProvider; import android.view.animation.AccelerateDecelerateInterpolator; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt index 141983ba548d..c09e68d4ace6 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt @@ -31,7 +31,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.keyguard.logging.KeyguardLogger import com.android.settingslib.Utils import com.android.systemui.CoreStartable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.FeatureFlags diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationDialogFactory.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationDialogFactory.java index 3e6508c6da70..2962be8e55a2 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationDialogFactory.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationDialogFactory.java @@ -27,7 +27,7 @@ import android.hardware.fingerprint.FingerprintManager; import android.provider.Settings; import android.util.Log; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.statusbar.phone.SystemUIDialog; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java index dc874d83b75b..d6a4cbb67487 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java @@ -21,6 +21,8 @@ import static android.app.PendingIntent.FLAG_IMMUTABLE; import static com.android.systemui.biometrics.BiometricNotificationBroadcastReceiver.ACTION_SHOW_FACE_REENROLL_DIALOG; import static com.android.systemui.biometrics.BiometricNotificationBroadcastReceiver.ACTION_SHOW_FINGERPRINT_REENROLL_DIALOG; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; @@ -29,8 +31,10 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.hardware.biometrics.BiometricFaceConstants; -import android.hardware.biometrics.BiometricFingerprintConstants; import android.hardware.biometrics.BiometricSourceType; +import android.hardware.biometrics.BiometricStateListener; +import android.hardware.face.FaceManager; +import android.hardware.fingerprint.FingerprintManager; import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; @@ -39,10 +43,12 @@ import android.util.Log; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.CoreStartable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.statusbar.policy.KeyguardStateController; +import java.util.Optional; + import javax.inject.Inject; /** @@ -66,6 +72,9 @@ public class BiometricNotificationService implements CoreStartable { private final Handler mHandler; private final NotificationManager mNotificationManager; private final BiometricNotificationBroadcastReceiver mBroadcastReceiver; + private final FingerprintReEnrollNotification mFingerprintReEnrollNotification; + private final FingerprintManager mFingerprintManager; + private final FaceManager mFaceManager; private NotificationChannel mNotificationChannel; private boolean mFaceNotificationQueued; private boolean mFingerprintNotificationQueued; @@ -102,26 +111,53 @@ public class BiometricNotificationService implements CoreStartable { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.FACE_UNLOCK_RE_ENROLL, REENROLL_REQUIRED, UserHandle.USER_CURRENT); - } else if (msgId == BiometricFingerprintConstants.BIOMETRIC_ERROR_RE_ENROLL - && biometricSourceType == BiometricSourceType.FINGERPRINT) { + } + } + + @Override + public void onBiometricHelp(int msgId, String helpString, + BiometricSourceType biometricSourceType) { + if (biometricSourceType == BiometricSourceType.FINGERPRINT + && mFingerprintReEnrollNotification.isFingerprintReEnrollRequired( + msgId)) { mFingerprintReenrollRequired = true; } } }; + private final BiometricStateListener mFaceStateListener = new BiometricStateListener() { + @Override + public void onEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments) { + mNotificationManager.cancelAsUser(TAG, FACE_NOTIFICATION_ID, UserHandle.CURRENT); + } + }; + + private final BiometricStateListener mFingerprintStateListener = new BiometricStateListener() { + @Override + public void onEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments) { + mNotificationManager.cancelAsUser(TAG, FINGERPRINT_NOTIFICATION_ID, UserHandle.CURRENT); + } + }; @Inject - public BiometricNotificationService(Context context, - KeyguardUpdateMonitor keyguardUpdateMonitor, - KeyguardStateController keyguardStateController, - Handler handler, NotificationManager notificationManager, - BiometricNotificationBroadcastReceiver biometricNotificationBroadcastReceiver) { + public BiometricNotificationService(@NonNull Context context, + @NonNull KeyguardUpdateMonitor keyguardUpdateMonitor, + @NonNull KeyguardStateController keyguardStateController, + @NonNull Handler handler, @NonNull NotificationManager notificationManager, + @NonNull BiometricNotificationBroadcastReceiver biometricNotificationBroadcastReceiver, + @NonNull Optional<FingerprintReEnrollNotification> fingerprintReEnrollNotification, + @Nullable FingerprintManager fingerprintManager, + @Nullable FaceManager faceManager) { mContext = context; mKeyguardUpdateMonitor = keyguardUpdateMonitor; mKeyguardStateController = keyguardStateController; mHandler = handler; mNotificationManager = notificationManager; mBroadcastReceiver = biometricNotificationBroadcastReceiver; + mFingerprintReEnrollNotification = fingerprintReEnrollNotification.orElse( + new FingerprintReEnrollNotificationImpl()); + mFingerprintManager = fingerprintManager; + mFaceManager = faceManager; } @Override @@ -135,12 +171,19 @@ public class BiometricNotificationService implements CoreStartable { intentFilter.addAction(ACTION_SHOW_FACE_REENROLL_DIALOG); mContext.registerReceiver(mBroadcastReceiver, intentFilter, Context.RECEIVER_EXPORTED_UNAUDITED); + if (mFingerprintManager != null) { + mFingerprintManager.registerBiometricStateListener(mFingerprintStateListener); + } + if (mFaceManager != null) { + mFaceManager.registerBiometricStateListener(mFaceStateListener); + } Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.FACE_UNLOCK_RE_ENROLL, REENROLL_NOT_REQUIRED, UserHandle.USER_CURRENT); } private void queueFaceReenrollNotification() { + Log.d(TAG, "Face re-enroll notification queued."); mFaceNotificationQueued = true; final String title = mContext.getString(R.string.face_re_enroll_notification_title); final String content = mContext.getString( @@ -153,6 +196,7 @@ public class BiometricNotificationService implements CoreStartable { } private void queueFingerprintReenrollNotification() { + Log.d(TAG, "Fingerprint re-enroll notification queued."); mFingerprintNotificationQueued = true; final String title = mContext.getString(R.string.fingerprint_re_enroll_notification_title); final String content = mContext.getString( diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FaceAuthAccessibilityDelegate.kt b/packages/SystemUI/src/com/android/systemui/biometrics/FaceAuthAccessibilityDelegate.kt index a24a47bb44df..bbdcadbb19c6 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/FaceAuthAccessibilityDelegate.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/FaceAuthAccessibilityDelegate.kt @@ -22,7 +22,7 @@ import android.view.View import android.view.accessibility.AccessibilityNodeInfo import com.android.keyguard.FaceAuthApiRequestReason import com.android.keyguard.KeyguardUpdateMonitor -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDeferral.kt b/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDeferral.kt index 320e362dd9c7..b015f7078a83 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDeferral.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDeferral.kt @@ -20,7 +20,7 @@ import android.content.res.Resources import com.android.keyguard.logging.BiometricMessageDeferralLogger import com.android.keyguard.logging.FaceMessageDeferralLogger import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotification.java b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotification.java new file mode 100644 index 000000000000..9050f26d39e4 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotification.java @@ -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 com.android.systemui.biometrics; + +import android.hardware.biometrics.BiometricFingerprintConstants; + +/** + * Checks if the fingerprint HAL has sent a re-enrollment request. + */ +public interface FingerprintReEnrollNotification { + //TODO: Remove this class and add a constant in the HAL API instead (b/281841852) + /** Returns true if msgId corresponds to FINGERPRINT_ACQUIRED_RE_ENROLL. */ + boolean isFingerprintReEnrollRequired( + @BiometricFingerprintConstants.FingerprintAcquired int msgId); +} diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotificationImpl.java b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotificationImpl.java new file mode 100644 index 000000000000..1f86bc6ae298 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintReEnrollNotificationImpl.java @@ -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 com.android.systemui.biometrics; + +import android.hardware.biometrics.BiometricFingerprintConstants; + +/** + * Checks if the fingerprint HAL has sent a re-enrollment request. + */ +public class FingerprintReEnrollNotificationImpl implements FingerprintReEnrollNotification{ + @Override + public boolean isFingerprintReEnrollRequired(int msgId) { + return msgId == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_RE_ENROLL; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt index 017ac6019b65..c1f6259d94f7 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt @@ -54,7 +54,7 @@ import com.android.app.animation.Interpolators import com.android.internal.annotations.VisibleForTesting import com.android.keyguard.KeyguardPINView import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor import com.android.systemui.dagger.SysUISingleton diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 026435623042..46d3c8a0c3e3 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -580,7 +580,9 @@ public class UdfpsController implements DozeReceiver, Dumpable { + mOverlay.getRequestId()); return false; } - if (mLockscreenShadeTransitionController.getQSDragProgress() != 0f + + if ((mLockscreenShadeTransitionController.getQSDragProgress() != 0f + && !mAlternateBouncerInteractor.isVisibleState()) || mPrimaryBouncerInteractor.isInTransit()) { return false; } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt index 941df687ead9..34a0d8a46e52 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt @@ -46,7 +46,7 @@ import android.view.accessibility.AccessibilityManager.TouchExplorationStateChan import androidx.annotation.LayoutRes import androidx.annotation.VisibleForTesting import com.android.keyguard.KeyguardUpdateMonitor -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.ActivityLaunchAnimator import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams import com.android.systemui.biometrics.ui.controller.UdfpsKeyguardViewController diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java index 16dc42acde46..abbfa017c13e 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java @@ -35,7 +35,7 @@ import android.view.WindowMetrics; import android.widget.FrameLayout; import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Adapter that remeasures an auth dialog view to ensure that it matches the location of a physical diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.kt index 511b4e34fa0e..c16dfb1ea1a8 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.kt @@ -24,7 +24,7 @@ import android.graphics.drawable.Drawable import android.graphics.drawable.ShapeDrawable import android.graphics.drawable.shapes.PathShape import android.util.PathParser -import com.android.systemui.R +import com.android.systemui.res.R private const val DEFAULT_STROKE_WIDTH = 3f diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt index 5dafa61f9a27..0838855f4756 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt @@ -20,7 +20,7 @@ import android.graphics.Rect import android.util.AttributeSet import android.view.View import android.view.ViewGroup -import com.android.systemui.R +import com.android.systemui.res.R /** * View corresponding with udfps_fpm_empty_view.xml diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardAccessibilityDelegate.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardAccessibilityDelegate.kt index 84978790f49c..99da660d1fda 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardAccessibilityDelegate.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardAccessibilityDelegate.kt @@ -20,7 +20,7 @@ import android.content.res.Resources import android.os.Bundle import android.view.View import android.view.accessibility.AccessibilityNodeInfo -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt index 84a746ca2b8f..8ce98a92adbd 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt @@ -27,7 +27,7 @@ import androidx.lifecycle.repeatOnLifecycle import com.android.app.animation.Interpolators import com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerProgress import com.android.keyguard.KeyguardUpdateMonitor -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.ActivityLaunchAnimator import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacy.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacy.java index b916810c57d0..36a42f945235 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacy.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacy.java @@ -42,7 +42,7 @@ import androidx.asynclayoutinflater.view.AsyncLayoutInflater; import com.android.app.animation.Interpolators; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.airbnb.lottie.LottieAnimationView; import com.airbnb.lottie.LottieProperty; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt index 54e62154bca3..6ce6172c9faa 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt @@ -26,7 +26,7 @@ import android.util.AttributeSet import android.util.Log import android.view.MotionEvent import android.widget.FrameLayout -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams import com.android.systemui.doze.DozeReceiver diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractor.kt index 2a026675adcb..191533c8f377 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractor.kt @@ -7,7 +7,7 @@ import android.os.UserManager import com.android.internal.widget.LockPatternUtils import com.android.internal.widget.LockscreenCredential import com.android.internal.widget.VerifyCredentialResponse -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.domain.model.BiometricPromptRequest import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.util.time.SystemClock diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/BiometricPromptLayout.java b/packages/SystemUI/src/com/android/systemui/biometrics/ui/BiometricPromptLayout.java index fb246cd51d8a..cef0be09d3ce 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/BiometricPromptLayout.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/BiometricPromptLayout.java @@ -29,7 +29,7 @@ import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.TextView; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.biometrics.AuthBiometricFingerprintIconController; import com.android.systemui.biometrics.AuthController; import com.android.systemui.biometrics.AuthDialog; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt index a7ecf38ef598..56e3f3995d1c 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt @@ -10,7 +10,7 @@ import android.view.WindowInsets.Type.ime import android.view.accessibility.AccessibilityManager import android.widget.LinearLayout import android.widget.TextView -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.AuthPanelController import com.android.systemui.biometrics.ui.binder.CredentialViewBinder import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt index 02847c283738..c29efc0fcab9 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt @@ -38,7 +38,7 @@ import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import com.airbnb.lottie.LottieAnimationView -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.AuthBiometricFaceIconController import com.android.systemui.biometrics.AuthBiometricFingerprintAndFaceIconController import com.android.systemui.biometrics.AuthBiometricFingerprintIconController diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt index b9af03166fed..7e16d1e1d668 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt @@ -30,7 +30,7 @@ import androidx.core.animation.addListener import androidx.core.view.doOnLayout import androidx.core.view.isGone import androidx.lifecycle.lifecycleScope -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.AuthPanelController import com.android.systemui.biometrics.Utils import com.android.systemui.biometrics.ui.BiometricPromptLayout diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt index 996b62e084cb..0ad07ba924a0 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt @@ -12,7 +12,7 @@ import android.window.OnBackInvokedDispatcher import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.ui.CredentialPasswordView import com.android.systemui.biometrics.ui.CredentialView import com.android.systemui.biometrics.ui.IPinPad diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPatternViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPatternViewBinder.kt index b692ad35caee..eff698705042 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPatternViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPatternViewBinder.kt @@ -4,7 +4,7 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.android.internal.widget.LockPatternUtils import com.android.internal.widget.LockPatternView -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.ui.CredentialPatternView import com.android.systemui.biometrics.ui.CredentialView import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt index 931946aaa382..ce52e1d78fda 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt @@ -8,7 +8,7 @@ import android.widget.TextView import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.android.app.animation.Interpolators -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.AuthPanelController import com.android.systemui.biometrics.ui.CredentialPasswordView import com.android.systemui.biometrics.ui.CredentialPatternView diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PinPadViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PinPadViewBinder.kt index 906206c27455..05fdb2f22a9f 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PinPadViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PinPadViewBinder.kt @@ -20,7 +20,7 @@ package com.android.systemui.biometrics.ui.binder import android.view.KeyEvent import android.widget.ImeAwareEditText import com.android.internal.widget.LockscreenCredential -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.ui.CredentialPasswordView import com.android.systemui.biometrics.ui.IPinPad import com.android.systemui.biometrics.ui.PinPadClickListener diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt index 6212ef000ff1..03c5c5354ad7 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt @@ -4,7 +4,7 @@ import android.content.Context import android.graphics.drawable.Drawable import android.text.InputType import com.android.internal.widget.LockPatternView -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.Utils import com.android.systemui.biometrics.domain.interactor.CredentialStatus import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptFingerprintIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptFingerprintIconViewModel.kt index b406ea41eff0..a95e257188dc 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptFingerprintIconViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptFingerprintIconViewModel.kt @@ -20,7 +20,7 @@ package com.android.systemui.biometrics.ui.viewmodel import android.annotation.RawRes import android.content.res.Configuration import android.view.Surface -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor import com.android.systemui.biometrics.shared.model.FingerprintSensorType diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java index 83e61d69e4f3..00e952718436 100644 --- a/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java +++ b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java @@ -38,7 +38,7 @@ import com.android.internal.logging.UiEventLogger; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.media.MediaOutputConstants; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.media.controls.util.MediaDataUtils; import com.android.systemui.media.dialog.MediaOutputDialogFactory; diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/data/factory/BouncerMessageFactory.kt b/packages/SystemUI/src/com/android/systemui/bouncer/data/factory/BouncerMessageFactory.kt index 64bf688b3c5d..f93337c993c8 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/data/factory/BouncerMessageFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/data/factory/BouncerMessageFactory.kt @@ -36,46 +36,46 @@ import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART_FOR_MAINL import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TIMEOUT import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TRUSTAGENT_EXPIRED import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_USER_REQUEST -import com.android.systemui.R.string.bouncer_face_not_recognized -import com.android.systemui.R.string.keyguard_enter_password -import com.android.systemui.R.string.keyguard_enter_pattern -import com.android.systemui.R.string.keyguard_enter_pin -import com.android.systemui.R.string.kg_bio_too_many_attempts_password -import com.android.systemui.R.string.kg_bio_too_many_attempts_pattern -import com.android.systemui.R.string.kg_bio_too_many_attempts_pin -import com.android.systemui.R.string.kg_bio_try_again_or_password -import com.android.systemui.R.string.kg_bio_try_again_or_pattern -import com.android.systemui.R.string.kg_bio_try_again_or_pin -import com.android.systemui.R.string.kg_face_locked_out -import com.android.systemui.R.string.kg_fp_locked_out -import com.android.systemui.R.string.kg_fp_not_recognized -import com.android.systemui.R.string.kg_primary_auth_locked_out_password -import com.android.systemui.R.string.kg_primary_auth_locked_out_pattern -import com.android.systemui.R.string.kg_primary_auth_locked_out_pin -import com.android.systemui.R.string.kg_prompt_after_dpm_lock -import com.android.systemui.R.string.kg_prompt_after_update_password -import com.android.systemui.R.string.kg_prompt_after_update_pattern -import com.android.systemui.R.string.kg_prompt_after_update_pin -import com.android.systemui.R.string.kg_prompt_after_user_lockdown_password -import com.android.systemui.R.string.kg_prompt_after_user_lockdown_pattern -import com.android.systemui.R.string.kg_prompt_after_user_lockdown_pin -import com.android.systemui.R.string.kg_prompt_auth_timeout -import com.android.systemui.R.string.kg_prompt_password_auth_timeout -import com.android.systemui.R.string.kg_prompt_pattern_auth_timeout -import com.android.systemui.R.string.kg_prompt_pin_auth_timeout -import com.android.systemui.R.string.kg_prompt_reason_restart_password -import com.android.systemui.R.string.kg_prompt_reason_restart_pattern -import com.android.systemui.R.string.kg_prompt_reason_restart_pin -import com.android.systemui.R.string.kg_prompt_unattended_update -import com.android.systemui.R.string.kg_too_many_failed_attempts_countdown -import com.android.systemui.R.string.kg_trust_agent_disabled -import com.android.systemui.R.string.kg_unlock_with_password_or_fp -import com.android.systemui.R.string.kg_unlock_with_pattern_or_fp -import com.android.systemui.R.string.kg_unlock_with_pin_or_fp -import com.android.systemui.R.string.kg_wrong_input_try_fp_suggestion -import com.android.systemui.R.string.kg_wrong_password_try_again -import com.android.systemui.R.string.kg_wrong_pattern_try_again -import com.android.systemui.R.string.kg_wrong_pin_try_again +import com.android.systemui.res.R.string.bouncer_face_not_recognized +import com.android.systemui.res.R.string.keyguard_enter_password +import com.android.systemui.res.R.string.keyguard_enter_pattern +import com.android.systemui.res.R.string.keyguard_enter_pin +import com.android.systemui.res.R.string.kg_bio_too_many_attempts_password +import com.android.systemui.res.R.string.kg_bio_too_many_attempts_pattern +import com.android.systemui.res.R.string.kg_bio_too_many_attempts_pin +import com.android.systemui.res.R.string.kg_bio_try_again_or_password +import com.android.systemui.res.R.string.kg_bio_try_again_or_pattern +import com.android.systemui.res.R.string.kg_bio_try_again_or_pin +import com.android.systemui.res.R.string.kg_face_locked_out +import com.android.systemui.res.R.string.kg_fp_locked_out +import com.android.systemui.res.R.string.kg_fp_not_recognized +import com.android.systemui.res.R.string.kg_primary_auth_locked_out_password +import com.android.systemui.res.R.string.kg_primary_auth_locked_out_pattern +import com.android.systemui.res.R.string.kg_primary_auth_locked_out_pin +import com.android.systemui.res.R.string.kg_prompt_after_dpm_lock +import com.android.systemui.res.R.string.kg_prompt_after_update_password +import com.android.systemui.res.R.string.kg_prompt_after_update_pattern +import com.android.systemui.res.R.string.kg_prompt_after_update_pin +import com.android.systemui.res.R.string.kg_prompt_after_user_lockdown_password +import com.android.systemui.res.R.string.kg_prompt_after_user_lockdown_pattern +import com.android.systemui.res.R.string.kg_prompt_after_user_lockdown_pin +import com.android.systemui.res.R.string.kg_prompt_auth_timeout +import com.android.systemui.res.R.string.kg_prompt_password_auth_timeout +import com.android.systemui.res.R.string.kg_prompt_pattern_auth_timeout +import com.android.systemui.res.R.string.kg_prompt_pin_auth_timeout +import com.android.systemui.res.R.string.kg_prompt_reason_restart_password +import com.android.systemui.res.R.string.kg_prompt_reason_restart_pattern +import com.android.systemui.res.R.string.kg_prompt_reason_restart_pin +import com.android.systemui.res.R.string.kg_prompt_unattended_update +import com.android.systemui.res.R.string.kg_too_many_failed_attempts_countdown +import com.android.systemui.res.R.string.kg_trust_agent_disabled +import com.android.systemui.res.R.string.kg_unlock_with_password_or_fp +import com.android.systemui.res.R.string.kg_unlock_with_pattern_or_fp +import com.android.systemui.res.R.string.kg_unlock_with_pin_or_fp +import com.android.systemui.res.R.string.kg_wrong_input_try_fp_suggestion +import com.android.systemui.res.R.string.kg_wrong_password_try_again +import com.android.systemui.res.R.string.kg_wrong_pattern_try_again +import com.android.systemui.res.R.string.kg_wrong_pin_try_again import com.android.systemui.bouncer.shared.model.BouncerMessageModel import com.android.systemui.bouncer.shared.model.Message import com.android.systemui.dagger.SysUISingleton diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt index abddb0a322ea..9b2f2baba94b 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt @@ -17,7 +17,7 @@ package com.android.systemui.bouncer.domain.interactor import android.content.Context -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor import com.android.systemui.authentication.domain.model.AuthenticationMethodModel import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel @@ -225,6 +225,20 @@ constructor( repository.setMessage(errorMessage(authenticationInteractor.getAuthenticationMethod())) } + /** If the bouncer is showing, hides the bouncer and return to the lockscreen scene. */ + fun hide( + loggingReason: String, + ) { + if (sceneInteractor.desiredScene.value.key != SceneKey.Bouncer) { + return + } + + sceneInteractor.changeScene( + scene = SceneModel(SceneKey.Lockscreen), + loggingReason = loggingReason, + ) + } + private fun promptMessage(authMethod: AuthenticationMethodModel): String { return when (authMethod) { is AuthenticationMethodModel.Pin -> diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt index 579f0b7b3185..6e26fe952749 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt @@ -28,7 +28,7 @@ import com.android.keyguard.KeyguardSecurityModel import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.DejankUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.EXPANSION_HIDDEN @@ -38,8 +38,6 @@ import com.android.systemui.classifier.FalsingCollector import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main -import com.android.systemui.flags.FeatureFlags -import com.android.systemui.flags.Flags import com.android.systemui.keyguard.DismissCallbackRegistry import com.android.systemui.keyguard.data.repository.TrustRepository import com.android.systemui.plugins.ActivityStarter @@ -74,7 +72,6 @@ constructor( private val context: Context, private val keyguardUpdateMonitor: KeyguardUpdateMonitor, private val trustRepository: TrustRepository, - private val featureFlags: FeatureFlags, @Application private val applicationScope: CoroutineScope, ) { private val passiveAuthBouncerDelay = @@ -135,11 +132,9 @@ constructor( init { keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback) - if (featureFlags.isEnabled(Flags.DELAY_BOUNCER)) { - applicationScope.launch { - trustRepository.isCurrentUserActiveUnlockRunning.collect { - currentUserActiveUnlockRunning = it - } + applicationScope.launch { + trustRepository.isCurrentUserActiveUnlockRunning.collect { + currentUserActiveUnlockRunning = it } } } @@ -415,9 +410,7 @@ constructor( currentUserActiveUnlockRunning && keyguardUpdateMonitor.canTriggerActiveUnlockBasedOnDeviceState() - return featureFlags.isEnabled(Flags.DELAY_BOUNCER) && - !needsFullscreenBouncer() && - (canRunFaceAuth || canRunActiveUnlock) + return !needsFullscreenBouncer() && (canRunFaceAuth || canRunActiveUnlock) } companion object { diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/BouncerMessageView.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/BouncerMessageView.kt index 648680293e3d..79a11ee88826 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/BouncerMessageView.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/BouncerMessageView.kt @@ -22,7 +22,7 @@ import android.widget.LinearLayout import com.android.keyguard.BouncerKeyguardMessageArea import com.android.keyguard.KeyguardMessageArea import com.android.keyguard.KeyguardMessageAreaController -import com.android.systemui.R +import com.android.systemui.res.R class BouncerMessageView : LinearLayout { constructor(context: Context?) : super(context) diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt index d95b70c85fe0..4546bea3b89b 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt @@ -16,6 +16,7 @@ package com.android.systemui.bouncer.ui.viewmodel +import com.android.systemui.bouncer.domain.interactor.BouncerInteractor import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow @@ -28,6 +29,7 @@ sealed class AuthMethodBouncerViewModel( * being able to attempt to unlock the device. */ val isInputEnabled: StateFlow<Boolean>, + private val interactor: BouncerInteractor, ) { private val _animateFailure = MutableStateFlow(false) @@ -37,6 +39,9 @@ sealed class AuthMethodBouncerViewModel( */ val animateFailure: StateFlow<Boolean> = _animateFailure.asStateFlow() + /** Whether the input method editor (for example, the software keyboard) is visible. */ + private var isImeVisible: Boolean = false + /** * Notifies that the failure animation has been shown. This should be called to consume a `true` * value in [animateFailure]. @@ -45,6 +50,21 @@ sealed class AuthMethodBouncerViewModel( _animateFailure.value = false } + /** + * Notifies that the input method editor (for example, the software keyboard) has been shown or + * hidden. + */ + fun onImeVisibilityChanged(isVisible: Boolean) { + if (isImeVisible && !isVisible) { + // The IME has gone from visible to invisible, dismiss the bouncer. + interactor.hide( + loggingReason = "IME hidden", + ) + } + + isImeVisible = isVisible + } + /** Ask the UI to show the failure animation. */ protected fun showFailureAnimation() { _animateFailure.value = true diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt index f6794d4f40b3..15d1dae239a0 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt @@ -17,7 +17,7 @@ package com.android.systemui.bouncer.ui.viewmodel import android.content.Context -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor import com.android.systemui.authentication.domain.model.AuthenticationMethodModel import com.android.systemui.bouncer.domain.interactor.BouncerInteractor diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt index d21479746744..9e10f29a00f9 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt @@ -31,6 +31,7 @@ class PasswordBouncerViewModel( ) : AuthMethodBouncerViewModel( isInputEnabled = isInputEnabled, + interactor = interactor, ) { private val _password = MutableStateFlow("") @@ -60,6 +61,10 @@ class PasswordBouncerViewModel( /** Notifies that the user has pressed the key for attempting to authenticate the password. */ fun onAuthenticateKeyPressed() { val password = _password.value.toCharArray().toList() + if (password.isEmpty()) { + return + } + _password.value = "" applicationScope.launch { diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt index 1985c37e1d5d..497276b47996 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt @@ -42,6 +42,7 @@ class PatternBouncerViewModel( ) : AuthMethodBouncerViewModel( isInputEnabled = isInputEnabled, + interactor = interactor, ) { /** The number of columns in the dot grid. */ diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt index dc5c5288df9f..8e6421ed3f0a 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt @@ -37,6 +37,7 @@ class PinBouncerViewModel( ) : AuthMethodBouncerViewModel( isInputEnabled = isInputEnabled, + interactor = interactor, ) { val pinShapes = PinShapeAdapter(applicationContext) diff --git a/packages/SystemUI/src/com/android/systemui/camera/CameraIntents.kt b/packages/SystemUI/src/com/android/systemui/camera/CameraIntents.kt index cc43e7ed25a5..1e17059d20e4 100644 --- a/packages/SystemUI/src/com/android/systemui/camera/CameraIntents.kt +++ b/packages/SystemUI/src/com/android/systemui/camera/CameraIntents.kt @@ -20,7 +20,7 @@ import android.content.Context import android.content.Intent import android.provider.MediaStore import android.text.TextUtils -import com.android.systemui.R +import com.android.systemui.res.R class CameraIntents { companion object { diff --git a/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt b/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt index ddb097491988..718ef51aa161 100644 --- a/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt +++ b/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt @@ -27,7 +27,7 @@ import com.android.internal.annotations.VisibleForTesting import com.android.internal.logging.UiEvent import com.android.internal.logging.UiEventLogger import com.android.settingslib.Utils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags diff --git a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java index 7bf8f4dac1fb..047d15daf6f8 100644 --- a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java +++ b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java @@ -32,7 +32,7 @@ import android.widget.TextView; import com.android.app.animation.Interpolators; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.shared.recents.utilities.Utilities; import com.android.systemui.surfaceeffects.ripple.RippleShader; import com.android.systemui.surfaceeffects.ripple.RippleShader.RippleShape; diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java index 0a1aed65c205..2729b7b0a4fd 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java @@ -19,7 +19,7 @@ package com.android.systemui.classifier; import android.content.res.Resources; import android.view.ViewConfiguration; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.scene.shared.flag.SceneContainerFlags; diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardImageLoader.kt b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardImageLoader.kt index 0542e13ba6da..e83a825a0072 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardImageLoader.kt +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardImageLoader.kt @@ -20,7 +20,7 @@ import android.graphics.Bitmap import android.net.Uri import android.util.Log import android.util.Size -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import java.io.IOException diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardModel.kt b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardModel.kt index 789833c6d849..12597a7679fa 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardModel.kt +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardModel.kt @@ -24,7 +24,7 @@ import android.text.TextUtils import android.util.Log import android.util.Size import android.view.textclassifier.TextLinks -import com.android.systemui.R +import com.android.systemui.res.R import java.io.IOException data class ClipboardModel( diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java index ffd836b3230f..70736ae3fcc1 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java @@ -61,7 +61,7 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.UiEventLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.clipboardoverlay.dagger.ClipboardOverlayModule.OverlayWindowContext; diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java index 758a6563323e..2406d6104c1a 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtils.java @@ -30,7 +30,7 @@ import android.view.textclassifier.TextClassifier; import android.view.textclassifier.TextLinks; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.ArrayList; import java.util.Optional; diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java index a76d2ea816a7..2af49cfbf1b1 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java @@ -54,7 +54,7 @@ import android.widget.TextView; import androidx.core.view.ViewCompat; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.screenshot.DraggableConstraintLayout; import com.android.systemui.screenshot.FloatingWindowUtil; import com.android.systemui.screenshot.OverlayActionChip; diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardToast.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardToast.java index e9daa462c022..0a4d76ef1a92 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardToast.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardToast.java @@ -19,7 +19,7 @@ package com.android.systemui.clipboardoverlay; import android.content.Context; import android.widget.Toast; -import com.android.systemui.R; +import com.android.systemui.res.R; import javax.inject.Inject; diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java index 1ffbe3230bda..bb201b624a71 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java @@ -31,7 +31,7 @@ import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import android.widget.TextView; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Lightweight activity for editing text clipboard contents diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java index d58fab45093d..a18b4c84b081 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java @@ -24,7 +24,7 @@ import android.content.Intent; import android.net.Uri; import android.text.TextUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; class IntentCreator { private static final String EXTRA_EDIT_SOURCE = "edit_source"; diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java index 09b2e44c1be1..0fd34bd757b0 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java @@ -25,7 +25,7 @@ import android.hardware.display.DisplayManager; import android.view.Display; import android.view.LayoutInflater; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.clipboardoverlay.ClipboardOverlayView; import com.android.systemui.settings.DisplayTracker; diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java b/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java index f362831e8c88..7fe00322ef27 100644 --- a/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java +++ b/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java @@ -29,7 +29,7 @@ import android.widget.LinearLayout; import android.widget.SeekBar; import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalWidgetViewBinder.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalWidgetViewBinder.kt index 1b6d3a8095f0..65bf4b3e69cd 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalWidgetViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalWidgetViewBinder.kt @@ -18,7 +18,7 @@ package com.android.systemui.communal.ui.binder import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.communal.ui.adapter.CommunalWidgetViewAdapter import com.android.systemui.communal.ui.view.CommunalWidgetWrapper import com.android.systemui.communal.ui.viewmodel.CommunalWidgetViewModel diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/view/CommunalWidgetWrapper.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/view/CommunalWidgetWrapper.kt index 560f4fac048f..039078eb1f21 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/ui/view/CommunalWidgetWrapper.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/view/CommunalWidgetWrapper.kt @@ -20,7 +20,7 @@ package com.android.systemui.communal.ui.view import android.content.Context import android.util.AttributeSet import android.widget.LinearLayout -import com.android.systemui.R +import com.android.systemui.res.R /** Wraps around a widget rendered in communal mode. */ class CommunalWidgetWrapper(context: Context, attrs: AttributeSet? = null) : diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/DefaultCommunalWidgetSection.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/DefaultCommunalWidgetSection.kt index 8640c97bb1e1..c3e8a96701ea 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/DefaultCommunalWidgetSection.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/DefaultCommunalWidgetSection.kt @@ -22,7 +22,7 @@ import androidx.constraintlayout.widget.ConstraintSet import androidx.constraintlayout.widget.ConstraintSet.BOTTOM import androidx.constraintlayout.widget.ConstraintSet.END import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.communal.ui.adapter.CommunalWidgetViewAdapter import com.android.systemui.communal.ui.binder.CommunalWidgetViewBinder import com.android.systemui.communal.ui.viewmodel.CommunalWidgetViewModel diff --git a/packages/SystemUI/src/com/android/systemui/complication/ComplicationLayoutEngine.java b/packages/SystemUI/src/com/android/systemui/complication/ComplicationLayoutEngine.java index e1dd1a69158b..20b2494a6c29 100644 --- a/packages/SystemUI/src/com/android/systemui/complication/ComplicationLayoutEngine.java +++ b/packages/SystemUI/src/com/android/systemui/complication/ComplicationLayoutEngine.java @@ -40,7 +40,7 @@ import android.view.ViewGroup; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.Constraints; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.complication.ComplicationLayoutParams.Direction; import com.android.systemui.complication.ComplicationLayoutParams.Position; import com.android.systemui.complication.dagger.ComplicationModule; diff --git a/packages/SystemUI/src/com/android/systemui/complication/dagger/ComplicationHostViewModule.java b/packages/SystemUI/src/com/android/systemui/complication/dagger/ComplicationHostViewModule.java index a7d017dda21e..712213ab0b12 100644 --- a/packages/SystemUI/src/com/android/systemui/complication/dagger/ComplicationHostViewModule.java +++ b/packages/SystemUI/src/com/android/systemui/complication/dagger/ComplicationHostViewModule.java @@ -22,7 +22,7 @@ import android.view.LayoutInflater; import androidx.constraintlayout.widget.ConstraintLayout; import com.android.internal.util.Preconditions; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Main; import dagger.Module; diff --git a/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamClockTimeComplicationComponent.kt b/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamClockTimeComplicationComponent.kt index 87c3b2f4117b..099e3fcf227d 100644 --- a/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamClockTimeComplicationComponent.kt +++ b/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamClockTimeComplicationComponent.kt @@ -21,7 +21,7 @@ import android.view.LayoutInflater import android.view.View import android.widget.TextClock import com.android.internal.util.Preconditions -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.complication.DreamClockTimeComplication import com.android.systemui.complication.DreamClockTimeComplication.DreamClockTimeViewHolder import dagger.Module diff --git a/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamHomeControlsComplicationComponent.java b/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamHomeControlsComplicationComponent.java index 2b5aa7cd9c51..08d0595eba23 100644 --- a/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamHomeControlsComplicationComponent.java +++ b/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamHomeControlsComplicationComponent.java @@ -25,7 +25,7 @@ import android.view.LayoutInflater; import android.widget.ImageView; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.complication.DreamHomeControlsComplication; import com.android.systemui.shared.shadow.DoubleShadowIconDrawable; import com.android.systemui.shared.shadow.DoubleShadowTextHelper; diff --git a/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamMediaEntryComplicationComponent.java b/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamMediaEntryComplicationComponent.java index f15a5862104f..c0a292cd0d33 100644 --- a/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamMediaEntryComplicationComponent.java +++ b/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamMediaEntryComplicationComponent.java @@ -21,7 +21,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; import android.view.LayoutInflater; import android.view.View; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.complication.DreamMediaEntryComplication; import dagger.Module; diff --git a/packages/SystemUI/src/com/android/systemui/complication/dagger/RegisteredComplicationsModule.java b/packages/SystemUI/src/com/android/systemui/complication/dagger/RegisteredComplicationsModule.java index 776c9721aea5..92fdb1e69c83 100644 --- a/packages/SystemUI/src/com/android/systemui/complication/dagger/RegisteredComplicationsModule.java +++ b/packages/SystemUI/src/com/android/systemui/complication/dagger/RegisteredComplicationsModule.java @@ -19,7 +19,7 @@ package com.android.systemui.complication.dagger; import android.content.res.Resources; import android.view.ViewGroup; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.complication.ComplicationLayoutParams; import com.android.systemui.dagger.SystemUIBinder; import com.android.systemui.dagger.qualifiers.Main; diff --git a/packages/SystemUI/src/com/android/systemui/contrast/ContrastDialog.kt b/packages/SystemUI/src/com/android/systemui/contrast/ContrastDialog.kt index e627b68dc171..e9b59306c552 100644 --- a/packages/SystemUI/src/com/android/systemui/contrast/ContrastDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/contrast/ContrastDialog.kt @@ -28,7 +28,7 @@ import android.view.LayoutInflater import android.view.View import android.widget.FrameLayout import com.android.internal.annotations.VisibleForTesting -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.settings.UserTracker import com.android.systemui.statusbar.phone.SystemUIDialog diff --git a/packages/SystemUI/src/com/android/systemui/controls/ControlsServiceInfo.kt b/packages/SystemUI/src/com/android/systemui/controls/ControlsServiceInfo.kt index adb0bf38b51f..97b4c94cb9a9 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ControlsServiceInfo.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ControlsServiceInfo.kt @@ -32,7 +32,7 @@ import android.service.controls.ControlsProviderService import android.util.IconDrawableFactory import androidx.annotation.WorkerThread import com.android.settingslib.applications.DefaultAppInfo -import com.android.systemui.R +import com.android.systemui.res.R import java.util.Objects open class ControlsServiceInfo( diff --git a/packages/SystemUI/src/com/android/systemui/controls/TooltipManager.kt b/packages/SystemUI/src/com/android/systemui/controls/TooltipManager.kt index 6e17bc94b16b..21458e89583e 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/TooltipManager.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/TooltipManager.kt @@ -28,7 +28,7 @@ import android.view.animation.AccelerateInterpolator import android.view.animation.DecelerateInterpolator import android.widget.TextView import com.android.systemui.Prefs -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.recents.TriangleShape /** diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImpl.kt index 02490605fbb8..05ff7b71684c 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImpl.kt @@ -16,7 +16,7 @@ package com.android.systemui.controls.controller -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt index 3fe0f03488d1..72483bbe135d 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt @@ -26,7 +26,7 @@ import android.widget.TextView import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.recyclerview.widget.RecyclerView -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.util.icuMessageFormat import java.text.Collator diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt index ec76f433b23b..f034851e5d80 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt @@ -36,7 +36,7 @@ import androidx.core.view.AccessibilityDelegateCompat import androidx.core.view.ViewCompat import androidx.core.view.accessibility.AccessibilityNodeInfoCompat import androidx.recyclerview.widget.RecyclerView -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.controls.ControlInterface import com.android.systemui.controls.ui.CanUseIconPredicate import com.android.systemui.controls.ui.RenderInfo diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt index b447d66c08dd..a534097458f7 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt @@ -31,7 +31,7 @@ import android.view.Window import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleObserver import androidx.lifecycle.OnLifecycleEvent -import com.android.systemui.R +import com.android.systemui.res.R import com.android.app.animation.Interpolators import com.android.systemui.controls.ui.ControlsUiController diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt index 4c9dbe02fad8..41edb4a1ffaf 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt @@ -34,7 +34,7 @@ import androidx.activity.ComponentActivity import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.controls.CustomIconCache import com.android.systemui.controls.controller.ControlsControllerImpl import com.android.systemui.controls.controller.StructureInfo diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt index 8bae6674aa11..2ea4303e2290 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt @@ -39,7 +39,7 @@ import androidx.activity.ComponentActivity import androidx.annotation.VisibleForTesting import androidx.viewpager2.widget.ViewPager2 import com.android.systemui.Prefs -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.controls.TooltipManager import com.android.systemui.controls.controller.ControlsControllerImpl import com.android.systemui.controls.controller.StructureInfo diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt index d5b8693af42d..10a0117f8757 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt @@ -35,7 +35,7 @@ import androidx.activity.ComponentActivity import androidx.annotation.VisibleForTesting import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.controls.controller.ControlsController import com.android.systemui.controls.panels.AuthorizedPanelsRepository diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt index 86bde5c3cf4d..d7a68b317a61 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt @@ -32,7 +32,7 @@ import android.view.View import android.widget.ImageView import android.widget.TextView import androidx.activity.ComponentActivity -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.controls.controller.ControlInfo import com.android.systemui.controls.controller.ControlsController diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/PanelConfirmationDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/controls/management/PanelConfirmationDialogFactory.kt index 6f87aa996f94..5df26b3176ff 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/PanelConfirmationDialogFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/PanelConfirmationDialogFactory.kt @@ -20,7 +20,7 @@ package com.android.systemui.controls.management import android.app.Dialog import android.content.Context import android.content.DialogInterface -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.statusbar.phone.SystemUIDialog import java.util.function.Consumer import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt index 5977d379acde..7e56077dec29 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt @@ -21,7 +21,7 @@ import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.android.systemui.R +import com.android.systemui.res.R class StructureAdapter( private val models: List<StructureContainer>, diff --git a/packages/SystemUI/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImpl.kt index 4aef20928bb8..4e935df12ac1 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImpl.kt @@ -19,7 +19,7 @@ package com.android.systemui.controls.panels import android.content.Context import android.content.SharedPreferences -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.settings.UserFileManager import com.android.systemui.settings.UserTracker import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl diff --git a/packages/SystemUI/src/com/android/systemui/controls/settings/ControlsSettingsDialogManager.kt b/packages/SystemUI/src/com/android/systemui/controls/settings/ControlsSettingsDialogManager.kt index 501bcf054d20..4e391b7662e3 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/settings/ControlsSettingsDialogManager.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/settings/ControlsSettingsDialogManager.kt @@ -24,7 +24,7 @@ import android.content.DialogInterface import android.content.SharedPreferences import android.provider.Settings import androidx.annotation.VisibleForTesting -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.controls.settings.ControlsSettingsDialogManager.Companion.MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG import com.android.systemui.controls.settings.ControlsSettingsDialogManager.Companion.PREFS_SETTINGS_DIALOG_ATTEMPTS import com.android.systemui.dagger.SysUISingleton diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt index a13f717bc77d..7e039cdcf204 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt @@ -32,7 +32,7 @@ import android.view.inputmethod.InputMethodManager import android.widget.CheckBox import android.widget.EditText -import com.android.systemui.R +import com.android.systemui.res.R /** * Creates all dialogs for challengeValues that can occur from a call to diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt index abe342320858..fdb9971a7d63 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt @@ -49,7 +49,7 @@ import android.widget.TextView import androidx.annotation.ColorInt import androidx.annotation.VisibleForTesting import com.android.internal.graphics.ColorUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.app.animation.Interpolators import com.android.systemui.controls.ControlsMetricsLogger import com.android.systemui.controls.controller.ControlsController diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt index 8341964e1533..955a5a35d82f 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt @@ -31,7 +31,7 @@ import android.view.WindowInsets import android.view.WindowInsets.Type import android.view.WindowManager import androidx.activity.ComponentActivity -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.controls.management.ControlsAnimations import com.android.systemui.controls.settings.ControlsSettingsDialogManager diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialogsFactory.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialogsFactory.kt index d6cfb79101d7..2ad6014fd7cd 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialogsFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialogsFactory.kt @@ -20,7 +20,7 @@ package com.android.systemui.controls.ui import android.app.Dialog import android.content.Context import android.content.DialogInterface -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.statusbar.phone.SystemUIDialog import java.util.function.Consumer import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsPopupMenu.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsPopupMenu.kt index f7c8e9652e4e..252f02ec2466 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsPopupMenu.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsPopupMenu.kt @@ -30,7 +30,7 @@ import android.view.ViewGroup import android.widget.ListPopupWindow import android.widget.ListView import android.widget.PopupWindow -import com.android.systemui.R +import com.android.systemui.res.R import kotlin.math.max class ControlsPopupMenu(context: Context) : ListPopupWindow(context) { diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt index 3cdf9ab69942..be9a2993dab1 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt @@ -51,7 +51,7 @@ import android.widget.Space import android.widget.TextView import androidx.annotation.VisibleForTesting import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.controls.ControlsMetricsLogger import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.controls.CustomIconCache diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt index 98f17f409184..9b93522b2d5f 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt @@ -34,7 +34,7 @@ import android.view.WindowInsets.Type import android.view.WindowManager import android.widget.ImageView import com.android.internal.policy.ScreenDecorationsUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.broadcast.BroadcastSender import com.android.systemui.plugins.ActivityStarter import com.android.systemui.statusbar.policy.KeyguardStateController diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt index db009dc46d89..1b0d03276415 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt @@ -28,7 +28,7 @@ import android.graphics.drawable.ShapeDrawable import android.graphics.drawable.shapes.RoundRectShape import android.os.Trace import com.android.internal.annotations.VisibleForTesting -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.util.boundsOnScreen import com.android.wm.shell.taskview.TaskView import java.util.concurrent.Executor diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt index dbbda9aad518..ac589eb900a3 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt @@ -26,7 +26,7 @@ import android.service.controls.templates.TemperatureControlTemplate import android.util.ArrayMap import android.util.SparseArray -import com.android.systemui.R +import com.android.systemui.res.R data class RenderInfo( val icon: Drawable, diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt index 3c2bfa0efc39..0706a9670561 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt @@ -26,7 +26,7 @@ import android.service.controls.Control import android.view.View import android.view.WindowManager -import com.android.systemui.R +import com.android.systemui.res.R class StatusBehavior : Behavior { lateinit var cvh: ControlViewHolder diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt index 39d69704d817..2c9eb3e058bd 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt @@ -22,7 +22,7 @@ import android.service.controls.Control import android.service.controls.templates.ControlTemplate import android.service.controls.templates.TemperatureControlTemplate -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.controls.ui.ControlViewHolder.Companion.MIN_LEVEL import com.android.systemui.controls.ui.ControlViewHolder.Companion.MAX_LEVEL diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ThumbnailBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ThumbnailBehavior.kt index d011dd421f7f..41907882a443 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ThumbnailBehavior.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ThumbnailBehavior.kt @@ -26,7 +26,7 @@ import android.service.controls.templates.TemperatureControlTemplate import android.service.controls.templates.ThumbnailTemplate import android.util.TypedValue -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.controls.ui.ControlViewHolder.Companion.MAX_LEVEL import com.android.systemui.controls.ui.ControlViewHolder.Companion.MIN_LEVEL diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt index dc7247cd7096..4f47012b3e93 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt @@ -23,7 +23,7 @@ import android.service.controls.templates.TemperatureControlTemplate import android.service.controls.templates.ToggleTemplate import android.util.Log import android.view.View -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.controls.ui.ControlViewHolder.Companion.MAX_LEVEL class ToggleBehavior : Behavior { diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt index 0d570d2dcc73..e34a94b6ccf7 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt @@ -37,7 +37,7 @@ import android.view.View import android.view.ViewGroup import android.view.accessibility.AccessibilityEvent import android.view.accessibility.AccessibilityNodeInfo -import com.android.systemui.R +import com.android.systemui.res.R import com.android.app.animation.Interpolators import com.android.systemui.controls.ui.ControlViewHolder.Companion.MAX_LEVEL import com.android.systemui.controls.ui.ControlViewHolder.Companion.MIN_LEVEL diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt index 9dd0f534e3a8..580a61556740 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt @@ -23,7 +23,7 @@ import android.service.controls.Control import android.service.controls.templates.ControlTemplate import android.service.controls.templates.StatelessTemplate -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.controls.ui.ControlViewHolder.Companion.MAX_LEVEL import com.android.systemui.controls.ui.ControlViewHolder.Companion.MIN_LEVEL diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index 58ba3c9c9915..a325ee203838 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -35,6 +35,7 @@ import com.android.systemui.assist.AssistModule; import com.android.systemui.authentication.AuthenticationModule; import com.android.systemui.biometrics.AlternateUdfpsTouchProvider; import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider; +import com.android.systemui.biometrics.FingerprintReEnrollNotification; import com.android.systemui.biometrics.UdfpsDisplayModeProvider; import com.android.systemui.biometrics.dagger.BiometricsModule; import com.android.systemui.bouncer.ui.BouncerViewModule; @@ -299,6 +300,9 @@ public abstract class SystemUIModule { @BindsOptionalOf abstract SystemStatusAnimationScheduler optionalSystemStatusAnimationScheduler(); + @BindsOptionalOf + abstract FingerprintReEnrollNotification optionalFingerprintReEnrollNotification(); + @SysUISingleton @Binds abstract SystemClock bindSystemClock(SystemClockImpl systemClock); diff --git a/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderImpl.kt index ded0fb79cd6f..dbe6b0ba3719 100644 --- a/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderImpl.kt @@ -21,7 +21,7 @@ import android.view.DisplayCutout import android.view.Surface import android.view.View import android.view.ViewGroup -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.ScreenDecorations.DisplayCutoutView class CutoutDecorProviderImpl( diff --git a/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt b/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt index ac0d3c8f3d36..31a5d37a4450 100644 --- a/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt @@ -115,7 +115,7 @@ class FaceScanningOverlayProviderImpl( private val logger: ScreenDecorationsLogger, private val featureFlags: FeatureFlags, ) : BoundDecorProvider() { - override val viewId: Int = com.android.systemui.R.id.face_scanning_anim + override val viewId: Int = com.android.systemui.res.R.id.face_scanning_anim override fun onReloadResAndMeasure( view: View, diff --git a/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt b/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt index 8cfd39148f1c..14ecc66f555e 100644 --- a/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt @@ -23,7 +23,7 @@ import android.view.LayoutInflater import android.view.Surface import android.view.View import android.view.ViewGroup -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderFactory.kt b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderFactory.kt index 0ffb4fb5b456..2f2c952fb778 100644 --- a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderFactory.kt @@ -17,7 +17,7 @@ package com.android.systemui.decor import android.view.DisplayCutout -import com.android.systemui.R +import com.android.systemui.res.R class RoundedCornerDecorProviderFactory( private val roundedCornerResDelegate: RoundedCornerResDelegate diff --git a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt index 8156797c5a67..0ee11ae84e48 100644 --- a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt @@ -25,7 +25,7 @@ import android.view.View import android.view.ViewGroup import android.widget.FrameLayout import android.widget.ImageView -import com.android.systemui.R +import com.android.systemui.res.R class RoundedCornerDecorProviderImpl( override val viewId: Int, diff --git a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt index c64766a3eb3c..0314b0fe2ca3 100644 --- a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt +++ b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt @@ -24,7 +24,7 @@ import android.util.DisplayUtils import android.util.Size import android.view.RoundedCorners import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import java.io.PrintWriter interface RoundedCornerResDelegate { diff --git a/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt b/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt index f730935e1b73..7510cf6ce04c 100644 --- a/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt @@ -22,7 +22,7 @@ import android.view.Gravity import android.view.View import android.view.WindowManager import android.widget.TextView -import com.android.systemui.R +import com.android.systemui.res.R /** * Dialog used to decide what to do with a connected display. diff --git a/packages/SystemUI/src/com/android/systemui/doze/AlwaysOnDisplayPolicy.java b/packages/SystemUI/src/com/android/systemui/doze/AlwaysOnDisplayPolicy.java index 55df7792e2e6..8e542b59a7cc 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/AlwaysOnDisplayPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/doze/AlwaysOnDisplayPolicy.java @@ -28,7 +28,7 @@ import android.text.format.DateUtils; import android.util.KeyValueListParser; import android.util.Log; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import javax.inject.Inject; diff --git a/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java b/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java index d408472efca5..db0c3c68107a 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java +++ b/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java @@ -20,7 +20,7 @@ import android.content.Context; import android.hardware.Sensor; import android.os.Handler; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.doze.DozeAuthRemover; diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt index 01fb5227749f..4cfed33af95b 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt +++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt @@ -27,7 +27,7 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.android.app.animation.Interpolators import com.android.dream.lowlight.util.TruncatedInterpolator -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.complication.ComplicationHostViewController import com.android.systemui.complication.ComplicationLayoutParams import com.android.systemui.complication.ComplicationLayoutParams.POSITION_BOTTOM diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java index 78ac45325072..d0f255943a84 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java @@ -33,7 +33,7 @@ import android.view.ViewGroup; import com.android.app.animation.Interpolators; import com.android.dream.lowlight.LowLightTransitionCoordinator; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.complication.ComplicationHostViewController; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dreams.dagger.DreamOverlayComponent; diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayDotImageView.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayDotImageView.java index 02a8b39a106a..409b196fe525 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayDotImageView.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayDotImageView.java @@ -31,7 +31,7 @@ import android.util.AttributeSet; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.AlphaOptimizedImageView; /** diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java index 1865c38632e5..8e77079e0b5d 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java @@ -26,7 +26,7 @@ import android.view.ViewGroup; import androidx.constraintlayout.widget.ConstraintLayout; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.shared.shadow.DoubleShadowIconDrawable; import com.android.systemui.shared.shadow.DoubleShadowTextHelper.ShadowInfo; import com.android.systemui.statusbar.AlphaOptimizedImageView; diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java index a6401b6594ba..8d8702ebc6c7 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java @@ -32,7 +32,7 @@ import android.view.View; import androidx.annotation.Nullable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dreams.DreamOverlayStatusBarItemsProvider.StatusBarItem; import com.android.systemui.dreams.dagger.DreamOverlayComponent; diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationModule.kt b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationModule.kt index 95c225de9598..6fd6f4e3d4eb 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationModule.kt +++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationModule.kt @@ -1,7 +1,7 @@ package com.android.systemui.dreams.complication.dagger import android.content.res.Resources -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.qualifiers.Main import dagger.Module import dagger.Provides diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java index 4bafe325cda0..5ebb2ddcff36 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java @@ -23,7 +23,7 @@ import android.content.res.Resources; import com.android.dream.lowlight.dagger.LowLightDreamModule; import com.android.settingslib.dream.DreamBackend; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.complication.dagger.RegisteredComplicationsModule; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java index 51eefd6bed37..34dd10084116 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java @@ -25,7 +25,7 @@ import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleOwner; import com.android.internal.util.Preconditions; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dreams.DreamOverlayContainerView; import com.android.systemui.dreams.DreamOverlayStatusBarView; diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java index 5f03743f48b8..8cf11a9817b7 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java @@ -21,7 +21,7 @@ import android.content.res.Resources; import android.util.TypedValue; import android.view.VelocityTracker; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dreams.touch.BouncerSwipeTouchHandler; import com.android.systemui.dreams.touch.DreamTouchHandler; diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/ShadeModule.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/ShadeModule.java index 9e0ae4119f24..94fe4bd04dab 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/ShadeModule.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/ShadeModule.java @@ -18,7 +18,7 @@ package com.android.systemui.dreams.touch.dagger; import android.content.res.Resources; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dreams.touch.DreamTouchHandler; import com.android.systemui.dreams.touch.ShadeTouchHandler; diff --git a/packages/SystemUI/src/com/android/systemui/dump/SystemUIConfigDumpable.kt b/packages/SystemUI/src/com/android/systemui/dump/SystemUIConfigDumpable.kt index b70edcc27254..7a441d6b4a6b 100644 --- a/packages/SystemUI/src/com/android/systemui/dump/SystemUIConfigDumpable.kt +++ b/packages/SystemUI/src/com/android/systemui/dump/SystemUIConfigDumpable.kt @@ -19,7 +19,7 @@ package com.android.systemui.dump import android.content.Context import com.android.systemui.CoreStartable import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import java.io.PrintWriter import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index 02575eb8adf4..e170849e487f 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -17,7 +17,7 @@ package com.android.systemui.flags import android.provider.DeviceConfig import com.android.internal.annotations.Keep -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.flags.FlagsFactory.releasedFlag import com.android.systemui.flags.FlagsFactory.resourceBooleanFlag import com.android.systemui.flags.FlagsFactory.sysPropBooleanFlag @@ -250,10 +250,6 @@ object Flags { // TODO(b/277961132): Tracking bug. @JvmField val REVAMPED_BOUNCER_MESSAGES = unreleasedFlag("revamped_bouncer_messages") - /** Whether to delay showing bouncer UI when face auth or active unlock are enrolled. */ - // TODO(b/279794160): Tracking bug. - @JvmField val DELAY_BOUNCER = releasedFlag("delay_bouncer") - /** Keyguard Migration */ /** @@ -390,13 +386,15 @@ object Flags { // 600- status bar // TODO(b/291315866): Tracking Bug - @JvmField val SIGNAL_CALLBACK_DEPRECATION = unreleasedFlag("signal_callback_deprecation") + @JvmField val SIGNAL_CALLBACK_DEPRECATION = + unreleasedFlag("signal_callback_deprecation", teamfood = true) // TODO(b/265892345): Tracking Bug val PLUG_IN_STATUS_BAR_CHIP = releasedFlag("plug_in_status_bar_chip") // TODO(b/292533677): Tracking Bug - val WIFI_TRACKER_LIB_FOR_WIFI_ICON = releasedFlag("wifi_tracker_lib_for_wifi_icon") + val WIFI_TRACKER_LIB_FOR_WIFI_ICON = + unreleasedFlag("wifi_tracker_lib_for_wifi_icon", teamfood = true) // TODO(b/293863612): Tracking Bug @JvmField val INCOMPATIBLE_CHARGING_BATTERY_ICON = @@ -757,7 +755,7 @@ object Flags { unreleasedFlag("enable_new_privacy_dialog", teamfood = true) // TODO(b/289573946): Tracking Bug - @JvmField val PRECOMPUTED_TEXT = unreleasedFlag("precomputed_text") + @JvmField val PRECOMPUTED_TEXT = unreleasedFlag("precomputed_text", teamfood = true) // 2900 - CentralSurfaces-related flags @@ -795,7 +793,8 @@ object Flags { // TODO(b/287205379): Tracking bug @JvmField - val QS_CONTAINER_GRAPH_OPTIMIZER = unreleasedFlag( "qs_container_graph_optimizer") + val QS_CONTAINER_GRAPH_OPTIMIZER = unreleasedFlag( "qs_container_graph_optimizer", + teamfood = true) /** Enable showing a dialog when clicking on Quick Settings bluetooth tile. */ @JvmField diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsColumnLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsColumnLayout.java index 59070287cc5c..a3065d3cca59 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsColumnLayout.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsColumnLayout.java @@ -26,7 +26,7 @@ import android.view.Gravity; import android.view.View; import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Grid-based implementation of the button layout created by the global actions dialog. diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java index 3eb17400446c..ac402303bf69 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java @@ -546,8 +546,8 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene */ @VisibleForTesting protected int getMaxShownPowerItems() { - return mResources.getInteger(com.android.systemui.R.integer.power_menu_lite_max_columns) - * mResources.getInteger(com.android.systemui.R.integer.power_menu_lite_max_rows); + return mResources.getInteger(com.android.systemui.res.R.integer.power_menu_lite_max_columns) + * mResources.getInteger(com.android.systemui.res.R.integer.power_menu_lite_max_rows); } /** @@ -698,7 +698,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene ActionsDialogLite dialog = new ActionsDialogLite( mContext, - com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActionsLite, + com.android.systemui.res.R.style.Theme_SystemUI_Dialog_GlobalActionsLite, mAdapter, mOverflowAdapter, mSysuiColorExtractor, @@ -776,7 +776,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene @VisibleForTesting protected final class PowerOptionsAction extends SinglePressAction { private PowerOptionsAction() { - super(com.android.systemui.R.drawable.ic_settings_power, + super(com.android.systemui.res.R.drawable.ic_settings_power, R.string.global_action_power_options); } @@ -884,17 +884,17 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene protected int getEmergencyTextColor(Context context) { return context.getResources().getColor( - com.android.systemui.R.color.global_actions_lite_text); + com.android.systemui.res.R.color.global_actions_lite_text); } protected int getEmergencyIconColor(Context context) { return context.getResources().getColor( - com.android.systemui.R.color.global_actions_lite_emergency_icon); + com.android.systemui.res.R.color.global_actions_lite_emergency_icon); } protected int getEmergencyBackgroundColor(Context context) { return context.getResources().getColor( - com.android.systemui.R.color.global_actions_lite_emergency_background); + com.android.systemui.res.R.color.global_actions_lite_emergency_background); } private class EmergencyAffordanceAction extends EmergencyAction { @@ -912,7 +912,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene @VisibleForTesting class EmergencyDialerAction extends EmergencyAction { private EmergencyDialerAction() { - super(com.android.systemui.R.drawable.ic_emergency_star, + super(com.android.systemui.res.R.drawable.ic_emergency_star, R.string.global_action_emergency); } @@ -1482,7 +1482,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene Log.w(TAG, "No power options action found at position: " + position); return null; } - int viewLayoutResource = com.android.systemui.R.layout.global_actions_power_item; + int viewLayoutResource = com.android.systemui.res.R.layout.global_actions_power_item; View view = convertView != null ? convertView : LayoutInflater.from(mContext).inflate(viewLayoutResource, parent, false); view.setOnClickListener(v -> onClickItem(position)); @@ -1564,7 +1564,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene Log.w(TAG, "No overflow action found at position: " + position); return null; } - int viewLayoutResource = com.android.systemui.R.layout.controls_more_item; + int viewLayoutResource = com.android.systemui.res.R.layout.controls_more_item; View view = convertView != null ? convertView : LayoutInflater.from(mContext).inflate(viewLayoutResource, parent, false); TextView textView = (TextView) view; @@ -1778,7 +1778,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene } protected int getGridItemLayoutResource() { - return com.android.systemui.R.layout.global_actions_grid_item_lite; + return com.android.systemui.res.R.layout.global_actions_grid_item_lite; } private enum ToggleState { @@ -1870,7 +1870,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene LayoutInflater inflater) { willCreate(); - View v = inflater.inflate(com.android.systemui.R.layout.global_actions_grid_item_v2, + View v = inflater.inflate(com.android.systemui.res.R.layout.global_actions_grid_item_v2, parent, false /* attach */); ViewGroup.LayoutParams p = v.getLayoutParams(); p.width = WRAP_CONTENT; @@ -2327,7 +2327,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setTitle(getContext().getString( - com.android.systemui.R.string.accessibility_quick_settings_power_menu)); + com.android.systemui.res.R.string.accessibility_quick_settings_power_menu)); initializeLayout(); mWindowDimAmount = getWindow().getAttributes().dimAmount; getOnBackInvokedDispatcher().registerOnBackInvokedCallback( @@ -2379,14 +2379,14 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene GlobalActionsPopupMenu popup = new GlobalActionsPopupMenu( new ContextThemeWrapper( mContext, - com.android.systemui.R.style.Control_ListPopupWindow + com.android.systemui.res.R.style.Control_ListPopupWindow ), false /* isDropDownMode */); popup.setOnItemClickListener( (parent, view, position, id) -> mOverflowAdapter.onClickItem(position)); popup.setOnItemLongClickListener( (parent, view, position, id) -> mOverflowAdapter.onLongClickItem(position)); View overflowButton = - findViewById(com.android.systemui.R.id.global_actions_overflow_button); + findViewById(com.android.systemui.res.R.id.global_actions_overflow_button); popup.setAnchorView(overflowButton); popup.setAdapter(mOverflowAdapter); return popup; @@ -2403,14 +2403,14 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene } protected int getLayoutResource() { - return com.android.systemui.R.layout.global_actions_grid_lite; + return com.android.systemui.res.R.layout.global_actions_grid_lite; } protected void initializeLayout() { setContentView(getLayoutResource()); fixNavBarClipping(); - mGlobalActionsLayout = findViewById(com.android.systemui.R.id.global_actions_view); + mGlobalActionsLayout = findViewById(com.android.systemui.res.R.id.global_actions_view); mGlobalActionsLayout.setListViewAccessibilityDelegate(new View.AccessibilityDelegate() { @Override public boolean dispatchPopulateAccessibilityEvent( @@ -2422,14 +2422,14 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene }); mGlobalActionsLayout.setRotationListener(this::onRotate); mGlobalActionsLayout.setAdapter(mAdapter); - mContainer = findViewById(com.android.systemui.R.id.global_actions_container); + mContainer = findViewById(com.android.systemui.res.R.id.global_actions_container); mContainer.setOnTouchListener((v, event) -> { mGestureDetector.onTouchEvent(event); return v.onTouchEvent(event); }); View overflowButton = findViewById( - com.android.systemui.R.id.global_actions_overflow_button); + com.android.systemui.res.R.id.global_actions_overflow_button); if (overflowButton != null) { if (mOverflowAdapter.getCount() > 0) { overflowButton.setOnClickListener((view) -> showPowerOverflowMenu()); @@ -2442,7 +2442,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mGlobalActionsLayout.getLayoutParams(); params.setMarginEnd(mContext.getResources().getDimensionPixelSize( - com.android.systemui.R.dimen.global_actions_side_margin)); + com.android.systemui.res.R.dimen.global_actions_side_margin)); mGlobalActionsLayout.setLayoutParams(params); } } @@ -2473,7 +2473,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene private void showSmartLockDisabledMessage() { // Since power menu is the top window, make a Toast-like view that will show up View message = LayoutInflater.from(mContext) - .inflate(com.android.systemui.R.layout.global_actions_toast, mContainer, false); + .inflate(com.android.systemui.res.R.layout.global_actions_toast, mContainer, false); // Set up animation AccessibilityManager mAccessibilityManager = diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java index 83046ef450c3..bc1e13f772fa 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java @@ -27,7 +27,7 @@ import android.view.ViewGroup; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.HardwareBgDrawable; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Flat, single-row implementation of the button layout created by the global actions dialog. @@ -55,7 +55,7 @@ public class GlobalActionsFlatLayout extends GlobalActionsLayout { } private View getOverflowButton() { - return findViewById(com.android.systemui.R.id.global_actions_overflow_button); + return findViewById(com.android.systemui.res.R.id.global_actions_overflow_button); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java index e1462d15c887..2272b8a888cd 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java @@ -148,7 +148,7 @@ public class GlobalActionsGridLayout extends GlobalActionsLayout { protected float getAnimationDistance() { int rows = getListView().getRowCount(); float gridItemSize = getContext().getResources().getDimension( - com.android.systemui.R.dimen.global_actions_grid_item_height); + com.android.systemui.res.R.dimen.global_actions_grid_item_height); return rows * gridItemSize / 2; } diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayout.java index 183ee458acb4..6afefb040626 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayout.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayout.java @@ -25,7 +25,7 @@ import android.view.ViewGroup; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.HardwareBgDrawable; import com.android.systemui.MultiListLayout; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.util.leak.RotationUtils; import java.util.Locale; diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayoutLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayoutLite.java index 42230aed15d5..9b318a288caf 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayoutLite.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayoutLite.java @@ -25,7 +25,7 @@ import androidx.constraintlayout.helper.widget.Flow; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.HardwareBgDrawable; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * ConstraintLayout implementation of the button layout created by the global actions dialog. @@ -53,7 +53,7 @@ public class GlobalActionsLayoutLite extends GlobalActionsLayout { public void onUpdateList() { super.onUpdateList(); int nElementsWrap = getResources().getInteger( - com.android.systemui.R.integer.power_menu_lite_max_columns); + com.android.systemui.res.R.integer.power_menu_lite_max_columns); int nChildren = getListView().getChildCount() - 1; // don't count flow element // Avoid having just one action on the last row if there are more than 2 columns because diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java index 6d083f6c8bfd..b9a6a5515729 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java @@ -27,7 +27,7 @@ import android.widget.ListAdapter; import android.widget.ListPopupWindow; import android.widget.ListView; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Customized widget for use in the GlobalActionsDialog. Ensures common positioning and user diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPowerDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPowerDialog.java index caa88a372036..b8bf1428bb28 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPowerDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPowerDialog.java @@ -36,7 +36,7 @@ public class GlobalActionsPowerDialog { */ public static Dialog create(@NonNull Context context, ListAdapter adapter) { ViewGroup listView = (ViewGroup) LayoutInflater.from(context).inflate( - com.android.systemui.R.layout.global_actions_power_dialog, null); + com.android.systemui.res.R.layout.global_actions_power_dialog, null); for (int i = 0; i < adapter.getCount(); i++) { View action = adapter.getView(i, null, listView); @@ -53,7 +53,7 @@ public class GlobalActionsPowerDialog { window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY); window.setTitle(""); // prevent Talkback from speaking first item name twice window.setBackgroundDrawable(res.getDrawable( - com.android.systemui.R.drawable.control_background, context.getTheme())); + com.android.systemui.res.R.drawable.control_background, context.getTheme())); window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); return dialog; diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/ShutdownUi.java b/packages/SystemUI/src/com/android/systemui/globalactions/ShutdownUi.java index 68dc1b3dc7d7..51978ece14db 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/ShutdownUi.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/ShutdownUi.java @@ -59,7 +59,7 @@ public class ShutdownUi { ScrimDrawable background = new ScrimDrawable(); final Dialog d = new Dialog(mContext, - com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions); + com.android.systemui.res.R.style.Theme_SystemUI_Dialog_GlobalActions); d.setOnShowListener(dialog -> { if (mBlurUtils.supportsBlursOnWindows()) { @@ -69,7 +69,7 @@ public class ShutdownUi { (int) mBlurUtils.blurRadiusOfRatio(1), backgroundAlpha == 255); } else { float backgroundAlpha = mContext.getResources().getFloat( - com.android.systemui.R.dimen.shutdown_scrim_behind_alpha); + com.android.systemui.res.R.dimen.shutdown_scrim_behind_alpha); background.setAlpha((int) (backgroundAlpha * 255)); } }); @@ -96,7 +96,7 @@ public class ShutdownUi { | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); window.setBackgroundDrawable(background); - window.setWindowAnimations(com.android.systemui.R.style.Animation_ShutdownUi); + window.setWindowAnimations(com.android.systemui.res.R.style.Animation_ShutdownUi); d.setContentView(getShutdownDialogContent(isReboot)); d.setCancelable(false); @@ -104,10 +104,10 @@ public class ShutdownUi { int color; if (mBlurUtils.supportsBlursOnWindows()) { color = Utils.getColorAttrDefaultColor(mContext, - com.android.systemui.R.attr.wallpaperTextColor); + com.android.systemui.res.R.attr.wallpaperTextColor); } else { color = mContext.getResources().getColor( - com.android.systemui.R.color.global_actions_shutdown_ui_text); + com.android.systemui.res.R.color.global_actions_shutdown_ui_text); } ProgressBar bar = d.findViewById(R.id.progress); diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTracker.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTracker.kt new file mode 100644 index 000000000000..cc51d21744e8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTracker.kt @@ -0,0 +1,212 @@ +/* + * 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.haptics.slider + +import androidx.annotation.VisibleForTesting +import com.android.systemui.dagger.qualifiers.Main +import kotlin.math.abs +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch + +/** + * Slider tracker attached to a seekable slider. + * + * The tracker runs a state machine to execute actions on touch-based events typical of a seekable + * slider such as [android.widget.SeekBar]. Coroutines responsible for running the state machine, + * collecting slider events and maintaining waiting states are run on the main thread via the + * [com.android.systemui.dagger.qualifiers.Main] coroutine dispatcher. + * + * @param[sliderStateListener] Listener of the slider state. + * @param[sliderEventProducer] Producer of slider events arising from the slider. + * @property[scope] [CoroutineScope] where the collection of slider events and the launch of timer + * jobs occur. + * @property[config] Configuration parameters of the slider tracker. + */ +class SeekableSliderTracker( + sliderStateListener: SliderStateListener, + sliderEventProducer: SliderEventProducer, + @Main mainDispatcher: CoroutineDispatcher, + private val config: SeekableSliderTrackerConfig = SeekableSliderTrackerConfig(), +) : SliderTracker(CoroutineScope(mainDispatcher), sliderStateListener, sliderEventProducer) { + + // History of the latest progress collected from slider events + private var latestProgress = 0f + // Timer job for the wait state + private var timerJob: Job? = null + // Indicator that there is waiting job active + var isWaiting = false + private set + get() = timerJob != null && timerJob?.isActive == true + + override suspend fun iterateState(event: SliderEvent) { + when (currentState) { + SliderState.IDLE -> handleIdle(event.type) + SliderState.WAIT -> handleWait(event.type, event.currentProgress) + SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH -> handleAcquired(event.type) + SliderState.DRAG_HANDLE_DRAGGING -> handleDragging(event.type, event.currentProgress) + SliderState.DRAG_HANDLE_REACHED_BOOKEND -> + handleReachedBookend(event.type, event.currentProgress) + SliderState.DRAG_HANDLE_RELEASED_FROM_TOUCH -> setState(SliderState.IDLE) + SliderState.JUMP_TRACK_LOCATION_SELECTED -> handleJumpToTrack(event.type) + SliderState.JUMP_BOOKEND_SELECTED -> handleJumpToBookend(event.type) + } + latestProgress = event.currentProgress + } + + private fun handleIdle(newEventType: SliderEventType) { + if (newEventType == SliderEventType.STARTED_TRACKING_TOUCH) { + timerJob = launchTimer() + // The WAIT state will wait for the timer to complete or a slider progress to occur. + // This will disambiguate between an imprecise touch that acquires the slider handle, + // and a select and jump operation in the slider track. + setState(SliderState.WAIT) + } + } + + private fun launchTimer() = + scope.launch { + delay(config.waitTimeMillis) + if (isActive && currentState == SliderState.WAIT) { + setState(SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH) + // This transitory state must also trigger the corresponding action + executeOnState(currentState) + } + } + + private fun handleWait(newEventType: SliderEventType, currentProgress: Float) { + // The timer may have completed and may have already modified the state + if (currentState != SliderState.WAIT) return + + // The timer is still running but the state may be modified by the progress change + val deltaProgressIsJump = deltaProgressIsAboveThreshold(currentProgress) + if (newEventType == SliderEventType.PROGRESS_CHANGE_BY_USER) { + if (bookendReached(currentProgress)) { + setState(SliderState.JUMP_BOOKEND_SELECTED) + } else if (deltaProgressIsJump) { + setState(SliderState.JUMP_TRACK_LOCATION_SELECTED) + } else { + setState(SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH) + } + } else if (newEventType == SliderEventType.STOPPED_TRACKING_TOUCH) { + setState(SliderState.IDLE) + } + + // If the state changed, the timer does not need to complete. No further synchronization + // will be required onwards until WAIT is reached again. + if (currentState != SliderState.WAIT) { + timerJob?.cancel() + timerJob = null + } + } + + private fun handleAcquired(newEventType: SliderEventType) { + if (newEventType == SliderEventType.STOPPED_TRACKING_TOUCH) { + setState(SliderState.DRAG_HANDLE_RELEASED_FROM_TOUCH) + } else if (newEventType == SliderEventType.PROGRESS_CHANGE_BY_USER) { + setState(SliderState.DRAG_HANDLE_DRAGGING) + } + } + + private fun handleDragging(newEventType: SliderEventType, currentProgress: Float) { + if (newEventType == SliderEventType.STOPPED_TRACKING_TOUCH) { + setState(SliderState.DRAG_HANDLE_RELEASED_FROM_TOUCH) + } else if ( + newEventType == SliderEventType.PROGRESS_CHANGE_BY_USER && + bookendReached(currentProgress) + ) { + setState(SliderState.DRAG_HANDLE_REACHED_BOOKEND) + } + } + + private fun handleReachedBookend(newEventType: SliderEventType, currentProgress: Float) { + if (newEventType == SliderEventType.PROGRESS_CHANGE_BY_USER) { + if (!bookendReached(currentProgress)) { + setState(SliderState.DRAG_HANDLE_DRAGGING) + } + } else if (newEventType == SliderEventType.STOPPED_TRACKING_TOUCH) { + setState(SliderState.DRAG_HANDLE_RELEASED_FROM_TOUCH) + } + } + + private fun handleJumpToTrack(newEventType: SliderEventType) { + when (newEventType) { + SliderEventType.PROGRESS_CHANGE_BY_USER -> setState(SliderState.DRAG_HANDLE_DRAGGING) + SliderEventType.STOPPED_TRACKING_TOUCH -> + setState(SliderState.DRAG_HANDLE_RELEASED_FROM_TOUCH) + else -> {} + } + } + + private fun handleJumpToBookend(newEventType: SliderEventType) { + when (newEventType) { + SliderEventType.PROGRESS_CHANGE_BY_USER -> setState(SliderState.DRAG_HANDLE_DRAGGING) + SliderEventType.STOPPED_TRACKING_TOUCH -> + setState(SliderState.DRAG_HANDLE_RELEASED_FROM_TOUCH) + else -> {} + } + } + + override fun executeOnState(currentState: SliderState) { + when (currentState) { + SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH -> sliderListener.onHandleAcquiredByTouch() + SliderState.DRAG_HANDLE_RELEASED_FROM_TOUCH -> { + sliderListener.onHandleReleasedFromTouch() + // This transitory state must also reset the state machine + resetState() + } + SliderState.DRAG_HANDLE_DRAGGING -> sliderListener.onProgress(latestProgress) + SliderState.DRAG_HANDLE_REACHED_BOOKEND -> executeOnBookend() + SliderState.JUMP_TRACK_LOCATION_SELECTED -> + sliderListener.onProgressJump(latestProgress) + SliderState.JUMP_BOOKEND_SELECTED -> executeOnBookend() + else -> {} + } + } + + private fun executeOnBookend() { + if (latestProgress >= config.upperBookendThreshold) sliderListener.onUpperBookend() + else sliderListener.onLowerBookend() + } + + override fun resetState() { + timerJob?.cancel() + timerJob = null + super.resetState() + } + + private fun deltaProgressIsAboveThreshold( + currentProgress: Float, + epsilon: Float = 0.00001f, + ): Boolean { + val delta = abs(currentProgress - latestProgress) + return abs(delta - config.jumpThreshold) < epsilon + } + + private fun bookendReached(currentProgress: Float): Boolean { + return currentProgress >= config.upperBookendThreshold || + currentProgress <= config.lowerBookendThreshold + } + + @VisibleForTesting + fun setState(state: SliderState) { + currentState = state + } +} diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTrackerConfig.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTrackerConfig.kt new file mode 100644 index 000000000000..cb0f43b8235a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/haptics/slider/SeekableSliderTrackerConfig.kt @@ -0,0 +1,37 @@ +/* + * 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.haptics.slider + +import androidx.annotation.FloatRange + +/** + * Configuration parameters of a seekable slider tracker. + * + * @property[waitTimeMillis] Wait period to determine if a touch event acquires the slider handle. + * @property[jumpThreshold] Threshold on the slider progress to detect if a touch event is qualified + * as an imprecise acquisition of the slider handle. + * @property[lowerBookendThreshold] Threshold to determine the progress on the slider that qualifies + * as reaching the lower bookend. + * @property[upperBookendThreshold] Threshold to determine the progress on the slider that qualifies + * as reaching the upper bookend. + */ +data class SeekableSliderTrackerConfig( + val waitTimeMillis: Long = 100, + @FloatRange(from = 0.0, to = 1.0) val jumpThreshold: Float = 0.02f, + @FloatRange(from = 0.0, to = 1.0) val lowerBookendThreshold: Float = 0.05f, + @FloatRange(from = 0.0, to = 1.0) val upperBookendThreshold: Float = 0.95f, +) diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderHapticFeedbackConfig.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderHapticFeedbackConfig.kt new file mode 100644 index 000000000000..20d99d1e75fb --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderHapticFeedbackConfig.kt @@ -0,0 +1,43 @@ +/* + * 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.haptics.slider + +import androidx.annotation.FloatRange + +/** Configuration parameters of a [SliderHapticFeedbackProvider] */ +data class SliderHapticFeedbackConfig( + /** Interpolator factor for velocity-based vibration scale interpolations. Must be positive */ + val velocityInterpolatorFactor: Float = 1f, + /** Interpolator factor for progress-based vibration scale interpolations. Must be positive */ + val progressInterpolatorFactor: Float = 1f, + /** Minimum vibration scale for vibrations based on slider progress */ + @FloatRange(from = 0.0, to = 1.0) val progressBasedDragMinScale: Float = 0f, + /** Maximum vibration scale for vibrations based on slider progress */ + @FloatRange(from = 0.0, to = 1.0) val progressBasedDragMaxScale: Float = 0.2f, + /** Additional vibration scaling due to velocity */ + @FloatRange(from = 0.0, to = 1.0) val additionalVelocityMaxBump: Float = 0.15f, + /** Additional time delta to wait between drag texture vibrations */ + @FloatRange(from = 0.0) val deltaMillisForDragInterval: Float = 0f, + /** Number of low ticks in a drag texture composition. This is not expected to change */ + val numberOfLowTicks: Int = 5, + /** Maximum velocity allowed for vibration scaling. This is not expected to change. */ + val maxVelocityToScale: Float = 2000f, /* In pixels/sec */ + /** Vibration scale at the upper bookend of the slider */ + @FloatRange(from = 0.0, to = 1.0) val upperBookendScale: Float = 1f, + /** Vibration scale at the lower bookend of the slider */ + @FloatRange(from = 0.0, to = 1.0) val lowerBookendScale: Float = 0.05f, +) diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderHapticFeedbackProvider.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderHapticFeedbackProvider.kt new file mode 100644 index 000000000000..e6de156de0c4 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderHapticFeedbackProvider.kt @@ -0,0 +1,160 @@ +/* + * 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.haptics.slider + +import android.os.VibrationAttributes +import android.os.VibrationEffect +import android.view.VelocityTracker +import android.view.animation.AccelerateInterpolator +import androidx.annotation.FloatRange +import com.android.systemui.statusbar.VibratorHelper +import kotlin.math.abs +import kotlin.math.min + +/** + * Listener of slider events that triggers haptic feedback. + * + * @property[vibratorHelper] Singleton instance of the [VibratorHelper] to deliver haptics. + * @property[velocityTracker] Instance of a [VelocityTracker] that tracks slider dragging velocity. + * @property[config] Configuration parameters for vibration encapsulated as a + * [SliderHapticFeedbackConfig]. + * @property[clock] Clock to obtain elapsed real time values. + */ +class SliderHapticFeedbackProvider( + private val vibratorHelper: VibratorHelper, + private val velocityTracker: VelocityTracker, + private val config: SliderHapticFeedbackConfig = SliderHapticFeedbackConfig(), + private val clock: com.android.systemui.util.time.SystemClock, +) : SliderStateListener { + + private val velocityAccelerateInterpolator = + AccelerateInterpolator(config.velocityInterpolatorFactor) + private val positionAccelerateInterpolator = + AccelerateInterpolator(config.progressInterpolatorFactor) + private var dragTextureLastTime = clock.elapsedRealtime() + private val lowTickDurationMs = + vibratorHelper.getPrimitiveDurations(VibrationEffect.Composition.PRIMITIVE_LOW_TICK)[0] + private var hasVibratedAtLowerBookend = false + private var hasVibratedAtUpperBookend = false + + /** Time threshold to wait before making new API call. */ + private val thresholdUntilNextDragCallMillis = + lowTickDurationMs * config.numberOfLowTicks + config.deltaMillisForDragInterval + + /** + * Vibrate when the handle reaches either bookend with a certain velocity. + * + * @param[absoluteVelocity] Velocity of the handle when it reached the bookend. + */ + private fun vibrateOnEdgeCollision(absoluteVelocity: Float) { + val velocityInterpolated = + velocityAccelerateInterpolator.getInterpolation( + min(absoluteVelocity / config.maxVelocityToScale, 1f) + ) + val bookendScaleRange = config.upperBookendScale - config.lowerBookendScale + val bookendsHitScale = bookendScaleRange * velocityInterpolated + config.lowerBookendScale + + val vibration = + VibrationEffect.startComposition() + .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, bookendsHitScale) + .compose() + vibratorHelper.vibrate(vibration, VIBRATION_ATTRIBUTES_PIPELINING) + } + + /** + * Create a drag texture vibration based on velocity and slider progress. + * + * @param[absoluteVelocity] Absolute velocity of the handle. + * @param[normalizedSliderProgress] Progress of the slider handled normalized to the range from + * 0F to 1F (inclusive). + */ + private fun vibrateDragTexture( + absoluteVelocity: Float, + @FloatRange(from = 0.0, to = 1.0) normalizedSliderProgress: Float + ) { + // Check if its time to vibrate + val currentTime = clock.elapsedRealtime() + val elapsedSinceLastDrag = currentTime - dragTextureLastTime + if (elapsedSinceLastDrag < thresholdUntilNextDragCallMillis) return + + val velocityInterpolated = + velocityAccelerateInterpolator.getInterpolation( + min(absoluteVelocity / config.maxVelocityToScale, 1f) + ) + + // Scaling of vibration due to the position of the slider + val positionScaleRange = config.progressBasedDragMaxScale - config.progressBasedDragMinScale + val sliderProgressInterpolated = + positionAccelerateInterpolator.getInterpolation(normalizedSliderProgress) + val positionBasedScale = + positionScaleRange * sliderProgressInterpolated + config.progressBasedDragMinScale + + // Scaling bump due to velocity + val velocityBasedScale = velocityInterpolated * config.additionalVelocityMaxBump + + // Total scale + val scale = positionBasedScale + velocityBasedScale + + // Trigger the vibration composition + val composition = VibrationEffect.startComposition() + repeat(config.numberOfLowTicks) { + composition.addPrimitive(VibrationEffect.Composition.PRIMITIVE_LOW_TICK, scale) + } + vibratorHelper.vibrate(composition.compose(), VIBRATION_ATTRIBUTES_PIPELINING) + dragTextureLastTime = currentTime + } + + override fun onHandleAcquiredByTouch() {} + + override fun onHandleReleasedFromTouch() {} + + override fun onLowerBookend() { + if (!hasVibratedAtLowerBookend) { + velocityTracker.computeCurrentVelocity(UNITS_SECOND, config.maxVelocityToScale) + vibrateOnEdgeCollision(abs(velocityTracker.xVelocity)) + hasVibratedAtLowerBookend = true + } + } + + override fun onUpperBookend() { + if (!hasVibratedAtUpperBookend) { + velocityTracker.computeCurrentVelocity(UNITS_SECOND, config.maxVelocityToScale) + vibrateOnEdgeCollision(abs(velocityTracker.xVelocity)) + hasVibratedAtUpperBookend = true + } + } + + override fun onProgress(@FloatRange(from = 0.0, to = 1.0) progress: Float) { + velocityTracker.computeCurrentVelocity(UNITS_SECOND, config.maxVelocityToScale) + vibrateDragTexture(abs(velocityTracker.xVelocity), progress) + hasVibratedAtUpperBookend = false + hasVibratedAtLowerBookend = false + } + + override fun onProgressJump(@FloatRange(from = 0.0, to = 1.0) progress: Float) {} + + override fun onSelectAndArrow(@FloatRange(from = 0.0, to = 1.0) progress: Float) {} + + private companion object { + private val VIBRATION_ATTRIBUTES_PIPELINING = + VibrationAttributes.Builder() + .setUsage(VibrationAttributes.USAGE_TOUCH) + .setFlags(VibrationAttributes.FLAG_PIPELINED_EFFECT) + .build() + private const val UNITS_SECOND = 1000 + } +} diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderState.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderState.kt new file mode 100644 index 000000000000..fe092e67036b --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderState.kt @@ -0,0 +1,37 @@ +/* + * 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.haptics.slider + +/** State of a slider */ +enum class SliderState { + /* The slider is idle */ + IDLE, + /* Waiting state to disambiguate between handle acquisition and select and jump operations */ + WAIT, + /* The slider handle was acquired by touch. */ + DRAG_HANDLE_ACQUIRED_BY_TOUCH, + /* The slider handle was released. */ + DRAG_HANDLE_RELEASED_FROM_TOUCH, + /* The slider handle is being dragged by touch. */ + DRAG_HANDLE_DRAGGING, + /* The slider handle reached a bookend. */ + DRAG_HANDLE_REACHED_BOOKEND, + /* A location in the slider track has been selected. */ + JUMP_TRACK_LOCATION_SELECTED, + /* The slider handled moved to a bookend after it was selected. */ + JUMP_BOOKEND_SELECTED, +} diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderStateListener.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderStateListener.kt new file mode 100644 index 000000000000..9c99c90bb910 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderStateListener.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.haptics.slider + +import androidx.annotation.FloatRange + +/** Listener of events from a slider (such as [android.widget.SeekBar]) */ +interface SliderStateListener { + + /** Notification that the handle is acquired by touch */ + fun onHandleAcquiredByTouch() + + /** Notification that the handle was released from touch */ + fun onHandleReleasedFromTouch() + + /** Notification that the handle reached the lower bookend */ + fun onLowerBookend() + + /** Notification that the handle reached the upper bookend */ + fun onUpperBookend() + + /** + * Notification that the slider reached a certain progress on the slider track. + * + * This method is called in all intermediate steps of a continuous progress change as the slider + * moves through the slider track. + * + * @param[progress] The progress of the slider in the range from 0F to 1F (inclusive). + */ + fun onProgress(@FloatRange(from = 0.0, to = 1.0) progress: Float) + + /** + * Notification that the slider handle jumped to a selected progress on the slider track. + * + * This method is specific to the case when the handle performed a single jump to a position on + * the slider track and reached the corresponding progress. In this case, [onProgress] is not + * called and the new progress reached is represented by the [progress] parameter. + * + * @param[progress] The selected progress on the slider track that the handle jumps to. The + * progress is in the range from 0F to 1F (inclusive). + */ + fun onProgressJump(@FloatRange(from = 0.0, to = 1.0) progress: Float) + + /** + * Notification that the slider handle was moved by a button press. + * + * @param[progress] The progress of the slider in the range from 0F to 1F (inclusive). + */ + fun onSelectAndArrow(@FloatRange(from = 0.0, to = 1.0) progress: Float) +} diff --git a/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderTracker.kt b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderTracker.kt new file mode 100644 index 000000000000..e1f57089d792 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/haptics/slider/SliderTracker.kt @@ -0,0 +1,93 @@ +/* + * 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.haptics.slider + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch + +/** + * Tracker component for a slider. + * + * The tracker maintains a state machine operated by slider events coming from a + * [SliderEventProducer]. An action is executed in each state via a [SliderListener]. + * + * @param[scope] [CoroutineScope] to launch the collection of [SliderEvent]. + * @property[sliderListener] [SliderListener] to execute actions on a given [SliderState]. + * @property[eventProducer] Producer of [SliderEvent] to iterate over a state machine. + */ +sealed class SliderTracker( + protected val scope: CoroutineScope, + protected val sliderListener: SliderStateListener, + protected val eventProducer: SliderEventProducer, +) { + + /* Reference to the current state of the internal state machine */ + var currentState: SliderState = SliderState.IDLE + protected set + + /** + * Job that launches and maintains the coroutine that collects events and operates the state + * machine. + */ + protected var job: Job? = null + + /** Indicator that the tracker is active and tracking */ + var isTracking = false + get() = job != null && job?.isActive == true + private set + + /** Starts the [Job] that collects slider events and runs the state machine */ + fun startTracking() { + job = + scope.launch { + eventProducer.produceEvents().collect { event -> + iterateState(event) + executeOnState(currentState) + } + } + } + + /** Stops the collection of slider events and the state machine */ + fun stopTracking() { + job?.cancel("Stopped tracking slider state") + job = null + resetState() + } + + /** + * Iterate through the state machine due to a new slider event. As a result, the current state + * is modified. + * + * @param[event] The slider event that is received. + */ + protected abstract suspend fun iterateState(event: SliderEvent) + + /** + * Execute an action based on the state of the state machine. This method should use the + * [SliderListener] to act on the current state. + * + * @param[currentState] A [SliderState] in the state machine + */ + protected abstract fun executeOnState(currentState: SliderState) + + /** Reset the state machine by setting the current state to [SliderState.IDLE] */ + protected open fun resetState() { + currentState = SliderState.IDLE + } +} diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java index ad7973ed0b7a..1cdbe6fed58a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java +++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java @@ -50,7 +50,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothAdapter; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import com.android.systemui.CoreStartable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.util.settings.SecureSettings; diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt index 6f25f7c1921a..e16bb0bb8482 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt @@ -38,7 +38,7 @@ import android.widget.LinearLayout.LayoutParams.WRAP_CONTENT import androidx.annotation.IdRes import androidx.core.view.setPadding import com.android.settingslib.Utils -import com.android.systemui.R +import com.android.systemui.res.R class KeyboardBacklightDialog( context: Context, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java index 732102e0cf9e..1f69cc0a8ec3 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java @@ -48,7 +48,7 @@ import androidx.slice.builders.SliceAction; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SystemUIAppComponentFactoryBase; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.plugins.statusbar.StatusBarStateController; diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt index 22bcf0aa2799..fb02c7d68a9f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt @@ -26,7 +26,7 @@ import com.android.keyguard.LockIconView import com.android.keyguard.LockIconViewController import com.android.keyguard.dagger.KeyguardStatusViewComponent import com.android.systemui.CoreStartable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 9241776191d4..efd25d5d69e6 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -128,7 +128,7 @@ import com.android.systemui.CoreStartable; import com.android.systemui.DejankUtils; import com.android.systemui.Dumpable; import com.android.systemui.EventLogTags; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.LaunchAnimator; import com.android.systemui.broadcast.BroadcastDispatcher; @@ -764,6 +764,13 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, } } } + + @Override + public void onStrongAuthStateChanged(int userId) { + if (mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) { + doKeyguardLocked(null); + } + } }; ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() { @@ -1961,6 +1968,10 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, mExternallyEnabled = enabled; if (!enabled && mShowing) { + if (mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) { + Log.d(TAG, "keyguardEnabled(false) overridden by user lockdown"); + return; + } // hiding keyguard that is showing, remember to reshow later if (DEBUG) Log.d(TAG, "remembering to reshow, hiding keyguard, " + "disabling status bar expansion"); @@ -2187,7 +2198,8 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, */ private void doKeyguardLocked(Bundle options) { // if another app is disabling us, don't show - if (!mExternallyEnabled) { + if (!mExternallyEnabled + && !mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) { if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled"); mNeedToReshowWhenReenabled = true; @@ -3231,7 +3243,11 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, + "mPendingLock=" + mPendingLock + "." + "One of these being false means we re-locked the device during unlock. " + "Do not proceed to finish keyguard exit and unlock."); + doKeyguardLocked(null); finishSurfaceBehindRemoteAnimation(true /* showKeyguard */); + // Ensure WM is notified that we made a decision to show + setShowingLocked(true /* showing */, true /* force */); + return; } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java index ffd8a0244a86..d5316cd40801 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java @@ -30,7 +30,7 @@ import android.util.DisplayMetrics; import androidx.annotation.Nullable; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dump.DumpManager; import com.android.systemui.util.time.SystemClock; diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt index 75677f2d9e9a..8ebcece940c2 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt @@ -45,8 +45,13 @@ constructor( /** * Whether the lockscreen is showing, which we pass to [IActivityTaskManager.setLockScreenShown] * in order to show the lockscreen and hide the surface behind the keyguard (or the inverse). + * + * This value is null if we have not yet called setLockScreenShown with any value. This will + * happen during the boot sequence, but we can't default to true here since otherwise we'll + * short-circuit on the first call to setLockScreenShown since we'll think we're already + * showing. */ - private var isLockscreenShowing = true + private var isLockscreenShowing: Boolean? = null /** * Whether AOD is showing, which we pass to [IActivityTaskManager.setLockScreenShown] in order @@ -102,7 +107,7 @@ constructor( // The surface behind is always visible if the lockscreen is not showing, so we're already // visible. - if (visible && !isLockscreenShowing) { + if (visible && isLockscreenShowing != true) { Log.d(TAG, "#setVisibility -> already visible since the lockscreen isn't showing") return } @@ -159,9 +164,23 @@ constructor( } } + /** + * Sets the lockscreen state WM-side by calling ATMS#setLockScreenShown. + * + * [lockscreenShowing] defaults to true, since it's only ever null during the boot sequence, + * when we haven't yet called ATMS#setLockScreenShown. Typically, + * setWmLockscreenState(lockscreenShowing = true) is called early in the boot sequence, before + * setWmLockscreenState(aodVisible = true), so we don't expect to need to use this default, but + * if so, true should be the right choice. + */ private fun setWmLockscreenState( - lockscreenShowing: Boolean = this.isLockscreenShowing, - aodVisible: Boolean = this.isAodVisible + lockscreenShowing: Boolean = this.isLockscreenShowing ?: true.also { + Log.d(TAG, "Using isLockscreenShowing=true default in setWmLockscreenState, " + + "because setAodVisible was called before the first setLockscreenShown " + + "call during boot. This is not typical, but is theoretically possible. " + + "If you're investigating the lockscreen showing unexpectedly, start here.") + }, + aodVisible: Boolean = this.isAodVisible ) { Log.d( TAG, @@ -201,6 +220,6 @@ constructor( } companion object { - private val TAG = this::class.java.simpleName + private val TAG = WindowManagerLockscreenVisibilityManager::class.java.simpleName } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java index 82be009a7560..09875a52e07d 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java @@ -37,7 +37,7 @@ import android.window.OnBackInvokedCallback; import android.window.OnBackInvokedDispatcher; import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastDispatcher; import javax.inject.Inject; diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt index 5e5caba060ae..77e8179195a1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt @@ -21,7 +21,7 @@ import android.app.StatusBarManager import android.app.admin.DevicePolicyManager import android.content.Context import android.content.pm.PackageManager -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.camera.CameraGestureHelper import com.android.systemui.common.shared.model.ContentDescription diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt index 16385ec59aa7..9b5f4615a6d5 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt @@ -27,7 +27,7 @@ import android.provider.Settings.Secure.ZEN_DURATION_PROMPT import android.service.notification.ZenModeConfig import com.android.settingslib.notification.EnableZenModeDialog import com.android.settingslib.notification.ZenModeDialogMetricsLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt index ed8823a53fe2..a7999c192643 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt @@ -18,7 +18,7 @@ package com.android.systemui.keyguard.data.quickaffordance import android.content.Context -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt index f3fc8096f5d7..4e71ef4e34f2 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt @@ -21,7 +21,7 @@ import android.content.ComponentName import android.content.Context import android.content.Intent import androidx.annotation.DrawableRes -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt index 320d158fb13e..1cf6183fec6c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt @@ -21,7 +21,7 @@ import android.app.AlertDialog import android.content.Context import android.content.Intent import android.net.Uri -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.common.shared.model.Icon import com.android.systemui.keyguard.shared.quickaffordance.ActivationState diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt index 4dad17907aca..deedbdb9e72b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt @@ -20,7 +20,7 @@ package com.android.systemui.keyguard.data.quickaffordance import android.content.Context import android.content.IntentFilter import android.content.SharedPreferences -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.backup.BackupHelper import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt index 250356819baf..1fe94d5fa43b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt @@ -21,7 +21,7 @@ import android.content.Context import android.media.AudioManager import androidx.lifecycle.LiveData import androidx.lifecycle.Observer -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.common.shared.model.ContentDescription diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt index 45277b833ea3..a503541dcf59 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt @@ -18,7 +18,7 @@ package com.android.systemui.keyguard.data.quickaffordance import android.content.Context -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt index 23f50eaba7e7..7337292a9ac5 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt @@ -24,7 +24,7 @@ import android.service.quickaccesswallet.GetWalletCardsResponse import android.service.quickaccesswallet.QuickAccessWalletClient import android.service.quickaccesswallet.WalletCard import android.util.Log -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt index 1ccc689da368..bbdd90375ece 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt @@ -22,7 +22,7 @@ import android.app.admin.DevicePolicyManager import android.content.Context import android.content.Intent import com.android.systemui.ActivityIntentHelper -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.camera.CameraIntents import com.android.systemui.camera.CameraIntentsWrapper diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt index 682e841c3521..06cf7235ad2c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt @@ -26,7 +26,7 @@ import android.os.UserHandle import android.util.Log import com.android.internal.widget.LockPatternUtils import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.AuthController import com.android.systemui.biometrics.data.repository.FacePropertyRepository import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt index 233acd90aee3..fd048ff11f14 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt @@ -18,14 +18,13 @@ package com.android.systemui.keyguard.data.repository import android.app.StatusBarManager import android.content.Context -import android.hardware.face.FaceAuthenticateOptions import android.hardware.face.FaceManager import android.os.CancellationSignal import com.android.internal.logging.InstanceId import com.android.internal.logging.UiEventLogger import com.android.keyguard.FaceAuthUiEvent import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging @@ -47,6 +46,7 @@ import com.android.systemui.keyguard.shared.model.FailedFaceAuthenticationStatus import com.android.systemui.keyguard.shared.model.HelpFaceAuthenticationStatus import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.SuccessFaceAuthenticationStatus +import com.android.systemui.keyguard.shared.model.SysUiFaceAuthenticateOptions import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.log.FaceAuthenticationLogger import com.android.systemui.log.SessionTracker @@ -578,7 +578,12 @@ constructor( authCancellationSignal, faceAuthCallback, null, - FaceAuthenticateOptions.Builder().setUserId(currentUserId).build() + SysUiFaceAuthenticateOptions( + currentUserId, + uiEvent, + wakeReason = uiEvent.extraInfo + ) + .toFaceAuthenticateOptions() ) } } else if (canRunDetection.value) { @@ -587,7 +592,7 @@ constructor( uiEvent, "face auth gating check is false, falling back to detection." ) - detect() + detect(uiEvent) } else { faceAuthLogger.ignoredFaceAuthTrigger( uiEvent = uiEvent, @@ -602,7 +607,7 @@ constructor( } } - suspend fun detect() { + suspend fun detect(uiEvent: FaceAuthUiEvent) { if (!isDetectionSupported) { faceAuthLogger.detectionNotSupported(faceManager, faceManager?.sensorPropertiesInternal) return @@ -619,7 +624,8 @@ constructor( faceManager?.detectFace( checkNotNull(detectCancellationSignal), detectionCallback, - FaceAuthenticateOptions.Builder().setUserId(currentUserId).build() + SysUiFaceAuthenticateOptions(currentUserId, uiEvent, uiEvent.extraInfo) + .toFaceAuthenticateOptions() ) } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt index 34f6b4d74f2b..698328ecd7fb 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt @@ -22,7 +22,7 @@ import android.content.Intent import android.os.UserHandle import android.util.LayoutDirection import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow import com.android.systemui.dagger.SysUISingleton diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepository.kt index 1c0b73fcfa2d..af01626c5c1d 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepository.kt @@ -22,7 +22,7 @@ import android.content.Context import android.graphics.Point import androidx.core.animation.Animator import androidx.core.animation.ValueAnimator -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.shared.model.BiometricUnlockModel import com.android.systemui.keyguard.shared.model.BiometricUnlockSource diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt index ac936b10fe43..b2e436cd2af6 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt @@ -19,7 +19,7 @@ package com.android.systemui.keyguard.domain.interactor import android.content.Context import androidx.annotation.DimenRes -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.ui.data.repository.ConfigurationRepository import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application 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 9c6a1b1b6cc0..8f3943133eb1 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 @@ -265,7 +265,11 @@ constructor( !isKeyguardUnlocked && statusBarState == KEYGUARD ) { - transitionId = startTransitionTo(KeyguardState.PRIMARY_BOUNCER) + transitionId = + startTransitionTo( + toState = KeyguardState.PRIMARY_BOUNCER, + animator = null, // transition will be manually controlled + ) } } } 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 572785721b4f..338f9945f5db 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 @@ -23,7 +23,7 @@ import android.app.StatusBarManager import android.graphics.Point import android.util.MathUtils import com.android.app.animation.Interpolators -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt index a257f529357f..299c8cf410cc 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt @@ -24,7 +24,7 @@ import android.view.accessibility.AccessibilityManager import androidx.annotation.VisibleForTesting import com.android.internal.logging.UiEvent import com.android.internal.logging.UiEventLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt index 7f43cbc69fa2..de791aa23e22 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt @@ -23,7 +23,7 @@ import android.content.Context import android.content.Intent import android.util.Log import com.android.internal.widget.LockPatternUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.DialogLaunchAnimator import com.android.systemui.animation.Expandable import com.android.systemui.dagger.SysUISingleton diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt index f0df3a2e6a6f..20e55e527fc2 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt @@ -19,9 +19,10 @@ package com.android.systemui.keyguard.domain.interactor import android.content.Context import android.hardware.biometrics.BiometricFaceConstants import com.android.keyguard.FaceAuthUiEvent +import com.android.keyguard.FaceWakeUpTriggersConfig import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.CoreStartable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.data.repository.FacePropertyRepository import com.android.systemui.biometrics.shared.model.LockoutMode import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor @@ -31,8 +32,10 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags +import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository import com.android.systemui.keyguard.data.repository.DeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository +import com.android.systemui.keyguard.data.repository.KeyguardRepository import com.android.systemui.keyguard.shared.model.ErrorFaceAuthenticationStatus import com.android.systemui.keyguard.shared.model.FaceAuthenticationStatus import com.android.systemui.keyguard.shared.model.TransitionState @@ -40,6 +43,7 @@ import com.android.systemui.log.FaceAuthenticationLogger import com.android.systemui.user.data.model.SelectionStatus import com.android.systemui.user.data.repository.UserRepository import com.android.systemui.util.kotlin.pairwise +import com.android.systemui.util.kotlin.sample import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope @@ -75,6 +79,8 @@ constructor( private val deviceEntryFingerprintAuthRepository: DeviceEntryFingerprintAuthRepository, private val userRepository: UserRepository, private val facePropertyRepository: FacePropertyRepository, + private val keyguardRepository: KeyguardRepository, + private val faceWakeUpTriggersConfig: FaceWakeUpTriggersConfig, ) : CoreStartable, KeyguardFaceAuthInteractor { private val listeners: MutableList<FaceAuthenticationListener> = mutableListOf() @@ -117,8 +123,21 @@ constructor( keyguardTransitionInteractor.dozingToLockscreenTransition ) .filter { it.transitionState == TransitionState.STARTED } + .sample(keyguardRepository.wakefulness) + .filter { wakefulnessModel -> + val validWakeupReason = + faceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom( + wakefulnessModel.lastWakeReason + ) + if (!validWakeupReason) { + faceAuthenticationLogger.ignoredWakeupReason(wakefulnessModel.lastWakeReason) + } + validWakeupReason + } .onEach { faceAuthenticationLogger.lockscreenBecameVisible(it) + FaceAuthUiEvent.FACE_AUTH_UPDATED_KEYGUARD_VISIBILITY_CHANGED.extraInfo = + it.lastWakeReason.powerManagerWakeReason runFaceAuth( FaceAuthUiEvent.FACE_AUTH_UPDATED_KEYGUARD_VISIBILITY_CHANGED, fallbackToDetect = true diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/WakeSleepReason.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/WakeSleepReason.kt index c8a04fdbca52..3602be8e62a4 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/WakeSleepReason.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/WakeSleepReason.kt @@ -21,18 +21,37 @@ import android.os.PowerManager /** The reason we're waking up or going to sleep, such as pressing the power button. */ enum class WakeSleepReason( val isTouch: Boolean, + @PowerManager.WakeReason val powerManagerWakeReason: Int, ) { /** The physical power button was pressed to wake up or sleep the device. */ - POWER_BUTTON(isTouch = false), + POWER_BUTTON(isTouch = false, PowerManager.WAKE_REASON_POWER_BUTTON), /** The user has tapped or double tapped to wake the screen. */ - TAP(isTouch = true), + TAP(isTouch = true, PowerManager.WAKE_REASON_TAP), /** The user performed some sort of gesture to wake the screen. */ - GESTURE(isTouch = true), + GESTURE(isTouch = true, PowerManager.WAKE_REASON_GESTURE), + + /** Waking up because a wake key other than power was pressed. */ + KEY(isTouch = false, PowerManager.WAKE_REASON_WAKE_KEY), + + /** Waking up because a wake motion was performed */ + MOTION(isTouch = false, PowerManager.WAKE_REASON_WAKE_MOTION), + + /** Waking due to the lid being opened. */ + LID(isTouch = false, PowerManager.WAKE_REASON_LID), + + /** Waking the device due to unfolding of a foldable device. */ + UNFOLD(isTouch = false, PowerManager.WAKE_REASON_UNFOLD_DEVICE), + + /** Waking up due to a user performed lift gesture. */ + LIFT(isTouch = false, PowerManager.WAKE_REASON_LIFT), + + /** Waking up due to a user interacting with a biometric. */ + BIOMETRIC(isTouch = false, PowerManager.WAKE_REASON_BIOMETRIC), /** Something else happened to wake up or sleep the device. */ - OTHER(isTouch = false); + OTHER(isTouch = false, PowerManager.WAKE_REASON_UNKNOWN); companion object { fun fromPowerManagerWakeReason(reason: Int): WakeSleepReason { @@ -40,6 +59,12 @@ enum class WakeSleepReason( PowerManager.WAKE_REASON_POWER_BUTTON -> POWER_BUTTON PowerManager.WAKE_REASON_TAP -> TAP PowerManager.WAKE_REASON_GESTURE -> GESTURE + PowerManager.WAKE_REASON_WAKE_KEY -> KEY + PowerManager.WAKE_REASON_WAKE_MOTION -> MOTION + PowerManager.WAKE_REASON_LID -> LID + PowerManager.WAKE_REASON_UNFOLD_DEVICE -> UNFOLD + PowerManager.WAKE_REASON_LIFT -> LIFT + PowerManager.WAKE_REASON_BIOMETRIC -> BIOMETRIC else -> OTHER } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardAmbientIndicationAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardAmbientIndicationAreaViewBinder.kt index 5c072fbfdb01..5900a2467994 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardAmbientIndicationAreaViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardAmbientIndicationAreaViewBinder.kt @@ -22,7 +22,7 @@ import android.view.ViewGroup import android.view.ViewPropertyAnimator import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.keyguard.ui.viewmodel.KeyguardAmbientIndicationViewModel import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel import com.android.systemui.lifecycle.repeatWhenAttached 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 a9c71adc095d..dd7eee924007 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 @@ -32,7 +32,7 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.android.app.animation.Interpolators import com.android.settingslib.Utils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.ActivityLaunchAnimator import com.android.systemui.animation.Expandable import com.android.systemui.animation.view.LaunchableLinearLayout diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt index dc51944ddc08..f20a66604ebf 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt @@ -22,7 +22,7 @@ import android.view.ViewGroup import android.widget.TextView import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.ui.viewmodel.KeyguardIndicationAreaViewModel diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt index 7685345805f4..125e2dac7bb7 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceOnTouchListener.kt @@ -24,7 +24,7 @@ import android.view.ViewConfiguration import android.view.ViewPropertyAnimator import androidx.core.animation.CycleInterpolator import androidx.core.animation.ObjectAnimator -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.common.ui.view.rawDistanceFrom import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordanceViewModel diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt index 83b5463ea19c..eeb4ac34bf37 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt @@ -30,7 +30,7 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.android.app.animation.Interpolators import com.android.settingslib.Utils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.animation.view.LaunchableImageView import com.android.systemui.common.shared.model.Icon diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt index 4b768211dc61..f564d0073e42 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt @@ -23,7 +23,7 @@ import android.view.ViewGroup import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.android.app.animation.Interpolators -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Text import com.android.systemui.common.shared.model.TintedIcon diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt index 82610e6ea59d..6beef8ec1ff3 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt @@ -22,7 +22,7 @@ import android.view.View import androidx.core.view.isVisible import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.ActivityLaunchAnimator import com.android.systemui.animation.view.LaunchableLinearLayout import com.android.systemui.common.ui.binder.IconViewBinder diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/UdfpsKeyguardInternalViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/UdfpsKeyguardInternalViewBinder.kt index 3bb01f29aadf..aabb3f41e881 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/UdfpsKeyguardInternalViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/UdfpsKeyguardInternalViewBinder.kt @@ -18,7 +18,7 @@ package com.android.systemui.biometrics.ui.binder import android.view.View -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.keyguard.ui.binder.UdfpsAodFingerprintViewBinder import com.android.systemui.keyguard.ui.binder.UdfpsBackgroundViewBinder import com.android.systemui.keyguard.ui.binder.UdfpsFingerprintViewBinder diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/UdfpsKeyguardViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/UdfpsKeyguardViewBinder.kt index 667abaea0b24..a0e0da452036 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/UdfpsKeyguardViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/UdfpsKeyguardViewBinder.kt @@ -23,7 +23,7 @@ import android.widget.FrameLayout import androidx.asynclayoutinflater.view.AsyncLayoutInflater import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.UdfpsKeyguardView import com.android.systemui.biometrics.ui.binder.UdfpsKeyguardInternalViewBinder import com.android.systemui.keyguard.ui.viewmodel.BackgroundViewModel diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt index 85a2fd5a6d01..2ad74fbc6674 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt @@ -38,7 +38,7 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.view.isInvisible import com.android.keyguard.ClockEventController import com.android.keyguard.KeyguardClockSwitch -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.view.LaunchableImageView import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor import com.android.systemui.broadcast.BroadcastDispatcher diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardIndicationArea.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardIndicationArea.kt index 890d565b03a5..78099d9f5d90 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardIndicationArea.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardIndicationArea.kt @@ -25,7 +25,7 @@ import android.view.View import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import android.widget.LinearLayout -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.statusbar.phone.KeyguardIndicationTextView class KeyguardIndicationArea( diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt index 5aba229434d7..28e6a954a3d1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt @@ -25,7 +25,7 @@ import androidx.constraintlayout.widget.ConstraintSet.LEFT import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID import androidx.constraintlayout.widget.ConstraintSet.RIGHT import androidx.constraintlayout.widget.ConstraintSet.TOP -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt index ac11ba5b5ec6..669db34b97aa 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt @@ -26,7 +26,7 @@ import androidx.constraintlayout.widget.ConstraintSet.END import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID import androidx.constraintlayout.widget.ConstraintSet.START import androidx.constraintlayout.widget.ConstraintSet.TOP -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.shared.model.KeyguardSection diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/BaseShortcutSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/BaseShortcutSection.kt index d046a196e94e..a4137ac934a1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/BaseShortcutSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/BaseShortcutSection.kt @@ -4,7 +4,7 @@ import android.view.View import android.widget.ImageView import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.content.res.ResourcesCompat -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.view.LaunchableImageView import com.android.systemui.keyguard.shared.model.KeyguardSection import com.android.systemui.keyguard.ui.binder.KeyguardQuickAffordanceViewBinder diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultAmbientIndicationAreaSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultAmbientIndicationAreaSection.kt index ce86e9784180..9371d4e2d465 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultAmbientIndicationAreaSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultAmbientIndicationAreaSection.kt @@ -29,7 +29,7 @@ import androidx.constraintlayout.widget.ConstraintSet.START import androidx.constraintlayout.widget.ConstraintSet.TOP import androidx.constraintlayout.widget.ConstraintSet.WRAP_CONTENT import com.android.keyguard.KeyguardUpdateMonitor -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.shared.model.KeyguardSection diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSection.kt index a45223cbd449..623eac013a35 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSection.kt @@ -21,7 +21,7 @@ import android.content.Context import android.view.ViewGroup import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.shared.model.KeyguardSection diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSection.kt index 100099d3988e..9409036586e8 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSection.kt @@ -29,7 +29,7 @@ import androidx.constraintlayout.widget.ConstraintSet import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.LockIconView import com.android.keyguard.LockIconViewController -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.AuthController import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt index 7fff43b82e93..afa49bdd69d8 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt @@ -27,7 +27,7 @@ import androidx.constraintlayout.widget.ConstraintSet.END import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID import androidx.constraintlayout.widget.ConstraintSet.START import androidx.constraintlayout.widget.ConstraintSet.TOP -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.shared.model.KeyguardSection diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultSettingsPopupMenuSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultSettingsPopupMenuSection.kt index b25f9afc0d1e..6fd13e0931aa 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultSettingsPopupMenuSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultSettingsPopupMenuSection.kt @@ -28,7 +28,7 @@ import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID import androidx.constraintlayout.widget.ConstraintSet.START import androidx.constraintlayout.widget.ConstraintSet.WRAP_CONTENT import androidx.core.view.isVisible -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.view.LaunchableLinearLayout import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.flags.FeatureFlags diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt index 13ef985287f6..a67912017e54 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt @@ -24,7 +24,7 @@ import androidx.constraintlayout.widget.ConstraintSet.BOTTOM import androidx.constraintlayout.widget.ConstraintSet.LEFT import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID import androidx.constraintlayout.widget.ConstraintSet.RIGHT -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusBarSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusBarSection.kt index d6c69b3c442f..f713d5e312f1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusBarSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusBarSection.kt @@ -27,7 +27,7 @@ import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID import androidx.constraintlayout.widget.ConstraintSet.START import androidx.constraintlayout.widget.ConstraintSet.TOP import com.android.keyguard.dagger.KeyguardStatusBarViewComponent -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.shared.model.KeyguardSection diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt index 1cb10bd762a5..1a9f021a7622 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt @@ -31,7 +31,7 @@ import androidx.constraintlayout.widget.ConstraintSet.START import androidx.constraintlayout.widget.ConstraintSet.TOP import com.android.keyguard.KeyguardStatusView import com.android.keyguard.dagger.KeyguardStatusViewComponent -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.KeyguardViewConfigurator diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeGuidelines.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeGuidelines.kt index 5e3ea059ddd5..c8697717f1fd 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeGuidelines.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeGuidelines.kt @@ -20,7 +20,7 @@ package com.android.systemui.keyguard.ui.view.layout.sections import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet import androidx.constraintlayout.widget.ConstraintSet.VERTICAL -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.keyguard.shared.model.KeyguardSection import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt index 63d165daa303..33718c410905 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt @@ -18,7 +18,7 @@ package com.android.systemui.keyguard.ui.viewmodel import android.content.Context import android.content.res.Resources -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor import com.android.systemui.keyguard.shared.model.SettingsClockSize diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSettingsMenuViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSettingsMenuViewModel.kt index c36da9da58a5..66ceded2040d 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSettingsMenuViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSettingsMenuViewModel.kt @@ -17,7 +17,7 @@ package com.android.systemui.keyguard.ui.viewmodel -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Text import com.android.systemui.keyguard.domain.interactor.KeyguardLongPressInteractor diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModel.kt index 667c2f1bd998..c10a4635644f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModel.kt @@ -17,7 +17,7 @@ package com.android.systemui.keyguard.ui.viewmodel import android.content.Context -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.keyguard.domain.interactor.BurnInOffsets import com.android.systemui.keyguard.domain.interactor.UdfpsKeyguardInteractor import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModel.kt index dd586076be83..54abc5bc695f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModel.kt @@ -19,7 +19,7 @@ package com.android.systemui.keyguard.ui.viewmodel import android.content.Context import androidx.annotation.ColorInt import com.android.settingslib.Utils.getColorAttrDefaultColor -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.keyguard.domain.interactor.BurnInOffsets import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor diff --git a/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt index 8143f99c4d0a..66af36a71d38 100644 --- a/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt @@ -5,7 +5,8 @@ import android.hardware.face.FaceSensorPropertiesInternal import com.android.keyguard.FaceAuthUiEvent import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.shared.model.ErrorFaceAuthenticationStatus -import com.android.systemui.keyguard.shared.model.TransitionStep +import com.android.systemui.keyguard.shared.model.WakeSleepReason +import com.android.systemui.keyguard.shared.model.WakefulnessModel import com.android.systemui.log.core.LogLevel.DEBUG import com.android.systemui.log.dagger.FaceAuthLog import com.google.errorprone.annotations.CompileTimeConstant @@ -29,6 +30,18 @@ class FaceAuthenticationLogger constructor( @FaceAuthLog private val logBuffer: LogBuffer, ) { + + fun ignoredWakeupReason(lastWakeReason: WakeSleepReason) { + logBuffer.log( + TAG, + DEBUG, + { str1 = "$lastWakeReason" }, + { + "Ignoring off/aod/dozing -> Lockscreen transition " + + "because the last wake up reason is not allow-listed: $str1" + } + ) + } fun ignoredFaceAuthTrigger(uiEvent: FaceAuthUiEvent?, ignoredReason: String) { logBuffer.log( TAG, @@ -175,12 +188,12 @@ constructor( logBuffer.log(TAG, DEBUG, "Triggering face auth because alternate bouncer is visible") } - fun lockscreenBecameVisible(transitionStep: TransitionStep?) { + fun lockscreenBecameVisible(wake: WakefulnessModel?) { logBuffer.log( TAG, DEBUG, - { str1 = "$transitionStep" }, - { "Triggering face auth because lockscreen became visible due to transition: $str1" } + { str1 = "${wake?.lastWakeReason}" }, + { "Triggering face auth because lockscreen became visible due to wake reason: $str1" } ) } diff --git a/packages/SystemUI/src/com/android/systemui/logcat/LogAccessDialogActivity.java b/packages/SystemUI/src/com/android/systemui/logcat/LogAccessDialogActivity.java index 2cfe5a719f09..d01917a5d0fc 100644 --- a/packages/SystemUI/src/com/android/systemui/logcat/LogAccessDialogActivity.java +++ b/packages/SystemUI/src/com/android/systemui/logcat/LogAccessDialogActivity.java @@ -43,7 +43,7 @@ import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.ILogAccessDialogCallback; -import com.android.systemui.R; +import com.android.systemui.res.R; /** diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt index be487561961c..88bc064c60f7 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt @@ -46,7 +46,7 @@ import com.android.internal.app.chooser.TargetInfo import com.android.internal.widget.RecyclerView import com.android.internal.widget.RecyclerViewAccessibilityDelegate import com.android.internal.widget.ResolverDrawerLayout -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorComponent import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorController import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorResultHandler diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java index d403788f2c66..4de6278400b3 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java @@ -51,7 +51,7 @@ import android.text.style.StyleSpan; import android.util.Log; import android.view.Window; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver; diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/models/GutsViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/models/GutsViewHolder.kt index 531506771459..f5f5d388a278 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/models/GutsViewHolder.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/models/GutsViewHolder.kt @@ -22,7 +22,7 @@ import android.view.View import android.view.ViewGroup import android.widget.ImageButton import android.widget.TextView -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.media.controls.ui.accentPrimaryFromScheme import com.android.systemui.media.controls.ui.surfaceFromScheme import com.android.systemui.media.controls.ui.textPrimaryFromScheme 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 b7a2522037af..b98e9c232d58 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 @@ -21,7 +21,7 @@ import android.graphics.drawable.Drawable import android.graphics.drawable.Icon import android.media.session.MediaSession import com.android.internal.logging.InstanceId -import com.android.systemui.R +import com.android.systemui.res.R /** State of a media view. */ data class MediaData( 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 8b7426336b80..1b14f75d54ef 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 @@ -25,7 +25,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.res.R import com.android.systemui.media.controls.models.GutsViewHolder import com.android.systemui.surfaceeffects.ripple.MultiRippleView import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseView diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/SeekBarObserver.kt b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/SeekBarObserver.kt index 6eaff3fcb929..3f4f34745c4b 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/models/player/SeekBarObserver.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/models/player/SeekBarObserver.kt @@ -23,7 +23,7 @@ import androidx.annotation.UiThread import androidx.lifecycle.Observer import com.android.app.animation.Interpolators import com.android.internal.annotations.VisibleForTesting -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.media.controls.ui.SquigglyProgress /** diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/RecommendationViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/RecommendationViewHolder.kt index 258284e8af51..8ac8a2da4478 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/RecommendationViewHolder.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/RecommendationViewHolder.kt @@ -23,7 +23,7 @@ import android.widget.ImageView import android.widget.SeekBar import android.widget.TextView import com.android.internal.widget.CachingIconView -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.media.controls.models.GutsViewHolder import com.android.systemui.media.controls.ui.IlluminationDrawable import com.android.systemui.util.animation.TransitionLayout 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 e79fc74ffc86..0f3e0acd007d 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 @@ -60,7 +60,7 @@ import com.android.internal.annotations.Keep import com.android.internal.logging.InstanceId import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt index c90a3c10c6bd..1fe93ed5503d 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt @@ -32,7 +32,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager import com.android.settingslib.media.LocalMediaManager import com.android.settingslib.media.MediaDevice import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/IlluminationDrawable.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/IlluminationDrawable.kt index b9cc772e7136..5aa6824a98b1 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/IlluminationDrawable.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/IlluminationDrawable.kt @@ -37,7 +37,7 @@ import androidx.annotation.Keep import com.android.app.animation.Interpolators import com.android.internal.graphics.ColorUtils import com.android.internal.graphics.ColorUtils.blendARGB -import com.android.systemui.R +import com.android.systemui.res.R import org.xmlpull.v1.XmlPullParser private const val BACKGROUND_ANIM_DURATION = 370L diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/LightSourceDrawable.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/LightSourceDrawable.kt index 646d1d0ff0fc..6ee072d41ecc 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/LightSourceDrawable.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/LightSourceDrawable.kt @@ -37,7 +37,7 @@ import android.util.MathUtils.lerp import androidx.annotation.Keep import com.android.app.animation.Interpolators import com.android.internal.graphics.ColorUtils -import com.android.systemui.R +import com.android.systemui.res.R import org.xmlpull.v1.XmlPullParser private const val RIPPLE_ANIM_DURATION = 800L 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 38a6a8f3470b..e59fc15c3876 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 @@ -38,7 +38,7 @@ import com.android.internal.logging.InstanceId import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt index ec0c40ec69a3..126115294e75 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt @@ -29,7 +29,7 @@ import androidx.dynamicanimation.animation.SpringForce import com.android.internal.annotations.VisibleForTesting import com.android.settingslib.Utils import com.android.systemui.Gefingerpoken -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.classifier.Classifier.NOTIFICATION_DISMISS import com.android.systemui.media.controls.util.MediaUiEventLogger import com.android.systemui.plugins.FalsingManager 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 a12bc2c99d63..cce4cda8af8a 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 @@ -81,7 +81,7 @@ 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; +import com.android.systemui.res.R; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.GhostedViewLaunchAnimatorController; import com.android.systemui.bluetooth.BroadcastDialogController; 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 0b30e597ab1c..ae3c912d6d1b 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 @@ -35,7 +35,7 @@ import android.view.ViewGroupOverlay import androidx.annotation.VisibleForTesting import com.android.app.animation.Interpolators import com.android.keyguard.KeyguardViewController -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dreams.DreamOverlayStateController 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 1dd969f9bea5..b436f5d5a1ef 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 @@ -20,7 +20,7 @@ import android.content.Context import android.content.res.Configuration import androidx.annotation.VisibleForTesting import androidx.constraintlayout.widget.ConstraintSet -import com.android.systemui.R +import com.android.systemui.res.R 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 diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaUiEventLogger.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaUiEventLogger.kt index ea943be85f21..20ea60fa3a5f 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaUiEventLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaUiEventLogger.kt @@ -20,7 +20,7 @@ import com.android.internal.logging.InstanceId import com.android.internal.logging.InstanceIdSequence import com.android.internal.logging.UiEvent import com.android.internal.logging.UiEventLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.media.controls.models.player.MediaData import com.android.systemui.media.controls.ui.MediaHierarchyManager diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaItem.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaItem.java index 875a01087908..fbb84defc372 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaItem.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaItem.java @@ -19,7 +19,7 @@ package com.android.systemui.media.dialog; import androidx.annotation.IntDef; import com.android.settingslib.media.MediaDevice; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java index 26a7d048cf27..ff9495daaa22 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java @@ -41,7 +41,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.media.LocalMediaManager.MediaDeviceState; import com.android.settingslib.media.MediaDevice; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java index d88249830739..5958b0a24a5e 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java @@ -49,7 +49,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.settingslib.media.MediaDevice; import com.android.settingslib.utils.ThreadUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java index 3a1d8b0e238e..0c5a14f5720a 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java @@ -58,7 +58,7 @@ import androidx.core.graphics.drawable.IconCompat; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.statusbar.phone.SystemUIDialog; diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java index 11a16a427c6b..ac64300a6570 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java @@ -45,7 +45,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.media.BluetoothMediaDevice; import com.android.settingslib.media.MediaDevice; import com.android.settingslib.qrcode.QrCodeGenerator; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.statusbar.phone.SystemUIDialog; 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 7011ad992a91..426a497fa329 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java @@ -78,7 +78,7 @@ import com.android.settingslib.media.InfoMediaManager; import com.android.settingslib.media.LocalMediaManager; import com.android.settingslib.media.MediaDevice; import com.android.settingslib.utils.ThreadUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastSender; diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java index e5a6bb523916..4640a5d4d801 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java @@ -27,7 +27,7 @@ import androidx.core.graphics.drawable.IconCompat; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.dagger.SysUISingleton; diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSessionReleaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSessionReleaseDialog.java index 2680a2ff4567..87c9cd08abc3 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSessionReleaseDialog.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSessionReleaseDialog.java @@ -30,7 +30,7 @@ import android.view.WindowManager; import android.widget.Button; import android.widget.ImageView; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.phone.SystemUIDialog; /** diff --git a/packages/SystemUI/src/com/android/systemui/media/systemsounds/HomeSoundEffectController.java b/packages/SystemUI/src/com/android/systemui/media/systemsounds/HomeSoundEffectController.java index 0ba5f28c351f..9de2b4f4a97a 100644 --- a/packages/SystemUI/src/com/android/systemui/media/systemsounds/HomeSoundEffectController.java +++ b/packages/SystemUI/src/com/android/systemui/media/systemsounds/HomeSoundEffectController.java @@ -26,7 +26,7 @@ import android.media.AudioManager; import android.util.Slog; import com.android.systemui.CoreStartable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.TaskStackChangeListener; diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt index b29b5887545a..2f0e1298499c 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt @@ -21,7 +21,7 @@ import android.content.pm.PackageManager import android.graphics.drawable.Drawable import androidx.annotation.AttrRes import androidx.annotation.DrawableRes -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.TintedIcon diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt index da8e106d3019..6e9485e5947c 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt @@ -35,7 +35,7 @@ import android.view.accessibility.AccessibilityManager import android.view.View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE import android.view.View.ACCESSIBILITY_LIVE_REGION_NONE import com.android.internal.widget.CachingIconView -import com.android.systemui.R +import com.android.systemui.res.R import com.android.app.animation.Interpolators import com.android.internal.logging.InstanceId import com.android.systemui.common.shared.model.ContentDescription diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverRippleController.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverRippleController.kt index fbf7e25981da..fbd7fd3fe821 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverRippleController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverRippleController.kt @@ -20,7 +20,7 @@ import android.content.res.ColorStateList import android.view.View import android.view.WindowManager import com.android.settingslib.Utils -import com.android.systemui.R +import com.android.systemui.res.R import javax.inject.Inject /** diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt index d3efae427cb0..339145c71215 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt @@ -21,7 +21,7 @@ import android.content.Context import android.util.Log import androidx.annotation.StringRes import com.android.internal.logging.UiEventLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.shared.model.Text /** 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 87d0098805b3..e827a1ec099d 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 @@ -25,7 +25,7 @@ import com.android.internal.logging.UiEventLogger import com.android.internal.statusbar.IUndoMediaTransferCallback import com.android.systemui.CoreStartable import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.shared.model.Text import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dump.DumpManager diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionBlockerEmptyStateProvider.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionBlockerEmptyStateProvider.kt index 829b0ddbe3a8..950b695953ab 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionBlockerEmptyStateProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionBlockerEmptyStateProvider.kt @@ -21,7 +21,7 @@ import com.android.internal.R as AndroidR import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyState import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyStateProvider import com.android.internal.app.ResolverListAdapter -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.mediaprojection.devicepolicy.PersonalProfile import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt index cbb7e1d0ef83..fd1a683dc78f 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt @@ -26,7 +26,7 @@ import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorResultHandler import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorScope import com.android.systemui.mediaprojection.appselector.data.RecentTask diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionTaskView.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionTaskView.kt index 0c7705467e10..412c006806bf 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionTaskView.kt +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionTaskView.kt @@ -28,7 +28,7 @@ import android.view.View import android.view.WindowManager import androidx.core.content.getSystemService import androidx.core.content.res.use -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.mediaprojection.appselector.data.RecentTask import com.android.systemui.shared.recents.model.ThumbnailData import com.android.systemui.shared.recents.utilities.PreviewPositionHelper diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTaskViewHolder.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTaskViewHolder.kt index a09935b9fb6a..3fe040a0d715 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTaskViewHolder.kt +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTaskViewHolder.kt @@ -21,7 +21,7 @@ import android.view.View import android.view.ViewGroup import android.widget.ImageView import androidx.recyclerview.widget.RecyclerView.ViewHolder -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelector import com.android.systemui.mediaprojection.appselector.data.AppIconLoader import com.android.systemui.mediaprojection.appselector.data.RecentTask diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTasksAdapter.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTasksAdapter.kt index 6af50a0eb699..78dbd9245d8a 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTasksAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTasksAdapter.kt @@ -20,7 +20,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.mediaprojection.appselector.data.RecentTask import dagger.assisted.Assisted import dagger.assisted.AssistedFactory diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDisabledDialog.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDisabledDialog.kt index a6b3da04ad80..fc452288f86d 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDisabledDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDisabledDialog.kt @@ -16,7 +16,7 @@ package com.android.systemui.mediaprojection.devicepolicy import android.content.Context -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.statusbar.phone.SystemUIDialog /** Dialog that shows that screen capture is disabled on this device. */ diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinator.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinator.kt index a437139226de..7840da960a83 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinator.kt @@ -21,7 +21,7 @@ import android.app.NotificationChannel import android.app.NotificationManager import android.content.Context import android.util.Log -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java index c6f73efdfdb1..d7e062fb926f 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java @@ -233,6 +233,9 @@ public final class NavBarHelper implements Settings.Secure.getUriFor(Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED), false, mAssistContentObserver, UserHandle.USER_ALL); mContentResolver.registerContentObserver( + Settings.Secure.getUriFor(Secure.SEARCH_LONG_PRESS_HOME_ENABLED), + false, mAssistContentObserver, UserHandle.USER_ALL); + mContentResolver.registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED), false, mAssistContentObserver, UserHandle.USER_ALL); @@ -422,11 +425,17 @@ public final class NavBarHelper implements private void updateAssistantAvailability() { boolean assistantAvailableForUser = mAssistManagerLazy.get() .getAssistInfoForUser(mUserTracker.getUserId()) != null; - boolean longPressDefault = mContext.getResources().getBoolean( - com.android.internal.R.bool.config_assistLongPressHomeEnabledDefault); + + boolean overrideLongPressHome = mAssistManagerLazy.get() + .shouldOverrideAssist(AssistManager.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS); + boolean longPressDefault = mContext.getResources().getBoolean(overrideLongPressHome + ? com.android.internal.R.bool.config_searchLongPressHomeEnabledDefault + : com.android.internal.R.bool.config_assistLongPressHomeEnabledDefault); mLongPressHomeEnabled = Settings.Secure.getIntForUser(mContentResolver, - Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, longPressDefault ? 1 : 0, + overrideLongPressHome ? Secure.SEARCH_LONG_PRESS_HOME_ENABLED + : Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, longPressDefault ? 1 : 0, mUserTracker.getUserId()) != 0; + boolean gestureDefault = mContext.getResources().getBoolean( com.android.internal.R.bool.config_assistTouchGestureEnabledDefault); mAssistantTouchGestureEnabled = Settings.Secure.getIntForUser(mContentResolver, @@ -455,6 +464,7 @@ public final class NavBarHelper implements @Override public void setAssistantOverridesRequested(int[] invocationTypes) { mAssistManagerLazy.get().setAssistantOverridesRequested(invocationTypes); + updateAssistantAvailability(); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index 62b22c50c1dc..cb52a5fb53fa 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -112,7 +112,7 @@ import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.util.LatencyTracker; import com.android.internal.view.AppearanceRegion; import com.android.systemui.Gefingerpoken; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.assist.AssistManager; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.DisplayId; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java index 2a7704f13c3b..c1d98c9daf1d 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java @@ -36,7 +36,7 @@ import android.widget.Space; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.navigationbar.buttons.ButtonDispatcher; import com.android.systemui.navigationbar.buttons.KeyButtonView; import com.android.systemui.navigationbar.buttons.ReverseLinearLayout; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java index f6bfd6c8f9c5..3ef5094e55ed 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java @@ -21,7 +21,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.DisplayId; import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope; import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java index 1d73bc205dc4..3e34318a5fb5 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java @@ -24,7 +24,7 @@ import android.graphics.Rect; import android.util.SparseArray; import android.view.View; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope; import com.android.systemui.navigationbar.buttons.ButtonDispatcher; import com.android.systemui.settings.DisplayTracker; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java index 79e7b710c56e..4d6d95a05b1b 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java @@ -62,7 +62,7 @@ import com.android.app.animation.Interpolators; import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.Utils; import com.android.systemui.Gefingerpoken; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.model.SysUiState; import com.android.systemui.navigationbar.buttons.ButtonDispatcher; import com.android.systemui.navigationbar.buttons.ContextualButton; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/ScreenPinningNotify.java b/packages/SystemUI/src/com/android/systemui/navigationbar/ScreenPinningNotify.java index ac7baf592599..939c09603c22 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/ScreenPinningNotify.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/ScreenPinningNotify.java @@ -21,7 +21,7 @@ import android.os.SystemClock; import android.util.Slog; import android.widget.Toast; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysUIToast; /** diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java index 9305d0518732..bd3a0c1b0efa 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java @@ -26,7 +26,7 @@ import android.view.MotionEvent; import android.view.Surface; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.navigationbar.NavigationBarController; import com.android.systemui.navigationbar.NavigationBarView; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java index 702be72ff4ed..686faccc639a 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java @@ -40,7 +40,7 @@ import android.util.FloatProperty; import android.view.View; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Drawable for {@link KeyButtonView}s that supports tinting between two colors, rotation and shows diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java index 3529142467d5..dcf1a8e98f1c 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java @@ -58,7 +58,7 @@ import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.UiEventLoggerImpl; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.shared.system.QuickStepContract; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java index 8ff7b7ae8e59..d780f7c11608 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java @@ -28,7 +28,7 @@ import android.widget.FrameLayout; import androidx.annotation.VisibleForTesting; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.ArrayList; import java.util.Comparator; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java index b21b0017208c..3dfd2925a1b2 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java @@ -69,7 +69,7 @@ import androidx.annotation.DimenRes; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.internal.policy.GestureNavigationSettingsObserver; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.flags.FeatureFlags; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt index 9ddb78ae19ee..439b7e18e0df 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt @@ -5,7 +5,7 @@ import android.util.TypedValue import androidx.core.animation.Interpolator import androidx.core.animation.PathInterpolator import androidx.dynamicanimation.animation.SpringForce -import com.android.systemui.R +import com.android.systemui.res.R data class EdgePanelParams(private var resources: Resources) { diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java index ff22398cc3be..380846e17a13 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java @@ -51,7 +51,7 @@ import androidx.dynamicanimation.animation.SpringForce; import com.android.app.animation.Interpolators; import com.android.internal.util.LatencyTracker; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.plugins.NavigationEdgeBackPlugin; import com.android.systemui.settings.DisplayTracker; diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java index 913b65289e12..5a22c385cb51 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java @@ -28,7 +28,7 @@ import android.view.ContextThemeWrapper; import android.view.View; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.navigationbar.buttons.ButtonInterface; public class NavigationHandle extends View implements ButtonInterface { diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/QuickswitchOrientedNavHandle.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/QuickswitchOrientedNavHandle.java index 88622aadd543..b55de279dc28 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/QuickswitchOrientedNavHandle.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/QuickswitchOrientedNavHandle.java @@ -21,7 +21,7 @@ import android.graphics.Canvas; import android.graphics.RectF; import android.view.Surface; -import com.android.systemui.R; +import com.android.systemui.res.R; /** Temporarily shown view when using QuickSwitch to switch between apps of different rotations */ public class QuickswitchOrientedNavHandle extends NavigationHandle { diff --git a/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java b/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java index be3168c3b208..c2163370b4a1 100644 --- a/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java +++ b/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java @@ -33,7 +33,7 @@ import android.os.ServiceManager; import android.util.Log; import android.view.WindowManager; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Notify user that a {@link NetworkTemplate} is over its diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt index ea8eb363cc47..093d098de3e3 100644 --- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt +++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt @@ -37,7 +37,7 @@ import android.os.UserManager import android.provider.Settings import android.widget.Toast import androidx.annotation.VisibleForTesting -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskRoleManagerExt.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskRoleManagerExt.kt index 63d463402655..9785446d7a43 100644 --- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskRoleManagerExt.kt +++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskRoleManagerExt.kt @@ -24,7 +24,7 @@ import android.content.pm.ShortcutInfo import android.graphics.drawable.Icon import android.os.PersistableBundle import android.os.UserHandle -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.notetask.shortcut.LaunchNoteTaskActivity /** Extension functions for [RoleManager] used **internally** by note task. */ diff --git a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt index f02d362501d5..6d55d0549d2e 100644 --- a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt @@ -27,7 +27,7 @@ import android.os.UserManager import android.util.Log import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceTileView.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceTileView.java index 36b435b04fd6..59c76adb721b 100644 --- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceTileView.java +++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceTileView.java @@ -27,7 +27,7 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * PeopleSpaceTileView renders an individual person's tile with associated status. diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java index c6c9aca0b161..188e8677e4ba 100644 --- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java +++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java @@ -55,7 +55,7 @@ import com.android.internal.logging.UiEventLogger; import com.android.internal.util.ArrayUtils; import com.android.internal.widget.MessagingMessage; import com.android.settingslib.utils.ThreadUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.people.widget.PeopleSpaceWidgetManager; import com.android.systemui.people.widget.PeopleTileKey; import com.android.systemui.statusbar.notification.collection.NotificationEntry; diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java index 67e96645f9c5..733383e344b8 100644 --- a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java +++ b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java @@ -74,7 +74,7 @@ import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; import androidx.core.math.MathUtils; import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.people.data.model.PeopleTileModel; import com.android.systemui.people.widget.LaunchConversationActivity; import com.android.systemui.people.widget.PeopleSpaceWidgetProvider; diff --git a/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt b/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt index 46c8d358aaac..c567d56fd424 100644 --- a/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/people/ui/view/PeopleViewBinder.kt @@ -31,7 +31,7 @@ import androidx.lifecycle.Lifecycle.State.CREATED import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.people.PeopleSpaceTileView import com.android.systemui.people.ui.viewmodel.PeopleTileViewModel import com.android.systemui.people.ui.viewmodel.PeopleViewModel diff --git a/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleViewModel.kt b/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleViewModel.kt index e27bfb34ee3e..ed7c21b787ca 100644 --- a/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/people/ui/viewmodel/PeopleViewModel.kt @@ -23,7 +23,7 @@ import android.content.Intent import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.people.PeopleSpaceUtils import com.android.systemui.people.PeopleTileViewHelper diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java index fbf1a0e46ce3..1f66b8407f9e 100644 --- a/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java +++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java @@ -21,7 +21,7 @@ import android.content.Context; import android.content.pm.PackageManager; import android.os.Build; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.PluginModule; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.shared.plugins.PluginActionManager; diff --git a/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java b/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java index 03d1f15bf379..1cd5d91ef69e 100644 --- a/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java +++ b/packages/SystemUI/src/com/android/systemui/power/InattentiveSleepWarningView.java @@ -29,7 +29,7 @@ import android.view.ViewGroup; import android.view.WindowManager; import android.widget.FrameLayout; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * View that shows a warning shortly before the device goes into sleep diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java index a765702a95b2..38204ab1b6d9 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java @@ -65,7 +65,7 @@ import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.settingslib.Utils; import com.android.settingslib.fuelgauge.BatterySaverUtils; import com.android.settingslib.utils.PowerUtil; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SystemUIApplication; import com.android.systemui.animation.DialogCuj; import com.android.systemui.animation.DialogLaunchAnimator; diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java index e1e1aaef6f2f..1534653bc1dd 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java @@ -48,7 +48,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.fuelgauge.Estimate; import com.android.settingslib.utils.ThreadUtils; import com.android.systemui.CoreStartable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.keyguard.WakefulnessLifecycle; diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt index 310d23407d5d..8e1b00d825aa 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt @@ -26,7 +26,7 @@ import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import android.widget.ImageView import android.widget.LinearLayout import com.android.settingslib.Utils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.view.LaunchableFrameLayout import com.android.systemui.statusbar.events.BackgroundAnimatableView diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt index eec69f98b9be..4952d8dd8ad8 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt @@ -15,7 +15,7 @@ package com.android.systemui.privacy import android.content.Context -import com.android.systemui.R +import com.android.systemui.res.R class PrivacyChipBuilder(private val context: Context, itemsList: List<PrivacyItem>) { diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt index 35a7cf1bf402..ac9a5905782b 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt @@ -29,7 +29,7 @@ import android.view.WindowInsets import android.widget.ImageView import android.widget.TextView import com.android.settingslib.Utils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.statusbar.phone.SystemUIDialog import java.lang.ref.WeakReference import java.util.concurrent.atomic.AtomicBoolean diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogV2.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogV2.kt index c202f14edc4d..b26ae6cdf0bd 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogV2.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogV2.kt @@ -40,7 +40,7 @@ import androidx.annotation.WorkerThread import androidx.core.view.ViewCompat import androidx.core.view.accessibility.AccessibilityNodeInfoCompat import com.android.settingslib.Utils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.ViewHierarchyAnimator import com.android.systemui.statusbar.phone.SystemUIDialog import com.android.systemui.util.maybeForceFullscreen diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt index 8b41000d2543..d09fbb379190 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt @@ -15,7 +15,7 @@ package com.android.systemui.privacy import android.content.Context -import com.android.systemui.R +import com.android.systemui.res.R typealias Privacy = PrivacyType diff --git a/packages/SystemUI/src/com/android/systemui/qs/DataUsageGraph.java b/packages/SystemUI/src/com/android/systemui/qs/DataUsageGraph.java index afce69e7f2d0..1b22f9889949 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/DataUsageGraph.java +++ b/packages/SystemUI/src/com/android/systemui/qs/DataUsageGraph.java @@ -25,7 +25,7 @@ import android.util.AttributeSet; import android.view.View; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; public class DataUsageGraph extends View { diff --git a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt index a3b901b675ed..6f35cfbfb4a5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt @@ -54,7 +54,7 @@ import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_ import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_USER_VISIBLE_JOBS import com.android.internal.jank.InteractionJankMonitor import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.DialogCuj import com.android.systemui.animation.DialogLaunchAnimator import com.android.systemui.animation.Expandable diff --git a/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java b/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java index e822dd58fb98..4770d5272508 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java +++ b/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java @@ -16,7 +16,7 @@ import android.widget.ImageView; import androidx.annotation.NonNull; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.ArrayList; diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java index ddd9463affd9..826f75f2f63b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java @@ -27,7 +27,7 @@ import androidx.viewpager.widget.ViewPager; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.UiEventLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.qs.QSPanel.QSTileLayout; import com.android.systemui.qs.QSPanelControllerBase.TileRecord; diff --git a/packages/SystemUI/src/com/android/systemui/qs/PseudoGridView.java b/packages/SystemUI/src/com/android/systemui/qs/PseudoGridView.java index 768598af6885..f0404357fab7 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/PseudoGridView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/PseudoGridView.java @@ -24,7 +24,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.lang.ref.WeakReference; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java index 37e750b86c21..b0f54ee78482 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java @@ -28,7 +28,7 @@ import android.view.View; import android.widget.FrameLayout; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.qs.customize.QSCustomizer; import com.android.systemui.shade.TouchLogger; import com.android.systemui.util.LargeScreenUtils; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java b/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java index 26399d8789aa..235fc0d1f657 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java @@ -29,7 +29,7 @@ import android.widget.TextView; import androidx.annotation.Nullable; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.Objects; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java index 61905ae00be8..c908e6e2afbe 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java @@ -35,7 +35,7 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.android.settingslib.development.DevelopmentSettingsEnabler; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Footer of expanded Quick Settings, tiles page indicator, (optionally) build number and diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java index 85f557b10762..ffbd06f64908 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java @@ -23,7 +23,7 @@ import android.view.View; import android.widget.TextView; import android.widget.Toast; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.qs.dagger.QSScope; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java index 596d024958b0..fd81e9a5cd0a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java @@ -47,7 +47,7 @@ import androidx.lifecycle.LifecycleRegistry; import com.android.app.animation.Interpolators; import com.android.keyguard.BouncerPanelExpansionCalculator; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.ShadeInterpolation; import com.android.systemui.compose.ComposeFacade; import com.android.systemui.dump.DumpManager; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java index 4e914a592304..1ab64b76b0dc 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java @@ -20,7 +20,7 @@ import android.content.res.Resources; import android.os.Build; import android.provider.Settings; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.util.leak.GarbageMonitor; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index b936c41d9295..3227f75ed067 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -39,7 +39,7 @@ import androidx.annotation.VisibleForTesting; import com.android.internal.logging.UiEventLogger; import com.android.internal.widget.RemeasuringLinearLayout; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.settings.brightness.BrightnessSliderController; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSScrollLayout.java b/packages/SystemUI/src/com/android/systemui/qs/QSScrollLayout.java index 001cbbac5606..77a5ce34d3ea 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSScrollLayout.java @@ -26,7 +26,7 @@ import android.widget.LinearLayout; import androidx.core.widget.NestedScrollView; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.qs.touch.OverScroll; import com.android.systemui.qs.touch.SwipeDetector; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java index b70b94b00923..5c96e98a4047 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java @@ -73,7 +73,7 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.android.internal.jank.InteractionJankMonitor; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.DialogCuj; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.animation.Expandable; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java index 4c292e70c111..9a9626d7c7a0 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java @@ -31,7 +31,7 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Dumpable; import com.android.systemui.ProtoDumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.nano.SystemUIProtoDump; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java index 150137910f91..6c32ed384419 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java @@ -25,7 +25,7 @@ import android.widget.LinearLayout; import com.android.internal.logging.UiEventLogger; import com.android.systemui.FontSizeUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.qs.QSTile; /** diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java index 585136ad0789..099d19d8619f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java @@ -24,7 +24,7 @@ import androidx.annotation.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dump.DumpManager; import com.android.systemui.media.controls.ui.MediaHierarchyManager; import com.android.systemui.media.controls.ui.MediaHost; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index 691a1a14444a..67c42086364c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -26,7 +26,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.util.LargeScreenUtils; /** diff --git a/packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt index 1ba11efc49a2..b52554d4e997 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt @@ -18,7 +18,7 @@ package com.android.systemui.qs import android.content.Context import android.util.AttributeSet -import com.android.systemui.R +import com.android.systemui.res.R open class SideLabelTileLayout( context: Context, diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java index 19bf0188c9d2..9dc6aeebc41c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java @@ -15,7 +15,7 @@ import androidx.annotation.Nullable; import com.android.internal.logging.UiEventLogger; import com.android.systemui.FontSizeUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.qs.QSPanel.QSTileLayout; import com.android.systemui.qs.QSPanelControllerBase.TileRecord; import com.android.systemui.qs.tileimpl.HeightOverrideable; 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 d511d8aea019..7888f4c7388d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java @@ -33,7 +33,7 @@ import androidx.annotation.Nullable; import androidx.recyclerview.widget.DefaultItemAnimator; import androidx.recyclerview.widget.RecyclerView; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.qs.QS; import com.android.systemui.plugins.qs.QSContainerController; import com.android.systemui.qs.QSDetailClipper; diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java index 4002ac3aa120..ce504b2c10a6 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java @@ -34,7 +34,7 @@ import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.android.internal.logging.UiEventLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.plugins.qs.QSContainerController; import com.android.systemui.plugins.qs.QSTile; diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java index e8901701c3ac..c9a24d6a4608 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java @@ -44,7 +44,7 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder; import com.android.internal.logging.UiEventLogger; import com.android.systemui.FontSizeUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.qs.QSEditEvent; import com.android.systemui.qs.QSHost; import com.android.systemui.qs.TileLayout; diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapterDelegate.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapterDelegate.java index 1e426adac0b8..92f17f9db0f4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapterDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapterDelegate.java @@ -23,7 +23,7 @@ import android.view.accessibility.AccessibilityNodeInfo; import androidx.core.view.AccessibilityDelegateCompat; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java index d9f448493591..a6226b36b0fd 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java @@ -33,7 +33,7 @@ import android.widget.Button; import androidx.annotation.Nullable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.qs.QSTile; diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java index ce6b8d499ee0..bcd98035a8b9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java +++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java @@ -23,7 +23,7 @@ import android.content.Context; import android.view.LayoutInflater; import android.view.View; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.RootView; import com.android.systemui.plugins.qs.QS; import com.android.systemui.qs.QSContainerImpl; diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileColorPicker.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileColorPicker.java index 1caab5aa77ef..8b6d914d2ad8 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/TileColorPicker.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileColorPicker.java @@ -21,7 +21,7 @@ import android.service.quicksettings.Tile; import androidx.annotation.VisibleForTesting; -import com.android.systemui.R; +import com.android.systemui.res.R; public class TileColorPicker { @VisibleForTesting static final int[] DISABLE_STATE_SET = {-android.R.attr.state_enabled}; diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt b/packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt index d2c51e50c60d..1659c3e673ef 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt @@ -22,7 +22,7 @@ import android.view.ContextThemeWrapper import android.view.LayoutInflater import android.view.ViewGroup import android.widget.TextView -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.plugins.qs.QSTile import com.android.systemui.plugins.qs.QSTileView import com.android.systemui.qs.tileimpl.QSTileImpl diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceRequestController.kt b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceRequestController.kt index d9e5580fc14c..899d0e2a4e35 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceRequestController.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceRequestController.kt @@ -25,7 +25,7 @@ import android.os.RemoteException import android.util.Log import androidx.annotation.VisibleForTesting import com.android.internal.statusbar.IAddTileResultCallback -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.qs.QSHost import com.android.systemui.statusbar.CommandQueue diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/data/repository/UserSwitcherRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/data/repository/UserSwitcherRepository.kt index e969d4c6e08a..5fa75ad68165 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/footer/data/repository/UserSwitcherRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/footer/data/repository/UserSwitcherRepository.kt @@ -22,7 +22,7 @@ import android.os.Handler import android.os.UserManager import android.provider.Settings.Global.USER_SWITCHER_ENABLED import com.android.keyguard.KeyguardUpdateMonitor -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.dagger.SysUISingleton diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt index 3c53d77c6beb..d09b21035cae 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt @@ -30,7 +30,7 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.common.ui.binder.IconViewBinder import com.android.systemui.dagger.SysUISingleton diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt index 32146b5b00e4..769cb1fe1370 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt @@ -23,7 +23,7 @@ import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import com.android.settingslib.Utils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.Expandable import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/TileSpecRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/TileSpecRepository.kt index 18f59b1f2b28..47c99f25730b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/TileSpecRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/TileSpecRepository.kt @@ -21,7 +21,7 @@ import android.content.res.Resources import android.database.ContentObserver import android.provider.Settings import android.util.SparseArray -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingList.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingList.kt index b1c7433770de..83c8bc3b11fb 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingList.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingList.kt @@ -18,7 +18,7 @@ package com.android.systemui.qs.pipeline.domain.autoaddable import android.content.res.Resources import android.util.Log -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.qs.pipeline.domain.model.AutoAddable import com.android.systemui.qs.pipeline.shared.TileSpec diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddable.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddable.kt index 58a31bc22a57..88d7f06dfada 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddable.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddable.kt @@ -20,7 +20,7 @@ import android.content.ComponentName import android.content.pm.PackageManager import android.content.res.Resources import android.text.TextUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java index 88c8e81bf1b5..d04e4f52ac4d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java @@ -34,7 +34,7 @@ import android.widget.ImageView; import android.widget.ImageView.ScaleType; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.qs.QSIconView; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile.State; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt index 966d94161f91..5a9c0a1893f8 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt @@ -44,7 +44,7 @@ import android.widget.TextView import androidx.annotation.VisibleForTesting import com.android.settingslib.Utils import com.android.systemui.FontSizeUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.LaunchableView import com.android.systemui.animation.LaunchableViewDelegate import com.android.systemui.plugins.qs.QSIconView diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt index f672e518f0b3..168fa088cff2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt @@ -15,7 +15,7 @@ */ package com.android.systemui.qs.tileimpl -import com.android.systemui.R +import com.android.systemui.res.R /** Return the subtitle resource Id of the given tile. */ object SubtitleArrayMapping { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java index 30765f7f974d..fb71cefe8e0a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java @@ -36,7 +36,7 @@ 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.res.R; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt index c709969ec6e2..d98141fcd6b9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt @@ -13,7 +13,7 @@ import android.view.View import androidx.annotation.VisibleForTesting import com.android.internal.jank.InteractionJankMonitor import com.android.internal.logging.MetricsLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.ActivityLaunchAnimator import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java index 9f10e6f1f2c6..18d472b9c755 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java @@ -29,7 +29,7 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java index 83b09bebee69..d862f563c8f9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java @@ -39,9 +39,11 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.Utils; import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.flags.Flags; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.qs.QSTile.BooleanState; @@ -50,6 +52,7 @@ import com.android.systemui.qs.QSHost; import com.android.systemui.qs.QsEventLogger; import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; +import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialogViewModel; import com.android.systemui.statusbar.policy.BluetoothController; import java.util.List; @@ -72,6 +75,10 @@ public class BluetoothTile extends QSTileImpl<BooleanState> { private final Executor mExecutor; + private final BluetoothTileDialogViewModel mDialogViewModel; + + private final FeatureFlags mFeatureFlags; + @Inject public BluetoothTile( QSHost host, @@ -83,13 +90,17 @@ public class BluetoothTile extends QSTileImpl<BooleanState> { StatusBarStateController statusBarStateController, ActivityStarter activityStarter, QSLogger qsLogger, - BluetoothController bluetoothController + BluetoothController bluetoothController, + FeatureFlags featureFlags, + BluetoothTileDialogViewModel dialogViewModel ) { super(host, uiEventLogger, backgroundLooper, mainHandler, falsingManager, metricsLogger, statusBarStateController, activityStarter, qsLogger); mController = bluetoothController; mController.observe(getLifecycle(), mCallback); mExecutor = new HandlerExecutor(mainHandler); + mFeatureFlags = featureFlags; + mDialogViewModel = dialogViewModel; } @Override @@ -99,11 +110,15 @@ public class BluetoothTile extends QSTileImpl<BooleanState> { @Override protected void handleClick(@Nullable View view) { - // Secondary clicks are header clicks, just toggle. - final boolean isEnabled = mState.value; - // Immediately enter transient enabling state when turning bluetooth on. - refreshState(isEnabled ? null : ARG_SHOW_TRANSIENT_ENABLING); - mController.setBluetoothEnabled(!isEnabled); + if (mFeatureFlags.isEnabled(Flags.BLUETOOTH_QS_TILE_DIALOG)) { + mDialogViewModel.showDialog(mContext, view); + } else { + // Secondary clicks are header clicks, just toggle. + final boolean isEnabled = mState.value; + // Immediately enter transient enabling state when turning bluetooth on. + refreshState(isEnabled ? null : ARG_SHOW_TRANSIENT_ENABLING); + mController.setBluetoothEnabled(!isEnabled); + } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java index 65ef6b9c31a5..b393f39719e7 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CameraToggleTile.java @@ -30,7 +30,7 @@ import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java index e9a242847362..5c6e9028545a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java @@ -38,7 +38,7 @@ import com.android.internal.app.MediaRouteDialogPresenter; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.DialogCuj; import com.android.systemui.animation.DialogLaunchAnimator; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorCorrectionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorCorrectionTile.java index cf9e3468c8f5..ee57b2b62d49 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorCorrectionTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorCorrectionTile.java @@ -28,8 +28,8 @@ import android.widget.Switch; import androidx.annotation.Nullable; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R; -import com.android.systemui.R.drawable; +import com.android.systemui.res.R; +import com.android.systemui.res.R.drawable; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java index 4ecde6123dd5..993ada6b86aa 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java @@ -29,8 +29,8 @@ 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.R.drawable; +import com.android.systemui.res.R; +import com.android.systemui.res.R.drawable; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java index e769b5ef9989..ccf7afbe7016 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java @@ -28,7 +28,7 @@ import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Prefs; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.DialogCuj; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.dagger.qualifiers.Background; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java index 55785586464f..c15289fddb20 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java @@ -28,7 +28,7 @@ import android.widget.TextView; import com.android.settingslib.Utils; import com.android.settingslib.net.DataUsageController; import com.android.systemui.FontSizeUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.qs.DataUsageGraph; import java.text.DecimalFormat; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt index ddaff3bb9a64..91b2d971c004 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt @@ -25,7 +25,7 @@ import android.view.View import androidx.annotation.VisibleForTesting import com.android.internal.jank.InteractionJankMonitor import com.android.internal.logging.MetricsLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.ActivityLaunchAnimator import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.controls.dagger.ControlsComponent diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java index 9bb192b4c271..0617b30eb8fa 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java @@ -45,7 +45,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.notification.EnableZenModeDialog; import com.android.systemui.Prefs; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.DialogCuj; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.dagger.qualifiers.Background; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java index b5e6a0f5c60b..a08b3fca15aa 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java @@ -38,7 +38,7 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java index 2c986da8370a..9fab51fd931e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java @@ -29,7 +29,7 @@ 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.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt index 1f9979a8b37c..64e3f16abec3 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt @@ -22,7 +22,7 @@ import android.provider.Settings import android.view.View import com.android.internal.jank.InteractionJankMonitor import com.android.internal.logging.MetricsLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.accessibility.fontscaling.FontScalingDialog import com.android.systemui.animation.DialogCuj import com.android.systemui.animation.DialogLaunchAnimator diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java index 7c76c1ae1bf5..9ee417e98d2d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java @@ -33,7 +33,7 @@ import androidx.annotation.Nullable; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java index fb2f2ced1d3a..1b504a81a651 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java @@ -41,7 +41,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.graph.SignalDrawable; import com.android.settingslib.mobile.TelephonyIcons; import com.android.settingslib.net.DataUsageController; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt index 956e7ab6d7ab..8103152dda37 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt @@ -22,7 +22,7 @@ import android.os.Looper import android.provider.Settings import android.view.View import com.android.internal.logging.MetricsLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.plugins.ActivityStarter diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java index 8b69f614dedd..9ddcf2953491 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java @@ -29,7 +29,7 @@ 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.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java index 86a6a8c6a2b6..7a7dbbc79558 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/MicrophoneToggleTile.java @@ -30,7 +30,7 @@ import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java index 29ccb76de820..a239c28f4342 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java @@ -34,7 +34,7 @@ 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.res.R; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java index 405e1394871c..7e0fa07d951f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java @@ -36,7 +36,7 @@ import androidx.annotation.StringRes; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.NightDisplayListenerModule; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/OneHandedModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/OneHandedModeTile.java index 5b0237f87153..78af97668fc0 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/OneHandedModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/OneHandedModeTile.java @@ -28,7 +28,7 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java index 1ba377bc9702..f70e27d72d69 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QRCodeScannerTile.java @@ -27,7 +27,7 @@ import androidx.annotation.Nullable; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java index e382eca17369..3a247c5843d4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java @@ -42,7 +42,7 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java index 2e04afb0048a..b9d902afb891 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java @@ -30,7 +30,7 @@ import androidx.annotation.Nullable; import com.android.internal.R; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R.drawable; +import com.android.systemui.res.R.drawable; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java index 2d9f7dd038bc..ea162fa2921f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java @@ -36,7 +36,7 @@ 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.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java index 2d4652db6b80..959afd86ee8d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java @@ -30,7 +30,7 @@ import androidx.annotation.Nullable; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.DialogCuj; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.dagger.qualifiers.Background; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java index 7c4f097a1724..5832217f3e85 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java @@ -31,7 +31,7 @@ import androidx.annotation.DrawableRes; import androidx.annotation.Nullable; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java index 9ffcba62ad09..300cc564939d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java @@ -31,7 +31,7 @@ import androidx.annotation.Nullable; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java index 5840a3ddf44d..7426615a7f1a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java @@ -32,7 +32,7 @@ import androidx.annotation.Nullable; import com.android.internal.util.ArrayUtils; import com.android.systemui.FontSizeUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.phone.UserAvatarView; /** diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java index b6b657ec82f6..32deb30d926b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java @@ -34,7 +34,7 @@ import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.drawable.CircleFramedDrawable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.qs.PseudoGridView; import com.android.systemui.qs.QSUserSwitcherEvent; 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 c8c3c30a7302..7a9384a4bba4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java @@ -32,7 +32,7 @@ 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.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java index 176983e4b444..b866dda80134 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java @@ -36,7 +36,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.Utils; import com.android.settingslib.wifi.WifiUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.wifitrackerlib.WifiEntry; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java index c67078ff9093..2350b5dce8b8 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java @@ -59,7 +59,7 @@ import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils; import com.android.systemui.Prefs; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.accessibility.floatingmenu.AnnotationLinkSpan; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.dagger.SysUISingleton; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java index f026d20b23b1..f516f5521d25 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java @@ -75,7 +75,7 @@ import com.android.settingslib.mobile.TelephonyIcons; import com.android.settingslib.net.SignalStrengthUtil; import com.android.settingslib.wifi.WifiUtils; import com.android.settingslib.wifi.dpp.WifiDppIntentHelper; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastDispatcher; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothStateInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothStateInteractor.kt new file mode 100644 index 000000000000..efad9ec548f9 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothStateInteractor.kt @@ -0,0 +1,80 @@ +/* + * 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.qs.tiles.dialog.bluetooth + +import android.bluetooth.BluetoothAdapter.STATE_OFF +import android.bluetooth.BluetoothAdapter.STATE_ON +import com.android.settingslib.bluetooth.BluetoothCallback +import com.android.settingslib.bluetooth.LocalBluetoothManager +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.dagger.qualifiers.Application +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.stateIn + +/** Holds business logic for the Bluetooth Dialog's bluetooth and device connection state */ +@SysUISingleton +internal class BluetoothStateInteractor +@Inject +constructor( + private val localBluetoothManager: LocalBluetoothManager?, + @Application private val coroutineScope: CoroutineScope, +) { + + internal val updateBluetoothStateFlow: StateFlow<Boolean?> = + conflatedCallbackFlow { + val listener = + object : BluetoothCallback { + override fun onBluetoothStateChanged(bluetoothState: Int) { + if (bluetoothState == STATE_ON || bluetoothState == STATE_OFF) { + super.onBluetoothStateChanged(bluetoothState) + trySendWithFailureLogging( + bluetoothState == STATE_ON, + TAG, + "onBluetoothStateChanged" + ) + } + } + } + localBluetoothManager?.eventManager?.registerCallback(listener) + awaitClose { localBluetoothManager?.eventManager?.unregisterCallback(listener) } + } + .stateIn( + coroutineScope, + SharingStarted.WhileSubscribed(replayExpirationMillis = 0), + initialValue = null + ) + + internal var isBluetoothEnabled: Boolean + get() = localBluetoothManager?.bluetoothAdapter?.isEnabled == true + set(value) { + if (isBluetoothEnabled != value) { + localBluetoothManager?.bluetoothAdapter?.apply { + if (value) enable() else disable() + } + } + } + + companion object { + private const val TAG = "BtStateInteractor" + } +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialog.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialog.kt new file mode 100644 index 000000000000..7a436a761594 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialog.kt @@ -0,0 +1,175 @@ +/* + * 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.qs.tiles.dialog.bluetooth + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.View.GONE +import android.view.View.VISIBLE +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.Switch +import android.widget.TextView +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.res.R +import com.android.systemui.statusbar.phone.SystemUIDialog +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.flow.asStateFlow + +/** Dialog for showing active, connected and saved bluetooth devices. */ +@SysUISingleton +internal class BluetoothTileDialog +constructor( + private val bluetoothToggleInitialValue: Boolean, + private val bluetoothTileDialogCallback: BluetoothTileDialogCallback, + context: Context, +) : SystemUIDialog(context, DEFAULT_THEME, DEFAULT_DISMISS_ON_DEVICE_LOCK) { + + private val mutableBluetoothStateSwitchedFlow: MutableStateFlow<Boolean?> = + MutableStateFlow(null) + internal val bluetoothStateSwitchedFlow + get() = mutableBluetoothStateSwitchedFlow.asStateFlow() + + private val mutableClickedFlow: MutableSharedFlow<Pair<DeviceItem, Int>> = + MutableSharedFlow(extraBufferCapacity = 1) + internal val deviceItemClickedFlow + get() = mutableClickedFlow.asSharedFlow() + + private val deviceItemAdapter: Adapter = Adapter() + + private lateinit var toggleView: Switch + private lateinit var doneButton: View + private lateinit var seeAllView: View + private lateinit var deviceListView: RecyclerView + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContentView(LayoutInflater.from(context).inflate(R.layout.bluetooth_tile_dialog, null)) + + toggleView = requireViewById(R.id.bluetooth_toggle) + doneButton = requireViewById(R.id.done_button) + seeAllView = requireViewById(R.id.see_all_layout) + deviceListView = requireViewById<RecyclerView>(R.id.device_list) + + setupToggle() + setupRecyclerView() + + doneButton.setOnClickListener { dismiss() } + } + + internal fun onDeviceItemUpdated(deviceItem: List<DeviceItem>, showSeeAll: Boolean) { + seeAllView.visibility = if (showSeeAll) VISIBLE else GONE + deviceItemAdapter.refreshDeviceItemList(deviceItem) + } + + internal fun onDeviceItemUpdatedAtPosition(deviceItem: DeviceItem, position: Int) { + deviceItemAdapter.refreshDeviceItem(deviceItem, position) + } + + internal fun onBluetoothStateUpdated(isEnabled: Boolean) { + toggleView.isChecked = isEnabled + } + + private fun setupToggle() { + toggleView.isChecked = bluetoothToggleInitialValue + toggleView.setOnCheckedChangeListener { _, isChecked -> + mutableBluetoothStateSwitchedFlow.value = isChecked + } + } + + private fun setupRecyclerView() { + deviceListView.apply { + layoutManager = LinearLayoutManager(context) + adapter = deviceItemAdapter + } + } + + internal inner class Adapter : RecyclerView.Adapter<Adapter.DeviceItemViewHolder>() { + + init { + setHasStableIds(true) + } + + private val deviceItem: MutableList<DeviceItem> = mutableListOf() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DeviceItemViewHolder { + val view = + LayoutInflater.from(parent.context) + .inflate(R.layout.bluetooth_device_item, parent, false) + return DeviceItemViewHolder(view) + } + + override fun getItemCount() = deviceItem.size + + override fun getItemId(position: Int) = position.toLong() + + override fun onBindViewHolder(holder: DeviceItemViewHolder, position: Int) { + val item = getItem(position) + holder.bind(item, position) + } + + internal fun getItem(position: Int) = deviceItem[position] + + internal fun refreshDeviceItemList(updated: List<DeviceItem>) { + deviceItem.clear() + deviceItem.addAll(updated) + notifyDataSetChanged() + } + + internal fun refreshDeviceItem(updated: DeviceItem, position: Int) { + deviceItem[position] = updated + notifyItemChanged(position) + } + + internal inner class DeviceItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + private val container = view.requireViewById<View>(R.id.bluetooth_device) + private val nameView = view.requireViewById<TextView>(R.id.bluetooth_device_name) + private val summaryView = view.requireViewById<TextView>(R.id.bluetooth_device_summary) + private val iconView = view.requireViewById<ImageView>(R.id.bluetooth_device_icon) + + internal fun bind(item: DeviceItem, position: Int) { + container.apply { + isEnabled = item.isEnabled + alpha = item.alpha + background = item.background + setOnClickListener { mutableClickedFlow.tryEmit(Pair(item, position)) } + } + nameView.text = item.deviceName + summaryView.text = item.connectionSummary + iconView.apply { + item.iconWithDescription?.let { + setImageDrawable(it.first) + contentDescription = it.second + } + } + } + } + } + + internal companion object { + const val ENABLED_ALPHA = 1.0f + const val DISABLED_ALPHA = 0.3f + const val MAX_DEVICE_ITEM_ENTRY = 3 + } +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogRepository.kt new file mode 100644 index 000000000000..ea51beecc2c1 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogRepository.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.systemui.qs.tiles.dialog.bluetooth + +import android.bluetooth.BluetoothAdapter +import com.android.settingslib.bluetooth.CachedBluetoothDevice +import com.android.settingslib.bluetooth.LocalBluetoothManager +import com.android.systemui.dagger.SysUISingleton +import javax.inject.Inject + +/** Repository to get CachedBluetoothDevices for the Bluetooth Dialog. */ +@SysUISingleton +internal class BluetoothTileDialogRepository +@Inject +constructor( + private val localBluetoothManager: LocalBluetoothManager?, + private val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter() +) { + internal val cachedDevices: Collection<CachedBluetoothDevice> + get() { + return if ( + localBluetoothManager == null || + bluetoothAdapter == null || + !bluetoothAdapter.isEnabled + ) { + emptyList() + } else { + localBluetoothManager.cachedDeviceManager.cachedDevicesCopy + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModel.kt new file mode 100644 index 000000000000..63f05318facc --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModel.kt @@ -0,0 +1,137 @@ +/* + * 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.qs.tiles.dialog.bluetooth + +import android.content.Context +import android.view.View +import androidx.annotation.VisibleForTesting +import com.android.systemui.animation.DialogLaunchAnimator +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialog.Companion.MAX_DEVICE_ITEM_ENTRY +import com.android.systemui.statusbar.phone.SystemUIDialog +import javax.inject.Inject +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.filterNotNull +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch + +/** ViewModel for Bluetooth Dialog after clicking on the Bluetooth QS tile. */ +@SysUISingleton +internal class BluetoothTileDialogViewModel +@Inject +constructor( + private val deviceItemInteractor: DeviceItemInteractor, + private val bluetoothStateInteractor: BluetoothStateInteractor, + private val dialogLaunchAnimator: DialogLaunchAnimator, + @Application private val coroutineScope: CoroutineScope, + @Main private val mainDispatcher: CoroutineDispatcher, +) : BluetoothTileDialogCallback { + + private var job: Job? = null + + @VisibleForTesting internal var dialog: BluetoothTileDialog? = null + + /** + * Shows the dialog. + * + * @param context The context in which the dialog is displayed. + * @param view The view from which the dialog is shown. + */ + fun showDialog(context: Context, view: View?) { + dismissDialog() + + var updateDeviceItemJob: Job? = null + + job = + coroutineScope.launch(mainDispatcher) { + dialog = createBluetoothTileDialog(context) + view?.let { dialogLaunchAnimator.showFromView(dialog!!, it) } ?: dialog!!.show() + updateDeviceItemJob?.cancel() + updateDeviceItemJob = launch { deviceItemInteractor.updateDeviceItems(context) } + + bluetoothStateInteractor.updateBluetoothStateFlow + .filterNotNull() + .onEach { + dialog!!.onBluetoothStateUpdated(it) + updateDeviceItemJob?.cancel() + updateDeviceItemJob = launch { + deviceItemInteractor.updateDeviceItems(context) + } + } + .launchIn(this) + + deviceItemInteractor.updateDeviceItemsFlow + .onEach { + updateDeviceItemJob?.cancel() + updateDeviceItemJob = launch { + deviceItemInteractor.updateDeviceItems(context) + } + } + .launchIn(this) + + deviceItemInteractor.deviceItemFlow + .filterNotNull() + .onEach { + dialog!!.onDeviceItemUpdated( + it.take(MAX_DEVICE_ITEM_ENTRY), + showSeeAll = it.size > MAX_DEVICE_ITEM_ENTRY + ) + } + .launchIn(this) + + dialog!! + .bluetoothStateSwitchedFlow + .filterNotNull() + .onEach { bluetoothStateInteractor.isBluetoothEnabled = it } + .launchIn(this) + + dialog!! + .deviceItemClickedFlow + .onEach { + if (deviceItemInteractor.updateDeviceItemOnClick(it.first)) { + dialog!!.onDeviceItemUpdatedAtPosition(it.first, it.second) + } + } + .launchIn(this) + } + } + + private fun createBluetoothTileDialog(context: Context): BluetoothTileDialog { + return BluetoothTileDialog( + bluetoothStateInteractor.isBluetoothEnabled, + this@BluetoothTileDialogViewModel, + context + ) + .apply { SystemUIDialog.registerDismissListener(this) { dismissDialog() } } + } + + private fun dismissDialog() { + job?.cancel() + job = null + dialog?.dismiss() + dialog = null + } +} + +internal interface BluetoothTileDialogCallback { + // TODO(b/298124674): Add click events for gear, see all and pair new device. +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItem.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItem.kt new file mode 100644 index 000000000000..03ae5e88f1b0 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItem.kt @@ -0,0 +1,54 @@ +/* + * 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. + */ + +/* + * 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.qs.tiles.dialog.bluetooth + +import android.graphics.drawable.Drawable +import com.android.settingslib.bluetooth.CachedBluetoothDevice +import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialog.Companion.ENABLED_ALPHA + +enum class DeviceItemType { + AVAILABLE_MEDIA_BLUETOOTH_DEVICE, + CONNECTED_BLUETOOTH_DEVICE, + SAVED_BLUETOOTH_DEVICE, +} + +data class DeviceItem( + val type: DeviceItemType, + val cachedBluetoothDevice: CachedBluetoothDevice, + val deviceName: String = "", + val connectionSummary: String = "", + val iconWithDescription: Pair<Drawable, String>? = null, + val background: Drawable? = null, + var isEnabled: Boolean = true, + var alpha: Float = ENABLED_ALPHA +) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactory.kt new file mode 100644 index 000000000000..fd57fd490eb3 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactory.kt @@ -0,0 +1,122 @@ +/* + * 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.qs.tiles.dialog.bluetooth + +import android.bluetooth.BluetoothDevice +import android.content.Context +import android.media.AudioManager +import com.android.settingslib.bluetooth.BluetoothUtils +import com.android.settingslib.bluetooth.CachedBluetoothDevice +import com.android.systemui.res.R + +private val backgroundOn = R.drawable.settingslib_switch_bar_bg_on +private val connected = R.string.quick_settings_bluetooth_device_connected +private val saved = R.string.quick_settings_bluetooth_device_saved + +/** Factories to create different types of Bluetooth device items from CachedBluetoothDevice. */ +internal abstract class DeviceItemFactory { + abstract fun isFilterMatched( + cachedDevice: CachedBluetoothDevice, + audioManager: AudioManager? + ): Boolean + + abstract fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem +} + +internal class AvailableMediaDeviceItemFactory : DeviceItemFactory() { + override fun isFilterMatched( + cachedDevice: CachedBluetoothDevice, + audioManager: AudioManager? + ): Boolean { + return BluetoothUtils.isAvailableMediaBluetoothDevice(cachedDevice, audioManager) + } + + // TODO(b/298124674): move create() to the abstract class to reduce duplicate code + override fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem { + return DeviceItem( + type = DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE, + cachedBluetoothDevice = cachedDevice, + deviceName = cachedDevice.name, + connectionSummary = cachedDevice.connectionSummary.takeUnless { it.isNullOrEmpty() } + ?: context.getString(connected), + iconWithDescription = + BluetoothUtils.getBtClassDrawableWithDescription(context, cachedDevice).let { p -> + Pair(p.first, p.second) + }, + background = context.getDrawable(backgroundOn), + isEnabled = !cachedDevice.isBusy, + alpha = + if (cachedDevice.isBusy) BluetoothTileDialog.DISABLED_ALPHA + else BluetoothTileDialog.ENABLED_ALPHA, + ) + } +} + +internal class ConnectedDeviceItemFactory : DeviceItemFactory() { + override fun isFilterMatched( + cachedDevice: CachedBluetoothDevice, + audioManager: AudioManager? + ): Boolean { + return BluetoothUtils.isConnectedBluetoothDevice(cachedDevice, audioManager) + } + + override fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem { + return DeviceItem( + type = DeviceItemType.CONNECTED_BLUETOOTH_DEVICE, + cachedBluetoothDevice = cachedDevice, + deviceName = cachedDevice.name, + connectionSummary = cachedDevice.connectionSummary.takeUnless { it.isNullOrEmpty() } + ?: context.getString(connected), + iconWithDescription = + BluetoothUtils.getBtClassDrawableWithDescription(context, cachedDevice).let { p -> + Pair(p.first, p.second) + }, + background = context.getDrawable(backgroundOn), + isEnabled = !cachedDevice.isBusy, + alpha = + if (cachedDevice.isBusy) BluetoothTileDialog.DISABLED_ALPHA + else BluetoothTileDialog.ENABLED_ALPHA, + ) + } +} + +internal class SavedDeviceItemFactory : DeviceItemFactory() { + override fun isFilterMatched( + cachedDevice: CachedBluetoothDevice, + audioManager: AudioManager? + ): Boolean { + return cachedDevice.bondState == BluetoothDevice.BOND_BONDED && !cachedDevice.isConnected + } + + override fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem { + return DeviceItem( + type = DeviceItemType.SAVED_BLUETOOTH_DEVICE, + cachedBluetoothDevice = cachedDevice, + deviceName = cachedDevice.name, + connectionSummary = cachedDevice.connectionSummary.takeUnless { it.isNullOrEmpty() } + ?: context.getString(saved), + iconWithDescription = + BluetoothUtils.getBtClassDrawableWithDescription(context, cachedDevice).let { p -> + Pair(p.first, p.second) + }, + isEnabled = !cachedDevice.isBusy, + alpha = + if (cachedDevice.isBusy) BluetoothTileDialog.DISABLED_ALPHA + else BluetoothTileDialog.ENABLED_ALPHA, + ) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt new file mode 100644 index 000000000000..6ffb61439c0c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt @@ -0,0 +1,177 @@ +/* + * 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.qs.tiles.dialog.bluetooth + +import android.bluetooth.BluetoothAdapter +import android.bluetooth.BluetoothDevice +import android.content.Context +import android.media.AudioManager +import com.android.settingslib.bluetooth.BluetoothCallback +import com.android.settingslib.bluetooth.BluetoothUtils +import com.android.settingslib.bluetooth.CachedBluetoothDevice +import com.android.settingslib.bluetooth.LocalBluetoothManager +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.dagger.qualifiers.Application +import com.android.systemui.dagger.qualifiers.Background +import javax.inject.Inject +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.shareIn +import kotlinx.coroutines.withContext + +/** Holds business logic for the Bluetooth Dialog after clicking on the Bluetooth QS tile. */ +@SysUISingleton +internal class DeviceItemInteractor +@Inject +constructor( + private val bluetoothTileDialogRepository: BluetoothTileDialogRepository, + private val audioManager: AudioManager, + private val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter(), + private val localBluetoothManager: LocalBluetoothManager?, + @Application private val coroutineScope: CoroutineScope, + @Background private val backgroundDispatcher: CoroutineDispatcher, +) { + + private val mutableDeviceItemFlow: MutableStateFlow<List<DeviceItem>?> = MutableStateFlow(null) + internal val deviceItemFlow + get() = mutableDeviceItemFlow.asStateFlow() + + internal val updateDeviceItemsFlow: SharedFlow<Unit> = + conflatedCallbackFlow { + val listener = + object : BluetoothCallback { + override fun onActiveDeviceChanged( + activeDevice: CachedBluetoothDevice?, + bluetoothProfile: Int + ) { + super.onActiveDeviceChanged(activeDevice, bluetoothProfile) + trySendWithFailureLogging(Unit, TAG, "onActiveDeviceChanged") + } + + override fun onConnectionStateChanged( + cachedDevice: CachedBluetoothDevice?, + state: Int + ) { + super.onConnectionStateChanged(cachedDevice, state) + trySendWithFailureLogging(Unit, TAG, "onConnectionStateChanged") + } + + override fun onDeviceAdded(cachedDevice: CachedBluetoothDevice) { + super.onDeviceAdded(cachedDevice) + trySendWithFailureLogging(Unit, TAG, "onDeviceAdded") + } + + override fun onProfileConnectionStateChanged( + cachedDevice: CachedBluetoothDevice, + state: Int, + bluetoothProfile: Int + ) { + super.onProfileConnectionStateChanged( + cachedDevice, + state, + bluetoothProfile + ) + trySendWithFailureLogging(Unit, TAG, "onProfileConnectionStateChanged") + } + } + localBluetoothManager?.eventManager?.registerCallback(listener) + awaitClose { localBluetoothManager?.eventManager?.unregisterCallback(listener) } + } + .shareIn(coroutineScope, SharingStarted.WhileSubscribed(replayExpirationMillis = 0)) + + private var deviceItemFactoryList: List<DeviceItemFactory> = + listOf( + AvailableMediaDeviceItemFactory(), + ConnectedDeviceItemFactory(), + SavedDeviceItemFactory() + ) + + private var displayPriority: List<DeviceItemType> = + listOf( + DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE, + DeviceItemType.CONNECTED_BLUETOOTH_DEVICE, + DeviceItemType.SAVED_BLUETOOTH_DEVICE, + ) + + internal suspend fun updateDeviceItems(context: Context) { + withContext(backgroundDispatcher) { + val mostRecentlyConnectedDevices = bluetoothAdapter?.mostRecentlyConnectedDevices + + mutableDeviceItemFlow.value = + bluetoothTileDialogRepository.cachedDevices + .mapNotNull { cachedDevice -> + deviceItemFactoryList + .firstOrNull { it.isFilterMatched(cachedDevice, audioManager) } + ?.create(context, cachedDevice) + } + .sort(displayPriority, mostRecentlyConnectedDevices) + } + } + + private fun List<DeviceItem>.sort( + displayPriority: List<DeviceItemType>, + mostRecentlyConnectedDevices: List<BluetoothDevice>? + ): List<DeviceItem> { + return this.sortedWith( + compareBy<DeviceItem> { displayPriority.indexOf(it.type) } + .thenBy { + mostRecentlyConnectedDevices?.indexOf(it.cachedBluetoothDevice.device) ?: 0 + } + ) + } + + internal fun updateDeviceItemOnClick(deviceItem: DeviceItem): Boolean { + var isClicked = false + when (deviceItem.type) { + DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE -> { + if (!BluetoothUtils.isActiveMediaDevice(deviceItem.cachedBluetoothDevice)) { + deviceItem.cachedBluetoothDevice.setActive() + isClicked = true + } + } + DeviceItemType.CONNECTED_BLUETOOTH_DEVICE -> {} + DeviceItemType.SAVED_BLUETOOTH_DEVICE -> { + deviceItem.cachedBluetoothDevice.connect() + isClicked = true + } + } + if (isClicked) { + deviceItem.isEnabled = false + deviceItem.alpha = BluetoothTileDialog.DISABLED_ALPHA + } + return isClicked + } + + internal fun setDeviceItemFactoryListForTesting(list: List<DeviceItemFactory>) { + deviceItemFactoryList = list + } + + internal fun setDisplayPriorityForTesting(list: List<DeviceItemType>) { + displayPriority = list + } + + companion object { + private const val TAG = "DeviceItemInteractor" + } +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt b/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt index 4c9c99cc16f0..acd7510a6c2a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt @@ -26,7 +26,7 @@ import android.view.LayoutInflater import androidx.annotation.VisibleForTesting import com.android.internal.jank.InteractionJankMonitor import com.android.internal.logging.UiEventLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.DialogCuj import com.android.systemui.animation.DialogLaunchAnimator import com.android.systemui.animation.Expandable diff --git a/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayDialogController.java b/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayDialogController.java index 6912114140b0..4b21e447ebf5 100644 --- a/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayDialogController.java +++ b/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayDialogController.java @@ -29,7 +29,7 @@ import android.widget.LinearLayout; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.CoreStartable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.statusbar.CommandQueue; diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsModule.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsModule.java index f57bfad890ff..77a4b9f72cd8 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsModule.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsModule.java @@ -18,7 +18,7 @@ package com.android.systemui.recents; import android.content.Context; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.ContextComponentHelper; import dagger.Binds; diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java index 3577c00a7d0a..3e574e788494 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java +++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java @@ -54,7 +54,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; import com.android.systemui.CoreStartable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.navigationbar.NavigationBarController; diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt index 291d273d611f..f0650d34fc9d 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt @@ -60,6 +60,8 @@ constructor( Flags.MIGRATE_LOCK_ICON, Flags.MIGRATE_NSSL, Flags.MIGRATE_KEYGUARD_STATUS_VIEW, + Flags.NOTIFICATION_SHELF_REFACTOR, + Flags.MIGRATE_KEYGUARD_STATUS_BAR_VIEW, ) } diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt index 3e766073f720..3fb886d46890 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt @@ -27,7 +27,7 @@ import androidx.core.view.isVisible import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.compose.ComposeFacade import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.scene.shared.model.Scene diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt index ef688a8e4337..7cff7ff1fd71 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt @@ -25,7 +25,7 @@ import android.view.View import android.view.WindowInsets import android.widget.FrameLayout import androidx.core.view.updateMargins -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.compose.ComposeFacade /** A view that can serve as the root of the main SysUI window. */ diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt index 8dd25bc78746..64006fe4c265 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/BaseScreenSharePermissionDialog.kt @@ -32,7 +32,7 @@ import androidx.annotation.ColorRes import androidx.annotation.DrawableRes import androidx.annotation.LayoutRes import androidx.annotation.StringRes -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.statusbar.phone.SystemUIDialog /** Base permission dialog for screen share and recording */ diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt index 8cbc4aab3bd3..47e28d86e01d 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/MediaProjectionPermissionDialog.kt @@ -18,7 +18,7 @@ package com.android.systemui.screenrecord import android.content.Context import android.media.projection.MediaProjectionConfig import android.os.Bundle -import com.android.systemui.R +import com.android.systemui.res.R /** Dialog to select screen recording options */ class MediaProjectionPermissionDialog( diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java index 2c4555a2378a..7cdb6553c47e 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java @@ -41,7 +41,7 @@ import android.widget.Toast; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.UiEventLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.LongRunning; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.media.MediaProjectionCaptureTarget; diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java index 91e3b60a2cf5..f0ce8a465d0d 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java @@ -41,7 +41,7 @@ import android.widget.TextView; import androidx.annotation.Nullable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.media.MediaProjectionCaptureTarget; import com.android.systemui.settings.UserContextProvider; import com.android.systemui.statusbar.phone.SystemUIDialog; diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt index 56d732eb230b..b5b7043e37a0 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt @@ -32,7 +32,7 @@ import android.widget.ArrayAdapter import android.widget.Spinner import android.widget.Switch import androidx.annotation.LayoutRes -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.media.MediaProjectionAppSelectorActivity import com.android.systemui.media.MediaProjectionCaptureTarget import com.android.systemui.plugins.ActivityStarter diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordingAdapter.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordingAdapter.java index 9962c914b476..eb58b2f1a112 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordingAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordingAdapter.java @@ -25,7 +25,7 @@ import android.widget.ArrayAdapter; import android.widget.LinearLayout; import android.widget.TextView; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentCreator.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentCreator.kt index ab2a8d9c6e95..8e9769ab7d0e 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentCreator.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentCreator.kt @@ -23,7 +23,7 @@ import android.content.ContentProvider import android.content.Context import android.content.Intent import android.net.Uri -import com.android.systemui.R +import com.android.systemui.res.R object ActionIntentCreator { /** @return a chooser intent to share the given URI. */ diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java index 6f2256eb6b31..2f411ea3cb33 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java @@ -45,7 +45,7 @@ import androidx.customview.widget.ExploreByTouchHelper; import androidx.interpolator.view.animation.FastOutSlowInInterpolator; import com.android.internal.graphics.ColorUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java b/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java index bdbc470a61f1..b55bba9f2279 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/DraggableConstraintLayout.java @@ -36,7 +36,7 @@ import android.view.ViewTreeObserver; import androidx.constraintlayout.widget.ConstraintLayout; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * ConstraintLayout that is draggable when touched in a specific region diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java index bf536a475fd4..9325e18abce7 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java @@ -44,7 +44,7 @@ import androidx.constraintlayout.widget.ConstraintLayout; import com.android.internal.app.ChooserActivity; import com.android.internal.logging.UiEventLogger; import com.android.internal.view.OneShotPreDrawListener; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.flags.FeatureFlags; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java b/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java index 78737329750a..0c543cd8909c 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java @@ -34,7 +34,7 @@ import android.view.ViewPropertyAnimator; import androidx.annotation.Nullable; import com.android.internal.graphics.ColorUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * MagnifierView shows a full-res cropped circular display of a given ImageTileSet, contents and diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt index b4ffabd78b8a..5cbea90580a1 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt @@ -10,7 +10,7 @@ import android.view.ViewGroup.MarginLayoutParams import android.view.ViewTreeObserver import android.view.animation.AccelerateDecelerateInterpolator import androidx.constraintlayout.widget.Guideline -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java b/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java index 9e8ea3aaec56..0588fe2bba82 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java @@ -29,7 +29,7 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; -import com.android.systemui.R; +import com.android.systemui.res.R; /** diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java index cfd9a4930304..31086d85f747 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java @@ -47,7 +47,7 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ActionTransition; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java index 87f6e4472d48..f08eb143efb4 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java @@ -92,7 +92,7 @@ import com.android.internal.app.ChooserActivity; import com.android.internal.logging.UiEventLogger; import com.android.internal.policy.PhoneWindow; import com.android.settingslib.applications.InterestingConfigChanges; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.clipboardoverlay.ClipboardOverlayController; import com.android.systemui.dagger.qualifiers.Main; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotDetectionController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotDetectionController.kt index 253f07de7b3c..be39d2edf1ea 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotDetectionController.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotDetectionController.kt @@ -24,7 +24,7 @@ import android.view.IWindowManager import android.view.ViewGroup import android.view.WindowManager import android.widget.TextView -import com.android.systemui.R +import com.android.systemui.res.R import javax.inject.Inject class ScreenshotDetectionController diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java index 35f2a39e02ae..4344fd1a7567 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationsController.java @@ -30,7 +30,7 @@ import android.util.DisplayMetrics; import android.view.WindowManager; import com.android.internal.messages.nano.SystemMessageProto; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SystemUIApplication; import com.android.systemui.util.NotificationChannels; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java index 522f729a25d6..070fb1eef99a 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java @@ -21,7 +21,7 @@ import android.content.Context; import android.content.Intent; import android.view.WindowManager; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Performs a number of miscellaneous, non-system-critical actions diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java index 03e1e15c5210..31c928406aac 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java @@ -86,7 +86,7 @@ import androidx.constraintlayout.widget.ConstraintLayout; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.UiEventLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.shared.system.InputChannelCompat; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java index 32df5121b0b8..0be2265bf8fa 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java @@ -53,7 +53,7 @@ import android.widget.Toast; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.UiEventLogger; import com.android.internal.util.ScreenshotRequest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.flags.FeatureFlags; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt index 798c4908e467..c801ca5aa8a1 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt @@ -28,7 +28,7 @@ import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView -import com.android.systemui.R +import com.android.systemui.res.R import javax.inject.Inject /** diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java index 2f96f6c656c4..aa23d6bed5e1 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java @@ -51,7 +51,7 @@ import androidx.lifecycle.ViewModelProvider; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.UiEventLogger.UiEventEnum; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.screenshot.CropView; import com.android.systemui.settings.UserTracker; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsService.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsService.java index dce8c81c3462..06c0b8b6e769 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsService.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsService.java @@ -37,7 +37,7 @@ import android.os.IBinder; import androidx.annotation.Nullable; import com.android.internal.statusbar.IAppClipsService; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Application; import com.android.systemui.flags.FeatureFlags; import com.android.wm.shell.bubbles.Bubbles; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java index 6e5cef47400f..a31b30195fe9 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java @@ -48,7 +48,7 @@ import com.android.internal.infra.AndroidFuture; import com.android.internal.infra.ServiceConnector; import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IAppClipsService; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.dagger.qualifiers.Application; import com.android.systemui.dagger.qualifiers.Background; diff --git a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseDialog.kt b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseDialog.kt index 71c5fad5322e..9d1278fd58e6 100644 --- a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseDialog.kt @@ -9,7 +9,7 @@ import android.view.View import android.view.WindowManager import android.widget.ImageView import com.android.internal.widget.DialogTitle -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.statusbar.phone.SystemUIDialog class SensorUseDialog( diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java index 38b1f14e45de..6783afa3eb9d 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java +++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java @@ -35,7 +35,7 @@ import android.widget.FrameLayout; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.util.concurrency.DelayableExecutor; diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java index d0d37c4e685f..b7152370624e 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java +++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderController.java @@ -16,6 +16,8 @@ package com.android.systemui.settings.brightness; +import static com.android.systemui.flags.Flags.HAPTIC_BRIGHTNESS_SLIDER; + import android.content.Context; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -28,14 +30,21 @@ import androidx.annotation.Nullable; import com.android.internal.logging.UiEventLogger; import com.android.settingslib.RestrictedLockUtils; import com.android.systemui.Gefingerpoken; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.classifier.Classifier; +import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.flags.FeatureFlagsClassic; +import com.android.systemui.haptics.slider.SeekableSliderEventProducer; import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.policy.BrightnessMirrorController; import com.android.systemui.util.ViewController; +import com.android.systemui.util.time.SystemClock; import javax.inject.Inject; +import kotlinx.coroutines.CoroutineDispatcher; + /** * {@code ViewController} for a {@code BrightnessSliderView} * @@ -55,12 +64,21 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV private final FalsingManager mFalsingManager; private final UiEventLogger mUiEventLogger; + private final BrightnessSliderHapticPlugin mBrightnessSliderHapticPlugin; + private final Gefingerpoken mOnInterceptListener = new Gefingerpoken() { @Override public boolean onInterceptTouchEvent(MotionEvent ev) { int action = ev.getActionMasked(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { mFalsingManager.isFalseTouch(Classifier.BRIGHTNESS_SLIDER); + if (mBrightnessSliderHapticPlugin.getVelocityTracker() != null) { + mBrightnessSliderHapticPlugin.getVelocityTracker().clear(); + } + } else if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) { + if (mBrightnessSliderHapticPlugin.getVelocityTracker() != null) { + mBrightnessSliderHapticPlugin.getVelocityTracker().addMovement(ev); + } } return false; @@ -75,10 +93,12 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV BrightnessSliderController( BrightnessSliderView brightnessSliderView, FalsingManager falsingManager, - UiEventLogger uiEventLogger) { + UiEventLogger uiEventLogger, + BrightnessSliderHapticPlugin brightnessSliderHapticPlugin) { super(brightnessSliderView); mFalsingManager = falsingManager; mUiEventLogger = uiEventLogger; + mBrightnessSliderHapticPlugin = brightnessSliderHapticPlugin; } /** @@ -93,6 +113,7 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV protected void onViewAttached() { mView.setOnSeekBarChangeListener(mSeekListener); mView.setOnInterceptListener(mOnInterceptListener); + mBrightnessSliderHapticPlugin.start(); } @Override @@ -100,6 +121,7 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV mView.setOnSeekBarChangeListener(null); mView.setOnDispatchTouchEventListener(null); mView.setOnInterceptListener(null); + mBrightnessSliderHapticPlugin.stop(); } @Override @@ -204,6 +226,11 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (mListener != null) { mListener.onChanged(mTracking, progress, false); + SeekableSliderEventProducer eventProducer = + mBrightnessSliderHapticPlugin.getSeekableSliderEventProducer(); + if (eventProducer != null) { + eventProducer.onProgressChanged(seekBar, progress, fromUser); + } } } @@ -213,6 +240,11 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV mUiEventLogger.log(BrightnessSliderEvent.SLIDER_STARTED_TRACKING_TOUCH); if (mListener != null) { mListener.onChanged(mTracking, getValue(), false); + SeekableSliderEventProducer eventProducer = + mBrightnessSliderHapticPlugin.getSeekableSliderEventProducer(); + if (eventProducer != null) { + eventProducer.onStartTrackingTouch(seekBar); + } } if (mMirrorController != null) { @@ -227,6 +259,11 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV mUiEventLogger.log(BrightnessSliderEvent.SLIDER_STOPPED_TRACKING_TOUCH); if (mListener != null) { mListener.onChanged(mTracking, getValue(), true); + SeekableSliderEventProducer eventProducer = + mBrightnessSliderHapticPlugin.getSeekableSliderEventProducer(); + if (eventProducer != null) { + eventProducer.onStopTrackingTouch(seekBar); + } } if (mMirrorController != null) { @@ -242,11 +279,26 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV private final FalsingManager mFalsingManager; private final UiEventLogger mUiEventLogger; + private final FeatureFlagsClassic mFeatureFlags; + private final VibratorHelper mVibratorHelper; + private final SystemClock mSystemClock; + private final CoroutineDispatcher mMainDispatcher; @Inject - public Factory(FalsingManager falsingManager, UiEventLogger uiEventLogger) { + public Factory( + FalsingManager falsingManager, + UiEventLogger uiEventLogger, + VibratorHelper vibratorHelper, + SystemClock clock, + FeatureFlagsClassic featureFlags, + @Main CoroutineDispatcher mainDispatcher + ) { mFalsingManager = falsingManager; mUiEventLogger = uiEventLogger; + mFeatureFlags = featureFlags; + mVibratorHelper = vibratorHelper; + mSystemClock = clock; + mMainDispatcher = mainDispatcher; } /** @@ -262,7 +314,17 @@ public class BrightnessSliderController extends ViewController<BrightnessSliderV int layout = getLayout(); BrightnessSliderView root = (BrightnessSliderView) LayoutInflater.from(context) .inflate(layout, viewRoot, false); - return new BrightnessSliderController(root, mFalsingManager, mUiEventLogger); + BrightnessSliderHapticPlugin plugin; + if (mFeatureFlags.isEnabled(HAPTIC_BRIGHTNESS_SLIDER)) { + plugin = new BrightnessSliderHapticPluginImpl( + mVibratorHelper, + mSystemClock, + mMainDispatcher + ); + } else { + plugin = new BrightnessSliderHapticPlugin() {}; + } + return new BrightnessSliderController(root, mFalsingManager, mUiEventLogger, plugin); } /** Get the layout to inflate based on what slider to use */ diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPlugin.kt b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPlugin.kt new file mode 100644 index 000000000000..f77511420491 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPlugin.kt @@ -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.systemui.settings.brightness + +import android.view.VelocityTracker +import com.android.systemui.haptics.slider.SeekableSliderEventProducer + +/** Plugin component for the System UI brightness slider to incorporate dynamic haptics */ +interface BrightnessSliderHapticPlugin { + + /** Finger velocity tracker */ + val velocityTracker: VelocityTracker? + get() = null + + /** Producer of slider events from the underlying [android.widget.SeekBar] */ + val seekableSliderEventProducer: SeekableSliderEventProducer? + get() = null + + /** + * Start the plugin. + * + * This starts the tracking of slider states, events and triggering of haptic feedback. + */ + fun start() {} + + /** + * Stop the plugin + * + * This stops the tracking of slider states, events and triggers of haptic feedback. + */ + fun stop() {} +} diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImpl.kt new file mode 100644 index 000000000000..32561f0b4c4f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImpl.kt @@ -0,0 +1,69 @@ +/* + * 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.settings.brightness + +import android.view.VelocityTracker +import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.haptics.slider.SeekableSliderEventProducer +import com.android.systemui.haptics.slider.SeekableSliderTracker +import com.android.systemui.haptics.slider.SliderHapticFeedbackProvider +import com.android.systemui.haptics.slider.SliderTracker +import com.android.systemui.statusbar.VibratorHelper +import com.android.systemui.util.time.SystemClock +import kotlinx.coroutines.CoroutineDispatcher + +/** + * Implementation of the [BrightnessSliderHapticPlugin]. + * + * For the specifics of the brightness slider in System UI, a [SeekableSliderEventProducer] is used + * as the producer of slider events, a [SliderHapticFeedbackProvider] is used as the listener of + * slider states to play haptic feedback depending on the state, and a [SeekableSliderTracker] is + * used as the state machine handler that tracks and manipulates the slider state. + */ +class BrightnessSliderHapticPluginImpl +@JvmOverloads +constructor( + vibratorHelper: VibratorHelper, + systemClock: SystemClock, + @Main mainDispatcher: CoroutineDispatcher, + override val velocityTracker: VelocityTracker = VelocityTracker.obtain(), + override val seekableSliderEventProducer: SeekableSliderEventProducer = + SeekableSliderEventProducer(), +) : BrightnessSliderHapticPlugin { + + private val sliderHapticFeedbackProvider: SliderHapticFeedbackProvider = + SliderHapticFeedbackProvider(vibratorHelper, velocityTracker, clock = systemClock) + private val sliderTracker: SliderTracker = + SeekableSliderTracker( + sliderHapticFeedbackProvider, + seekableSliderEventProducer, + mainDispatcher, + ) + + val isTracking: Boolean + get() = sliderTracker.isTracking + + override fun start() { + if (!sliderTracker.isTracking) { + sliderTracker.startTracking() + } + } + + override fun stop() { + sliderTracker.stopTracking() + } +} diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java index 38cb441a4f8c..c88549224183 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java +++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java @@ -33,7 +33,7 @@ import androidx.annotation.Nullable; import com.android.settingslib.RestrictedLockUtils; import com.android.systemui.Gefingerpoken; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * {@code FrameLayout} used to show and manipulate a {@link ToggleSeekBar}. diff --git a/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt index a9b3d0a1f3aa..b2e473685daa 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt @@ -18,7 +18,7 @@ package com.android.systemui.shade import android.view.ViewGroup import androidx.constraintlayout.widget.ConstraintSet -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton /** diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt index 5850a846eed6..14659e7909ab 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt @@ -18,7 +18,7 @@ package com.android.systemui.shade import android.content.Context import android.view.ViewGroup -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.StatusBarState.SHADE import com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index 92ccdb5abf84..d5934e614d4e 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -114,7 +114,7 @@ import com.android.keyguard.dagger.KeyguardUserSwitcherComponent; import com.android.systemui.DejankUtils; import com.android.systemui.Dumpable; import com.android.systemui.Gefingerpoken; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.LaunchAnimator; import com.android.systemui.biometrics.AuthController; diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java index 2dbcbc9e0f22..c803e6f0c9f3 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java @@ -48,7 +48,7 @@ import android.view.WindowManagerGlobal; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.biometrics.AuthController; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.SysUISingleton; diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java index 96fae14cec60..6cf4ff569662 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java @@ -36,7 +36,7 @@ import com.android.keyguard.KeyguardMessageAreaController; import com.android.keyguard.LockIconViewController; import com.android.keyguard.dagger.KeyguardBouncerComponent; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.back.domain.interactor.BackActionInteractor; import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor; diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt index 3873ac47040d..cc46b23ec75f 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt @@ -26,7 +26,7 @@ import androidx.constraintlayout.widget.ConstraintSet.END import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID import androidx.constraintlayout.widget.ConstraintSet.START import androidx.constraintlayout.widget.ConstraintSet.TOP -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.flags.FeatureFlags diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java index 292cf8ec1d98..af44c4e36315 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQuickSettingsContainer.java @@ -32,7 +32,7 @@ import androidx.annotation.Nullable; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintSet; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.fragments.FragmentHostManager.FragmentListener; import com.android.systemui.plugins.qs.QS; import com.android.systemui.statusbar.notification.AboveShelfObserver; diff --git a/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt b/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt index 3eec7fa0e84a..1fcb70c6bc95 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt @@ -2,7 +2,7 @@ package com.android.systemui.shade import android.content.Context import android.view.DisplayCutout -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.battery.BatteryMeterView import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java index d653cb4fa9d7..e8be40eaf3fe 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java @@ -65,7 +65,7 @@ import com.android.keyguard.FaceAuthApiRequestReason; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.DejankUtils; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.classifier.Classifier; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dump.DumpManager; diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt index 19a4ee8ef6a0..25bd8e7446bc 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt @@ -38,7 +38,7 @@ import androidx.core.view.doOnLayout import com.android.app.animation.Interpolators import com.android.settingslib.Utils import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.ShadeInterpolation import com.android.systemui.battery.BatteryMeterView import com.android.systemui.battery.BatteryMeterViewController diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt index 3f7512a25732..38b358ff927e 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt @@ -22,7 +22,7 @@ import android.os.Handler import android.view.LayoutInflater import android.view.ViewStub import androidx.constraintlayout.motion.widget.MotionLayout -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.battery.BatteryMeterView import com.android.systemui.battery.BatteryMeterViewController import com.android.systemui.biometrics.AuthRippleView diff --git a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrier.java b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrier.java index 8612cdf12c6e..6ca0ad47a0a7 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrier.java +++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrier.java @@ -33,7 +33,7 @@ import androidx.annotation.VisibleForTesting; import com.android.settingslib.Utils; import com.android.settingslib.graph.SignalDrawable; import com.android.systemui.FontSizeUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernShadeCarrierGroupMobileView; import com.android.systemui.util.LargeScreenUtils; diff --git a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroup.java b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroup.java index 68561d1cfd0f..e84fb485829c 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroup.java +++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroup.java @@ -24,7 +24,7 @@ import android.widget.LinearLayout; import android.widget.TextView; import com.android.systemui.FontSizeUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Displays Carrier name and network status in the shade header diff --git a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java index 98d8a53b83c8..3349345b1391 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java @@ -39,7 +39,7 @@ import androidx.annotation.VisibleForTesting; import com.android.keyguard.CarrierTextManager; import com.android.settingslib.AccessibilityContentDescriptions; import com.android.settingslib.mobile.TelephonyIcons; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt index c6c664dbdcf0..51276c6560a4 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt @@ -22,7 +22,7 @@ import android.content.IntentFilter import android.icu.text.DateFormat import android.icu.text.DisplayContext import android.os.UserHandle -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java index ba92c451f764..f54d0e70e3c7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java @@ -25,7 +25,7 @@ import android.view.View; import android.widget.ImageView; import android.widget.RemoteViews.RemoteView; -import com.android.systemui.R; +import com.android.systemui.res.R; @RemoteView public class AnimatedImageView extends ImageView { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BatteryStatusChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/BatteryStatusChip.kt index 520976746785..2281ea02aaf8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BatteryStatusChip.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BatteryStatusChip.kt @@ -23,7 +23,7 @@ import android.view.View import android.widget.FrameLayout import android.widget.LinearLayout import com.android.settingslib.Utils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.battery.BatteryMeterView import com.android.systemui.statusbar.events.BackgroundAnimatableView diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt index a0cbdf3e3e01..6bbd4a504471 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt @@ -29,7 +29,7 @@ import android.view.SurfaceControl import android.view.ViewRootImpl import androidx.annotation.VisibleForTesting import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CastDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/CastDrawable.java index 2f385d04c793..b1acc64d7fa8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CastDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CastDrawable.java @@ -24,7 +24,7 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.DrawableWrapper; import android.util.AttributeSet; -import com.android.systemui.R; +import com.android.systemui.res.R; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ConnectedDisplayChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/ConnectedDisplayChip.kt index 76636ab8e5f3..4c0f6f0cc672 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ConnectedDisplayChip.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ConnectedDisplayChip.kt @@ -19,7 +19,7 @@ import android.content.Context import android.content.res.Configuration import android.util.AttributeSet import android.widget.FrameLayout -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.statusbar.events.BackgroundAnimatableView /** Chip that appears in the status bar when an external display is connected. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java index c1ebf1236def..d24f9d8f476c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java @@ -19,7 +19,7 @@ package com.android.systemui.statusbar; import android.view.View; import com.android.app.animation.Interpolators; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java index 24c66eb5d442..33c42e043901 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java @@ -29,7 +29,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.row.StackScrollerDecorView; import com.android.systemui.statusbar.notification.stack.ExpandableViewState; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java index 4d933d9ad21e..0715dfca8507 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java @@ -26,7 +26,7 @@ import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.AlphaOptimizedLinearLayout; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntry.OnSensitivityChangedListener; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java b/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java index a7ec02ff43c3..95768e55de34 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java @@ -74,7 +74,7 @@ import android.widget.FrameLayout; import android.widget.ImageView; import com.android.systemui.CoreStartable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.systemui.util.settings.SecureSettings; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutAppItemLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutAppItemLayout.java index 5377deef337e..3e854a40251b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutAppItemLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutAppItemLayout.java @@ -23,7 +23,7 @@ import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Layout used for displaying keyboard shortcut items inside an alert dialog. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java index ec66e994b58a..68c48b9a261f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java @@ -70,7 +70,7 @@ import com.android.internal.app.AssistUtils; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.bottomsheet.BottomSheetDialog; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java index ae3d41e19b5f..61eaff9c2f8e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java @@ -67,7 +67,7 @@ import com.android.internal.app.AssistUtils; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.ArrayList; import java.util.Collections; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java index 1a32d70a9745..1198d1baeaee 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java @@ -39,7 +39,7 @@ import android.view.animation.Interpolator; import android.widget.ImageView; import com.android.app.animation.Interpolators; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.wm.shell.animation.FlingAnimationUtils; /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index feb02586a820..98e5124f7736 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -84,7 +84,7 @@ import com.android.keyguard.TrustGrantFlags; import com.android.keyguard.logging.KeyguardLogger; import com.android.settingslib.Utils; import com.android.settingslib.fuelgauge.BatteryStatus; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.biometrics.AuthController; import com.android.systemui.biometrics.FaceHelpMessageDeferral; import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor; @@ -309,7 +309,7 @@ public class KeyguardIndicationController { mFaceAcquiredMessageDeferral = faceHelpMessageDeferral; mCoExFaceAcquisitionMsgIdsToShow = new HashSet<>(); int[] msgIds = context.getResources().getIntArray( - com.android.systemui.R.array.config_face_help_msgs_when_fingerprint_enrolled); + com.android.systemui.res.R.array.config_face_help_msgs_when_fingerprint_enrolled); for (int msgId : msgIds) { mCoExFaceAcquisitionMsgIdsToShow.add(msgId); } @@ -704,7 +704,7 @@ public class KeyguardIndicationController { .setTextColor(Utils.getColorAttr( mContext, com.android.internal.R.attr.textColorOnAccent)) .setBackground(mContext.getDrawable( - com.android.systemui.R.drawable.logout_button_background)) + com.android.systemui.res.R.drawable.logout_button_background)) .setClickListener((view) -> { if (mFalsingManager.isFalseTap(LOW_PENALTY)) { return; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt index 238317cfc99e..62c9980c336c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt @@ -3,7 +3,7 @@ package com.android.systemui.statusbar import android.content.Context import android.util.IndentingPrintWriter import android.util.MathUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dump.DumpManager import com.android.systemui.media.controls.ui.MediaHierarchyManager import com.android.systemui.shade.ShadeViewController diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionController.kt index 5f3d75786973..4d0552e7cb31 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionController.kt @@ -21,7 +21,7 @@ import android.util.IndentingPrintWriter import android.util.MathUtils import androidx.annotation.FloatRange import androidx.annotation.Px -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.qs.QS import com.android.systemui.statusbar.policy.ConfigurationController diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt index af4a1aa98d9e..77a09608dbd3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt @@ -3,7 +3,7 @@ package com.android.systemui.statusbar import android.content.Context import android.util.IndentingPrintWriter import android.util.MathUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dump.DumpManager import com.android.systemui.statusbar.phone.ScrimController import com.android.systemui.statusbar.policy.ConfigurationController diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt index 29ca0f438aac..143e620abfa1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt @@ -16,7 +16,7 @@ import androidx.annotation.VisibleForTesting import com.android.systemui.Dumpable import com.android.systemui.ExpandHelper import com.android.systemui.Gefingerpoken -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.biometrics.UdfpsKeyguardViewControllerLegacy import com.android.systemui.classifier.Classifier import com.android.systemui.classifier.FalsingCollector diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java index 8089fd94f7db..befc64d07426 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java @@ -48,7 +48,7 @@ import androidx.annotation.Nullable; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dump.DumpManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.power.domain.interactor.PowerInteractor; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index c760227aa124..09ad55e005d4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -37,7 +37,7 @@ import androidx.annotation.NonNull; import com.android.app.animation.Interpolators; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.SystemBarUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.ShadeInterpolation; import com.android.systemui.flags.Flags; import com.android.systemui.flags.ViewRefactorFlag; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt index 2c0741ecf986..3640ae067537 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt @@ -31,7 +31,7 @@ import androidx.annotation.VisibleForTesting import com.android.app.animation.Interpolators import com.android.systemui.Dumpable import com.android.systemui.Gefingerpoken -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN import com.android.systemui.classifier.FalsingCollector import com.android.systemui.dagger.SysUISingleton diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScreenRecordDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScreenRecordDrawable.java index 006b219d8e61..2b7e9c55ee4e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ScreenRecordDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScreenRecordDrawable.java @@ -26,7 +26,7 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.DrawableWrapper; import android.util.AttributeSet; -import com.android.systemui.R; +import com.android.systemui.res.R; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScroller.kt b/packages/SystemUI/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScroller.kt index f1e51e21a9e5..603e863f9a10 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScroller.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScroller.kt @@ -3,7 +3,7 @@ package com.android.systemui.statusbar import android.content.Context import android.content.res.Configuration import android.util.MathUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.app.animation.Interpolators import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController import com.android.systemui.statusbar.policy.ConfigurationController diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt b/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt index 3d574caf3192..e47c914341a6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt @@ -7,7 +7,7 @@ import android.content.res.Configuration import android.util.MathUtils import android.view.animation.PathInterpolator import com.android.internal.annotations.VisibleForTesting -import com.android.systemui.R +import com.android.systemui.res.R import com.android.app.animation.Interpolators import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.qs.QS diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java index fbbee53468c5..8baab25e5c59 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java @@ -57,7 +57,7 @@ import com.android.app.animation.Interpolators; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.util.ContrastColorUtil; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.NotificationIconDozeHelper; import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.util.drawable.DrawableSize; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java index 99297b21c9a0..e632214bcb2b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java @@ -43,7 +43,7 @@ import com.android.internal.logging.UiEventLogger; import com.android.keyguard.KeyguardClockSwitch; import com.android.systemui.DejankUtils; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dump.DumpManager; import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java index 645595c1f7bf..d089252759c7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java @@ -118,6 +118,16 @@ public class VibratorHelper { } /** + * @see Vibrator#vibrate(VibrationEffect, VibrationAttributes) + */ + public void vibrate(@NonNull VibrationEffect effect, @NonNull VibrationAttributes attributes) { + if (!hasVibrator()) { + return; + } + mExecutor.execute(() -> mVibrator.vibrate(effect, attributes)); + } + + /** * @see Vibrator#hasVibrator() */ public boolean hasVibrator() { @@ -154,6 +164,17 @@ public class VibratorHelper { } /** + * @see Vibrator#getPrimitiveDurations(int...) + */ + public int[] getPrimitiveDurations(int... primitiveIds) { + if (!hasVibrator()) { + return new int[]{0}; + } else { + return mVibrator.getPrimitiveDurations(primitiveIds); + } + } + + /** * Perform a vibration using a view and the one-way API with flags * @see View#performHapticFeedback(int feedbackConstant, int flags) */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java index 67ab0601cbf8..092e5b4c0e2c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java @@ -26,7 +26,7 @@ import android.view.ViewGroup; import android.view.animation.Interpolator; import com.android.app.animation.Interpolators; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.TransformState; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/EthernetIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/EthernetIcons.java index 196aad99dcb5..9734e262369d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/EthernetIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/EthernetIcons.java @@ -16,7 +16,7 @@ package com.android.systemui.statusbar.connectivity; -import com.android.systemui.R; +import com.android.systemui.res.R; class EthernetIcons { static final int[][] ETHERNET_ICONS = { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java index c523d22456f6..d6df987ba5a1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java @@ -43,7 +43,7 @@ import com.android.settingslib.mobile.MobileStatusTracker.MobileStatus; import com.android.settingslib.mobile.MobileStatusTracker.SubscriptionDefaults; import com.android.settingslib.mobile.TelephonyIcons; import com.android.settingslib.net.SignalStrengthUtil; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy; import com.android.systemui.util.CarrierConfigTracker; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java index f381b3792f68..9db61c6b3ba2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java @@ -61,7 +61,7 @@ import com.android.settingslib.mobile.MobileStatusTracker.SubscriptionDefaults; import com.android.settingslib.mobile.TelephonyIcons; import com.android.settingslib.net.DataUsageController; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java index f84b96c94a91..08defcce4b7c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java @@ -34,7 +34,7 @@ import com.android.settingslib.SignalIcon.MobileIconGroup; import com.android.settingslib.graph.SignalDrawable; import com.android.settingslib.mobile.TelephonyIcons; import com.android.settingslib.wifi.WifiStatusTracker; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import java.io.PrintWriter; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt index 80274bde6ce2..4056e7b89c2c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt @@ -16,7 +16,7 @@ package com.android.systemui.statusbar.core import android.app.Fragment -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.fragments.FragmentHostManager import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt index d1e0a7193948..5af7cfc212d5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt @@ -25,7 +25,7 @@ import android.view.Gravity import android.view.View import android.widget.FrameLayout import com.android.internal.annotations.GuardedBy -import com.android.systemui.R +import com.android.systemui.res.R import com.android.app.animation.Interpolators import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt index 1ad4620f9dfa..dccc23f61092 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt @@ -31,7 +31,7 @@ import androidx.core.animation.AnimatorListenerAdapter import androidx.core.animation.AnimatorSet import androidx.core.animation.ValueAnimator import com.android.internal.annotations.VisibleForTesting -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.statusbar.phone.StatusBarContentInsetsChangedListener diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt index 2403920e69f9..7d866df73da9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt @@ -20,7 +20,7 @@ import android.annotation.IntRange import android.content.Context import android.provider.DeviceConfig import android.provider.DeviceConfig.NAMESPACE_PRIVACY -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt index d667b91ea5ab..0190d5c9759b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt @@ -39,7 +39,7 @@ import android.view.ViewGroup import com.android.keyguard.KeyguardUpdateMonitor import com.android.settingslib.Utils import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AnimatableProperty.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AnimatableProperty.java index fcff4376811e..8cefc56d135a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AnimatableProperty.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AnimatableProperty.java @@ -20,7 +20,7 @@ import android.util.FloatProperty; import android.util.Property; import android.view.View; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.function.BiConsumer; import java.util.function.Function; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AssistantFeedbackController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AssistantFeedbackController.java index 420dd3f0e464..24088d2dabfa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AssistantFeedbackController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AssistantFeedbackController.java @@ -155,17 +155,17 @@ public class AssistantFeedbackController { int feedbackStatus = getFeedbackStatus(entry); switch (feedbackStatus) { case STATUS_ALERTED: - return com.android.systemui.R.string.notification_channel_summary_automatic_alerted; + return com.android.systemui.res.R.string.notification_channel_summary_automatic_alerted; case STATUS_SILENCED: - return com.android.systemui.R.string + return com.android.systemui.res.R.string .notification_channel_summary_automatic_silenced; case STATUS_PROMOTED: - return com.android.systemui.R.string + return com.android.systemui.res.R.string .notification_channel_summary_automatic_promoted; case STATUS_DEMOTED: - return com.android.systemui.R.string.notification_channel_summary_automatic_demoted; + return com.android.systemui.res.R.string.notification_channel_summary_automatic_demoted; default: - return com.android.systemui.R.string.notification_channel_summary_automatic; + return com.android.systemui.res.R.string.notification_channel_summary_automatic; } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/FakeShadowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/FakeShadowView.java index 0c1891e1fde9..f3067c1042e0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/FakeShadowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/FakeShadowView.java @@ -25,7 +25,7 @@ import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.widget.LinearLayout; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.AlphaOptimizedFrameLayout; /** 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 b09b9f42e6af..2ffbe4bd4521 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java @@ -22,7 +22,7 @@ import android.view.View; import android.widget.ImageView; import com.android.app.animation.Interpolators; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.CrossFadeHelper; import com.android.systemui.statusbar.TransformableView; import com.android.systemui.statusbar.notification.row.HybridNotificationView; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java index 11582d7e3cc8..ad9e312e3c39 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java @@ -49,7 +49,7 @@ import android.util.Pair; import com.android.internal.messages.nano.SystemMessageProto; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.systemui.CoreStartable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.UiBackground; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java index 2ee21539ca1d..1f4f04cf85e3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java @@ -20,7 +20,7 @@ import android.util.Pools; import android.view.View; import com.android.internal.widget.MessagingImageMessage; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.ViewTransformationHelper; /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java index a0456985e8d9..167efc784ff5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java @@ -25,7 +25,7 @@ import android.view.View; import android.widget.ImageView; import com.android.app.animation.Interpolators; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import java.util.function.Consumer; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationIconDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationIconDozeHelper.java index 43e45b14cfbe..552bfb288d7a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationIconDozeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationIconDozeHelper.java @@ -24,7 +24,7 @@ import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; import android.widget.ImageView; -import com.android.systemui.R; +import com.android.systemui.res.R; public class NotificationIconDozeHelper extends NotificationDozeHelper { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java index fb712108a787..eb1be6772b99 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java @@ -23,7 +23,7 @@ import android.view.View; import android.widget.ImageView; import com.android.internal.util.ContrastColorUtil; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.collection.ListEntry; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.util.Compile; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt index 8029f48152f4..328a74100e48 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt @@ -3,7 +3,7 @@ package com.android.systemui.statusbar.notification import android.util.FloatProperty import android.view.View import androidx.annotation.FloatRange -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.flags.ViewRefactorFlag diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java index 90eb630949fa..aa7a63e90854 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java @@ -27,7 +27,7 @@ import com.android.app.animation.Interpolators; import com.android.internal.widget.MessagingImageMessage; import com.android.internal.widget.MessagingPropertyAnimator; import com.android.internal.widget.ViewClippingUtil; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.CrossFadeHelper; import com.android.systemui.statusbar.TransformableView; import com.android.systemui.statusbar.ViewTransformationHelper; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt index 1b43922f652a..af4df321953f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt @@ -21,7 +21,7 @@ import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator import android.view.View import android.view.ViewGroup -import com.android.systemui.R +import com.android.systemui.res.R import com.android.app.animation.Interpolators /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt index 93a34afc9fc9..94cc7e9d1a9f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt @@ -17,7 +17,7 @@ package com.android.systemui.statusbar.notification.collection.coordinator import android.content.Context -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.statusbar.notification.AssistantFeedbackController import com.android.systemui.statusbar.notification.collection.ListEntry import com.android.systemui.statusbar.notification.collection.NotifPipeline diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt index 82c7aae08f6a..6b70a0807b86 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt @@ -17,7 +17,7 @@ package com.android.systemui.statusbar.notification.collection.provider import android.content.Context -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/MediaContainerController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/MediaContainerController.kt index 8de03819ec32..70fabc0587d4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/MediaContainerController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/MediaContainerController.kt @@ -19,7 +19,7 @@ package com.android.systemui.statusbar.notification.collection.render import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.notification.stack.MediaContainerView import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/SectionHeaderController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/SectionHeaderController.kt index 49990d9c559e..c2b6f3277ffb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/SectionHeaderController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/SectionHeaderController.kt @@ -21,7 +21,7 @@ import android.content.Intent import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.plugins.ActivityStarter import com.android.systemui.statusbar.notification.dagger.HeaderClickAction import com.android.systemui.statusbar.notification.dagger.HeaderText diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt index 75801a8db65d..ca43591e0776 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt @@ -18,7 +18,7 @@ package com.android.systemui.statusbar.notification.dagger import android.annotation.StringRes import android.provider.Settings -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.notification.collection.render.NodeController import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java index 5664a2af7c0e..8ee0de691557 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java @@ -20,7 +20,7 @@ import android.content.Context; import com.android.internal.jank.InteractionJankMonitor; import com.android.systemui.CoreStartable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.plugins.statusbar.StatusBarStateController; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt index 98e167f84781..84678aa2ee23 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt @@ -27,7 +27,7 @@ import android.util.Log import android.view.View import android.widget.ImageView import com.android.internal.statusbar.StatusBarIcon -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.StatusBarIconView import com.android.systemui.statusbar.notification.InflationException diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt index 26dfe3edf793..a54687c6c46b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt @@ -30,7 +30,7 @@ import com.android.app.animation.Interpolators import com.android.internal.statusbar.StatusBarIcon import com.android.internal.util.ContrastColorUtil import com.android.settingslib.Utils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.demomode.DemoMode import com.android.systemui.demomode.DemoModeController diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java index cb21291dae1b..c61258b5e0ec 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java @@ -36,7 +36,7 @@ import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.jank.InteractionJankMonitor.Configuration; import com.android.settingslib.Utils; import com.android.systemui.Gefingerpoken; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.notification.FakeShadowView; import com.android.systemui.statusbar.notification.NotificationUtils; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureIconManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureIconManager.kt index 88dbb4cf1342..a5b32b8d4fa7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureIconManager.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BigPictureIconManager.kt @@ -89,6 +89,7 @@ constructor( this.lastLoadingJob?.cancel() this.lastLoadingJob = when { + skipLazyLoading(state.icon) -> null state is Empty && shown -> state.icon?.let(::startLoadingJob) state is PlaceHolder && shown -> startLoadingJob(state.icon) state is FullImage && !shown -> @@ -119,12 +120,6 @@ constructor( return Runnable {} } - if (displayedState.iconSameAs(icon)) { - // We're already handling this icon, nothing to do here. - log("skipping updateIcon for consumer:$drawableConsumer with icon:$icon") - return Runnable {} - } - this.drawableConsumer = drawableConsumer this.displayedState = Empty(icon) this.lastLoadingJob?.cancel() @@ -144,7 +139,7 @@ constructor( private fun loadImageOrPlaceHolderSync(icon: Icon?): Drawable? { icon ?: return null - if (viewShown) { + if (viewShown || skipLazyLoading(icon)) { return loadImageSync(icon) } @@ -228,6 +223,19 @@ constructor( } ) + /** + * We don't support lazy-loading or set placeholders for bitmap and data based icons, because + * they gonna stay in memory anyways. + */ + private fun skipLazyLoading(icon: Icon?): Boolean = + when (icon?.type) { + Icon.TYPE_BITMAP, + Icon.TYPE_ADAPTIVE_BITMAP, + Icon.TYPE_DATA, + null -> true + else -> false + } + private fun log(msg: String) { if (DEBUG) { Log.d(TAG, "$msg state=${getDebugString()}") @@ -242,15 +250,6 @@ constructor( data class PlaceHolder(override val icon: Icon, val drawableSize: Size) : DrawableState(icon) data class FullImage(override val icon: Icon, val drawableSize: Size) : DrawableState(icon) - - fun iconSameAs(other: Icon?): Boolean { - val displayedIcon = icon - return when { - displayedIcon == null && other == null -> true - displayedIcon != null && other != null -> displayedIcon.sameAs(other) - else -> false - } - } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt index 0de3246e01fa..4114eb2a7896 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt @@ -38,7 +38,7 @@ import android.view.WindowInsets.Type.statusBars import android.view.WindowManager import android.widget.TextView import com.android.internal.annotations.VisibleForTesting -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt index 9c4aa072a83d..2cfd075a17a9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt @@ -37,7 +37,7 @@ import android.widget.Switch import android.widget.TextView import com.android.settingslib.Utils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.util.Assert /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index acece33f0b93..fb8024c88191 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -73,7 +73,7 @@ import com.android.internal.statusbar.IStatusBarService; import com.android.internal.util.ContrastColorUtil; import com.android.internal.widget.CachingIconView; import com.android.internal.widget.CallLayout; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.flags.ViewRefactorFlag; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java index b95018777fea..77f5717d0e91 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java @@ -48,7 +48,7 @@ import androidx.annotation.VisibleForTesting; import com.android.app.animation.Interpolators; import com.android.internal.logging.InstanceId; import com.android.internal.logging.InstanceIdSequence; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.shade.ShadeController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.notification.logging.NotificationPanelLogger; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java index c8f13a6302cd..259923170477 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java @@ -28,7 +28,7 @@ import android.util.IndentingPrintWriter; import android.view.View; import android.view.ViewOutlineProvider; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.flags.Flags; import com.android.systemui.flags.ViewRefactorFlag; import com.android.systemui.statusbar.notification.RoundableState; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java index c4c116ba0613..5aae48899bc9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java @@ -34,7 +34,7 @@ import androidx.annotation.Nullable; import com.android.app.animation.Interpolators; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.StatusBarIconView; import com.android.systemui.statusbar.notification.Roundable; import com.android.systemui.statusbar.notification.RoundableState; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java index 3f4fd5006408..42c80ed22717 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java @@ -43,7 +43,7 @@ import android.widget.TextView; import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.statusbar.notification.AssistantFeedbackController; import com.android.systemui.statusbar.notification.collection.NotificationEntry; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java index 0989df61a5e3..26db5f2bc095 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java @@ -34,7 +34,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.stack.ExpandableViewState; import com.android.systemui.statusbar.notification.stack.ViewState; import com.android.systemui.util.DumpUtilsKt; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java index 99a24cb3e9ca..43d99a0e03f2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java @@ -27,7 +27,7 @@ import android.widget.ImageView; import android.widget.TextView; import com.android.internal.widget.ConversationLayout; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.NotificationFadeAware; /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java index 3e10f2ad52e5..ddd9bddc7375 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java @@ -31,7 +31,7 @@ import android.view.ViewGroup; import android.widget.TextView; import com.android.internal.widget.ConversationLayout; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * A class managing hybrid groups that include {@link HybridNotificationView} and the notification diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java index ce6dd893cb69..892a63505a71 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java @@ -30,7 +30,7 @@ import androidx.annotation.ColorInt; import com.android.internal.util.ContrastColorUtil; import com.android.keyguard.AlphaOptimizedLinearLayout; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.CrossFadeHelper; import com.android.systemui.statusbar.TransformableView; import com.android.systemui.statusbar.ViewTransformationHelper; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java index 1fd4d12c06ca..b95e053ae508 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java @@ -33,7 +33,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.io.PrintWriter; import java.util.Arrays; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java index f805183d52aa..f186e665f773 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java @@ -41,7 +41,7 @@ import android.widget.RemoteViews; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.widget.ImageMessageConsumer; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.media.controls.util.MediaFeatureFlag; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java index 065828bee746..a27a305428c4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java @@ -45,7 +45,7 @@ import androidx.annotation.MainThread; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.IStatusBarService; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.SmartReplyController; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java index 7134f15d4fec..62b268b90cf3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java @@ -65,7 +65,7 @@ import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.notification.ConversationIconFactory; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.people.widget.PeopleSpaceWidgetManager; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java index 047db2046529..b86d1d934269 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java @@ -35,7 +35,7 @@ import androidx.annotation.Nullable; import com.android.app.animation.Interpolators; import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java index 44ead26de012..1dd3739d0e84 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java @@ -46,7 +46,7 @@ import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.settingslib.notification.ConversationIconFactory; import com.android.systemui.CoreStartable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java index 99a77550cc76..d8f31d4fb8a2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java @@ -60,7 +60,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.AssistantFeedbackController; import com.android.systemui.statusbar.notification.collection.NotificationEntry; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java index 5a129fccff06..a317f95c9e65 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java @@ -41,7 +41,7 @@ import android.widget.FrameLayout.LayoutParams; import com.android.app.animation.Interpolators; import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.statusbar.AlphaOptimizedImageView; import com.android.systemui.statusbar.notification.collection.NotificationEntry; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java index d5d7f75fbaa1..3443da19895e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java @@ -49,7 +49,7 @@ import com.android.app.animation.Interpolators; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java index ac97e77f84a2..06c3b7951db3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java @@ -34,7 +34,7 @@ import android.widget.LinearLayout; import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import java.util.Set; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java index 6feffe654630..8e974c24dd0c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java @@ -23,7 +23,7 @@ import android.view.ViewGroup; import androidx.asynclayoutinflater.view.AsyncLayoutInflater; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.InflationTask; import com.android.systemui.statusbar.notification.collection.NotificationEntry; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt index bb43b95357db..2d946945597e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt @@ -20,7 +20,7 @@ import android.content.Context import android.view.View import com.android.internal.widget.CachingIconView import com.android.internal.widget.CallLayout -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.statusbar.notification.NotificationFadeAware import com.android.systemui.statusbar.notification.NotificationUtils import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt index 10753f215103..b4411f1a33a5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt @@ -25,7 +25,7 @@ import com.android.internal.widget.ConversationLayout import com.android.internal.widget.MessagingGroup import com.android.internal.widget.MessagingImageMessage import com.android.internal.widget.MessagingLinearLayout -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.statusbar.notification.NotificationFadeAware import com.android.systemui.statusbar.notification.NotificationUtils import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapper.java index fdff12d22354..45c35d8ff8d1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapper.java @@ -21,7 +21,7 @@ import android.graphics.Color; import android.view.View; import com.android.internal.graphics.ColorUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.NotificationFadeAware; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java index 87205e2df9c3..bd7f766c6860 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java @@ -37,7 +37,7 @@ import androidx.annotation.Nullable; import com.android.app.animation.Interpolators; import com.android.internal.widget.CachingIconView; import com.android.internal.widget.NotificationExpandButton; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.TransformableView; import com.android.systemui.statusbar.ViewTransformationHelper; import com.android.systemui.statusbar.notification.CustomInterpolatorTransformation; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapper.java index 4592fde69a93..ba1deede65a6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapper.java @@ -26,7 +26,7 @@ import com.android.internal.widget.MessagingGroup; import com.android.internal.widget.MessagingImageMessage; import com.android.internal.widget.MessagingLayout; import com.android.internal.widget.MessagingLinearLayout; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.TransformableView; import com.android.systemui.statusbar.ViewTransformationHelper; import com.android.systemui.statusbar.notification.NotificationUtils; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java index 199692bc3b79..875a409c07f0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java @@ -39,7 +39,7 @@ import androidx.annotation.Nullable; import com.android.internal.util.ContrastColorUtil; import com.android.internal.widget.NotificationActionListLayout; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.UiOffloadThread; import com.android.systemui.statusbar.CrossFadeHelper; import com.android.systemui.statusbar.TransformableView; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java index 38a368e1fdc8..cb671447bbb4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java @@ -26,7 +26,7 @@ import android.util.MathUtils; import androidx.annotation.VisibleForTesting; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dump.DumpManager; import com.android.systemui.shade.transition.LargeScreenShadeInterpolator; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java index d73bbebe40b4..33473a6f6b0a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java @@ -23,7 +23,7 @@ import android.animation.ValueAnimator; import android.view.View; import com.android.app.animation.Interpolators; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableView; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt index a8d8a8e03ed5..5d46f52dba87 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt @@ -22,7 +22,7 @@ import android.graphics.Canvas import android.graphics.Path import android.graphics.RectF import android.util.AttributeSet -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.statusbar.notification.row.ExpandableView /** 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 626f851d9d11..a929e4f3ea7f 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 @@ -42,7 +42,7 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.widget.NotificationExpandButton; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.CrossFadeHelper; import com.android.systemui.statusbar.NotificationGroupingUtil; import com.android.systemui.statusbar.notification.FeedbackIcon; 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 e8521d1673cf..28f0a0c5fd78 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 @@ -86,7 +86,7 @@ import com.android.settingslib.Utils; import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.ExpandHelper; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.flags.ViewRefactorFlag; @@ -569,6 +569,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private boolean mShouldUseSplitNotificationShade; private boolean mHasFilteredOutSeenNotifications; @Nullable private SplitShadeStateController mSplitShadeStateController = null; + private boolean mIsSmallLandscapeLockscreenEnabled = false; /** Pass splitShadeStateController to view and update split shade */ public void passSplitShadeStateController(SplitShadeStateController splitShadeStateController) { @@ -628,6 +629,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable super(context, attrs, 0, 0); Resources res = getResources(); FeatureFlags featureFlags = Dependency.get(FeatureFlags.class); + mIsSmallLandscapeLockscreenEnabled = featureFlags.isEnabled( + Flags.LOCKSCREEN_ENABLE_LANDSCAPE); mDebugLines = featureFlags.isEnabled(Flags.NSSL_DEBUG_LINES); mDebugRemoveAnimation = featureFlags.isEnabled(Flags.NSSL_DEBUG_REMOVE_ANIMATION); mSensitiveRevealAnimEndabled = featureFlags.isEnabled(Flags.SENSITIVE_REVEAL_ANIM); @@ -1054,6 +1057,17 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mOverflingDistance = configuration.getScaledOverflingDistance(); Resources res = context.getResources(); + boolean useSmallLandscapeLockscreenResources = mIsSmallLandscapeLockscreenEnabled + && res.getBoolean(R.bool.is_small_screen_landscape); + // TODO (b/293252410) remove condition here when flag is launched + // Instead update the config_skinnyNotifsInLandscape to be false whenever + // is_small_screen_landscape is true. Then, only use the config_skinnyNotifsInLandscape. + if (useSmallLandscapeLockscreenResources) { + mSkinnyNotifsInLandscape = false; + } else { + mSkinnyNotifsInLandscape = res.getBoolean( + R.bool.config_skinnyNotifsInLandscape); + } mGapHeight = res.getDimensionPixelSize(R.dimen.notification_section_divider_height); mStackScrollAlgorithm.initView(context); mAmbientState.reload(context); @@ -1065,7 +1079,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mBottomPadding = res.getDimensionPixelSize(R.dimen.notification_panel_padding_bottom); mMinimumPaddings = res.getDimensionPixelSize(R.dimen.notification_side_paddings); mQsTilePadding = res.getDimensionPixelOffset(R.dimen.qs_tile_margin_horizontal); - mSkinnyNotifsInLandscape = res.getBoolean(R.bool.config_skinnyNotifsInLandscape); mSidePaddings = mMinimumPaddings; // Updated in onMeasure by updateSidePadding() mMinInteractionHeight = res.getDimensionPixelSize( R.dimen.notification_min_interaction_height); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt index 24104d2f37e1..30708b708f25 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt @@ -20,7 +20,7 @@ import android.content.res.Resources import android.util.Log import android.view.View.GONE import androidx.annotation.VisibleForTesting -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.media.controls.pipeline.MediaDataManager diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java index baf09c70f936..722c28c43e8a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java @@ -28,7 +28,7 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.row.StackScrollerDecorView; /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java index 90e10a766cbc..f2d5394e0aee 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java @@ -27,7 +27,7 @@ import android.view.ViewGroup; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.SystemBarUtils; import com.android.keyguard.BouncerPanelExpansionCalculator; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.ShadeInterpolation; import com.android.systemui.shade.transition.LargeScreenShadeInterpolator; import com.android.systemui.statusbar.EmptyShadeView; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java index 2742a23d5fad..4e81d0c7cbdc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java @@ -24,7 +24,7 @@ import android.view.View; import com.android.app.animation.Interpolators; import com.android.keyguard.KeyguardSliceView; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.shared.clocks.AnimatableClockView; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java index f4605be2b9c5..f097d068e903 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java @@ -28,7 +28,7 @@ import android.view.animation.Interpolator; import com.android.app.animation.Interpolators; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.AnimatableProperty; import com.android.systemui.statusbar.notification.NotificationFadeAware.FadeOptimizedNotification; import com.android.systemui.statusbar.notification.PropertyAnimator; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt index 51b6c75f44b0..57cea5d3b31e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt @@ -18,7 +18,7 @@ package com.android.systemui.statusbar.notification.stack.domain.interactor import android.content.Context -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.ui.data.repository.ConfigurationRepository import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.policy.SplitShadeStateController diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/SharedNotificationContainer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/SharedNotificationContainer.kt index e52d604d7b02..b4f578fec910 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/SharedNotificationContainer.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/SharedNotificationContainer.kt @@ -28,7 +28,7 @@ import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID import androidx.constraintlayout.widget.ConstraintSet.START import androidx.constraintlayout.widget.ConstraintSet.TOP import androidx.constraintlayout.widget.ConstraintSet.VERTICAL -import com.android.systemui.R +import com.android.systemui.res.R /** * Container for the stack scroller, so that the bounds can be externally specified, such as from diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt index 45ae4e0afc3a..dee3973edb55 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt @@ -17,7 +17,7 @@ package com.android.systemui.statusbar.notification.stack.ui.viewbinder import android.view.LayoutInflater -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.flags.FeatureFlags import com.android.systemui.plugins.FalsingManager import com.android.systemui.statusbar.NotificationShelf diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt index baeae79f4d7d..07d3a1cf24c0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt @@ -30,7 +30,7 @@ import android.view.View import android.view.WindowManager import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.ActivityIntentHelper -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.ActivityLaunchAnimator import com.android.systemui.animation.ActivityLaunchAnimator.PendingIntentStarter import com.android.systemui.animation.DelegateLaunchAnimatorController 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 5eafa9e97088..697d2978db0c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java @@ -28,7 +28,7 @@ import android.os.UserHandle; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.NightDisplayListenerModule; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.plugins.qs.QSTile; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java index 459071280a1e..f62a79f199e9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java @@ -35,7 +35,7 @@ import android.view.View; import com.android.app.animation.Interpolators; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; 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 3b9afa1a5eab..023efdd9a2e2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java @@ -47,7 +47,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.KeyguardViewController; import com.android.keyguard.logging.BiometricUnlockLogger; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.biometrics.AuthController; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java index c9db153ff280..485ab3262725 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java @@ -47,7 +47,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.view.AppearanceRegion; import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.assist.AssistManager; import com.android.systemui.camera.CameraIntents; import com.android.systemui.dagger.SysUISingleton; 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 6b260ff77b3c..3a8850408f18 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -121,7 +121,7 @@ import com.android.systemui.DejankUtils; import com.android.systemui.EventLogTags; import com.android.systemui.InitController; import com.android.systemui.Prefs; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.assist.AssistManager; @@ -2049,7 +2049,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { } mPowerButtonReveal = new PowerButtonReveal(mContext.getResources().getDimensionPixelSize( - com.android.systemui.R.dimen.physical_power_button_center_screen_location_y)); + com.android.systemui.res.R.dimen.physical_power_button_center_screen_location_y)); } private void logStateToEventlog() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java index 374543dd0c58..de9854afdba1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java @@ -28,7 +28,7 @@ import android.view.ViewGroup; import android.widget.LinearLayout; import com.android.internal.statusbar.StatusBarIcon; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.demomode.DemoMode; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; 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 ae715b3f20c8..7730f7d99f51 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java @@ -37,7 +37,7 @@ import androidx.annotation.VisibleForTesting; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java index efc289185cfa..92b0f3f26258 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java @@ -19,7 +19,7 @@ import android.graphics.drawable.AnimatedVectorDrawable; import android.util.AttributeSet; import android.widget.ImageView; -import com.android.systemui.R; +import com.android.systemui.res.R; public class ExpandableIndicator extends ImageView { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java index a1f12b896d3b..270c40e801cd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java @@ -26,7 +26,7 @@ import androidx.annotation.NonNull; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.widget.ViewClippingUtil; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.shade.ShadeHeadsUpTracker; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java index 4f0cd80ab5ab..a5ea1426164b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java @@ -30,7 +30,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.UiEventLogger; import com.android.internal.policy.SystemBarUtils; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt index 5de0d15ee7d6..25e634a03ef7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt @@ -24,7 +24,7 @@ import android.view.WindowInsets import android.widget.FrameLayout import androidx.annotation.StringRes import com.android.keyguard.LockIconViewController -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.keyguard.ui.binder.KeyguardBottomAreaViewBinder import com.android.systemui.keyguard.ui.binder.KeyguardBottomAreaViewBinder.bind import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt index 924aac4e70be..430b0e9fab72 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt @@ -22,7 +22,7 @@ import android.content.pm.PackageManager import android.hardware.biometrics.BiometricSourceType import android.provider.Settings import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.statusbar.StatusBarStateController diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java index fc3c85a0807b..fb5a530e3875 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java @@ -26,7 +26,7 @@ import android.util.MathUtils; import com.android.app.animation.Interpolators; import com.android.keyguard.BouncerPanelExpansionCalculator; import com.android.keyguard.KeyguardStatusView; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.shade.ShadeViewController; import com.android.systemui.statusbar.policy.KeyguardUserSwitcherListView; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java index 29a249fcaa41..c6690c91c1f8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java @@ -32,7 +32,7 @@ import androidx.annotation.StyleRes; import com.android.app.animation.Interpolators; import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.keyguard.KeyguardIndication; /** @@ -296,6 +296,6 @@ public class KeyguardIndicationTextView extends TextView { private int getYTranslationPixels() { return mContext.getResources().getDimensionPixelSize( - com.android.systemui.R.dimen.keyguard_indication_y_translation); + com.android.systemui.res.R.dimen.keyguard_indication_y_translation); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java index 914e0c0af358..7efa705b7929 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java @@ -43,7 +43,7 @@ import android.widget.TextView; import androidx.annotation.VisibleForTesting; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.battery.BatteryMeterView; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher.DarkChange; 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 16413d2ef33a..fc9ecb3f14d6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java @@ -42,7 +42,7 @@ import com.android.keyguard.CarrierTextController; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.logging.KeyguardLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.battery.BatteryMeterViewController; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.flags.FeatureFlags; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java index d22ed3802eed..4bfce4cc173a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java @@ -34,7 +34,7 @@ import com.android.app.animation.Interpolators; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.util.ContrastColorUtil; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.demomode.DemoMode; import com.android.systemui.demomode.DemoModeController; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java index 46a2457670b0..572b7f12a8bf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java @@ -33,7 +33,7 @@ import android.view.ViewTreeObserver.OnPreDrawListener; import com.android.app.animation.Interpolators; import com.android.internal.graphics.ColorUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.KeyguardAffordanceView; import java.lang.annotation.Retention; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java index 365fbace1608..ec7767bca544 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java @@ -24,7 +24,7 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.widget.Button; import android.widget.FrameLayout; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Container for image of the multi user switcher (tappable). diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java index 3770c1df77ff..7cbaf63bc6db 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java @@ -39,7 +39,7 @@ import androidx.collection.ArrayMap; import com.android.app.animation.Interpolators; import com.android.internal.statusbar.StatusBarIcon; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.StatusBarIconView; import com.android.systemui.statusbar.notification.stack.AnimationFilter; import com.android.systemui.statusbar.notification.stack.AnimationProperties; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index 79151fd987d1..54d81b83197e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -43,7 +43,7 @@ import android.view.View; import androidx.lifecycle.Observer; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.qualifiers.DisplayId; import com.android.systemui.dagger.qualifiers.Main; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java index cc38405701f5..ae3f92355510 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java @@ -22,7 +22,7 @@ import android.animation.ObjectAnimator; import android.content.res.Resources; import android.view.View; -import com.android.systemui.R; +import com.android.systemui.res.R; public final class PhoneStatusBarTransitions extends BarTransitions { private static final float ICON_ALPHA_WHEN_NOT_OPAQUE = 1; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 1966033363d4..b53939e594fb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -36,7 +36,7 @@ import android.widget.LinearLayout; import com.android.internal.policy.SystemBarUtils; import com.android.systemui.Dependency; import com.android.systemui.Gefingerpoken; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherContainer; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt index fc5f91506c06..e1096e2d3482 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt @@ -24,7 +24,7 @@ import android.view.View import android.view.ViewGroup import android.view.ViewTreeObserver import com.android.systemui.Gefingerpoken -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.scene.shared.flag.SceneContainerFlags diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index 40432eee95bb..5b552640f397 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -51,7 +51,7 @@ import com.android.settingslib.Utils; import com.android.systemui.CoreStartable; import com.android.systemui.DejankUtils; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.ShadeInterpolation; import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants; import com.android.systemui.dagger.SysUISingleton; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt index ad1817019284..6a24174ff3cb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt @@ -26,7 +26,7 @@ import android.view.DisplayCutout import androidx.annotation.VisibleForTesting import com.android.internal.policy.SystemBarUtils import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dump.DumpManager import com.android.systemui.statusbar.policy.CallbackController diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java index 4878d45cec84..ffeb1a8cb8b6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java @@ -31,7 +31,7 @@ import android.widget.LinearLayout.LayoutParams; import androidx.annotation.VisibleForTesting; import com.android.internal.statusbar.StatusBarIcon; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.demomode.DemoModeCommandReceiver; import com.android.systemui.plugins.DarkIconDispatcher; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java index 53662f4334e1..fb7f9d1ec19b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java @@ -31,7 +31,7 @@ import android.view.View; import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.InitController; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java index 344e56cf570f..30a445f7ce4a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java @@ -23,7 +23,7 @@ import android.util.ArraySet; import android.util.Log; import com.android.settingslib.mobile.TelephonyIcons; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.statusbar.connectivity.IconState; import com.android.systemui.statusbar.connectivity.NetworkController; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java index 5773612d55c7..40bd8d3446b5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java @@ -31,7 +31,7 @@ import android.view.WindowInsets; import com.android.internal.policy.SystemBarUtils; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.ScreenDecorations; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.scene.domain.interactor.SceneInteractor; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java index d83664f9156a..7910e6f7413c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java @@ -33,7 +33,7 @@ import android.util.Log; import android.view.View; import com.android.keyguard.AlphaOptimizedLinearLayout; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.StatusIconDisplayable; import com.android.systemui.statusbar.notification.stack.AnimationFilter; import com.android.systemui.statusbar.notification.stack.AnimationProperties; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt index 881741ae5746..640ec281e162 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt @@ -27,7 +27,7 @@ import androidx.annotation.ColorInt import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.plugins.DarkIconDispatcher diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java index 69510cedaeb2..9d627af357cb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java @@ -42,7 +42,7 @@ import android.view.WindowManager.LayoutParams; import androidx.annotation.Nullable; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.flags.FeatureFlags; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java index 52e0e8a7a0cb..a033e1d55333 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java @@ -28,7 +28,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.wm.shell.animation.Interpolators; /** @@ -83,7 +83,7 @@ public class TapAgainView extends TextView { public void animateOut() { long fadeOutDuration = 167L; // From KeyguardIndicationTextView#getFadeOutDuration int yTranslation = mContext.getResources().getDimensionPixelSize( - com.android.systemui.R.dimen.keyguard_indication_y_translation); + com.android.systemui.res.R.dimen.keyguard_indication_y_translation); AnimatorSet animatorSet = new AnimatorSet(); ObjectAnimator fadeOut = ObjectAnimator.ofFloat(this, View.ALPHA, 0f); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java index 1b93c16dd45c..c6d2eca4d533 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java @@ -25,7 +25,7 @@ import android.util.AttributeSet; import android.view.View; import com.android.settingslib.drawable.UserIconDrawable; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * A view that displays a user image cropped to a circle with an optional frame. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java index 66f0f597ea6e..babd435c62ba 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java @@ -38,7 +38,7 @@ import com.android.app.animation.Interpolators; import com.android.app.animation.InterpolatorsAndroidX; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarIconBlocklist.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarIconBlocklist.kt index b845bada29dc..48a9e0f51979 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarIconBlocklist.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarIconBlocklist.kt @@ -37,7 +37,7 @@ fun getStatusBarIconBlocklist( ): List<String> { // Load the default blocklist from res val blocklist = res.getStringArray( - com.android.systemui.R.array.config_collapsed_statusbar_icon_blocklist).toList() + com.android.systemui.res.R.array.config_collapsed_statusbar_icon_blocklist).toList() val vibrateIconSlot: String = res.getString(R.string.status_bar_volume) val showVibrateIcon = settings.getIntForUser( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt index 5903fa3d5bd1..e73063b809cf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt @@ -21,7 +21,7 @@ import androidx.core.animation.AnimatorSet import androidx.core.animation.ValueAnimator import android.content.res.Resources import android.view.View -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.statusbar.events.STATUS_BAR_X_MOVE_IN import com.android.systemui.statusbar.events.STATUS_BAR_X_MOVE_OUT import com.android.systemui.statusbar.events.SystemStatusAnimationCallback diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java index cd6ccb5b9a8e..07c23d1f66a0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java @@ -19,7 +19,7 @@ package com.android.systemui.statusbar.phone.fragment.dagger; import android.view.View; import android.view.ViewStub; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.battery.BatteryMeterView; import com.android.systemui.dagger.qualifiers.RootView; import com.android.systemui.statusbar.HeadsUpStatusBarView; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt index 230bb58d0581..4b1e7a46836d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt @@ -29,7 +29,7 @@ import androidx.annotation.VisibleForTesting import com.android.internal.jank.InteractionJankMonitor import com.android.systemui.CoreStartable import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.ActivityLaunchAnimator import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt index 12594771a0df..387b970251fa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt @@ -20,7 +20,7 @@ import android.content.Context import android.util.AttributeSet import android.widget.ImageView import android.widget.TextView -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.view.LaunchableLinearLayout class StatusBarUserSwitcherContainer( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractor.kt index 3709e4c06009..b0b6b325bc83 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractor.kt @@ -17,7 +17,7 @@ package com.android.systemui.statusbar.pipeline.ethernet.domain import com.android.settingslib.AccessibilityContentDescriptions -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.dagger.SysUISingleton diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt index 67b04db64463..74a849a8c01f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt @@ -30,7 +30,7 @@ import androidx.annotation.VisibleForTesting import com.android.internal.telephony.PhoneConstants import com.android.settingslib.SignalIcon.MobileIconGroup import com.android.settingslib.mobile.MobileMappings.Config -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.dagger.SysUISingleton diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt index 7ec8e12e557e..f0470ca0a1ad 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt @@ -28,7 +28,7 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import com.android.settingslib.graph.SignalDrawable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.ui.binder.ContentDescriptionViewBinder import com.android.systemui.common.ui.binder.IconViewBinder import com.android.systemui.lifecycle.repeatWhenAttached diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernShadeCarrierGroupMobileView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernShadeCarrierGroupMobileView.kt index f407127f3161..fbd074d5b003 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernShadeCarrierGroupMobileView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernShadeCarrierGroupMobileView.kt @@ -20,7 +20,7 @@ import android.content.Context import android.util.AttributeSet import android.view.LayoutInflater import android.widget.LinearLayout -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.statusbar.StatusBarIconView.STATE_ICON import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger import com.android.systemui.statusbar.pipeline.mobile.ui.binder.MobileIconBinder diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt index 68d02de51dc9..900a92052153 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileView.kt @@ -19,7 +19,7 @@ package com.android.systemui.statusbar.pipeline.mobile.ui.view import android.content.Context import android.util.AttributeSet import android.view.LayoutInflater -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.statusbar.StatusBarIconView.getVisibleStateString import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger import com.android.systemui.statusbar.pipeline.mobile.ui.binder.MobileIconBinder diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityConstants.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityConstants.kt index 0fe53294fa7d..9ea167f4815c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityConstants.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityConstants.kt @@ -19,7 +19,7 @@ package com.android.systemui.statusbar.pipeline.shared import android.content.Context import android.telephony.TelephonyManager import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dump.DumpManager import java.io.PrintWriter diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt index 7076f345df97..4227f9eb8f10 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt @@ -31,7 +31,7 @@ import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID import androidx.annotation.ArrayRes import androidx.annotation.VisibleForTesting import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/InternetTileModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/InternetTileModel.kt index 1f076ed30f8a..18865900eef6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/InternetTileModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/InternetTileModel.kt @@ -20,6 +20,8 @@ import android.content.Context import android.graphics.drawable.Drawable import android.service.quicksettings.Tile import com.android.settingslib.graph.SignalDrawable +import com.android.systemui.common.shared.model.ContentDescription +import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription import com.android.systemui.common.shared.model.Text import com.android.systemui.common.shared.model.Text.Companion.loadText import com.android.systemui.plugins.qs.QSTile @@ -31,6 +33,8 @@ sealed interface InternetTileModel { val secondaryLabel: Text? val iconId: Int? val icon: QSTile.Icon? + val stateDescription: ContentDescription? + val contentDescription: ContentDescription? fun applyTo(state: QSTile.BooleanState, context: Context) { if (secondaryLabel != null) { @@ -39,6 +43,9 @@ sealed interface InternetTileModel { state.secondaryLabel = secondaryTitle } + state.stateDescription = stateDescription.loadContentDescription(context) + state.contentDescription = contentDescription.loadContentDescription(context) + // To support both SignalDrawable and other icons, give priority to icons over IDs if (icon != null) { state.icon = icon @@ -59,6 +66,8 @@ sealed interface InternetTileModel { override val secondaryLabel: Text? = null, override val iconId: Int? = null, override val icon: QSTile.Icon? = null, + override val stateDescription: ContentDescription? = null, + override val contentDescription: ContentDescription? = null, ) : InternetTileModel data class Inactive( @@ -66,6 +75,8 @@ sealed interface InternetTileModel { override val secondaryLabel: Text? = null, override val iconId: Int? = null, override val icon: QSTile.Icon? = null, + override val stateDescription: ContentDescription? = null, + override val contentDescription: ContentDescription? = null, ) : InternetTileModel } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt index a1b96dd327e9..fe69d818dedb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt @@ -20,7 +20,7 @@ import android.content.Context import android.graphics.Rect import android.util.AttributeSet import android.view.Gravity -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.plugins.DarkIconDispatcher import com.android.systemui.statusbar.BaseStatusBarFrameLayout import com.android.systemui.statusbar.StatusBarIconView diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt index b6f167704cd7..a80ea905e6e7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt @@ -17,7 +17,8 @@ package com.android.systemui.statusbar.pipeline.shared.ui.viewmodel import android.content.Context -import com.android.systemui.R +import com.android.systemui.res.R +import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Text import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application @@ -61,16 +62,21 @@ constructor( private val context: Context, @Application scope: CoroutineScope, ) { + private val internetLabel: String = context.getString(R.string.quick_settings_internet_label) + // Three symmetrical Flows that can be switched upon based on the value of // [DefaultConnectionModel] private val wifiIconFlow: Flow<InternetTileModel> = wifiInteractor.wifiNetwork.flatMapLatest { val wifiIcon = WifiIcon.fromModel(it, context, showHotspotInfo = true) if (it is WifiNetworkModel.Active && wifiIcon is WifiIcon.Visible) { + val secondary = removeDoubleQuotes(it.ssid) flowOf( InternetTileModel.Active( - secondaryTitle = removeDoubleQuotes(it.ssid), - icon = ResourceIcon.get(wifiIcon.icon.res) + secondaryTitle = secondary, + icon = ResourceIcon.get(wifiIcon.icon.res), + stateDescription = wifiIcon.contentDescription, + contentDescription = ContentDescription.Loaded("$internetLabel,$secondary"), ) ) } else { @@ -109,10 +115,13 @@ constructor( it.signalLevelIcon, mobileDataContentName, ) { networkNameModel, signalIcon, dataContentDescription -> + val secondary = + mobileDataContentConcat(networkNameModel.name, dataContentDescription) InternetTileModel.Active( - secondaryTitle = - mobileDataContentConcat(networkNameModel.name, dataContentDescription), + secondaryTitle = secondary, icon = SignalIcon(signalIcon.toSignalDrawableState()), + stateDescription = ContentDescription.Loaded(secondary), + contentDescription = ContentDescription.Loaded(internetLabel), ) } } @@ -148,10 +157,13 @@ constructor( if (it == null) { notConnectedFlow } else { + val secondary = it.contentDescription.toString() flowOf( InternetTileModel.Active( - secondaryTitle = it.contentDescription.toString(), - iconId = it.res + secondaryTitle = secondary, + iconId = it.res, + stateDescription = null, + contentDescription = ContentDescription.Loaded(secondary), ) ) } @@ -164,16 +176,23 @@ constructor( ) { networksAvailable, isAirplaneMode -> when { isAirplaneMode -> { + val secondary = context.getString(R.string.status_bar_airplane) InternetTileModel.Inactive( - secondaryTitle = context.getString(R.string.status_bar_airplane), - icon = ResourceIcon.get(R.drawable.ic_qs_no_internet_unavailable) + secondaryTitle = secondary, + icon = ResourceIcon.get(R.drawable.ic_qs_no_internet_unavailable), + stateDescription = null, + contentDescription = ContentDescription.Loaded(secondary), ) } networksAvailable -> { + val secondary = + context.getString(R.string.quick_settings_networks_available) InternetTileModel.Inactive( - secondaryTitle = - context.getString(R.string.quick_settings_networks_available), + secondaryTitle = secondary, iconId = R.drawable.ic_qs_no_internet_available, + stateDescription = null, + contentDescription = + ContentDescription.Loaded("$internetLabel,$secondary") ) } else -> { @@ -206,6 +225,9 @@ constructor( InternetTileModel.Inactive( secondaryLabel = Text.Resource(R.string.quick_settings_networks_unavailable), iconId = R.drawable.ic_qs_no_internet_unavailable, + stateDescription = null, + contentDescription = + ContentDescription.Resource(R.string.quick_settings_networks_unavailable), ) private fun removeDoubleQuotes(string: String?): String? { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt index 8bea7728170f..2da76d4f4051 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt @@ -18,7 +18,7 @@ package com.android.systemui.statusbar.pipeline.wifi.shared import android.content.Context import com.android.systemui.Dumpable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dump.DumpManager import java.io.PrintWriter diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt index e593575bd791..a9ac51d7c472 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/binder/WifiViewBinder.kt @@ -23,7 +23,7 @@ import android.widget.ImageView import androidx.core.view.isVisible import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.ui.binder.IconViewBinder import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.statusbar.StatusBarIconView diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/model/WifiIcon.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/model/WifiIcon.kt index 668c5b3c4b78..efa092bb3f40 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/model/WifiIcon.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/model/WifiIcon.kt @@ -22,7 +22,7 @@ import androidx.annotation.StringRes import androidx.annotation.VisibleForTesting import com.android.settingslib.AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH import com.android.settingslib.AccessibilityContentDescriptions.WIFI_NO_CONNECTION -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.log.table.Diffable diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt index f23e10287164..4cd348412f63 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt @@ -20,7 +20,7 @@ import android.annotation.SuppressLint import android.content.Context import android.util.AttributeSet import android.view.LayoutInflater -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.statusbar.StatusBarIconView import com.android.systemui.statusbar.pipeline.shared.ui.view.ModernStatusBarView import com.android.systemui.statusbar.pipeline.wifi.ui.binder.WifiViewBinder diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryStateNotifier.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryStateNotifier.kt index 27e40e06fcf0..a078dd5cf28c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryStateNotifier.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryStateNotifier.kt @@ -23,7 +23,7 @@ import android.app.PendingIntent import android.content.Context import android.content.Intent import android.net.Uri -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.util.concurrency.DelayableExecutor import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java index 6186c43017b3..13f76feca9fd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java @@ -25,7 +25,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.settings.brightness.BrightnessSliderController; import com.android.systemui.settings.brightness.ToggleSlider; import com.android.systemui.shade.NotificationShadeWindowView; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java index f7b601b9d284..b06ebe9b9358 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java @@ -35,7 +35,7 @@ import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import com.android.internal.annotations.GuardedBy; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dump.DumpManager; import com.android.systemui.util.Utils; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java index b7ae233c8e52..713283ebf947 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java @@ -47,7 +47,7 @@ import android.widget.TextView; import com.android.settingslib.Utils; import com.android.systemui.Dependency; import com.android.systemui.FontSizeUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.demomode.DemoModeCommandReceiver; import com.android.systemui.plugins.DarkIconDispatcher; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java index b5bd1d8f0102..74e02d7cfec1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java @@ -29,7 +29,7 @@ import android.util.AttributeSet; import android.widget.TextView; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastDispatcher; import java.util.Date; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt index ffb743ff926c..1224275aaf93 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt @@ -21,7 +21,7 @@ import android.content.Context import android.content.SharedPreferences import android.provider.Settings import android.util.Log -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.controls.dagger.ControlsComponent import com.android.systemui.controls.management.ControlsListingController diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java index d472c3572433..e59ec044bece 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java @@ -34,7 +34,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.systemui.EventLogTags; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.statusbar.AlertingNotificationManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpUtil.java index feef02913416..f4a1975fab52 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpUtil.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpUtil.java @@ -21,7 +21,7 @@ import android.annotation.Nullable; import android.util.Log; import android.view.View; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.util.Compile; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java index a4821e0e9299..4b97197536cc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java @@ -32,7 +32,7 @@ import android.util.Log; import androidx.annotation.NonNull; import com.android.internal.util.ConcurrentUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java index 880e0d2eef31..62e238164514 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java @@ -35,7 +35,7 @@ import com.android.keyguard.KeyguardConstants; import com.android.keyguard.KeyguardVisibilityHelper; import com.android.keyguard.dagger.KeyguardUserSwitcherScope; import com.android.settingslib.drawable.CircleFramedDrawable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.Expandable; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.FalsingManager; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java index 63dcad98f056..1c88289706f3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java @@ -37,7 +37,7 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.logging.KeyguardUpdateMonitorLogger; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserDetailItemView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserDetailItemView.java index e1ec94fada81..012408e29b49 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserDetailItemView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserDetailItemView.java @@ -26,7 +26,7 @@ import androidx.core.graphics.ColorUtils; import com.android.app.animation.Interpolators; import com.android.keyguard.KeyguardConstants; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.qs.tiles.UserDetailItemView; /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java index 2d04ffa9e624..bb074ac33ddb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java @@ -38,7 +38,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.KeyguardVisibilityHelper; import com.android.keyguard.dagger.KeyguardUserSwitcherScope; import com.android.settingslib.drawable.CircleFramedDrawable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.plugins.statusbar.StatusBarStateController; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherScrim.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherScrim.java index 1d9d33d2aab1..5ed207cc3447 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherScrim.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherScrim.java @@ -28,7 +28,7 @@ import android.graphics.Shader; import android.graphics.drawable.Drawable; import android.view.View; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Gradient background for the user switcher on Keyguard. 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 e00365d8fbcb..53fed3d2438f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java @@ -81,7 +81,7 @@ import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.internal.util.ContrastColorUtil; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt index 736b14574da0..a50fd6f86e09 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt @@ -30,7 +30,7 @@ import android.util.ArraySet import android.util.Log import android.view.View import com.android.internal.logging.UiEventLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags.NOTIFICATION_INLINE_REPLY_ANIMATION import com.android.systemui.statusbar.NotificationRemoteInputManager diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt index e71c972266f2..c302d6aeadbc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt @@ -16,7 +16,7 @@ package com.android.systemui.statusbar.policy import android.content.res.Resources -import com.android.systemui.R +import com.android.systemui.res.R /** * Fake SplitShadeStateController diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java index 03656f000c07..4a4d4e1f27b2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java @@ -50,7 +50,7 @@ import androidx.annotation.NonNull; import com.android.internal.annotations.GuardedBy; import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.VpnConfig; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java index 52a6bcaa6753..7ac3e9c2d94c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java @@ -26,7 +26,7 @@ import android.util.KeyValueListParser; import android.util.Log; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.util.DeviceConfigProxy; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt index 1776e5b76e55..616992eb0865 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt @@ -41,7 +41,7 @@ import android.view.ViewGroup import android.view.accessibility.AccessibilityNodeInfo import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction import android.widget.Button -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.plugins.ActivityStarter import com.android.systemui.shared.system.ActivityManagerWrapper import com.android.systemui.shared.system.DevicePolicyManagerWrapper diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java index fb6ba8542a3f..b46f52c2ac2d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java @@ -32,7 +32,7 @@ import androidx.annotation.NonNull; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ContrastColorUtil; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.NotificationUtils; import java.text.BreakIterator; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java index 9f6157492a38..0d36b48e9099 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java @@ -27,7 +27,7 @@ import android.util.AttributeSet; import android.widget.LinearLayout; import android.widget.TextClock; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Container for a clock which has two separate views for the clock itself and AM/PM indicator. This diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateControllerImpl.kt index ab4a8afcc3c9..43905c593bdc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitShadeStateControllerImpl.kt @@ -16,7 +16,7 @@ package com.android.systemui.statusbar.policy import android.content.res.Resources -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java index a593d518c207..2ed9d1548007 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java @@ -36,7 +36,7 @@ import androidx.annotation.NonNull; import com.android.internal.util.UserIcons; import com.android.settingslib.drawable.UserIconDrawable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.settings.UserTracker; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/VariableDateView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/VariableDateView.kt index cd1dcd585ed9..2f171bbc0bfc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/VariableDateView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/VariableDateView.kt @@ -20,7 +20,7 @@ import android.content.Context import android.text.StaticLayout import android.util.AttributeSet import android.widget.TextView -import com.android.systemui.R +import com.android.systemui.res.R /** * View for showing a date that can toggle between two different formats depending on size. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java index 927024fbdd34..a77c69236946 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java @@ -213,12 +213,11 @@ public interface StatusBarPolicyModule { return networkController.getDataSaverController(); } - /** Provides a log bufffer for BatteryControllerImpl */ + /** Provides a log buffer for BatteryControllerImpl */ @Provides @SysUISingleton @BatteryControllerLog - //TODO(b/300147438): reduce the size of this log buffer static LogBuffer provideBatteryControllerLog(LogBufferFactory factory) { - return factory.create(BatteryControllerLogger.TAG, 300); + return factory.create(BatteryControllerLogger.TAG, 30); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java index f4cc0ed30781..e4e9554e1ab7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java @@ -47,7 +47,7 @@ import android.view.WindowInsets; import android.view.WindowManager; import com.android.internal.policy.SystemBarUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.DelegateLaunchAnimatorController; import com.android.systemui.dagger.SysUISingleton; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowModule.kt index 874217a67613..1c7debcdf39d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowModule.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowModule.kt @@ -1,7 +1,7 @@ package com.android.systemui.statusbar.window import android.view.LayoutInflater -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import dagger.Module import dagger.Provides diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt index c1ac800b8159..fa9256f82dbd 100644 --- a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt +++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt @@ -36,7 +36,7 @@ import com.android.internal.annotations.VisibleForTesting import com.android.internal.logging.InstanceId import com.android.internal.logging.InstanceIdSequence import com.android.internal.logging.UiEventLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.log.DebugLogger.debugLog diff --git a/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.kt b/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.kt index b9c24871eac8..ccd8e48d164c 100644 --- a/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.kt @@ -26,7 +26,7 @@ import android.telecom.TelecomManager import android.util.Log import android.view.WindowManager import com.android.internal.app.AlertActivity -import com.android.systemui.R +import com.android.systemui.res.R import javax.inject.Inject /** Dialog shown to the user to switch to managed profile for making a call using work SIM. */ diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt index f0aae0f83722..fc414b66b042 100644 --- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt @@ -39,7 +39,7 @@ import androidx.annotation.VisibleForTesting import com.android.app.animation.Interpolators import com.android.internal.widget.CachingIconView import com.android.systemui.Gefingerpoken -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.classifier.FalsingCollector import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription import com.android.systemui.common.shared.model.Text.Companion.loadText diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt index f24d5263ff89..4449f8d06f15 100644 --- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt +++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt @@ -21,7 +21,7 @@ import android.view.HapticFeedbackConstants import android.view.View import androidx.annotation.AttrRes import com.android.internal.logging.InstanceId -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.shared.model.Text import com.android.systemui.common.shared.model.TintedIcon import com.android.systemui.temporarydisplay.TemporaryViewInfo diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeModule.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeModule.java index 7fa90df0e792..e78eba49a3da 100644 --- a/packages/SystemUI/src/com/android/systemui/theme/ThemeModule.java +++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeModule.java @@ -18,7 +18,7 @@ package com.android.systemui.theme; import android.content.res.Resources; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.util.concurrency.SysUIConcurrencyModule; diff --git a/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java b/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java index 29f16c7b924a..d97cae2a99e3 100644 --- a/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java +++ b/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java @@ -170,9 +170,9 @@ public class SystemUIToast implements ToastPlugin.Toast { } final View toastView = mLayoutInflater.inflate( - com.android.systemui.R.layout.text_toast, null); - final TextView textView = toastView.findViewById(com.android.systemui.R.id.text); - final ImageView iconView = toastView.findViewById(com.android.systemui.R.id.icon); + com.android.systemui.res.R.layout.text_toast, null); + final TextView textView = toastView.findViewById(com.android.systemui.res.R.id.text); + final ImageView iconView = toastView.findViewById(com.android.systemui.res.R.id.icon); textView.setText(mText); ApplicationInfo appInfo = null; @@ -189,7 +189,7 @@ public class SystemUIToast implements ToastPlugin.Toast { textView.setMaxLines(Integer.MAX_VALUE); // no app icon - toastView.findViewById(com.android.systemui.R.id.icon).setVisibility(View.GONE); + toastView.findViewById(com.android.systemui.res.R.id.icon).setVisibility(View.GONE); } else { Drawable icon = getBadgedIcon(mContext, mPackageName, mUserId); if (icon == null) { diff --git a/packages/SystemUI/src/com/android/systemui/toast/ToastDefaultAnimation.kt b/packages/SystemUI/src/com/android/systemui/toast/ToastDefaultAnimation.kt index 8187956962b6..8b5fd0b33658 100644 --- a/packages/SystemUI/src/com/android/systemui/toast/ToastDefaultAnimation.kt +++ b/packages/SystemUI/src/com/android/systemui/toast/ToastDefaultAnimation.kt @@ -31,8 +31,8 @@ class ToastDefaultAnimation { companion object { // total duration shouldn't exceed NotificationManagerService's delay for "in" animation fun toastIn(view: View): AnimatorSet? { - val icon: View? = view.findViewById(com.android.systemui.R.id.icon) - val text: View? = view.findViewById(com.android.systemui.R.id.text) + val icon: View? = view.findViewById(com.android.systemui.res.R.id.icon) + val text: View? = view.findViewById(com.android.systemui.res.R.id.text) if (icon == null || text == null) { return null } @@ -69,8 +69,8 @@ class ToastDefaultAnimation { fun toastOut(view: View): AnimatorSet? { // total duration shouldn't exceed NotificationManagerService's delay for "out" anim - val icon: View? = view.findViewById(com.android.systemui.R.id.icon) - val text: View? = view.findViewById(com.android.systemui.R.id.text) + val icon: View? = view.findViewById(com.android.systemui.res.R.id.icon) + val text: View? = view.findViewById(com.android.systemui.res.R.id.text) if (icon == null || text == null) { return null } diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ClipboardView.java b/packages/SystemUI/src/com/android/systemui/tuner/ClipboardView.java index 919f15050107..5ae4cdf1f56f 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/ClipboardView.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/ClipboardView.java @@ -24,7 +24,7 @@ import android.view.MotionEvent; import android.view.View; import android.widget.ImageView; -import com.android.systemui.R; +import com.android.systemui.res.R; public class ClipboardView extends ImageView implements OnPrimaryClipChangedListener { diff --git a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java index 246488600eef..a43524a15b67 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java @@ -29,7 +29,7 @@ import androidx.preference.SwitchPreference; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.demomode.DemoMode; import com.android.systemui.demomode.DemoModeAvailabilityTracker; import com.android.systemui.demomode.DemoModeController; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java index 4dbceac9b3a7..771a8c8a0cfd 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java @@ -41,7 +41,7 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView.ViewHolder; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.IntentButtonProvider.IntentButton; import com.android.systemui.statusbar.ScalingDrawableWrapper; import com.android.systemui.statusbar.phone.ExpandableIndicator; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java index 87d2063d18e9..ec6f86297bae 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java @@ -46,7 +46,7 @@ import androidx.preference.Preference; import androidx.preference.Preference.OnPreferenceChangeListener; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.tuner.TunerService.Tunable; import java.util.ArrayList; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/OtherPrefs.java b/packages/SystemUI/src/com/android/systemui/tuner/OtherPrefs.java index 7239c8a22a31..32b1b2607323 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/OtherPrefs.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/OtherPrefs.java @@ -18,7 +18,7 @@ import android.os.Bundle; import androidx.preference.PreferenceFragment; -import com.android.systemui.R; +import com.android.systemui.res.R; public class OtherPrefs extends PreferenceFragment { @Override diff --git a/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java index 49995155f251..7635a84539ca 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java @@ -36,7 +36,7 @@ import androidx.preference.SwitchPreference; import com.android.internal.util.ArrayUtils; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.PluginEnablerImpl; import com.android.systemui.plugins.PluginManager; import com.android.systemui.shared.plugins.PluginActionManager; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/PowerNotificationControlsFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/PowerNotificationControlsFragment.java index 80f9de6b4ba5..ce1a2e9b329c 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/PowerNotificationControlsFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/PowerNotificationControlsFragment.java @@ -27,7 +27,7 @@ import android.widget.TextView; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.R; +import com.android.systemui.res.R; public class PowerNotificationControlsFragment extends Fragment { diff --git a/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java index 24758908cff2..20ce23077cdd 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java @@ -29,7 +29,7 @@ import androidx.preference.PreferenceScreen; import com.android.settingslib.Utils; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.fragments.FragmentService; import java.util.Objects; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/SelectablePreference.java b/packages/SystemUI/src/com/android/systemui/tuner/SelectablePreference.java index 0be793eefa18..386b7bb1e049 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/SelectablePreference.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/SelectablePreference.java @@ -27,7 +27,7 @@ public class SelectablePreference extends CheckBoxPreference { public SelectablePreference(Context context) { super(context); - setWidgetLayoutResource(com.android.systemui.R.layout.preference_widget_radiobutton); + setWidgetLayoutResource(com.android.systemui.res.R.layout.preference_widget_radiobutton); setSelectable(true); mSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 32, context.getResources().getDisplayMetrics()); diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ShortcutPicker.java b/packages/SystemUI/src/com/android/systemui/tuner/ShortcutPicker.java index 11e1f278a271..5b340527dd3f 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/ShortcutPicker.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/ShortcutPicker.java @@ -30,7 +30,7 @@ import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceViewHolder; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.tuner.ShortcutParser.Shortcut; import com.android.systemui.tuner.TunerService.Tunable; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java index ecaf7921a4df..14d7281e5b99 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java @@ -30,7 +30,7 @@ import androidx.preference.PreferenceFragment; import androidx.preference.PreferenceScreen; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.demomode.DemoModeController; import com.android.systemui.fragments.FragmentService; import com.android.systemui.util.settings.GlobalSettings; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java index 989462a9fd34..9cc526a1c0f3 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java @@ -33,7 +33,7 @@ import androidx.preference.PreferenceFragment; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.shared.plugins.PluginPrefs; public class TunerFragment extends PreferenceFragment { diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java index ccc0a79d2cfe..8087a8755a6e 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java @@ -38,7 +38,7 @@ import androidx.annotation.WorkerThread; import com.android.internal.util.ArrayUtils; import com.android.systemui.DejankUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.demomode.DemoModeController; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java index 71355bbb23e1..1c441b39cc64 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java @@ -9,7 +9,7 @@ import androidx.preference.SwitchPreference; import com.android.internal.logging.MetricsLogger; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.tuner.TunerService.Tunable; public class TunerSwitch extends SwitchPreference implements Tunable { diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java index 3a7ac9c8a8bd..c1eb5b6a92df 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java @@ -30,7 +30,7 @@ import android.view.WindowManager; import com.android.internal.app.AlertActivity; import com.android.internal.app.AlertController; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import javax.inject.Inject; diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbAudioWarningDialogMessage.java b/packages/SystemUI/src/com/android/systemui/usb/UsbAudioWarningDialogMessage.java index e06353b3aad3..7e9c5e9546cd 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbAudioWarningDialogMessage.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbAudioWarningDialogMessage.java @@ -22,7 +22,7 @@ import android.annotation.IntDef; import android.content.res.Resources; import android.util.Log; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.lang.annotation.Retention; diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java index 534049b65cb4..7ede21a025c2 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java @@ -29,7 +29,7 @@ import android.view.WindowManager; import android.widget.TextView; import android.widget.Toast; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Activity that alerts the user when contaminant is detected on USB port. diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java index 941cd7783ed0..e7e907a90d34 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java @@ -38,7 +38,7 @@ import android.widget.CheckBox; import com.android.internal.app.AlertActivity; import com.android.internal.app.AlertController; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastDispatcher; import javax.inject.Inject; diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java index 2871263dbb1e..ea871be70936 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java @@ -34,7 +34,7 @@ import android.view.WindowManager; import com.android.internal.app.AlertActivity; import com.android.internal.app.AlertController; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastDispatcher; import javax.inject.Inject; diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDialogActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDialogActivity.java index 55dec5fbe344..44dee7234bd9 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbDialogActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDialogActivity.java @@ -29,7 +29,7 @@ import android.widget.TextView; import com.android.internal.app.AlertActivity; import com.android.internal.app.AlertController; -import com.android.systemui.R; +import com.android.systemui.res.R; abstract class UsbDialogActivity extends AlertActivity implements DialogInterface.OnClickListener, CheckBox.OnCheckedChangeListener { diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java index 02a763794a6c..080a9dc64ac8 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java @@ -38,7 +38,7 @@ import android.widget.CheckBox; import com.android.internal.app.ResolverActivity; import com.android.internal.app.chooser.TargetInfo; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.ArrayList; import java.util.Iterator; diff --git a/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java b/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java index 08b0c647628c..562feb2e7b45 100644 --- a/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java +++ b/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java @@ -33,7 +33,7 @@ import androidx.annotation.Nullable; import com.android.internal.logging.UiEventLogger; import com.android.settingslib.users.CreateUserDialogController; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.ActivityStarter; import javax.inject.Inject; diff --git a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherFullscreenDialog.kt b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherFullscreenDialog.kt index 5ad963035e36..6df02e86fb61 100644 --- a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherFullscreenDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherFullscreenDialog.kt @@ -22,7 +22,7 @@ import android.view.LayoutInflater import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.WindowInsets import android.view.WindowInsetsController -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.classifier.FalsingCollector import com.android.systemui.statusbar.phone.SystemUIDialog import com.android.systemui.user.ui.binder.UserSwitcherViewBinder diff --git a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt index ee84580ac4ec..1fa48723d0a6 100644 --- a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt +++ b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt @@ -23,7 +23,7 @@ import android.view.View.MeasureSpec import android.widget.ListAdapter import android.widget.ListPopupWindow import android.widget.ListView -import com.android.systemui.R +import com.android.systemui.res.R /** * Popup menu for displaying items on the fullscreen user switcher. diff --git a/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt b/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt index 8cfa55570723..f40454915ee3 100644 --- a/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt @@ -23,7 +23,7 @@ import android.os.UserHandle import android.os.UserManager import android.provider.Settings import androidx.annotation.VisibleForTesting -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.dagger.SysUISingleton diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt index a3e648d4fb1b..e4894992b49f 100644 --- a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt @@ -37,7 +37,7 @@ import com.android.internal.logging.UiEventLogger import com.android.internal.util.UserIcons import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SystemUISecondaryUserService import com.android.systemui.animation.Expandable import com.android.systemui.broadcast.BroadcastDispatcher diff --git a/packages/SystemUI/src/com/android/systemui/user/legacyhelper/data/LegacyUserDataHelper.kt b/packages/SystemUI/src/com/android/systemui/user/legacyhelper/data/LegacyUserDataHelper.kt index 03a7470a3fe6..93573fa42c96 100644 --- a/packages/SystemUI/src/com/android/systemui/user/legacyhelper/data/LegacyUserDataHelper.kt +++ b/packages/SystemUI/src/com/android/systemui/user/legacyhelper/data/LegacyUserDataHelper.kt @@ -23,7 +23,7 @@ import android.graphics.Bitmap import android.os.UserManager import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin import com.android.settingslib.RestrictedLockUtilsInternal -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.user.data.source.UserRecord import com.android.systemui.user.shared.model.UserActionModel diff --git a/packages/SystemUI/src/com/android/systemui/user/legacyhelper/ui/LegacyUserUiHelper.kt b/packages/SystemUI/src/com/android/systemui/user/legacyhelper/ui/LegacyUserUiHelper.kt index 1ac86ce6162b..8957fe1ee214 100644 --- a/packages/SystemUI/src/com/android/systemui/user/legacyhelper/ui/LegacyUserUiHelper.kt +++ b/packages/SystemUI/src/com/android/systemui/user/legacyhelper/ui/LegacyUserUiHelper.kt @@ -20,7 +20,7 @@ package com.android.systemui.user.legacyhelper.ui import android.content.Context import androidx.annotation.DrawableRes import androidx.annotation.StringRes -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.user.data.source.UserRecord /** diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/binder/UserSwitcherViewBinder.kt b/packages/SystemUI/src/com/android/systemui/user/ui/binder/UserSwitcherViewBinder.kt index 59f2cdb745ca..c57870291055 100644 --- a/packages/SystemUI/src/com/android/systemui/user/ui/binder/UserSwitcherViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/user/ui/binder/UserSwitcherViewBinder.kt @@ -34,7 +34,7 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import com.android.systemui.Gefingerpoken -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.classifier.FalsingCollector import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.user.UserSwitcherPopupMenu diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/binder/UserViewBinder.kt b/packages/SystemUI/src/com/android/systemui/user/ui/binder/UserViewBinder.kt index e78807e675b3..8fc1b2515c6a 100644 --- a/packages/SystemUI/src/com/android/systemui/user/ui/binder/UserViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/user/ui/binder/UserViewBinder.kt @@ -25,7 +25,7 @@ import android.view.View import android.widget.ImageView import androidx.core.content.res.ResourcesCompat import com.android.settingslib.Utils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.ui.binder.TextViewBinder import com.android.systemui.user.ui.viewmodel.UserViewModel diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/dialog/AddUserDialog.kt b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/AddUserDialog.kt index fdf13be13a9b..b88f9fb3cee2 100644 --- a/packages/SystemUI/src/com/android/systemui/user/ui/dialog/AddUserDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/AddUserDialog.kt @@ -82,7 +82,7 @@ class AddUserDialog( context.getString(R.string.user_add_user_message_short) + if (showEphemeralMessage) { context.getString( - com.android.systemui.R.string.user_add_user_message_guest_remove + com.android.systemui.res.R.string.user_add_user_message_guest_remove ) } else { "" diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/dialog/UserSwitchDialog.kt b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/UserSwitchDialog.kt index b8ae257aaac5..40582150a21d 100644 --- a/packages/SystemUI/src/com/android/systemui/user/ui/dialog/UserSwitchDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/user/ui/dialog/UserSwitchDialog.kt @@ -5,7 +5,7 @@ import android.content.Intent import android.provider.Settings import android.view.LayoutInflater import com.android.internal.logging.UiEventLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.animation.DialogLaunchAnimator import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.FalsingManager diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt b/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt index aeed5fc59281..61952baba7b1 100644 --- a/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt @@ -17,7 +17,7 @@ package com.android.systemui.user.ui.viewmodel -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.common.shared.model.Text import com.android.systemui.common.ui.drawable.CircularDrawable import com.android.systemui.dagger.SysUISingleton diff --git a/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java b/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java index 516efc06386a..947746c94198 100644 --- a/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/util/AlphaTintDrawableWrapper.java @@ -28,7 +28,7 @@ import android.util.AttributeSet; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.systemui.R; +import com.android.systemui.res.R; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; diff --git a/packages/SystemUI/src/com/android/systemui/util/DelayableMarqueeTextView.kt b/packages/SystemUI/src/com/android/systemui/util/DelayableMarqueeTextView.kt index 8b90547f7bdb..ef9340a332dc 100644 --- a/packages/SystemUI/src/com/android/systemui/util/DelayableMarqueeTextView.kt +++ b/packages/SystemUI/src/com/android/systemui/util/DelayableMarqueeTextView.kt @@ -18,7 +18,7 @@ package com.android.systemui.util import android.content.Context import android.util.AttributeSet -import com.android.systemui.R +import com.android.systemui.res.R class DelayableMarqueeTextView @JvmOverloads constructor( context: Context, diff --git a/packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt b/packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt index 9b241a72b708..bbfdaa368a03 100644 --- a/packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt +++ b/packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt @@ -1,7 +1,7 @@ package com.android.systemui.util import android.content.res.Resources -import com.android.systemui.R +import com.android.systemui.res.R object LargeScreenUtils { /** diff --git a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java index 904a98b5e54d..8a6f79dc93b3 100644 --- a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java +++ b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java @@ -24,7 +24,7 @@ import android.provider.Settings; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.CoreStartable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.wm.shell.pip.tv.TvPipNotificationController; import java.util.Arrays; diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java index e0daa0706b86..760fe6a96fda 100644 --- a/packages/SystemUI/src/com/android/systemui/util/Utils.java +++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java @@ -23,7 +23,7 @@ import android.provider.Settings; import android.view.DisplayCutout; import com.android.internal.policy.SystemBarUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.settings.DisplayTracker; import com.android.systemui.shared.system.QuickStepContract; diff --git a/packages/SystemUI/src/com/android/systemui/util/animation/UniqueObjectHostView.kt b/packages/SystemUI/src/com/android/systemui/util/animation/UniqueObjectHostView.kt index 47a2d35e57f5..577d18eaea84 100644 --- a/packages/SystemUI/src/com/android/systemui/util/animation/UniqueObjectHostView.kt +++ b/packages/SystemUI/src/com/android/systemui/util/animation/UniqueObjectHostView.kt @@ -21,7 +21,7 @@ import android.content.Context import android.view.View import android.view.ViewGroup import android.widget.FrameLayout -import com.android.systemui.R +import com.android.systemui.res.R /** * A special view that is designed to host a single "unique object". The unique object is diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java index 58cffa761a66..de392d3f444f 100644 --- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java +++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java @@ -48,7 +48,7 @@ import android.view.View; import com.android.internal.logging.MetricsLogger; import com.android.systemui.CoreStartable; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java b/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java index 96980b85e410..7934ab1c197e 100644 --- a/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java +++ b/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java @@ -24,7 +24,7 @@ import android.util.Log; import androidx.annotation.NonNull; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.statusbar.policy.DevicePostureController; import com.android.systemui.util.concurrency.DelayableExecutor; diff --git a/packages/SystemUI/src/com/android/systemui/util/service/dagger/ObservableServiceModule.java b/packages/SystemUI/src/com/android/systemui/util/service/dagger/ObservableServiceModule.java index c62c95755ce8..bcf34f833d32 100644 --- a/packages/SystemUI/src/com/android/systemui/util/service/dagger/ObservableServiceModule.java +++ b/packages/SystemUI/src/com/android/systemui/util/service/dagger/ObservableServiceModule.java @@ -19,7 +19,7 @@ package com.android.systemui.util.service.dagger; import android.content.res.Resources; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Main; import javax.inject.Named; diff --git a/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java b/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java index ae23ca64e31e..ac41a509213d 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java +++ b/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java @@ -26,7 +26,7 @@ import androidx.core.view.ViewCompat; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat; import com.android.keyguard.AlphaOptimizedImageButton; -import com.android.systemui.R; +import com.android.systemui.res.R; /** Toggle button in Volume Dialog for controlling system captions state */ public class CaptionsToggleImageButton extends AlphaOptimizedImageButton { diff --git a/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java b/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java index fb5a71c0b06f..eb0bf46159dd 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java +++ b/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java @@ -35,7 +35,7 @@ import android.view.WindowManager; import com.android.internal.annotations.GuardedBy; import com.android.internal.messages.nano.SystemMessageProto; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.util.NotificationChannels; diff --git a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java index 89bc75760b4b..d9593bd56f00 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java +++ b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java @@ -25,7 +25,7 @@ import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.Objects; diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java index 9cc3cdbf5c34..ea4d31bca035 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java @@ -64,7 +64,7 @@ import androidx.lifecycle.Observer; import com.android.internal.annotations.GuardedBy; import com.android.settingslib.volume.MediaSessions; import com.android.systemui.Dumpable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dump.DumpManager; diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java index dcc0525bb436..727d649c8118 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java @@ -120,7 +120,7 @@ import com.android.internal.view.RotationPolicy; import com.android.settingslib.Utils; import com.android.systemui.Dumpable; import com.android.systemui.Prefs; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.media.dialog.MediaOutputDialogFactory; diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialog.java index 96936e3eb5f0..605038766651 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialog.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialog.java @@ -51,7 +51,7 @@ import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import com.android.settingslib.media.MediaOutputConstants; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.phone.SystemUIDialog; diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelSlicesAdapter.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelSlicesAdapter.java index 23714021a2cc..d7669d45cb64 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelSlicesAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelSlicesAdapter.java @@ -33,7 +33,7 @@ import androidx.slice.Slice; import androidx.slice.SliceItem; import androidx.slice.widget.SliceView; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.ArrayList; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeToolTipView.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeToolTipView.java index 1de55856f942..2143771ef696 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeToolTipView.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeToolTipView.java @@ -28,7 +28,7 @@ import android.widget.LinearLayout; import androidx.core.content.ContextCompat; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.recents.TriangleShape; /** diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java index 0b3521b048c4..3451ae0a9be3 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java @@ -22,7 +22,7 @@ import android.os.Handler; import android.util.Log; import com.android.systemui.CoreStartable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.qs.tiles.DndTile; diff --git a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java index de9b5ee2e19a..0e6df6b11e7b 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java @@ -30,7 +30,7 @@ import android.service.quickaccesswallet.QuickAccessWalletClient; import android.service.quickaccesswallet.QuickAccessWalletClientImpl; import android.util.Log; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/DotIndicatorDecoration.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/DotIndicatorDecoration.java index e5c55b0a5e7f..e90d9e281a9b 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/ui/DotIndicatorDecoration.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/DotIndicatorDecoration.java @@ -27,7 +27,7 @@ import androidx.annotation.ColorInt; import androidx.core.graphics.ColorUtils; import androidx.recyclerview.widget.RecyclerView; -import com.android.systemui.R; +import com.android.systemui.res.R; final class DotIndicatorDecoration extends RecyclerView.ItemDecoration { private final int mUnselectedRadius; diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java index 2491e2bdd623..750b6f95d52e 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java @@ -40,7 +40,7 @@ import com.android.internal.logging.UiEventLogger; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardCarousel.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardCarousel.java index b7c8b4900e87..02a764c97126 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardCarousel.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardCarousel.java @@ -38,7 +38,7 @@ import androidx.recyclerview.widget.PagerSnapHelper; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate; -import com.android.systemui.R; +import com.android.systemui.res.R; import java.util.Collections; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardView.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardView.java index fc1adc37d09b..7b50a6568da9 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardView.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardView.java @@ -25,7 +25,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.cardview.widget.CardView; -import com.android.systemui.R; +import com.android.systemui.res.R; /** Customized card view of the wallet card carousel. */ public class WalletCardView extends CardView { diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardViewHolder.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardViewHolder.java index 3197976456e3..c33a8053133e 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardViewHolder.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletCardViewHolder.java @@ -22,7 +22,7 @@ import android.widget.ImageView; import androidx.cardview.widget.CardView; import androidx.recyclerview.widget.RecyclerView; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * View holder for the quick access wallet card. diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java index 6fd0a4db5a14..d21ccc9502cf 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java @@ -43,7 +43,7 @@ import androidx.annotation.NonNull; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.UiEventLogger; import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.settings.UserTracker; diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java index cab47a3c4b4b..f498520f219b 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java @@ -40,7 +40,7 @@ import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.Utils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.classifier.FalsingCollector; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingActivity.java b/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingActivity.java index 1c7a9b5e8681..f8ffab094e0f 100644 --- a/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingActivity.java +++ b/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingActivity.java @@ -43,7 +43,7 @@ import android.widget.Toast; import com.android.internal.app.AlertActivity; import com.android.internal.app.AlertController; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Alerts the user of an untrusted network when enabling wireless debugging. diff --git a/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingSecondaryUserActivity.java b/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingSecondaryUserActivity.java index f9f14e0bc362..972d3c01f75f 100644 --- a/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingSecondaryUserActivity.java +++ b/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingSecondaryUserActivity.java @@ -30,7 +30,7 @@ import android.os.Bundle; import com.android.internal.app.AlertActivity; import com.android.internal.app.AlertController; -import com.android.systemui.R; +import com.android.systemui.res.R; /** * Alerts the user that wireless debugging cannot be enabled by a secondary user. diff --git a/packages/SystemUI/tests/Android.bp b/packages/SystemUI/tests/Android.bp index 3c418ed49adc..ec0414e94eba 100644 --- a/packages/SystemUI/tests/Android.bp +++ b/packages/SystemUI/tests/Android.bp @@ -20,6 +20,7 @@ package { android_test { name: "SystemUITests", + use_resource_processor: true, dxflags: ["--multi-dex"], platform_apis: true, diff --git a/packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiResourceLoadingTest.java b/packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiResourceLoadingTest.java index 188dff21efa4..205168ea0b7d 100644 --- a/packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiResourceLoadingTest.java +++ b/packages/SystemUI/tests/robolectric/src/com/android/systemui/robotests/SysuiResourceLoadingTest.java @@ -27,7 +27,7 @@ import org.junit.runner.RunWith; public class SysuiResourceLoadingTest extends SysuiRoboBase { @Test public void testResources() { - assertThat(getContext().getString(com.android.systemui.R.string.app_label)) + assertThat(getContext().getString(com.android.systemui.res.R.string.app_label)) .isEqualTo("System UI"); assertThat(getContext().getString(com.android.systemui.tests.R.string.test_content)) .isNotEmpty(); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java index 9016220b40cf..9ce9bd6865a4 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java @@ -55,7 +55,7 @@ import android.testing.AndroidTestingRunner; import android.text.TextUtils; import com.android.keyguard.logging.CarrierTextManagerLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.LogBufferHelperKt; import com.android.systemui.keyguard.WakefulnessLifecycle; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/FaceWakeUpTriggersConfigTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/FaceWakeUpTriggersConfigTest.kt index 6c5620d42abb..94c34a525547 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/FaceWakeUpTriggersConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/FaceWakeUpTriggersConfigTest.kt @@ -67,7 +67,7 @@ class FaceWakeUpTriggersConfigTest : SysuiTestCase() { private fun createFaceWakeUpTriggersConfig(wakeUpTriggers: IntArray): FaceWakeUpTriggersConfig { overrideResource( - com.android.systemui.R.array.config_face_auth_wake_up_triggers, + com.android.systemui.res.R.array.config_face_auth_wake_up_triggers, wakeUpTriggers ) diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java index c894d914bfa3..42f65f6f53b4 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java @@ -37,7 +37,7 @@ import com.android.internal.util.LatencyTracker; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardAbsKeyInputView.KeyDownListener; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.classifier.FalsingCollectorFake; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java index 00f88bfa2abb..8401e6734d61 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java @@ -27,7 +27,7 @@ import android.widget.TextView; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java index 3d8719656a1e..00a2efe7f838 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java @@ -35,7 +35,7 @@ import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.RelativeLayout; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FakeFeatureFlags; @@ -148,7 +148,7 @@ public class KeyguardClockSwitchControllerBaseTest extends SysuiTestCase { when(mView.getResources()).thenReturn(mResources); when(mResources.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin)) .thenReturn(100); - when(mResources.getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin)) + when(mResources.getDimensionPixelSize(com.android.systemui.customization.R.dimen.keyguard_large_clock_top_margin)) .thenReturn(-200); when(mResources.getInteger(R.integer.keyguard_date_weather_view_invisibility)) .thenReturn(INVISIBLE); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java index 65c677ea7e5a..e54b1845ce6b 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java @@ -40,7 +40,7 @@ import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.TextView; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.ClockController; import com.android.systemui.plugins.ClockFaceController; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt index ee67348c9b93..f943acd9180e 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt @@ -24,7 +24,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.util.LatencyTracker import com.android.internal.widget.LockPatternUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt index 0ef9f4533015..e09009389f8b 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt @@ -24,7 +24,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.util.LatencyTracker import com.android.internal.widget.LockPatternUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java index 2b90e7c66e8d..8322b37151de 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java @@ -31,7 +31,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.util.LatencyTracker; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingCollector; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt index a9f044ccd144..2f08804d8c05 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt @@ -25,7 +25,7 @@ import androidx.test.filters.SmallTest import com.android.internal.util.LatencyTracker import com.android.internal.widget.LockPatternUtils import com.android.keyguard.KeyguardSecurityModel.SecurityMode -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java index 62906f3656c7..f3a1b68a87ae 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java @@ -32,7 +32,7 @@ import androidx.test.filters.SmallTest; import com.android.keyguard.KeyguardDisplayManager.KeyguardPresentation; import com.android.keyguard.dagger.KeyguardStatusViewComponent; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import org.junit.After; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt index 929604bc81b6..f6649bdc9d3f 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt @@ -36,7 +36,7 @@ import com.android.internal.logging.UiEventLogger import com.android.internal.widget.LockPatternUtils import com.android.keyguard.KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback import com.android.keyguard.KeyguardSecurityModel.SecurityMode -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java index 3e330d65329e..aad11d90f5a4 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java @@ -56,7 +56,7 @@ import androidx.constraintlayout.widget.ConstraintSet; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingA11yDelegate; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java index 19bc8186eee5..b02b1f9df9fb 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java @@ -35,7 +35,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.flags.FeatureFlags; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt index 4db5f35ca07d..d0bb5a999327 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt @@ -24,7 +24,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.util.LatencyTracker import com.android.internal.widget.LockPatternUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt index 47ff3b90e2e2..59cd26cc6b9b 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt @@ -24,7 +24,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.util.LatencyTracker import com.android.internal.widget.LockPatternUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java index 77302ce30f09..6654a6ce816b 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java @@ -28,7 +28,7 @@ import androidx.slice.SliceSpecs; import androidx.slice.builders.ListBuilder; import androidx.slice.widget.RowContent; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.keyguard.KeyguardSliceProvider; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt index 210f3cb65ac0..86439e557f8b 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt @@ -6,7 +6,7 @@ import android.testing.TestableLooper.RunWithLooper import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.util.children import com.google.common.truth.Truth.assertThat diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt index bb03f288147e..3afca5933e5d 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt @@ -20,7 +20,7 @@ import android.testing.AndroidTestingRunner import android.view.View import android.view.ViewGroup import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.StatusBarState.KEYGUARD diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index 1d7c32803248..47be236b1272 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -341,7 +341,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { when(mUserTracker.getUserId()).thenReturn(mCurrentUserId); mContext.getOrCreateTestableResources().addOverride( - com.android.systemui.R.integer.config_face_auth_supported_posture, + com.android.systemui.res.R.integer.config_face_auth_supported_posture, DEVICE_POSTURE_UNKNOWN); mFaceWakeUpTriggersConfig = new FaceWakeUpTriggersConfig( mContext.getResources(), @@ -349,7 +349,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mDumpManager ); - mContext.getOrCreateTestableResources().addOverride(com.android.systemui + mContext.getOrCreateTestableResources().addOverride(com.android.systemui.res .R.array.config_fingerprint_listen_on_occluding_activity_packages, new String[]{ PKG_ALLOWING_FP_LISTEN_ON_OCCLUDING_ACTIVITY }); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUserSwitcherAnchorTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUserSwitcherAnchorTest.kt index 08185af1238e..c6740535d903 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUserSwitcherAnchorTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUserSwitcherAnchorTest.kt @@ -18,7 +18,7 @@ package com.android.keyguard import android.testing.AndroidTestingRunner import androidx.core.view.accessibility.AccessibilityNodeInfoCompat import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import org.junit.Before diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java index 0e4b3c9b6a23..21a28222ccf4 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java @@ -39,7 +39,7 @@ import android.view.View; import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.AuthController; import com.android.systemui.biometrics.AuthRippleController; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt index 42e12df431c5..835c9ff51381 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt @@ -20,7 +20,7 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.view.LayoutInflater import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth import org.junit.Before diff --git a/packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt index c04fd39168de..d431731b710e 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt @@ -20,7 +20,7 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.view.LayoutInflater import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth import org.junit.Before diff --git a/packages/SystemUI/tests/src/com/android/systemui/BatteryMeterDrawableTest.java b/packages/SystemUI/tests/src/com/android/systemui/BatteryMeterDrawableTest.java index d1573c3cac76..532c59aab18b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/BatteryMeterDrawableTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/BatteryMeterDrawableTest.java @@ -32,6 +32,7 @@ import android.test.suitebuilder.annotation.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.settingslib.R; import com.android.settingslib.graph.BatteryMeterDrawableBase; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java index f81ef10e6b14..af88df79be87 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java @@ -78,6 +78,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.test.filters.SmallTest; +import com.android.systemui.res.R; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.biometrics.AuthController; import com.android.systemui.decor.CornerDecorProvider; diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java index 79dc057e4f28..8fd2bd6ad762 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java @@ -71,7 +71,7 @@ import android.widget.ImageView; import androidx.test.filters.SmallTest; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import org.junit.After; diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java index 09d0eebd510d..22ebd995b472 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java @@ -46,7 +46,7 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.LargeTest; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.model.SysUiState; import com.android.systemui.util.settings.SecureSettings; diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java index 39fe6fbe78fb..187f0986353e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java @@ -88,7 +88,7 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.LargeTest; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.model.SysUiState; import com.android.systemui.settings.FakeDisplayTracker; diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java index 91c47480ae45..95e21cf6138a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java @@ -59,7 +59,7 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView; import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView.OnSeekBarWithIconButtonsChangeListener; diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java index afd5f77f7a4c..403385f21db0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java @@ -28,7 +28,7 @@ import android.view.View; import androidx.test.filters.SmallTest; import com.android.internal.accessibility.dialog.AccessibilityTarget; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.accessibility.floatingmenu.AccessibilityTargetAdapter.ViewHolder; diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AnnotationLinkSpanTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AnnotationLinkSpanTest.java index 46c930f9a5eb..43ebeee3f597 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AnnotationLinkSpanTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AnnotationLinkSpanTest.java @@ -26,7 +26,7 @@ import android.view.View; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipViewTest.java index 42b610a18bc0..9b819479ec70 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipViewTest.java @@ -26,7 +26,7 @@ import android.widget.TextView; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java index 1b0a10e68062..5764839d160d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java @@ -37,7 +37,7 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.util.settings.SecureSettings; diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt index 7b99314692b4..83bee932fc59 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt @@ -24,7 +24,7 @@ import android.view.ViewGroup import android.widget.Button import android.widget.SeekBar import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView.OnSeekBarWithIconButtonsChangeListener diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt index cc004363a049..59c7e7669b63 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt @@ -57,7 +57,8 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() { @Before fun setup() { - activityLaunchAnimator = ActivityLaunchAnimator(testLaunchAnimator, testLaunchAnimator) + activityLaunchAnimator = + ActivityLaunchAnimator(testLaunchAnimator, testLaunchAnimator, disableWmTimeout = true) activityLaunchAnimator.callback = callback activityLaunchAnimator.addListener(listener) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/assist/ui/DisplayUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/assist/ui/DisplayUtilsTest.java index dd9683f83c37..957443a23f93 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/assist/ui/DisplayUtilsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/assist/ui/DisplayUtilsTest.java @@ -25,7 +25,7 @@ import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewControllerTest.java index ec8be8ef3047..323f15a2cb46 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewControllerTest.java @@ -33,7 +33,7 @@ import android.provider.Settings; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.flags.FakeFeatureFlags; import com.android.systemui.settings.UserTracker; diff --git a/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt index f0f4ca7f3e66..4ab7ab450fae 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt @@ -19,7 +19,7 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import android.widget.ImageView import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.battery.BatteryMeterView.BatteryEstimateFetcher import com.android.systemui.statusbar.policy.BatteryController.EstimateFetchCompletion diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconControllerTest.kt index 52bf350bfcc8..215d63508306 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconControllerTest.kt @@ -25,7 +25,7 @@ import android.view.ViewGroup.LayoutParams import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.airbnb.lottie.LottieAnimationView -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.ui.binder.Spaghetti.BiometricState import com.google.common.truth.Truth.assertThat diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt index 969a01164734..f899e2fb968a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt @@ -37,7 +37,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.jank.InteractionJankMonitor import com.android.internal.widget.LockPatternUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository import com.android.systemui.biometrics.data.repository.FakePromptRepository diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java index d0b3833a24a1..2bc0171939b4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java @@ -906,14 +906,14 @@ public class AuthControllerTest extends SysuiTestCase { when(mContextSpy.getResources()).thenReturn(mResources); doReturn(500).when(mResources) - .getDimensionPixelSize(eq(com.android.systemui.R.dimen + .getDimensionPixelSize(eq(com.android.systemui.res.R.dimen .physical_fingerprint_sensor_center_screen_location_y)); mAuthController.onConfigurationChanged(null /* newConfig */); final Point firstFpLocation = mAuthController.getFingerprintSensorLocation(); doReturn(1000).when(mResources) - .getDimensionPixelSize(eq(com.android.systemui.R.dimen + .getDimensionPixelSize(eq(com.android.systemui.res.R.dimen .physical_fingerprint_sensor_center_screen_location_y)); mAuthController.onConfigurationChanged(null /* newConfig */); diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java index b0d006353a98..3c106789290d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java @@ -30,9 +30,12 @@ import static org.mockito.Mockito.when; import android.app.Notification; import android.app.NotificationManager; import android.hardware.biometrics.BiometricFaceConstants; -import android.hardware.biometrics.BiometricFingerprintConstants; import android.hardware.biometrics.BiometricSourceType; +import android.hardware.biometrics.BiometricStateListener; +import android.hardware.face.FaceManager; +import android.hardware.fingerprint.FingerprintManager; import android.os.Handler; +import android.os.UserHandle; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -52,6 +55,8 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +import java.util.Optional; + @SmallTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper(setAsMainLooper = true) @@ -65,11 +70,20 @@ public class BiometricNotificationServiceTest extends SysuiTestCase { KeyguardStateController mKeyguardStateController; @Mock NotificationManager mNotificationManager; + @Mock + Optional<FingerprintReEnrollNotification> mFingerprintReEnrollNotificationOptional; + @Mock + FingerprintReEnrollNotification mFingerprintReEnrollNotification; + @Mock + FingerprintManager mFingerprintManager; + @Mock + FaceManager mFaceManager; private static final String TAG = "BiometricNotificationService"; private static final int FACE_NOTIFICATION_ID = 1; private static final int FINGERPRINT_NOTIFICATION_ID = 2; private static final long SHOW_NOTIFICATION_DELAY_MS = 5_000L; // 5 seconds + private static final int FINGERPRINT_ACQUIRED_RE_ENROLL = 0; private final ArgumentCaptor<Notification> mNotificationArgumentCaptor = ArgumentCaptor.forClass(Notification.class); @@ -77,39 +91,61 @@ public class BiometricNotificationServiceTest extends SysuiTestCase { private KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback; private KeyguardStateController.Callback mKeyguardStateControllerCallback; private BiometricNotificationService mBiometricNotificationService; + private BiometricStateListener mFaceStateListener; + private BiometricStateListener mFingerprintStateListener; @Before public void setUp() { + when(mFingerprintReEnrollNotificationOptional.orElse(any())) + .thenReturn(mFingerprintReEnrollNotification); + when(mFingerprintReEnrollNotification.isFingerprintReEnrollRequired( + FINGERPRINT_ACQUIRED_RE_ENROLL)).thenReturn(true); + mLooper = TestableLooper.get(this); Handler handler = new Handler(mLooper.getLooper()); BiometricNotificationDialogFactory dialogFactory = new BiometricNotificationDialogFactory(); BiometricNotificationBroadcastReceiver broadcastReceiver = new BiometricNotificationBroadcastReceiver(mContext, dialogFactory); - mBiometricNotificationService = new BiometricNotificationService(mContext, - mKeyguardUpdateMonitor, mKeyguardStateController, handler, - mNotificationManager, broadcastReceiver); + mBiometricNotificationService = + new BiometricNotificationService(mContext, + mKeyguardUpdateMonitor, mKeyguardStateController, handler, + mNotificationManager, + broadcastReceiver, + mFingerprintReEnrollNotificationOptional, + mFingerprintManager, + mFaceManager); mBiometricNotificationService.start(); ArgumentCaptor<KeyguardUpdateMonitorCallback> updateMonitorCallbackArgumentCaptor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class); ArgumentCaptor<KeyguardStateController.Callback> stateControllerCallbackArgumentCaptor = ArgumentCaptor.forClass(KeyguardStateController.Callback.class); + ArgumentCaptor<BiometricStateListener> faceStateListenerArgumentCaptor = + ArgumentCaptor.forClass(BiometricStateListener.class); + ArgumentCaptor<BiometricStateListener> fingerprintStateListenerArgumentCaptor = + ArgumentCaptor.forClass(BiometricStateListener.class); verify(mKeyguardUpdateMonitor).registerCallback( updateMonitorCallbackArgumentCaptor.capture()); verify(mKeyguardStateController).addCallback( stateControllerCallbackArgumentCaptor.capture()); + verify(mFaceManager).registerBiometricStateListener( + faceStateListenerArgumentCaptor.capture()); + verify(mFingerprintManager).registerBiometricStateListener( + fingerprintStateListenerArgumentCaptor.capture()); + mFaceStateListener = faceStateListenerArgumentCaptor.getValue(); + mFingerprintStateListener = fingerprintStateListenerArgumentCaptor.getValue(); mKeyguardUpdateMonitorCallback = updateMonitorCallbackArgumentCaptor.getValue(); mKeyguardStateControllerCallback = stateControllerCallbackArgumentCaptor.getValue(); } @Test - public void testShowFingerprintReEnrollNotification() { + public void testShowFingerprintReEnrollNotification_onAcquiredReEnroll() { when(mKeyguardStateController.isShowing()).thenReturn(false); - mKeyguardUpdateMonitorCallback.onBiometricError( - BiometricFingerprintConstants.BIOMETRIC_ERROR_RE_ENROLL, + mKeyguardUpdateMonitorCallback.onBiometricHelp( + FINGERPRINT_ACQUIRED_RE_ENROLL, "Testing Fingerprint Re-enrollment" /* errString */, BiometricSourceType.FINGERPRINT ); @@ -127,7 +163,7 @@ public class BiometricNotificationServiceTest extends SysuiTestCase { .isEqualTo(ACTION_SHOW_FINGERPRINT_REENROLL_DIALOG); } @Test - public void testShowFaceReEnrollNotification() { + public void testShowFaceReEnrollNotification_onErrorReEnroll() { when(mKeyguardStateController.isShowing()).thenReturn(false); mKeyguardUpdateMonitorCallback.onBiometricError( @@ -150,6 +186,54 @@ public class BiometricNotificationServiceTest extends SysuiTestCase { } @Test + public void testCancelReEnrollmentNotification_onFaceEnrollmentStateChange() { + when(mKeyguardStateController.isShowing()).thenReturn(false); + + mKeyguardUpdateMonitorCallback.onBiometricError( + BiometricFaceConstants.BIOMETRIC_ERROR_RE_ENROLL, + "Testing Face Re-enrollment" /* errString */, + BiometricSourceType.FACE + ); + mKeyguardStateControllerCallback.onKeyguardShowingChanged(); + + mLooper.moveTimeForward(SHOW_NOTIFICATION_DELAY_MS); + mLooper.processAllMessages(); + + verify(mNotificationManager).notifyAsUser(eq(TAG), eq(FACE_NOTIFICATION_ID), + mNotificationArgumentCaptor.capture(), any()); + + mFaceStateListener.onEnrollmentsChanged(0 /* userId */, 0 /* sensorId */, + false /* hasEnrollments */); + + verify(mNotificationManager).cancelAsUser(eq(TAG), eq(FACE_NOTIFICATION_ID), + eq(UserHandle.CURRENT)); + } + + @Test + public void testCancelReEnrollmentNotification_onFingerprintEnrollmentStateChange() { + when(mKeyguardStateController.isShowing()).thenReturn(false); + + mKeyguardUpdateMonitorCallback.onBiometricHelp( + FINGERPRINT_ACQUIRED_RE_ENROLL, + "Testing Fingerprint Re-enrollment" /* errString */, + BiometricSourceType.FINGERPRINT + ); + mKeyguardStateControllerCallback.onKeyguardShowingChanged(); + + mLooper.moveTimeForward(SHOW_NOTIFICATION_DELAY_MS); + mLooper.processAllMessages(); + + verify(mNotificationManager).notifyAsUser(eq(TAG), eq(FINGERPRINT_NOTIFICATION_ID), + mNotificationArgumentCaptor.capture(), any()); + + mFingerprintStateListener.onEnrollmentsChanged(0 /* userId */, 0 /* sensorId */, + false /* hasEnrollments */); + + verify(mNotificationManager).cancelAsUser(eq(TAG), eq(FINGERPRINT_NOTIFICATION_ID), + eq(UserHandle.CURRENT)); + } + + @Test public void testResetFaceUnlockReEnroll_onStart() { when(mKeyguardStateController.isShowing()).thenReturn(false); diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt index 17928a3da140..57cf834bfa38 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt @@ -52,7 +52,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.airbnb.lottie.LottieAnimationView import com.android.keyguard.KeyguardUpdateMonitor -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestableContext 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 c73541972a3c..21e614f3db3a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt @@ -37,7 +37,7 @@ import android.view.accessibility.AccessibilityManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardUpdateMonitor -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.animation.ActivityLaunchAnimator 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 b6bc7afe2c7a..ee3bd0d79ad8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -74,7 +74,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.InstanceIdSequence; import com.android.internal.util.LatencyTracker; import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.ActivityLaunchAnimator; @@ -1575,6 +1575,53 @@ public class UdfpsControllerTest extends SysuiTestCase { anyBoolean()); } + + @Test + public void onTouch_withNewTouchDetection_qsDrag_processesTouchWhenAlternateBouncerVisible() + throws RemoteException { + final NormalizedTouchData touchData = new NormalizedTouchData(0, 0f, 0f, 0f, 0f, 0f, 0L, + 0L); + final TouchProcessorResult processorResultMove = + new TouchProcessorResult.ProcessedTouch(InteractionEvent.DOWN, + 1 /* pointerId */, touchData); + + // Enable new touch detection. + when(mFeatureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)).thenReturn(true); + + // Configure UdfpsController to use FingerprintManager as opposed to AlternateTouchProvider. + initUdfpsController(mOpticalProps, false /* hasAlternateTouchProvider */); + + // Configure UdfpsView to accept the ACTION_MOVE event + when(mUdfpsView.isDisplayConfigured()).thenReturn(false); + when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true); + + // GIVEN that the alternate bouncer is showing and a11y touch exploration NOT enabled + when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false); + when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true); + mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId, + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); + mFgExecutor.runAllReady(); + + verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); + + // GIVEN swipe down for QS + when(mPrimaryBouncerInteractor.isInTransit()).thenReturn(false); + when(mLockscreenShadeTransitionController.getQSDragProgress()).thenReturn(1f); + + // WHEN ACTION_MOVE is received and touch is within sensor + when(mSinglePointerTouchProcessor.processTouch(any(), anyInt(), any())).thenReturn( + processorResultMove); + MotionEvent moveEvent = MotionEvent.obtain(0, 0, ACTION_MOVE, 0, 0, 0); + mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); + mBiometricExecutor.runAllReady(); + moveEvent.recycle(); + + // THEN the touch is still processed + verify(mFingerprintManager).onPointerDown(anyLong(), anyInt(), anyInt(), + anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyLong(), anyLong(), + anyBoolean()); + } + @Test public void onAodInterrupt_onAcquiredGood_fingerNoLongerDown() throws RemoteException { // GIVEN UDFPS overlay is showing diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt index 1885f6499299..17f435b75d5a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt @@ -30,8 +30,6 @@ import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants import com.android.systemui.bouncer.ui.BouncerView import com.android.systemui.classifier.FalsingCollector -import com.android.systemui.flags.FakeFeatureFlags -import com.android.systemui.flags.Flags import com.android.systemui.keyguard.DismissCallbackRegistry import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository import com.android.systemui.keyguard.data.repository.FakeTrustRepository @@ -99,7 +97,6 @@ class UdfpsKeyguardViewLegacyControllerWithCoroutinesTest : context, mKeyguardUpdateMonitor, FakeTrustRepository(), - FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) }, testScope.backgroundScope, ) mAlternateBouncerInteractor = diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt index 6d4588da7751..ebadfc78a079 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt @@ -25,7 +25,7 @@ import android.view.LayoutInflater import android.view.Surface import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams @@ -67,7 +67,7 @@ class UdfpsViewTest : SysuiTestCase() { @Before fun setup() { - context.setTheme(R.style.Theme_AppCompat) + context.setTheme(androidx.appcompat.R.style.Theme_AppCompat) view = LayoutInflater.from(context).inflate(R.layout.udfps_view, null) as UdfpsView view.animationViewController = animationViewController val sensorBounds = SensorLocationInternal("", SENSOR_X, SENSOR_Y, SENSOR_RADIUS).rect diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java index 6fa19162b150..eee0ed45345d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java @@ -36,7 +36,7 @@ import com.android.internal.logging.UiEventLogger; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.SysuiTestCase; import com.android.systemui.media.dialog.MediaOutputDialogFactory; diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repo/BouncerMessageRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repo/BouncerMessageRepositoryTest.kt index 562a8ef512d4..f158b433d5dc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repo/BouncerMessageRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repo/BouncerMessageRepositoryTest.kt @@ -35,15 +35,15 @@ import com.android.keyguard.KeyguardSecurityModel import com.android.keyguard.KeyguardSecurityModel.SecurityMode.PIN import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback -import com.android.systemui.R -import com.android.systemui.R.string.keyguard_enter_pin -import com.android.systemui.R.string.kg_prompt_after_dpm_lock -import com.android.systemui.R.string.kg_prompt_after_user_lockdown_pin -import com.android.systemui.R.string.kg_prompt_auth_timeout -import com.android.systemui.R.string.kg_prompt_pin_auth_timeout -import com.android.systemui.R.string.kg_prompt_reason_restart_pin -import com.android.systemui.R.string.kg_prompt_unattended_update -import com.android.systemui.R.string.kg_trust_agent_disabled +import com.android.systemui.res.R +import com.android.systemui.res.R.string.keyguard_enter_pin +import com.android.systemui.res.R.string.kg_prompt_after_dpm_lock +import com.android.systemui.res.R.string.kg_prompt_after_user_lockdown_pin +import com.android.systemui.res.R.string.kg_prompt_auth_timeout +import com.android.systemui.res.R.string.kg_prompt_pin_auth_timeout +import com.android.systemui.res.R.string.kg_prompt_reason_restart_pin +import com.android.systemui.res.R.string.kg_prompt_unattended_update +import com.android.systemui.res.R.string.kg_trust_agent_disabled import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.data.factory.BouncerMessageFactory import com.android.systemui.bouncer.data.repository.BouncerMessageRepository diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt index 86e0c751085b..77d8102fff2e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt @@ -17,7 +17,7 @@ package com.android.systemui.bouncer.domain.interactor import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.data.model.AuthenticationMethodModel import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository @@ -353,6 +353,34 @@ class BouncerInteractorTest : SysuiTestCase() { assertThat(throttling).isEqualTo(AuthenticationThrottlingModel()) } + @Test + fun hide_whenOnBouncerScene_hidesBouncerAndGoesToLockscreenScene() = + testScope.runTest { + sceneInteractor.changeScene(SceneModel(SceneKey.Bouncer), "") + sceneInteractor.onSceneChanged(SceneModel(SceneKey.Bouncer), "") + val currentScene by collectLastValue(sceneInteractor.desiredScene) + val bouncerSceneKey = currentScene?.key + assertThat(bouncerSceneKey).isEqualTo(SceneKey.Bouncer) + + underTest.hide("") + + assertThat(currentScene?.key).isEqualTo(SceneKey.Lockscreen) + } + + @Test + fun hide_whenNotOnBouncerScene_doesNothing() = + testScope.runTest { + sceneInteractor.changeScene(SceneModel(SceneKey.Shade), "") + sceneInteractor.onSceneChanged(SceneModel(SceneKey.Shade), "") + val currentScene by collectLastValue(sceneInteractor.desiredScene) + val notBouncerSceneKey = currentScene?.key + assertThat(notBouncerSceneKey).isNotEqualTo(SceneKey.Bouncer) + + underTest.hide("") + + assertThat(currentScene?.key).isEqualTo(notBouncerSceneKey) + } + private fun assertTryAgainMessage( message: String?, time: Int, diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractorTest.kt index 4089abef399b..c1286a166421 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractorTest.kt @@ -22,8 +22,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardSecurityModel import com.android.keyguard.KeyguardSecurityModel.SecurityMode.PIN -import com.android.systemui.R.string.kg_too_many_failed_attempts_countdown -import com.android.systemui.R.string.kg_unlock_with_pin_or_fp +import com.android.systemui.res.R.string.kg_too_many_failed_attempts_countdown +import com.android.systemui.res.R.string.kg_unlock_with_pin_or_fp import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.data.factory.BouncerMessageFactory import com.android.systemui.bouncer.data.repository.FakeBouncerMessageRepository diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorTest.kt index 420fdba7fde2..9a5b4585e0ae 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorTest.kt @@ -25,7 +25,7 @@ import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardSecurityModel import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.DejankUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.EXPANSION_HIDDEN @@ -34,8 +34,6 @@ import com.android.systemui.bouncer.shared.model.BouncerShowMessageModel import com.android.systemui.bouncer.ui.BouncerView import com.android.systemui.bouncer.ui.BouncerViewDelegate import com.android.systemui.classifier.FalsingCollector -import com.android.systemui.flags.FakeFeatureFlags -import com.android.systemui.flags.Flags import com.android.systemui.keyguard.DismissCallbackRegistry import com.android.systemui.keyguard.data.repository.FakeTrustRepository import com.android.systemui.plugins.ActivityStarter @@ -76,7 +74,6 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { private lateinit var underTest: PrimaryBouncerInteractor private lateinit var resources: TestableResources private lateinit var trustRepository: FakeTrustRepository - private lateinit var featureFlags: FakeFeatureFlags private lateinit var testScope: TestScope @Before @@ -89,7 +86,6 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { testScope = TestScope() mainHandler = FakeHandler(android.os.Looper.getMainLooper()) trustRepository = FakeTrustRepository() - featureFlags = FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) } underTest = PrimaryBouncerInteractor( repository, @@ -103,7 +99,6 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { context, keyguardUpdateMonitor, trustRepository, - featureFlags, testScope.backgroundScope, ) whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null) diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt index 665456d5cd80..cb0b74f3015d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt @@ -27,8 +27,6 @@ import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepositor import com.android.systemui.bouncer.ui.BouncerView import com.android.systemui.classifier.FalsingCollector import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.flags.FakeFeatureFlags -import com.android.systemui.flags.Flags import com.android.systemui.keyguard.DismissCallbackRegistry import com.android.systemui.keyguard.data.repository.TrustRepository import com.android.systemui.statusbar.phone.KeyguardBypassController @@ -77,7 +75,6 @@ class PrimaryBouncerInteractorWithCoroutinesTest : SysuiTestCase() { context, keyguardUpdateMonitor, Mockito.mock(TrustRepository::class.java), - FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) }, TestScope().backgroundScope, ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt index 7af8a0425402..9011c2f296c3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt @@ -22,6 +22,8 @@ import com.android.systemui.authentication.data.model.AuthenticationMethodModel import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository import com.android.systemui.coroutines.collectLastValue import com.android.systemui.scene.SceneTestUtils +import com.android.systemui.scene.shared.model.SceneKey +import com.android.systemui.scene.shared.model.SceneModel import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.runTest @@ -39,6 +41,7 @@ class AuthMethodBouncerViewModelTest : SysuiTestCase() { utils.authenticationInteractor( utils.authenticationRepository(), ) + private val sceneInteractor = utils.sceneInteractor() private val underTest = PinBouncerViewModel( applicationContext = context, @@ -46,7 +49,7 @@ class AuthMethodBouncerViewModelTest : SysuiTestCase() { interactor = utils.bouncerInteractor( authenticationInteractor = authenticationInteractor, - sceneInteractor = utils.sceneInteractor(), + sceneInteractor = sceneInteractor, ), isInputEnabled = MutableStateFlow(true), ) @@ -75,4 +78,22 @@ class AuthMethodBouncerViewModelTest : SysuiTestCase() { underTest.onAuthenticateButtonClicked() assertThat(animateFailure).isFalse() } + + @Test + fun onImeVisibilityChanged() = + testScope.runTest { + val desiredScene by collectLastValue(sceneInteractor.desiredScene) + sceneInteractor.changeScene(SceneModel(SceneKey.Bouncer), "") + sceneInteractor.onSceneChanged(SceneModel(SceneKey.Bouncer), "") + assertThat(desiredScene?.key).isEqualTo(SceneKey.Bouncer) + + underTest.onImeVisibilityChanged(false) + assertThat(desiredScene?.key).isEqualTo(SceneKey.Bouncer) + + underTest.onImeVisibilityChanged(true) + assertThat(desiredScene?.key).isEqualTo(SceneKey.Bouncer) + + underTest.onImeVisibilityChanged(false) + assertThat(desiredScene?.key).isEqualTo(SceneKey.Lockscreen) + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt index d4bba723a989..333bd214fe9a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt @@ -31,8 +31,6 @@ import com.android.systemui.bouncer.ui.BouncerView import com.android.systemui.classifier.FalsingCollector import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues -import com.android.systemui.flags.FakeFeatureFlags -import com.android.systemui.flags.Flags import com.android.systemui.keyguard.DismissCallbackRegistry import com.android.systemui.keyguard.data.repository.TrustRepository import com.android.systemui.statusbar.phone.KeyguardBypassController @@ -85,7 +83,6 @@ class KeyguardBouncerViewModelTest : SysuiTestCase() { context, keyguardUpdateMonitor, Mockito.mock(TrustRepository::class.java), - FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) }, TestScope().backgroundScope, ) underTest = KeyguardBouncerViewModel(bouncerView, bouncerInteractor) diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt index 12090e5264df..3375184c1cf6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt @@ -17,7 +17,7 @@ package com.android.systemui.bouncer.ui.viewmodel import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.data.model.AuthenticationMethodModel import com.android.systemui.coroutines.collectLastValue @@ -157,6 +157,29 @@ class PasswordBouncerViewModelTest : SysuiTestCase() { } @Test + fun onAuthenticateKeyPressed_whenEmpty() = + testScope.runTest { + val currentScene by collectLastValue(sceneInteractor.desiredScene) + val message by collectLastValue(bouncerViewModel.message) + val password by collectLastValue(underTest.password) + utils.authenticationRepository.setAuthenticationMethod( + AuthenticationMethodModel.Password + ) + utils.authenticationRepository.setUnlocked(false) + sceneInteractor.changeScene(SceneModel(SceneKey.Bouncer), "reason") + sceneInteractor.onSceneChanged(SceneModel(SceneKey.Bouncer), "reason") + assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) + underTest.onShown() + // Enter nothing. + + underTest.onAuthenticateKeyPressed() + + assertThat(password).isEqualTo("") + assertThat(message?.text).isEqualTo(ENTER_YOUR_PASSWORD) + assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) + } + + @Test fun onAuthenticateKeyPressed_correctAfterWrong() = testScope.runTest { val currentScene by collectLastValue(sceneInteractor.desiredScene) diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt index 8ce738ca89f6..102cfe21838e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt @@ -17,7 +17,7 @@ package com.android.systemui.bouncer.ui.viewmodel import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.data.model.AuthenticationMethodModel import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt index a684221e1a78..35238ce00057 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt @@ -17,7 +17,7 @@ package com.android.systemui.bouncer.ui.viewmodel import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.data.model.AuthenticationMethodModel import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository diff --git a/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt index 5a5c058793b2..11756d5b8ea2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt @@ -24,7 +24,7 @@ import android.view.WindowManager import android.view.WindowMetrics import androidx.test.filters.SmallTest import com.android.internal.logging.UiEventLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtilsTest.java index 673b5eb5dc3c..db85522f6cd8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtilsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayUtilsTest.java @@ -39,7 +39,7 @@ import android.view.textclassifier.TextLinks; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.google.android.collect.Lists; diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/IntentCreatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/IntentCreatorTest.java index 662c89c268e6..fb07e6e4fa10 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/IntentCreatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/IntentCreatorTest.java @@ -28,7 +28,7 @@ import android.text.SpannableString; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import org.junit.Test; diff --git a/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsViewTest.java index f0006e5e0ba7..98f7f590216f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsViewTest.java @@ -33,7 +33,7 @@ import android.widget.SeekBar; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView.OnSeekBarWithIconButtonsChangeListener; diff --git a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationLayoutEngineTest.java b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationLayoutEngineTest.java index 69d8d0b6f091..a78f0b7295b8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationLayoutEngineTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationLayoutEngineTest.java @@ -28,7 +28,7 @@ import android.view.View; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.complication.ComplicationLayoutEngine.Margins; import com.android.systemui.touch.TouchInsetManager; diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImplTest.kt index bd4e8da6b326..581e88b52c0f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImplTest.kt @@ -18,7 +18,7 @@ package com.android.systemui.controls.controller import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import org.junit.Assert.assertEquals diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsEditingActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsEditingActivityTest.kt index bd3d09dfbb20..2a4524b971a4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsEditingActivityTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsEditingActivityTest.kt @@ -11,7 +11,7 @@ import android.window.OnBackInvokedCallback import android.window.OnBackInvokedDispatcher import androidx.test.filters.SmallTest import androidx.test.rule.ActivityTestRule -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.activity.SingleActivityFactory import com.android.systemui.controls.CustomIconCache diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt index 70d93a10b445..88d36af71958 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt @@ -13,7 +13,7 @@ import android.window.OnBackInvokedDispatcher import androidx.test.filters.FlakyTest import androidx.test.filters.SmallTest import androidx.test.rule.ActivityTestRule -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.activity.SingleActivityFactory import com.android.systemui.controls.ControlStatus diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt index 74d0d210b9b0..6361e94bd0ef 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt @@ -31,7 +31,7 @@ import android.service.controls.ControlsProviderService import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest import com.android.settingslib.applications.ServiceListing -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.dump.DumpManager diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/PanelConfirmationDialogFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/PanelConfirmationDialogFactoryTest.kt index 756f267671e1..4e8f86615522 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/PanelConfirmationDialogFactoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/PanelConfirmationDialogFactoryTest.kt @@ -20,7 +20,7 @@ package com.android.systemui.controls.management import android.content.DialogInterface import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.phone.SystemUIDialog import com.android.systemui.util.mockito.argumentCaptor diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImplTest.kt index 7ac1953ee495..4828ba37ecb5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImplTest.kt @@ -20,7 +20,7 @@ package com.android.systemui.controls.panels import android.content.SharedPreferences import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.settings.UserFileManager import com.android.systemui.settings.UserTracker diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt index 2ae342a5cfa5..101b8ed4f6f0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt @@ -30,7 +30,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.controls.ControlsMetricsLogger import com.android.systemui.controls.controller.ControlInfo diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsDialogsFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsDialogsFactoryTest.kt index 1e8cd4117688..8eebceebe874 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsDialogsFactoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsDialogsFactoryTest.kt @@ -19,7 +19,7 @@ package com.android.systemui.controls.ui import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.util.FakeSystemUIDialogController import com.google.common.truth.Truth.assertThat diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsPopupMenuTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsPopupMenuTest.kt index df6fa11ff72c..48e3962717c1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsPopupMenuTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsPopupMenuTest.kt @@ -26,7 +26,7 @@ import android.view.ViewGroup import android.widget.PopupWindow.OnDismissListener import androidx.test.ext.junit.rules.ActivityScenarioRule import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.activity.EmptyTestActivity import com.android.systemui.util.mockito.whenever diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt index a400ff963026..5a4ad011bf49 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt @@ -33,7 +33,7 @@ import android.view.View import android.view.ViewGroup import android.widget.FrameLayout import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.controls.ControlsMetricsLogger import com.android.systemui.controls.ControlsServiceInfo diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/TemperatureControlBehaviorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/TemperatureControlBehaviorTest.kt index 588e34d3111d..ac1f90cc6dda 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/TemperatureControlBehaviorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/TemperatureControlBehaviorTest.kt @@ -11,7 +11,7 @@ import android.service.controls.templates.ThumbnailTemplate import android.view.LayoutInflater import android.view.ViewGroup import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.controls.ControlsMetricsLogger import com.android.systemui.controls.controller.ControlInfo diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt index 8bf17d7c62f9..a1cffc1419d5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt @@ -23,7 +23,7 @@ import android.view.DisplayCutout import android.view.Surface import android.view.View import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import org.junit.Assert import org.junit.Before diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt index 171b76748d26..e4ddc37c4f3c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt @@ -20,7 +20,7 @@ import android.content.res.Resources import android.testing.AndroidTestingRunner import android.view.DisplayCutout import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import org.junit.Assert import org.junit.Before diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt index 8f0b19307000..d1d48803c486 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt @@ -20,7 +20,7 @@ import android.testing.AndroidTestingRunner import android.util.Size import android.view.DisplayCutout import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import org.junit.Assert import org.junit.Before diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt index 4feba7bfd359..2bff7d22785a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt @@ -23,7 +23,7 @@ import android.util.Size import androidx.annotation.DrawableRes import androidx.test.filters.SmallTest import com.android.internal.R as InternalR -import com.android.systemui.R as SystemUIR +import com.android.systemui.res.R as SystemUIR import com.android.systemui.SysuiTestCase import com.android.systemui.tests.R import org.junit.Assert.assertEquals diff --git a/packages/SystemUI/tests/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogTest.kt index 46f758216aae..dcc15ae0e2c3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogTest.kt @@ -20,7 +20,7 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.view.View import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/AlwaysOnDisplayPolicyTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/AlwaysOnDisplayPolicyTest.java index ec9acdf26c8a..ea7467f9dc4d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/AlwaysOnDisplayPolicyTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/AlwaysOnDisplayPolicyTest.java @@ -24,7 +24,7 @@ import android.text.format.DateUtils; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import org.junit.After; diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java index af2dab599a66..9566e81ed08d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java @@ -46,7 +46,7 @@ import android.view.View; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.log.LogBuffer; diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsColumnLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsColumnLayoutTest.java index 16d665cbafcd..f89a0b698c69 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsColumnLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsColumnLayoutTest.java @@ -30,7 +30,7 @@ import android.view.View; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.util.leak.RotationUtils; diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsGridLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsGridLayoutTest.java index ea478597ef77..5a97b7489f39 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsGridLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsGridLayoutTest.java @@ -28,7 +28,7 @@ import android.view.ViewGroup; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.util.leak.RotationUtils; diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/ListGridLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/ListGridLayoutTest.java index 74e8cc280979..a003e077e7aa 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/ListGridLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/ListGridLayoutTest.java @@ -25,7 +25,7 @@ import android.view.ViewGroup; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderTest.kt index 8f6634478617..76c3349c25ba 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderTest.kt @@ -12,7 +12,7 @@ import android.net.Uri import android.util.Size import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import java.io.ByteArrayInputStream diff --git a/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/FakeSliderEventProducer.kt b/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/FakeSliderEventProducer.kt new file mode 100644 index 000000000000..9deabc76065c --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/FakeSliderEventProducer.kt @@ -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. + */ + +package com.android.systemui.haptics.slider + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow + +/** Fake implementation of a slider event producer */ +class FakeSliderEventProducer : SliderEventProducer { + + private val _currentEvent = MutableStateFlow(SliderEvent(SliderEventType.NOTHING, 0f)) + + fun sendEvent(event: SliderEvent) { + _currentEvent.value = event + } + override fun produceEvents(): Flow<SliderEvent> = _currentEvent.asStateFlow() +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/SeekableSliderTrackerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/SeekableSliderTrackerTest.kt new file mode 100644 index 000000000000..add601c4b1b3 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/SeekableSliderTrackerTest.kt @@ -0,0 +1,547 @@ +/* + * 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.haptics.slider + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestCoroutineScheduler +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.advanceTimeBy +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.anyFloat +import org.mockito.Mockito.verify +import org.mockito.Mockito.verifyNoMoreInteractions +import org.mockito.Mockito.verifyZeroInteractions +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidJUnit4::class) +class SeekableSliderTrackerTest : SysuiTestCase() { + + @Mock private lateinit var sliderStateListener: SliderStateListener + private val sliderEventProducer = FakeSliderEventProducer() + private lateinit var mSeekableSliderTracker: SeekableSliderTracker + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + } + + @Test + fun initializeSliderTracker_startsTracking() = runTest { + // GIVEN Initialized tracker + initTracker(testScheduler) + + // THEN the tracker job is active + assertThat(mSeekableSliderTracker.isTracking).isTrue() + } + + @Test + fun stopTracking_onAnyState_resetsToIdle() = runTest { + enumValues<SliderState>().forEach { + // GIVEN Initialized tracker + initTracker(testScheduler) + + // GIVEN a state in the state machine + mSeekableSliderTracker.setState(it) + + // WHEN the tracker stops tracking the state and listening to events + mSeekableSliderTracker.stopTracking() + + // THEN The state is idle and the tracker is not active + assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.IDLE) + assertThat(mSeekableSliderTracker.isTracking).isFalse() + } + } + + // Tests on the IDLE state + @Test + fun initializeSliderTracker_isIdle() = runTest { + // GIVEN Initialized tracker + initTracker(testScheduler) + + // THEN The state is idle and the listener is not called to play haptics + assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.IDLE) + verifyZeroInteractions(sliderStateListener) + } + + @Test + fun startsTrackingTouch_onIdle_entersWaitState() = runTest { + initTracker(testScheduler) + + // GIVEN a start of tracking touch event + val progress = 0f + sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STARTED_TRACKING_TOUCH, progress)) + + // THEN the tracker moves to the wait state and the timer job begins + assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.WAIT) + verifyZeroInteractions(sliderStateListener) + assertThat(mSeekableSliderTracker.isWaiting).isTrue() + } + + // Tests on the WAIT state + + @OptIn(ExperimentalCoroutinesApi::class) + @Test + fun waitCompletes_onWait_movesToHandleAcquired() = runTest { + val config = SeekableSliderTrackerConfig() + initTracker(testScheduler, config) + + // GIVEN a start of tracking touch event that moves the tracker to WAIT + val progress = 0f + sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STARTED_TRACKING_TOUCH, progress)) + + // WHEN the wait time completes plus a small buffer time + advanceTimeBy(config.waitTimeMillis + 10L) + + // THEN the tracker moves to the DRAG_HANDLE_ACQUIRED_BY_TOUCH state + assertThat(mSeekableSliderTracker.currentState) + .isEqualTo(SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH) + assertThat(mSeekableSliderTracker.isWaiting).isFalse() + verify(sliderStateListener).onHandleAcquiredByTouch() + verifyNoMoreInteractions(sliderStateListener) + } + + @Test + fun impreciseTouch_onWait_movesToHandleAcquired() = runTest { + val config = SeekableSliderTrackerConfig() + initTracker(testScheduler, config) + + // GIVEN a start of tracking touch event that moves the tracker to WAIT at the middle of the + // slider + var progress = 0.5f + sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STARTED_TRACKING_TOUCH, progress)) + + // GIVEN a progress event due to an imprecise touch with a progress below threshold + progress += (config.jumpThreshold - 0.01f) + sliderEventProducer.sendEvent( + SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress) + ) + + // THEN the tracker moves to the DRAG_HANDLE_ACQUIRED_BY_TOUCH state without the timer job + // being complete + assertThat(mSeekableSliderTracker.currentState) + .isEqualTo(SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH) + assertThat(mSeekableSliderTracker.isWaiting).isFalse() + verify(sliderStateListener).onHandleAcquiredByTouch() + verifyNoMoreInteractions(sliderStateListener) + } + + @Test + fun trackJump_onWait_movesToJumpTrackLocationSelected() = runTest { + val config = SeekableSliderTrackerConfig() + initTracker(testScheduler, config) + + // GIVEN a start of tracking touch event that moves the tracker to WAIT at the middle of the + // slider + var progress = 0.5f + sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STARTED_TRACKING_TOUCH, progress)) + + // GIVEN a progress event due to a touch on the slider track at threshold + progress += config.jumpThreshold + sliderEventProducer.sendEvent( + SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress) + ) + + // THEN the tracker moves to the jump-track location selected state + assertThat(mSeekableSliderTracker.currentState) + .isEqualTo(SliderState.JUMP_TRACK_LOCATION_SELECTED) + assertThat(mSeekableSliderTracker.isWaiting).isFalse() + verify(sliderStateListener).onProgressJump(anyFloat()) + verifyNoMoreInteractions(sliderStateListener) + } + + @Test + fun upperBookendSelection_onWait_movesToBookendSelected() = runTest { + val config = SeekableSliderTrackerConfig() + initTracker(testScheduler, config) + + // GIVEN a start of tracking touch event that moves the tracker to WAIT at the middle of the + // slider + var progress = 0.5f + sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STARTED_TRACKING_TOUCH, progress)) + + // GIVEN a progress event due to a touch on the slider upper bookend zone. + progress = (config.upperBookendThreshold + 0.01f) + sliderEventProducer.sendEvent( + SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress) + ) + + // THEN the tracker moves to the jump-track location selected state + assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.JUMP_BOOKEND_SELECTED) + assertThat(mSeekableSliderTracker.isWaiting).isFalse() + verify(sliderStateListener).onUpperBookend() + verifyNoMoreInteractions(sliderStateListener) + } + + @Test + fun lowerBookendSelection_onWait_movesToBookendSelected() = runTest { + val config = SeekableSliderTrackerConfig() + initTracker(testScheduler, config) + + // GIVEN a start of tracking touch event that moves the tracker to WAIT at the middle of the + // slider + var progress = 0.5f + sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STARTED_TRACKING_TOUCH, progress)) + + // GIVEN a progress event due to a touch on the slider lower bookend zone + progress = (config.lowerBookendThreshold - 0.01f) + sliderEventProducer.sendEvent( + SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress) + ) + + // THEN the tracker moves to the JUMP_TRACK_LOCATION_SELECTED state + assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.JUMP_BOOKEND_SELECTED) + assertThat(mSeekableSliderTracker.isWaiting).isFalse() + verify(sliderStateListener).onLowerBookend() + verifyNoMoreInteractions(sliderStateListener) + } + + @Test + fun stopTracking_onWait_whenWaitingJobIsActive_resetsToIdle() = runTest { + val config = SeekableSliderTrackerConfig() + initTracker(testScheduler, config) + + // GIVEN a start of tracking touch event that moves the tracker to WAIT at the middle of the + // slider + sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STARTED_TRACKING_TOUCH, 0.5f)) + assertThat(mSeekableSliderTracker.isWaiting).isTrue() + + // GIVEN that the tracker stops tracking the state and listening to events + mSeekableSliderTracker.stopTracking() + + // THEN the tracker moves to the IDLE state without the timer job being complete + assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.IDLE) + assertThat(mSeekableSliderTracker.isWaiting).isFalse() + assertThat(mSeekableSliderTracker.isTracking).isFalse() + verifyNoMoreInteractions(sliderStateListener) + } + + // Tests on the JUMP_TRACK_LOCATION_SELECTED state + + @Test + fun progressChangeByUser_onJumpTrackLocationSelected_movesToDragHandleDragging() = runTest { + initTracker(testScheduler) + + // GIVEN a JUMP_TRACK_LOCATION_SELECTED state + mSeekableSliderTracker.setState(SliderState.JUMP_TRACK_LOCATION_SELECTED) + + // GIVEN a progress event due to dragging the handle + sliderEventProducer.sendEvent(SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, 0.5f)) + + // THEN the tracker moves to the DRAG_HANDLE_DRAGGING state + assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.DRAG_HANDLE_DRAGGING) + verify(sliderStateListener).onProgress(anyFloat()) + verifyNoMoreInteractions(sliderStateListener) + } + + @Test + fun touchRelease_onJumpTrackLocationSelected_movesToIdle() = runTest { + initTracker(testScheduler) + + // GIVEN a JUMP_TRACK_LOCATION_SELECTED state + mSeekableSliderTracker.setState(SliderState.JUMP_TRACK_LOCATION_SELECTED) + + // GIVEN that the slider stopped tracking touch + sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STOPPED_TRACKING_TOUCH, 0.5f)) + + // THEN the tracker executes on onHandleReleasedFromTouch before moving to the IDLE state + verify(sliderStateListener).onHandleReleasedFromTouch() + assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.IDLE) + verifyNoMoreInteractions(sliderStateListener) + } + + @Test + fun progressChangeByUser_onJumpBookendSelected_movesToDragHandleDragging() = runTest { + initTracker(testScheduler) + + // GIVEN a JUMP_BOOKEND_SELECTED state + mSeekableSliderTracker.setState(SliderState.JUMP_BOOKEND_SELECTED) + + // GIVEN that the slider stopped tracking touch + sliderEventProducer.sendEvent(SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, 0.5f)) + + // THEN the tracker moves to the DRAG_HANDLE_DRAGGING state + assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.DRAG_HANDLE_DRAGGING) + verify(sliderStateListener).onProgress(anyFloat()) + verifyNoMoreInteractions(sliderStateListener) + } + + @Test + fun touchRelease_onJumpBookendSelected_movesToIdle() = runTest { + initTracker(testScheduler) + + // GIVEN a JUMP_BOOKEND_SELECTED state + mSeekableSliderTracker.setState(SliderState.JUMP_BOOKEND_SELECTED) + + // GIVEN that the slider stopped tracking touch + sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STOPPED_TRACKING_TOUCH, 0.5f)) + + // THEN the tracker executes on onHandleReleasedFromTouch before moving to the IDLE state + verify(sliderStateListener).onHandleReleasedFromTouch() + assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.IDLE) + verifyNoMoreInteractions(sliderStateListener) + } + + // Tests on the DRAG_HANDLE_ACQUIRED state + + @Test + fun progressChangeByUser_onHandleAcquired_movesToDragHandleDragging() = runTest { + initTracker(testScheduler) + + // GIVEN a DRAG_HANDLE_ACQUIRED_BY_TOUCH state + mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH) + + // GIVEN a progress change by the user + val progress = 0.5f + sliderEventProducer.sendEvent( + SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress) + ) + + // THEN the tracker moves to the DRAG_HANDLE_DRAGGING state + verify(sliderStateListener).onProgress(progress) + assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.DRAG_HANDLE_DRAGGING) + verifyNoMoreInteractions(sliderStateListener) + } + + @Test + fun touchRelease_onHandleAcquired_movesToIdle() = runTest { + initTracker(testScheduler) + + // GIVEN a DRAG_HANDLE_ACQUIRED_BY_TOUCH state + mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_ACQUIRED_BY_TOUCH) + + // GIVEN that the handle stops tracking touch + sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STOPPED_TRACKING_TOUCH, 0.5f)) + + // THEN the tracker executes on onHandleReleasedFromTouch before moving to the IDLE state + verify(sliderStateListener).onHandleReleasedFromTouch() + assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.IDLE) + verifyNoMoreInteractions(sliderStateListener) + } + + // Tests on DRAG_HANDLE_DRAGGING + + @Test + fun progressChangeByUser_onHandleDragging_progressOutsideOfBookends_doesNotChangeState() = + runTest { + initTracker(testScheduler) + + // GIVEN a DRAG_HANDLE_DRAGGING state + mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_DRAGGING) + + // GIVEN a progress change by the user outside of bookend bounds + val progress = 0.5f + sliderEventProducer.sendEvent( + SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress) + ) + + // THEN the tracker does not change state and executes the onProgress call + assertThat(mSeekableSliderTracker.currentState) + .isEqualTo(SliderState.DRAG_HANDLE_DRAGGING) + verify(sliderStateListener).onProgress(progress) + verifyNoMoreInteractions(sliderStateListener) + } + + @Test + fun progressChangeByUser_onHandleDragging_reachesLowerBookend_movesToHandleReachedBookend() = + runTest { + val config = SeekableSliderTrackerConfig() + initTracker(testScheduler, config) + + // GIVEN a DRAG_HANDLE_DRAGGING state + mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_DRAGGING) + + // GIVEN a progress change by the user reaching the lower bookend + val progress = config.lowerBookendThreshold - 0.01f + sliderEventProducer.sendEvent( + SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress) + ) + + // THEN the tracker moves to the DRAG_HANDLE_REACHED_BOOKEND state and executes the + // corresponding callback + assertThat(mSeekableSliderTracker.currentState) + .isEqualTo(SliderState.DRAG_HANDLE_REACHED_BOOKEND) + verify(sliderStateListener).onLowerBookend() + verifyNoMoreInteractions(sliderStateListener) + } + + @Test + fun progressChangeByUser_onHandleDragging_reachesUpperBookend_movesToHandleReachedBookend() = + runTest { + val config = SeekableSliderTrackerConfig() + initTracker(testScheduler, config) + + // GIVEN a DRAG_HANDLE_DRAGGING state + mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_DRAGGING) + + // GIVEN a progress change by the user reaching the upper bookend + val progress = config.upperBookendThreshold + 0.01f + sliderEventProducer.sendEvent( + SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress) + ) + + // THEN the tracker moves to the DRAG_HANDLE_REACHED_BOOKEND state and executes the + // corresponding callback + assertThat(mSeekableSliderTracker.currentState) + .isEqualTo(SliderState.DRAG_HANDLE_REACHED_BOOKEND) + verify(sliderStateListener).onUpperBookend() + verifyNoMoreInteractions(sliderStateListener) + } + + @Test + fun touchRelease_onHandleDragging_movesToIdle() = runTest { + initTracker(testScheduler) + + // GIVEN a DRAG_HANDLE_DRAGGING state + mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_DRAGGING) + + // GIVEN that the slider stops tracking touch + sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STOPPED_TRACKING_TOUCH, 0.5f)) + + // THEN the tracker executes on onHandleReleasedFromTouch before moving to the IDLE state + verify(sliderStateListener).onHandleReleasedFromTouch() + assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.IDLE) + verifyNoMoreInteractions(sliderStateListener) + } + + // Tests on the DRAG_HANDLE_REACHED_BOOKEND state + + @Test + fun progressChangeByUser_outsideOfBookendRange_onLowerBookend_movesToDragHandleDragging() = + runTest { + val config = SeekableSliderTrackerConfig() + initTracker(testScheduler, config) + + // GIVEN a DRAG_HANDLE_REACHED_BOOKEND state + mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_REACHED_BOOKEND) + + // GIVEN a progress event that falls outside of the lower bookend range + val progress = config.lowerBookendThreshold + 0.01f + sliderEventProducer.sendEvent( + SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress) + ) + + // THEN the tracker moves to the DRAG_HANDLE_DRAGGING state and executes accordingly + verify(sliderStateListener).onProgress(progress) + assertThat(mSeekableSliderTracker.currentState) + .isEqualTo(SliderState.DRAG_HANDLE_DRAGGING) + verifyNoMoreInteractions(sliderStateListener) + } + + @Test + fun progressChangeByUser_insideOfBookendRange_onLowerBookend_doesNotChangeState() = runTest { + val config = SeekableSliderTrackerConfig() + initTracker(testScheduler, config) + + // GIVEN a DRAG_HANDLE_REACHED_BOOKEND state + mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_REACHED_BOOKEND) + + // GIVEN a progress event that falls inside of the lower bookend range + val progress = config.lowerBookendThreshold - 0.01f + sliderEventProducer.sendEvent( + SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress) + ) + + // THEN the tracker stays in the current state and executes accordingly + verify(sliderStateListener).onLowerBookend() + assertThat(mSeekableSliderTracker.currentState) + .isEqualTo(SliderState.DRAG_HANDLE_REACHED_BOOKEND) + verifyNoMoreInteractions(sliderStateListener) + } + + @Test + fun progressChangeByUser_outsideOfBookendRange_onUpperBookend_movesToDragHandleDragging() = + runTest { + val config = SeekableSliderTrackerConfig() + initTracker(testScheduler, config) + + // GIVEN a DRAG_HANDLE_REACHED_BOOKEND state + mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_REACHED_BOOKEND) + + // GIVEN a progress event that falls outside of the upper bookend range + val progress = config.upperBookendThreshold - 0.01f + sliderEventProducer.sendEvent( + SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress) + ) + + // THEN the tracker moves to the DRAG_HANDLE_DRAGGING state and executes accordingly + verify(sliderStateListener).onProgress(progress) + assertThat(mSeekableSliderTracker.currentState) + .isEqualTo(SliderState.DRAG_HANDLE_DRAGGING) + verifyNoMoreInteractions(sliderStateListener) + } + + @Test + fun progressChangeByUser_insideOfBookendRange_onUpperBookend_doesNotChangeState() = runTest { + val config = SeekableSliderTrackerConfig() + initTracker(testScheduler, config) + + // GIVEN a DRAG_HANDLE_REACHED_BOOKEND state + mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_REACHED_BOOKEND) + + // GIVEN a progress event that falls inside of the upper bookend range + val progress = config.upperBookendThreshold + 0.01f + sliderEventProducer.sendEvent( + SliderEvent(SliderEventType.PROGRESS_CHANGE_BY_USER, progress) + ) + + // THEN the tracker stays in the current state and executes accordingly + verify(sliderStateListener).onUpperBookend() + assertThat(mSeekableSliderTracker.currentState) + .isEqualTo(SliderState.DRAG_HANDLE_REACHED_BOOKEND) + verifyNoMoreInteractions(sliderStateListener) + } + + @Test + fun touchRelease_onHandleReachedBookend_movesToIdle() = runTest { + initTracker(testScheduler) + + // GIVEN a DRAG_HANDLE_REACHED_BOOKEND state + mSeekableSliderTracker.setState(SliderState.DRAG_HANDLE_REACHED_BOOKEND) + + // GIVEN that the handle stops tracking touch + sliderEventProducer.sendEvent(SliderEvent(SliderEventType.STOPPED_TRACKING_TOUCH, 0.5f)) + + // THEN the tracker executes on onHandleReleasedFromTouch before moving to the IDLE state + verify(sliderStateListener).onHandleReleasedFromTouch() + assertThat(mSeekableSliderTracker.currentState).isEqualTo(SliderState.IDLE) + verifyNoMoreInteractions(sliderStateListener) + } + + @OptIn(ExperimentalCoroutinesApi::class) + private fun initTracker( + scheduler: TestCoroutineScheduler, + config: SeekableSliderTrackerConfig = SeekableSliderTrackerConfig(), + ) { + mSeekableSliderTracker = + SeekableSliderTracker( + sliderStateListener, + sliderEventProducer, + UnconfinedTestDispatcher(scheduler), + config + ) + mSeekableSliderTracker.startTracking() + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/SliderHapticFeedbackProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/SliderHapticFeedbackProviderTest.kt new file mode 100644 index 000000000000..0ee348e0d23d --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/haptics/slider/SliderHapticFeedbackProviderTest.kt @@ -0,0 +1,247 @@ +/* + * 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.haptics.slider + +import android.os.VibrationAttributes +import android.os.VibrationEffect +import android.view.VelocityTracker +import android.view.animation.AccelerateInterpolator +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.statusbar.VibratorHelper +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.eq +import com.android.systemui.util.mockito.whenever +import com.android.systemui.util.time.FakeSystemClock +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.times +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidJUnit4::class) +class SliderHapticFeedbackProviderTest : SysuiTestCase() { + + @Mock private lateinit var velocityTracker: VelocityTracker + @Mock private lateinit var vibratorHelper: VibratorHelper + + private val config = SliderHapticFeedbackConfig() + private val clock = FakeSystemClock() + + private val lowTickDuration = 12 // Mocked duration of a low tick + private val dragTextureThresholdMillis = + lowTickDuration * config.numberOfLowTicks + config.deltaMillisForDragInterval + private val progressInterpolator = AccelerateInterpolator(config.progressInterpolatorFactor) + private val velocityInterpolator = AccelerateInterpolator(config.velocityInterpolatorFactor) + private lateinit var sliderHapticFeedbackProvider: SliderHapticFeedbackProvider + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + whenever(vibratorHelper.getPrimitiveDurations(any())) + .thenReturn(intArrayOf(lowTickDuration)) + whenever(velocityTracker.xVelocity).thenReturn(config.maxVelocityToScale) + sliderHapticFeedbackProvider = + SliderHapticFeedbackProvider(vibratorHelper, velocityTracker, config, clock) + } + + @Test + fun playHapticAtLowerBookend_playsClick() { + val vibration = + VibrationEffect.startComposition() + .addPrimitive( + VibrationEffect.Composition.PRIMITIVE_CLICK, + scaleAtBookends(config.maxVelocityToScale) + ) + .compose() + + sliderHapticFeedbackProvider.onLowerBookend() + + verify(vibratorHelper).vibrate(eq(vibration), any(VibrationAttributes::class.java)) + } + + @Test + fun playHapticAtLowerBookend_twoTimes_playsClickOnlyOnce() { + val vibration = + VibrationEffect.startComposition() + .addPrimitive( + VibrationEffect.Composition.PRIMITIVE_CLICK, + scaleAtBookends(config.maxVelocityToScale) + ) + .compose() + + sliderHapticFeedbackProvider.onLowerBookend() + sliderHapticFeedbackProvider.onLowerBookend() + + verify(vibratorHelper).vibrate(eq(vibration), any(VibrationAttributes::class.java)) + } + + @Test + fun playHapticAtUpperBookend_playsClick() { + val vibration = + VibrationEffect.startComposition() + .addPrimitive( + VibrationEffect.Composition.PRIMITIVE_CLICK, + scaleAtBookends(config.maxVelocityToScale) + ) + .compose() + + sliderHapticFeedbackProvider.onUpperBookend() + + verify(vibratorHelper).vibrate(eq(vibration), any(VibrationAttributes::class.java)) + } + + @Test + fun playHapticAtUpperBookend_twoTimes_playsClickOnlyOnce() { + val vibration = + VibrationEffect.startComposition() + .addPrimitive( + VibrationEffect.Composition.PRIMITIVE_CLICK, + scaleAtBookends(config.maxVelocityToScale) + ) + .compose() + + sliderHapticFeedbackProvider.onUpperBookend() + sliderHapticFeedbackProvider.onUpperBookend() + + verify(vibratorHelper, times(1)) + .vibrate(eq(vibration), any(VibrationAttributes::class.java)) + } + + @Test + fun playHapticAtProgress_onQuickSuccession_playsLowTicksOnce() { + // GIVEN max velocity and slider progress + val progress = 1f + val expectedScale = scaleAtProgressChange(config.maxVelocityToScale.toFloat(), progress) + val ticks = VibrationEffect.startComposition() + repeat(config.numberOfLowTicks) { + ticks.addPrimitive(VibrationEffect.Composition.PRIMITIVE_LOW_TICK, expectedScale) + } + + // GIVEN system running for 1s + clock.advanceTime(1000) + + // WHEN two calls to play occur immediately + sliderHapticFeedbackProvider.onProgress(progress) + sliderHapticFeedbackProvider.onProgress(progress) + + // THEN the correct composition only plays once + verify(vibratorHelper, times(1)) + .vibrate(eq(ticks.compose()), any(VibrationAttributes::class.java)) + } + + @Test + fun playHapticAtProgress_afterNextDragThreshold_playsLowTicksTwice() { + // GIVEN max velocity and slider progress + val progress = 1f + val expectedScale = scaleAtProgressChange(config.maxVelocityToScale.toFloat(), progress) + val ticks = VibrationEffect.startComposition() + repeat(config.numberOfLowTicks) { + ticks.addPrimitive(VibrationEffect.Composition.PRIMITIVE_LOW_TICK, expectedScale) + } + + // GIVEN system running for 1s + clock.advanceTime(1000) + + // WHEN two calls to play occur with the required threshold separation + sliderHapticFeedbackProvider.onProgress(progress) + clock.advanceTime(dragTextureThresholdMillis.toLong()) + sliderHapticFeedbackProvider.onProgress(progress) + + // THEN the correct composition plays two times + verify(vibratorHelper, times(2)) + .vibrate(eq(ticks.compose()), any(VibrationAttributes::class.java)) + } + + @Test + fun playHapticAtLowerBookend_afterPlayingAtProgress_playsTwice() { + // GIVEN max velocity and slider progress + val progress = 1f + val expectedScale = scaleAtProgressChange(config.maxVelocityToScale.toFloat(), progress) + val ticks = VibrationEffect.startComposition() + repeat(config.numberOfLowTicks) { + ticks.addPrimitive(VibrationEffect.Composition.PRIMITIVE_LOW_TICK, expectedScale) + } + val bookendVibration = + VibrationEffect.startComposition() + .addPrimitive( + VibrationEffect.Composition.PRIMITIVE_CLICK, + scaleAtBookends(config.maxVelocityToScale) + ) + .compose() + + // GIVEN a vibration at the lower bookend followed by a request to vibrate at progress + sliderHapticFeedbackProvider.onLowerBookend() + sliderHapticFeedbackProvider.onProgress(progress) + + // WHEN a vibration is to trigger again at the lower bookend + sliderHapticFeedbackProvider.onLowerBookend() + + // THEN there are two bookend vibrations + verify(vibratorHelper, times(2)) + .vibrate(eq(bookendVibration), any(VibrationAttributes::class.java)) + } + + @Test + fun playHapticAtUpperBookend_afterPlayingAtProgress_playsTwice() { + // GIVEN max velocity and slider progress + val progress = 1f + val expectedScale = scaleAtProgressChange(config.maxVelocityToScale.toFloat(), progress) + val ticks = VibrationEffect.startComposition() + repeat(config.numberOfLowTicks) { + ticks.addPrimitive(VibrationEffect.Composition.PRIMITIVE_LOW_TICK, expectedScale) + } + val bookendVibration = + VibrationEffect.startComposition() + .addPrimitive( + VibrationEffect.Composition.PRIMITIVE_CLICK, + scaleAtBookends(config.maxVelocityToScale) + ) + .compose() + + // GIVEN a vibration at the upper bookend followed by a request to vibrate at progress + sliderHapticFeedbackProvider.onUpperBookend() + sliderHapticFeedbackProvider.onProgress(progress) + + // WHEN a vibration is to trigger again at the upper bookend + sliderHapticFeedbackProvider.onUpperBookend() + + // THEN there are two bookend vibrations + verify(vibratorHelper, times(2)) + .vibrate(eq(bookendVibration), any(VibrationAttributes::class.java)) + } + + private fun scaleAtBookends(velocity: Float): Float { + val range = config.upperBookendScale - config.lowerBookendScale + val interpolatedVelocity = + velocityInterpolator.getInterpolation(velocity / config.maxVelocityToScale) + return interpolatedVelocity * range + config.lowerBookendScale + } + + private fun scaleAtProgressChange(velocity: Float, progress: Float): Float { + val range = config.progressBasedDragMaxScale - config.progressBasedDragMinScale + val interpolatedVelocity = + velocityInterpolator.getInterpolation(velocity / config.maxVelocityToScale) + val interpolatedProgress = progressInterpolator.getInterpolation(progress) + val bump = interpolatedVelocity * config.additionalVelocityMaxBump + return interpolatedProgress * range + config.progressBasedDragMinScale + bump + } +} 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 f3c9432cb4bf..6c990e457209 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt @@ -30,7 +30,7 @@ import android.testing.TestableLooper import android.view.SurfaceControlViewHost import androidx.test.filters.SmallTest import com.android.internal.widget.LockPatternUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SystemUIAppComponentFactoryBase import com.android.systemui.SysuiTestCase import com.android.systemui.animation.DialogLaunchAnimator 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 a45b0bd4cca8..9d96ac736b5c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -188,6 +188,8 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { private @Mock ShadeWindowLogger mShadeWindowLogger; private @Captor ArgumentCaptor<KeyguardStateController.Callback> mKeyguardStateControllerCallback; + private @Captor ArgumentCaptor<KeyguardUpdateMonitorCallback> + mKeyguardUpdateMonitorCallbackCaptor; private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake(); private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock()); @@ -292,6 +294,45 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { } @Test + @TestableLooper.RunWithLooper(setAsMainLooper = true) + public void onLockdown_showKeyguard_evenIfKeyguardIsNotEnabledExternally() { + // GIVEN keyguard is not enabled and isn't showing + mViewMediator.onSystemReady(); + mViewMediator.setKeyguardEnabled(false); + TestableLooper.get(this).processAllMessages(); + captureKeyguardUpdateMonitorCallback(); + assertFalse(mViewMediator.isShowingAndNotOccluded()); + + // WHEN lockdown occurs + when(mLockPatternUtils.isUserInLockdown(anyInt())).thenReturn(true); + mKeyguardUpdateMonitorCallbackCaptor.getValue().onStrongAuthStateChanged(0); + + // THEN keyguard is shown + TestableLooper.get(this).processAllMessages(); + assertTrue(mViewMediator.isShowingAndNotOccluded()); + } + + @Test + @TestableLooper.RunWithLooper(setAsMainLooper = true) + public void doNotHideKeyguard_whenLockdown_onKeyguardNotEnabledExternally() { + // GIVEN keyguard is enabled and lockdown occurred so the keyguard is showing + mViewMediator.onSystemReady(); + mViewMediator.setKeyguardEnabled(true); + TestableLooper.get(this).processAllMessages(); + captureKeyguardUpdateMonitorCallback(); + when(mLockPatternUtils.isUserInLockdown(anyInt())).thenReturn(true); + mKeyguardUpdateMonitorCallbackCaptor.getValue().onStrongAuthStateChanged(0); + assertTrue(mViewMediator.isShowingAndNotOccluded()); + + // WHEN keyguard is externally not enabled anymore + mViewMediator.setKeyguardEnabled(false); + + // THEN keyguard is NOT dismissed; it continues to show + TestableLooper.get(this).processAllMessages(); + assertTrue(mViewMediator.isShowingAndNotOccluded()); + } + + @Test public void testOnGoingToSleep_UpdatesKeyguardGoingAway() { mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER); verify(mUpdateMonitor).dispatchKeyguardGoingAway(false); @@ -1102,4 +1143,8 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { private void captureKeyguardStateControllerCallback() { verify(mKeyguardStateController).addCallback(mKeyguardStateControllerCallback.capture()); } + + private void captureKeyguardUpdateMonitorCallback() { + verify(mUpdateMonitor).registerCallback(mKeyguardUpdateMonitorCallbackCaptor.capture()); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt index d84a4f741637..49168d087958 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt @@ -25,7 +25,7 @@ import android.provider.Settings.Secure.ZEN_DURATION_PROMPT import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.settingslib.notification.EnableZenModeDialog -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.animation.Expandable diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt index b6dffff4c797..c3e28ae84805 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt @@ -20,7 +20,7 @@ package com.android.systemui.keyguard.data.quickaffordance import android.content.Context import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.common.shared.model.Icon import com.android.systemui.keyguard.shared.quickaffordance.ActivationState diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt index 1815ea9530e2..12fa4c85c34d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt @@ -19,7 +19,7 @@ package com.android.systemui.keyguard.data.quickaffordance import android.app.Activity import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.controls.controller.ControlsController diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt index 2fd4947b968c..ef56a9892060 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt @@ -19,7 +19,7 @@ package com.android.systemui.keyguard.data.quickaffordance import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.animation.Expandable diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfigTest.kt index 7941a23fe30d..bd4525b28f71 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfigTest.kt @@ -19,7 +19,7 @@ package com.android.systemui.keyguard.data.quickaffordance import android.content.Intent import android.net.Uri import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import org.junit.Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt index de3bb6f3d031..4f071bd9904f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt @@ -22,7 +22,7 @@ import android.content.res.Resources import android.provider.Settings import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.settings.FakeUserTracker diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt index edaff44cf543..bd0b71df3e5c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt @@ -22,7 +22,7 @@ import android.content.SharedPreferences import android.content.pm.UserInfo import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.backup.BackupHelper diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt index b9c0b7fe35d7..613c4ce4ccef 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt @@ -23,7 +23,7 @@ import android.service.quickaccesswallet.QuickAccessWalletClient import android.service.quickaccesswallet.WalletCard import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.animation.ActivityLaunchAnimator diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt index a6930d595326..360fa5652e20 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt @@ -32,7 +32,7 @@ import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUT import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.AuthController diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt index 6b194f243b2c..5a95ebec1fb3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt @@ -25,6 +25,9 @@ import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_HW_UNAVAILA import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT import android.hardware.biometrics.ComponentInfoInternal import android.hardware.face.FaceAuthenticateOptions +import android.hardware.face.FaceAuthenticateOptions.AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN +import android.hardware.face.FaceAuthenticateOptions.AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED +import android.hardware.face.FaceAuthenticateOptions.AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER import android.hardware.face.FaceManager import android.hardware.face.FaceSensorProperties import android.hardware.face.FaceSensorPropertiesInternal @@ -39,7 +42,7 @@ import com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ALTERNATE_BIOMET import com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED import com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER import com.android.keyguard.KeyguardUpdateMonitor -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository @@ -102,7 +105,6 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.any -import org.mockito.ArgumentMatchers.eq import org.mockito.Captor import org.mockito.Mock import org.mockito.Mockito.atLeastOnce @@ -133,6 +135,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { @Captor private lateinit var detectionCallback: ArgumentCaptor<FaceManager.FaceDetectionCallback> + @Captor private lateinit var faceAuthenticateOptions: ArgumentCaptor<FaceAuthenticateOptions> @Captor private lateinit var cancellationSignal: ArgumentCaptor<CancellationSignal> private lateinit var bypassStateChangedListener: @@ -412,7 +415,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { underTest = createDeviceEntryFaceAuthRepositoryImpl() initCollectors() - underTest.detect() + underTest.detect(FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED) faceDetectIsCalled() detectionCallback.value.onFaceDetected(1, 1, true) @@ -421,6 +424,8 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { assertThat(status.sensorId).isEqualTo(1) assertThat(status.userId).isEqualTo(1) assertThat(status.isStrongBiometric).isEqualTo(true) + assertThat(faceAuthenticateOptions.value.authenticateReason) + .isEqualTo(AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED) } @Test @@ -432,7 +437,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { initCollectors() clearInvocations(faceManager) - underTest.detect() + underTest.detect(FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED) verify(faceManager, never()) .detectFace(any(), any(), any(FaceAuthenticateOptions::class.java)) @@ -467,6 +472,8 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { faceAuthenticateIsCalled() uiEventIsLogged(FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN) + assertThat(faceAuthenticateOptions.value.authenticateReason) + .isEqualTo(AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN) } @Test @@ -484,6 +491,8 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { underTest.requestAuthenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER) faceAuthenticateIsCalled() + assertThat(faceAuthenticateOptions.value.authenticateReason) + .isEqualTo(AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER) } @Test @@ -1238,7 +1247,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { .detectFace( cancellationSignal.capture(), detectionCallback.capture(), - eq(FaceAuthenticateOptions.Builder().setUserId(primaryUserId).build()) + faceAuthenticateOptions.capture(), ) } @@ -1251,7 +1260,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { cancellationSignal.capture(), authenticationCallback.capture(), isNull(), - eq(FaceAuthenticateOptions.Builder().setUserId(primaryUserId).build()) + faceAuthenticateOptions.capture(), ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt index 6b5be58b6d03..126b841610b4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt @@ -21,7 +21,7 @@ import android.content.pm.UserInfo import android.os.UserHandle import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt index 2ed9de26dfa3..518b3cc8933f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt @@ -23,6 +23,7 @@ import android.os.Handler import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.FaceAuthUiEvent +import com.android.keyguard.FaceWakeUpTriggersConfig import com.android.keyguard.KeyguardSecurityModel import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.SysuiTestCase @@ -42,17 +43,22 @@ import com.android.systemui.keyguard.DismissCallbackRegistry import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository +import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.FakeTrustRepository import com.android.systemui.keyguard.shared.model.ErrorFaceAuthenticationStatus 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.shared.model.WakeSleepReason +import com.android.systemui.keyguard.shared.model.WakefulnessModel +import com.android.systemui.keyguard.shared.model.WakefulnessState import com.android.systemui.log.FaceAuthenticationLogger import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.user.data.model.SelectionStatus import com.android.systemui.user.data.repository.FakeUserRepository +import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -83,8 +89,10 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() { private lateinit var facePropertyRepository: FakeFacePropertyRepository private lateinit var fakeDeviceEntryFingerprintAuthRepository: FakeDeviceEntryFingerprintAuthRepository + private lateinit var fakeKeyguardRepository: FakeKeyguardRepository @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor + @Mock private lateinit var faceWakeUpTriggersConfig: FaceWakeUpTriggersConfig @Before fun setup() { @@ -108,6 +116,7 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() { fakeUserRepository = FakeUserRepository() fakeUserRepository.setUserInfos(listOf(primaryUser, secondaryUser)) facePropertyRepository = FakeFacePropertyRepository() + fakeKeyguardRepository = FakeKeyguardRepository() underTest = SystemUIKeyguardFaceAuthInteractor( mContext, @@ -126,7 +135,6 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() { context, keyguardUpdateMonitor, FakeTrustRepository(), - FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) }, testScope.backgroundScope, ), AlternateBouncerInteractor( @@ -144,6 +152,8 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() { fakeDeviceEntryFingerprintAuthRepository, fakeUserRepository, facePropertyRepository, + fakeKeyguardRepository, + faceWakeUpTriggersConfig, ) } @@ -152,6 +162,18 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() { testScope.runTest { underTest.start() + fakeKeyguardRepository.setWakefulnessModel( + WakefulnessModel( + WakefulnessState.STARTING_TO_WAKE, + WakeSleepReason.LID, + WakeSleepReason.LID + ) + ) + whenever( + faceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(WakeSleepReason.LID) + ) + .thenReturn(true) + keyguardTransitionRepository.sendTransitionStep( TransitionStep( KeyguardState.OFF, @@ -188,6 +210,18 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() { testScope.runTest { underTest.start() + fakeKeyguardRepository.setWakefulnessModel( + WakefulnessModel( + WakefulnessState.STARTING_TO_WAKE, + WakeSleepReason.LID, + WakeSleepReason.LID + ) + ) + whenever( + faceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(WakeSleepReason.LID) + ) + .thenReturn(true) + keyguardTransitionRepository.sendTransitionStep( TransitionStep( KeyguardState.AOD, @@ -204,10 +238,51 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() { } @Test + fun faceAuthIsNotRequestedWhenLockscreenBecomesVisibleDueToIgnoredWakeReasons() = + testScope.runTest { + underTest.start() + + fakeKeyguardRepository.setWakefulnessModel( + WakefulnessModel( + WakefulnessState.STARTING_TO_WAKE, + WakeSleepReason.LIFT, + WakeSleepReason.POWER_BUTTON + ) + ) + whenever( + faceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(WakeSleepReason.LIFT) + ) + .thenReturn(false) + + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + KeyguardState.DOZING, + KeyguardState.LOCKSCREEN, + transitionState = TransitionState.STARTED + ) + ) + + runCurrent() + assertThat(faceAuthRepository.runningAuthRequest.value).isNull() + } + + @Test fun faceAuthIsRequestedWhenLockscreenBecomesVisibleFromDozingState() = testScope.runTest { underTest.start() + fakeKeyguardRepository.setWakefulnessModel( + WakefulnessModel( + WakefulnessState.STARTING_TO_WAKE, + WakeSleepReason.LID, + WakeSleepReason.LID + ) + ) + whenever( + faceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(WakeSleepReason.LID) + ) + .thenReturn(true) + keyguardTransitionRepository.sendTransitionStep( TransitionStep( KeyguardState.DOZING, diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt index 0bbeeff8eee3..13025a016eff 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt @@ -21,7 +21,7 @@ import android.content.Intent import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.logging.UiEventLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue 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 e8542aad9cd2..8c13bb465103 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 @@ -22,7 +22,7 @@ import android.os.UserHandle import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.widget.LockPatternUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.animation.DialogLaunchAnimator 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 d4576053f9c7..f2636c543844 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 @@ -32,6 +32,7 @@ import com.android.systemui.keyguard.shared.model.BiometricUnlockModel import com.android.systemui.keyguard.shared.model.DozeStateModel import com.android.systemui.keyguard.shared.model.DozeTransitionModel import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.keyguard.shared.model.TransitionInfo import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep @@ -39,11 +40,12 @@ import com.android.systemui.keyguard.shared.model.WakeSleepReason import com.android.systemui.keyguard.shared.model.WakefulnessModel import com.android.systemui.keyguard.shared.model.WakefulnessState import com.android.systemui.shade.data.repository.FakeShadeRepository -import com.android.systemui.shade.data.repository.ShadeRepository +import com.android.systemui.shade.domain.model.ShadeModel import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.whenever import com.android.systemui.util.mockito.withArgCaptor import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.advanceUntilIdle @@ -56,6 +58,7 @@ import org.junit.runners.JUnit4 import org.mockito.ArgumentMatchers.anyBoolean import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock +import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.never import org.mockito.Mockito.reset import org.mockito.Mockito.spy @@ -66,6 +69,7 @@ import org.mockito.MockitoAnnotations * Class for testing user journeys through the interactors. They will all be activated during setup, * to ensure the expected transitions are still triggered. */ +@ExperimentalCoroutinesApi @SmallTest @RunWith(JUnit4::class) class KeyguardTransitionScenariosTest : SysuiTestCase() { @@ -74,7 +78,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { private lateinit var keyguardRepository: FakeKeyguardRepository private lateinit var bouncerRepository: FakeKeyguardBouncerRepository private lateinit var commandQueue: FakeCommandQueue - private lateinit var shadeRepository: ShadeRepository + private lateinit var shadeRepository: FakeShadeRepository private lateinit var transitionRepository: FakeKeyguardTransitionRepository private lateinit var transitionInteractor: KeyguardTransitionInteractor private lateinit var featureFlags: FakeFeatureFlags @@ -1213,6 +1217,58 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() { coroutineContext.cancelChildren() } + @Test + fun lockscreenToPrimaryBouncerDragging() = + testScope.runTest { + // GIVEN a prior transition has run to LOCKSCREEN + runTransition(KeyguardState.AOD, KeyguardState.LOCKSCREEN) + runCurrent() + + // GIVEN the keyguard is showing locked + keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD) + keyguardRepository.setKeyguardUnlocked(false) + runCurrent() + shadeRepository.setShadeModel( + ShadeModel( + expansionAmount = .9f, + isUserDragging = true, + ) + ) + runCurrent() + + // THEN a transition from LOCKSCREEN => PRIMARY_BOUNCER should occur + val info = + withArgCaptor<TransitionInfo> { + verify(transitionRepository).startTransition(capture(), anyBoolean()) + } + assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor") + assertThat(info.from).isEqualTo(KeyguardState.LOCKSCREEN) + assertThat(info.to).isEqualTo(KeyguardState.PRIMARY_BOUNCER) + assertThat(info.animator).isNull() // dragging should be manually animated + + // WHEN the user stops dragging and shade is back to expanded + clearInvocations(transitionRepository) + runTransition(KeyguardState.LOCKSCREEN, KeyguardState.PRIMARY_BOUNCER) + shadeRepository.setShadeModel( + ShadeModel( + expansionAmount = 1f, + isUserDragging = false, + ) + ) + runCurrent() + + // THEN a transition from PRIMARY_BOUNCER => LOCKSCREEN should occur + val info2 = + withArgCaptor<TransitionInfo> { + verify(transitionRepository).startTransition(capture(), anyBoolean()) + } + assertThat(info2.from).isEqualTo(KeyguardState.PRIMARY_BOUNCER) + assertThat(info2.to).isEqualTo(KeyguardState.LOCKSCREEN) + assertThat(info2.animator).isNotNull() + + coroutineContext.cancelChildren() + } + private fun startingToWake() = WakefulnessModel( WakefulnessState.STARTING_TO_WAKE, diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt index b81a3d46b434..47365457d9e4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt @@ -100,11 +100,7 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() { keyguardRepository = FakeKeyguardRepository() bouncerRepository = FakeKeyguardBouncerRepository() configurationRepository = FakeConfigurationRepository() - featureFlags = - FakeFeatureFlags().apply { - set(Flags.FACE_AUTH_REFACTOR, false) - set(Flags.DELAY_BOUNCER, false) - } + featureFlags = FakeFeatureFlags().apply { set(Flags.FACE_AUTH_REFACTOR, false) } trustRepository = FakeTrustRepository() powerRepository = FakePowerRepository() underTest = @@ -138,7 +134,6 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() { context, keyguardUpdateMonitor, trustRepository, - featureFlags, testScope.backgroundScope, ), AlternateBouncerInteractor( diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt index 623c8771b3d2..7a17435b9165 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt @@ -67,6 +67,7 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() { underTest.setLockscreenShown(true) underTest.setAodVisible(true) + verify(activityTaskManagerService).setLockScreenShown(true, false) verify(activityTaskManagerService).setLockScreenShown(true, true) verifyNoMoreInteractions(activityTaskManagerService) } @@ -76,6 +77,7 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() { underTest.setLockscreenShown(true) underTest.setAodVisible(true) + verify(activityTaskManagerService).setLockScreenShown(true, false) verify(activityTaskManagerService).setLockScreenShown(true, true) verifyNoMoreInteractions(activityTaskManagerService) @@ -97,4 +99,12 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() { verifyNoMoreInteractions(activityTaskManagerService) } + + @Test + fun testAodVisible_noLockscreenShownCallYet_defaultsToShowLockscreen() { + underTest.setAodVisible(false) + + verify(activityTaskManagerService).setLockScreenShown(true, false) + verifyNoMoreInteractions(activityTaskManagerService) + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSectionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSectionTest.kt index 4e31af22f771..8b8c59b78e46 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSectionTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSectionTest.kt @@ -21,7 +21,7 @@ import android.view.ViewGroup import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSectionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSectionTest.kt index 1c3b5e616ddf..74956377d345 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSectionTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSectionTest.kt @@ -24,7 +24,7 @@ import androidx.constraintlayout.widget.ConstraintSet import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.LockIconViewController -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.AuthController import com.android.systemui.flags.FeatureFlags 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 06bf7f06a12d..32d28a3d7bb2 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 @@ -22,7 +22,7 @@ import android.os.UserHandle import androidx.test.filters.SmallTest import com.android.internal.logging.testing.UiEventLoggerFake import com.android.internal.widget.LockPatternUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.animation.DialogLaunchAnimator import com.android.systemui.animation.Expandable diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt index b935e1d3c65a..1c6cc873c547 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt @@ -22,7 +22,7 @@ import android.content.Intent import android.os.UserHandle import androidx.test.filters.SmallTest import com.android.internal.widget.LockPatternUtils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.animation.DialogLaunchAnimator import com.android.systemui.animation.Expandable diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModelTest.kt index bd17de3ee939..9ab9b3d160d1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModelTest.kt @@ -66,7 +66,7 @@ class UdfpsAodViewModelTest : SysuiTestCase() { @Before fun setUp() { MockitoAnnotations.initMocks(this) - overrideResource(com.android.systemui.R.dimen.lock_icon_padding, defaultPadding) + overrideResource(com.android.systemui.res.R.dimen.lock_icon_padding, defaultPadding) testScope = TestScope() shadeRepository = FakeShadeRepository() featureFlags = diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsFingerprintViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsFingerprintViewModelTest.kt index 0ad14d029e40..4f970d708425 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsFingerprintViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsFingerprintViewModelTest.kt @@ -69,7 +69,7 @@ class UdfpsFingerprintViewModelTest : SysuiTestCase() { @Before fun setUp() { MockitoAnnotations.initMocks(this) - overrideResource(com.android.systemui.R.dimen.lock_icon_padding, defaultPadding) + overrideResource(com.android.systemui.res.R.dimen.lock_icon_padding, defaultPadding) testScope = TestScope() configRepository = FakeConfigurationRepository() keyguardRepository = FakeKeyguardRepository() diff --git a/packages/SystemUI/tests/src/com/android/systemui/logcat/LogAccessDialogActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/logcat/LogAccessDialogActivityTest.java index 1d7d5df80f45..eed7ecd9d7b0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/logcat/LogAccessDialogActivityTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/logcat/LogAccessDialogActivityTest.java @@ -31,7 +31,7 @@ import androidx.test.filters.LargeTest; import androidx.test.platform.app.InstrumentationRegistry; import com.android.internal.app.ILogAccessDialogCallback; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/player/SeekBarObserverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/player/SeekBarObserverTest.kt index d6ceea11b801..043dae608aa7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/player/SeekBarObserverTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/player/SeekBarObserverTest.kt @@ -24,7 +24,7 @@ import android.view.View import android.widget.SeekBar import android.widget.TextView import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.media.controls.ui.SquigglyProgress import com.google.common.truth.Truth.assertThat diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/recommendation/SmartspaceMediaDataTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/recommendation/SmartspaceMediaDataTest.kt index 670f11787ce4..f7c20ac35957 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/recommendation/SmartspaceMediaDataTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/models/recommendation/SmartspaceMediaDataTest.kt @@ -20,7 +20,7 @@ import android.app.smartspace.SmartspaceAction import android.graphics.drawable.Icon import androidx.test.filters.SmallTest import com.android.internal.logging.InstanceId -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import org.junit.Test 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 5939bb50bb25..fb0a4be25aa0 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 @@ -48,7 +48,7 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito import com.android.internal.logging.InstanceId import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.InstanceIdSequenceFake -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.dump.DumpManager diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDeviceManagerTest.kt index 0c57e7b82586..85d3fbad5a6e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDeviceManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDeviceManagerTest.kt @@ -34,7 +34,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager import com.android.settingslib.bluetooth.LocalBluetoothProfileManager import com.android.settingslib.media.LocalMediaManager import com.android.settingslib.media.MediaDevice -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager import com.android.systemui.media.controls.MediaTestUtils 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 3961a945414d..a4c2a0850ce4 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 @@ -31,7 +31,7 @@ import com.android.internal.logging.InstanceId import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.keyguard.TestScopeProvider -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager 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 9a90a5ceb259..d6e2e973b29d 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 @@ -61,7 +61,7 @@ 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.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.bluetooth.BroadcastDialogController import com.android.systemui.broadcast.BroadcastSender @@ -1884,7 +1884,7 @@ public class MediaControlPanelTest : SysuiTestCase() { @Test fun bindRecommendation_listHasTooFewRecs_notDisplayed() { player.attachRecommendation(recommendationViewHolder) - val icon = Icon.createWithResource(context, R.drawable.ic_1x_mobiledata) + val icon = Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata) val data = smartspaceData.copy( recommendations = @@ -1911,7 +1911,7 @@ public class MediaControlPanelTest : SysuiTestCase() { @Test fun bindRecommendation_listHasTooFewRecsWithIcons_notDisplayed() { player.attachRecommendation(recommendationViewHolder) - val icon = Icon.createWithResource(context, R.drawable.ic_1x_mobiledata) + val icon = Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata) val data = smartspaceData.copy( recommendations = @@ -1955,7 +1955,7 @@ public class MediaControlPanelTest : SysuiTestCase() { val subtitle1 = "Subtitle1" val subtitle2 = "Subtitle2" val subtitle3 = "Subtitle3" - val icon = Icon.createWithResource(context, R.drawable.ic_1x_mobiledata) + val icon = Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata) val data = smartspaceData.copy( @@ -1998,7 +1998,7 @@ public class MediaControlPanelTest : SysuiTestCase() { listOf( SmartspaceAction.Builder("id1", "") .setSubtitle("fake subtitle") - .setIcon(Icon.createWithResource(context, R.drawable.ic_1x_mobiledata)) + .setIcon(Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)) .setExtras(Bundle.EMPTY) .build() ) @@ -2013,7 +2013,7 @@ public class MediaControlPanelTest : SysuiTestCase() { useRealConstraintSets() player.attachRecommendation(recommendationViewHolder) - val icon = Icon.createWithResource(context, R.drawable.ic_1x_mobiledata) + val icon = Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata) val data = smartspaceData.copy( recommendations = @@ -2047,7 +2047,7 @@ public class MediaControlPanelTest : SysuiTestCase() { useRealConstraintSets() player.attachRecommendation(recommendationViewHolder) - val icon = Icon.createWithResource(context, R.drawable.ic_1x_mobiledata) + val icon = Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata) val data = smartspaceData.copy( recommendations = @@ -2086,7 +2086,7 @@ public class MediaControlPanelTest : SysuiTestCase() { listOf( SmartspaceAction.Builder("id1", "title1") .setSubtitle("") - .setIcon(Icon.createWithResource(context, R.drawable.ic_1x_mobiledata)) + .setIcon(Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)) .setExtras(Bundle.EMPTY) .build(), SmartspaceAction.Builder("id2", "title2") @@ -2096,7 +2096,7 @@ public class MediaControlPanelTest : SysuiTestCase() { .build(), SmartspaceAction.Builder("id3", "title3") .setSubtitle("") - .setIcon(Icon.createWithResource(context, R.drawable.ic_3g_mobiledata)) + .setIcon(Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_3g_mobiledata)) .setExtras(Bundle.EMPTY) .build() ) @@ -2119,7 +2119,7 @@ public class MediaControlPanelTest : SysuiTestCase() { listOf( SmartspaceAction.Builder("id1", "") .setSubtitle("subtitle1") - .setIcon(Icon.createWithResource(context, R.drawable.ic_1x_mobiledata)) + .setIcon(Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_1x_mobiledata)) .setExtras(Bundle.EMPTY) .build(), SmartspaceAction.Builder("id2", "") @@ -2129,7 +2129,7 @@ public class MediaControlPanelTest : SysuiTestCase() { .build(), SmartspaceAction.Builder("id3", "") .setSubtitle("subtitle3") - .setIcon(Icon.createWithResource(context, R.drawable.ic_3g_mobiledata)) + .setIcon(Icon.createWithResource(context, com.android.settingslib.R.drawable.ic_3g_mobiledata)) .setExtras(Bundle.EMPTY) .build() ) 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 33ed01f115b5..25faeef85e50 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 @@ -24,7 +24,7 @@ import android.view.ViewGroup import android.widget.FrameLayout import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardViewController -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.controls.controller.ControlsControllerImplTest.Companion.eq import com.android.systemui.dreams.DreamOverlayStateController 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 ba97df910e43..1f99303f10ed 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,7 +22,7 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.view.View import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.media.controls.models.player.MediaViewHolder import com.android.systemui.media.controls.models.recommendation.RecommendationViewHolder diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java index e4f89a226a34..2f057a2e14e4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java @@ -46,7 +46,7 @@ import androidx.test.filters.SmallTest; import com.android.settingslib.media.LocalMediaManager; import com.android.settingslib.media.MediaDevice; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.google.common.collect.ImmutableList; @@ -467,7 +467,7 @@ public class MediaOutputAdapterTest extends SysuiTestCase { @Test public void subStatusSupported_onBindViewHolder_bindDeviceRequirePremium_verifyView() { String deviceStatus = (String) mContext.getText( - R.string.media_output_status_require_premium); + com.android.settingslib.R.string.media_output_status_require_premium); when(mMediaDevice2.hasSubtext()).thenReturn(true); when(mMediaDevice2.getSubtext()).thenReturn(SUBTEXT_SUBSCRIPTION_REQUIRED); when(mMediaDevice2.getSubtextString()).thenReturn(deviceStatus); @@ -491,7 +491,7 @@ public class MediaOutputAdapterTest extends SysuiTestCase { @Test public void subStatusSupported_onBindViewHolder_bindDeviceWithAdPlaying_verifyView() { String deviceStatus = (String) mContext.getText( - R.string.media_output_status_try_after_ad); + com.android.settingslib.R.string.media_output_status_try_after_ad); when(mMediaDevice2.hasSubtext()).thenReturn(true); when(mMediaDevice2.getSubtext()).thenReturn(SUBTEXT_AD_ROUTING_DISALLOWED); when(mMediaDevice2.getSubtextString()).thenReturn(deviceStatus); diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java index db00e0927886..9dfb5a5dcb3d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java @@ -47,7 +47,7 @@ import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastSender; diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java index f25454c19ac9..e7400e7ba454 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java @@ -50,7 +50,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import com.android.settingslib.media.BluetoothMediaDevice; import com.android.settingslib.media.LocalMediaManager; import com.android.settingslib.media.MediaDevice; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastSender; 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 19315803c740..ce999cb41e60 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 @@ -71,7 +71,7 @@ import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.media.LocalMediaManager; import com.android.settingslib.media.MediaDevice; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.DialogLaunchAnimator; diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java index bfc8c83c1c2a..379136b0586f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java @@ -49,7 +49,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import com.android.settingslib.media.LocalMediaManager; import com.android.settingslib.media.MediaDevice; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastSender; diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt index b09fc558d050..53e9dc814161 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt @@ -27,7 +27,7 @@ import android.media.AudioManager.MuteAwaitConnectionCallback.EVENT_CONNECTION import androidx.test.filters.SmallTest import com.android.settingslib.media.DeviceIconUtil import com.android.settingslib.media.LocalMediaManager -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.any diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt index 6c3d6f533ace..5c6d9131e1f0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt @@ -20,7 +20,7 @@ import android.content.pm.ApplicationInfo import android.content.pm.PackageManager import android.graphics.drawable.Drawable import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt index 2b66e7b3cd80..e2be4cbab14d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt @@ -33,7 +33,7 @@ import android.widget.ImageView import androidx.test.filters.SmallTest import com.android.internal.logging.InstanceId import com.android.internal.logging.testing.UiEventLoggerFake -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager import com.android.systemui.media.taptotransfer.MediaTttFlags 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 c7a74da0a87d..83145bd8bee8 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 @@ -35,7 +35,7 @@ import android.widget.TextView import androidx.test.filters.SmallTest import com.android.internal.logging.testing.UiEventLoggerFake import com.android.internal.statusbar.IUndoMediaTransferCallback -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector import com.android.systemui.common.shared.model.Text.Companion.loadText diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt index b396cafb28d5..d0c6d7cddc46 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt @@ -21,7 +21,7 @@ import android.app.NotificationManager import android.os.Handler import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.mediaprojection.taskswitcher.data.repository.ActivityTaskManagerTasksRepository import com.android.systemui.mediaprojection.taskswitcher.data.repository.FakeActivityTaskManager diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskBubblesServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskBubblesServiceTest.kt index baac9e020280..06127a7d83e7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskBubblesServiceTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskBubblesServiceTest.kt @@ -21,7 +21,7 @@ import android.graphics.drawable.Icon import android.os.UserHandle import androidx.test.filters.SmallTest import androidx.test.runner.AndroidJUnit4 -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.notetask.NoteTaskBubblesController.NoteTaskBubblesService import com.android.wm.shell.bubbles.Bubbles 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 b50032fb073b..cf43b2e12283 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt @@ -45,7 +45,7 @@ import android.provider.Settings import androidx.test.ext.truth.content.IntentSubject.assertThat import androidx.test.filters.SmallTest import androidx.test.runner.AndroidJUnit4 -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.notetask.NoteTaskController.Companion.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE import com.android.systemui.notetask.NoteTaskController.Companion.SHORTCUT_ID diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt index 58c762e3cc99..119ffd28bebe 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt @@ -28,7 +28,7 @@ import android.os.UserManager import android.test.suitebuilder.annotation.SmallTest import android.testing.AndroidTestingRunner import com.android.dx.mockito.inline.extended.ExtendedMockito -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java index bd913bab6f65..30d66dc8b040 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java @@ -58,7 +58,7 @@ import android.util.DisplayMetrics; import androidx.test.filters.SmallTest; import com.android.internal.appwidget.IAppWidgetService; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.people.widget.PeopleSpaceWidgetManager; import com.android.systemui.people.widget.PeopleTileKey; diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java index e6b960d75215..d0e8cce8559c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java @@ -60,7 +60,7 @@ import android.widget.TextView; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.people.widget.PeopleTileKey; diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java index e669d0697004..a63b2211f71a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java @@ -101,7 +101,7 @@ import android.text.TextUtils; import androidx.preference.PreferenceManager; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.people.PeopleBackupFollowUpJob; import com.android.systemui.people.PeopleSpaceUtils; diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java index b9ee19b9eaf2..2bdad2bc49a9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java @@ -45,7 +45,7 @@ import android.testing.TestableLooper.RunWithLooper; import android.testing.TestableResources; import com.android.settingslib.fuelgauge.Estimate; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.keyguard.WakefulnessLifecycle; diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt index 1d687b141d1e..b7541456a76c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt @@ -22,7 +22,7 @@ import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import org.junit.After diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogV2Test.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogV2Test.kt index f4644a578d24..6c01ba5b145b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogV2Test.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogV2Test.kt @@ -24,7 +24,7 @@ import android.view.ViewGroup import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.widget.TextView import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import org.junit.After diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt index bf237abba8fa..8c5d99a84411 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt @@ -5,7 +5,7 @@ import android.testing.TestableLooper import android.view.View import android.widget.FrameLayout import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.qs.customize.QSCustomizer import com.android.systemui.util.mockito.eq diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java index d9db60d77077..98e803f15561 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java @@ -34,7 +34,7 @@ import android.widget.TextView; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.retail.data.repository.FakeRetailModeRepository; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java index 8afe095cbaf0..c4c233ca5eef 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java @@ -48,7 +48,7 @@ import androidx.lifecycle.Lifecycle; import androidx.test.filters.SmallTest; import com.android.keyguard.BouncerPanelExpansionCalculator; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiBaseFragmentTest; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java index 24cd3e7de5b5..e2ac7bc4fc6e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java @@ -42,7 +42,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.testing.UiEventLoggerFake; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; import com.android.systemui.media.controls.ui.MediaHost; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt index 4cb194443112..5e4c954a0b26 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt @@ -7,7 +7,7 @@ import android.testing.TestableResources import android.view.ContextThemeWrapper import com.android.internal.logging.MetricsLogger import com.android.internal.logging.UiEventLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager import com.android.systemui.media.controls.ui.MediaHost diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt index 1df504a668f4..cc48640b15bc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt @@ -26,7 +26,7 @@ import android.view.accessibility.AccessibilityNodeInfo import android.widget.FrameLayout import android.widget.LinearLayout import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.plugins.qs.QSTile import com.android.systemui.plugins.qs.QSTileView diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java index 2dc78a323f55..fbf3724c1d38 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java @@ -53,7 +53,7 @@ import android.widget.TextView; import androidx.annotation.Nullable; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.animation.Expandable; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java index 64d3b822f13c..b595e8de3bad 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java @@ -48,7 +48,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.MetricsLogger; import com.android.internal.util.CollectionUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.dump.nano.SystemUIProtoDump; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt index 9bd3b7979946..2db79c2dc527 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt @@ -22,7 +22,7 @@ import android.view.ContextThemeWrapper import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger import com.android.internal.logging.testing.UiEventLoggerFake -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager import com.android.systemui.media.controls.ui.MediaHost diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java index 4a15d746eb32..f809259eedc1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java @@ -39,7 +39,7 @@ import android.view.accessibility.AccessibilityNodeInfo; import androidx.test.runner.AndroidJUnit4; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.qs.tileimpl.QSTileViewImpl; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterDelegateTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterDelegateTest.java index a5dead0f3258..6cad985c7b57 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterDelegateTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterDelegateTest.java @@ -31,7 +31,7 @@ import android.view.accessibility.AccessibilityNodeInfo; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java index 2eed38fcb767..bde30382ba05 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java @@ -50,7 +50,7 @@ import androidx.annotation.Nullable; import androidx.test.filters.SmallTest; import com.android.internal.logging.InstanceId; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.qs.QSHost; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt index 244f627c46b8..126dd633108e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt @@ -34,7 +34,7 @@ import android.testing.TestableLooper import android.view.IWindowManager import android.view.View import com.android.internal.logging.MetricsLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.animation.ActivityLaunchAnimator import com.android.systemui.animation.view.LaunchableFrameLayout diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileColorPickerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileColorPickerTest.java index ec8552b7f394..b8e6403696a5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileColorPickerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileColorPickerTest.java @@ -23,7 +23,7 @@ import android.test.suitebuilder.annotation.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt index fb17fc0a0595..365e8a5187d4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt @@ -23,7 +23,7 @@ import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.plugins.qs.QSTileView import com.google.common.truth.Truth.assertThat diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModelTest.kt index d647d6add512..4ada44c40f49 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModelTest.kt @@ -25,7 +25,7 @@ import android.view.ContextThemeWrapper import androidx.test.filters.SmallTest import com.android.settingslib.Utils import com.android.settingslib.drawable.UserIconDrawable -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.common.shared.model.ContentDescription diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt index aef5fafe05ba..1c28e4c022a6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt @@ -19,7 +19,7 @@ package com.android.systemui.qs.pipeline.data.repository import android.provider.Settings import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt index 6e579d46fc34..15e401d24b02 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt @@ -19,7 +19,7 @@ package com.android.systemui.qs.pipeline.domain.autoaddable import android.content.ComponentName import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.qs.pipeline.shared.TileSpec diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt index 8036cb44e45d..5ce15fa57b1f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt @@ -20,7 +20,7 @@ import android.content.ComponentName import android.content.pm.PackageManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt index 780c56cf7c52..e0fff9c10873 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt @@ -27,7 +27,7 @@ import android.view.View import android.view.accessibility.AccessibilityNodeInfo import android.widget.TextView import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.plugins.qs.QSTile import com.google.common.truth.Truth.assertThat diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt index b8d018f5f850..f2400ec85feb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt @@ -18,7 +18,7 @@ package com.android.systemui.qs.tileimpl import android.testing.AndroidTestingRunner import androidx.test.filters.MediumTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import org.junit.Assert.assertEquals diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt index c60cecb29d75..e2a3fac60ee8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt @@ -22,7 +22,7 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.classifier.FalsingManagerFake diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt index ff6814c06001..605dc1402fc3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt @@ -24,7 +24,7 @@ import android.testing.TestableLooper.RunWithLooper import android.view.View import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingManagerFake import com.android.systemui.plugins.ActivityStarter diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt index e5c55d8b6c56..82ee99a29427 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt @@ -11,9 +11,10 @@ import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger import com.android.settingslib.Utils import com.android.settingslib.bluetooth.CachedBluetoothDevice -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingManagerFake +import com.android.systemui.flags.FeatureFlagsClassic import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.qs.QSTile @@ -22,6 +23,7 @@ import com.android.systemui.qs.QSHost import com.android.systemui.qs.QsEventLogger import com.android.systemui.qs.logging.QSLogger import com.android.systemui.qs.tileimpl.QSTileImpl +import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialogViewModel import com.android.systemui.statusbar.policy.BluetoothController import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq @@ -50,6 +52,8 @@ class BluetoothTileTest : SysuiTestCase() { @Mock private lateinit var activityStarter: ActivityStarter @Mock private lateinit var bluetoothController: BluetoothController @Mock private lateinit var uiEventLogger: QsEventLogger + @Mock private lateinit var featureFlags: FeatureFlagsClassic + @Mock private lateinit var bluetoothTileDialogViewModel: BluetoothTileDialogViewModel private lateinit var testableLooper: TestableLooper private lateinit var tile: FakeBluetoothTile @@ -73,6 +77,8 @@ class BluetoothTileTest : SysuiTestCase() { activityStarter, qsLogger, bluetoothController, + featureFlags, + bluetoothTileDialogViewModel ) tile.initialize() @@ -220,6 +226,8 @@ class BluetoothTileTest : SysuiTestCase() { activityStarter: ActivityStarter, qsLogger: QSLogger, bluetoothController: BluetoothController, + featureFlags: FeatureFlagsClassic, + bluetoothTileDialogViewModel: BluetoothTileDialogViewModel ) : BluetoothTile( qsHost, @@ -232,6 +240,8 @@ class BluetoothTileTest : SysuiTestCase() { activityStarter, qsLogger, bluetoothController, + featureFlags, + bluetoothTileDialogViewModel ) { var restrictionChecked: String? = null diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt index 70d82fdb6e5a..c4cf3425ed76 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt @@ -21,7 +21,7 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingManagerFake import com.android.systemui.plugins.ActivityStarter diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java index 2e02bbe2ebf2..c93ff4b61f45 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java @@ -32,7 +32,7 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DataSaverTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DataSaverTileTest.kt index 176b33fa9fc8..51e95be3611b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DataSaverTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DataSaverTileTest.kt @@ -21,7 +21,7 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.animation.DialogLaunchAnimator import com.android.systemui.classifier.FalsingManagerFake diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt index 1346069d3c25..bce4c06d320f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt @@ -27,7 +27,7 @@ import android.testing.TestableLooper import androidx.lifecycle.LifecycleOwner import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.animation.ActivityLaunchAnimator import com.android.systemui.classifier.FalsingManagerFake diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt index 77a443666442..5dd297ca1bdc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt @@ -29,7 +29,7 @@ import android.view.ContextThemeWrapper import android.view.View import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.animation.DialogLaunchAnimator import com.android.systemui.classifier.FalsingManagerFake diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java index f231c6e56096..a0c107340dcd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java @@ -41,7 +41,7 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.classifier.FalsingManagerFake; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt index 73aa6991c18a..c1a09288d8a2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt @@ -6,7 +6,7 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingManagerFake import com.android.systemui.plugins.ActivityStarter diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java index 73f61d0690e2..14dfdea6fbc9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java @@ -31,7 +31,7 @@ import androidx.test.filters.SmallTest; import com.android.dx.mockito.inline.extended.ExtendedMockito; import com.android.internal.logging.MetricsLogger; import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.plugins.ActivityStarter; @@ -116,7 +116,7 @@ public class HotspotTileTest extends SysuiTestCase { assertThat(mState.state).isNotEqualTo(Tile.STATE_UNAVAILABLE); assertThat(String.valueOf(mState.secondaryLabel)) - .isNotEqualTo(mContext.getString(R.string.wifitrackerlib_admin_restricted_network)); + .isNotEqualTo(mContext.getString(com.android.wifitrackerlib.R.string.wifitrackerlib_admin_restricted_network)); mockitoSession.finishMocking(); } @@ -131,7 +131,7 @@ public class HotspotTileTest extends SysuiTestCase { assertThat(mState.state).isEqualTo(Tile.STATE_UNAVAILABLE); assertThat(String.valueOf(mState.secondaryLabel)) - .isEqualTo(mContext.getString(R.string.wifitrackerlib_admin_restricted_network)); + .isEqualTo(mContext.getString(com.android.wifitrackerlib.R.string.wifitrackerlib_admin_restricted_network)); mockitoSession.finishMocking(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt index b6cf459f579c..83f8f180ae9d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt @@ -22,7 +22,7 @@ import android.testing.TestableLooper import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingManagerFake import com.android.systemui.plugins.ActivityStarter diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileTest.java index 7957c6a7cfb6..c1f19645e4a7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileTest.java @@ -29,7 +29,7 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt index 0bf0b38f7471..62a50e369b7d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt @@ -22,7 +22,7 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingManagerFake import com.android.systemui.plugins.ActivityStarter diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt index ceff546106f4..3511bb31c443 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt @@ -21,7 +21,7 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingManagerFake import com.android.systemui.plugins.ActivityStarter diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NfcTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NfcTileTest.java index 763a7e5e4e06..118ad2c258a2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NfcTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NfcTileTest.java @@ -30,7 +30,7 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.classifier.FalsingManagerFake; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NightDisplayTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NightDisplayTileTest.kt index 6c8f76b48f03..a1d9e4149b95 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NightDisplayTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NightDisplayTileTest.kt @@ -23,7 +23,7 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingManagerFake import com.android.systemui.dagger.NightDisplayListenerModule diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java index 71aa7a8d0015..7b3171dbedd0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java @@ -30,7 +30,7 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java index dd55baddc2d9..2d18f9293ec8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java @@ -58,7 +58,7 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java index d2445944c182..c5721ffb912d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java @@ -32,7 +32,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.R; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R.drawable; +import com.android.systemui.res.R.drawable; import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java index 41545fc2abfd..df6993d11447 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java @@ -33,7 +33,7 @@ import android.testing.TestableLooper; import android.testing.TestableResources; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java index fff2b8f5f8cd..5b3d45bb6625 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java @@ -35,7 +35,7 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; import com.android.internal.logging.MetricsLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.classifier.FalsingManagerFake; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt index 79147e7e66b4..47fc3ec51078 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt @@ -25,7 +25,7 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingManagerFake import com.android.systemui.plugins.ActivityStarter diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt index 18e40f633955..f9d69c2cce64 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt @@ -26,7 +26,7 @@ import android.view.ViewGroup import androidx.test.filters.SmallTest import com.android.internal.logging.testing.UiEventLoggerFake import com.android.internal.util.UserIcons -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingManagerFake import com.android.systemui.qs.QSUserSwitcherEvent diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java index df037c0661f3..8004c6de1602 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java @@ -20,7 +20,7 @@ import android.widget.LinearLayout; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.wifitrackerlib.WifiEntry; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java index 25684ce23330..6dc7a064af15 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java @@ -63,7 +63,7 @@ import com.android.internal.logging.UiEventLogger; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.settingslib.wifi.WifiUtils; import com.android.settingslib.wifi.dpp.WifiDppIntentHelper; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastDispatcher; @@ -983,7 +983,7 @@ public class InternetDialogControllerTest extends SysuiTestCase { spyController.mCarrierNetworkChangeMode = true; String dds = spyController.getMobileNetworkSummary(SUB_ID); - assertThat(dds).contains(mContext.getString(R.string.carrier_network_change_mode)); + assertThat(dds).contains(mContext.getString(com.android.settingslib.R.string.carrier_network_change_mode)); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java index 2c74d4fa9748..039e58a64eb5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java @@ -33,7 +33,7 @@ import androidx.test.filters.SmallTest; import com.android.dx.mockito.inline.extended.ExtendedMockito; import com.android.internal.logging.UiEventLogger; import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.statusbar.policy.KeyguardStateController; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothStateInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothStateInteractorTest.kt new file mode 100644 index 000000000000..fc2b7a64957d --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothStateInteractorTest.kt @@ -0,0 +1,95 @@ +/* + * 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.qs.tiles.dialog.bluetooth + +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import androidx.test.filters.SmallTest +import com.android.settingslib.bluetooth.LocalBluetoothAdapter +import com.android.settingslib.bluetooth.LocalBluetoothManager +import com.android.systemui.SysuiTestCase +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.never +import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` +import org.mockito.junit.MockitoJUnit +import org.mockito.junit.MockitoRule + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +class BluetoothStateInteractorTest : SysuiTestCase() { + @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule() + private val testScope = TestScope() + + private lateinit var bluetoothStateInteractor: BluetoothStateInteractor + + @Mock private lateinit var bluetoothAdapter: LocalBluetoothAdapter + @Mock private lateinit var localBluetoothManager: LocalBluetoothManager + + @Before + fun setUp() { + bluetoothStateInteractor = + BluetoothStateInteractor(localBluetoothManager, testScope.backgroundScope) + `when`(localBluetoothManager.bluetoothAdapter).thenReturn(bluetoothAdapter) + } + + @Test + fun testGet_isBluetoothEnabled() { + testScope.runTest { + `when`(bluetoothAdapter.isEnabled).thenReturn(true) + + assertThat(bluetoothStateInteractor.isBluetoothEnabled).isTrue() + } + } + + @Test + fun testGet_isBluetoothDisabled() { + testScope.runTest { + `when`(bluetoothAdapter.isEnabled).thenReturn(false) + + assertThat(bluetoothStateInteractor.isBluetoothEnabled).isFalse() + } + } + + @Test + fun testSet_bluetoothEnabled() { + testScope.runTest { + `when`(bluetoothAdapter.isEnabled).thenReturn(false) + + bluetoothStateInteractor.isBluetoothEnabled = true + verify(bluetoothAdapter).enable() + } + } + + @Test + fun testSet_bluetoothNoChange() { + testScope.runTest { + `when`(bluetoothAdapter.isEnabled).thenReturn(false) + + bluetoothStateInteractor.isBluetoothEnabled = false + verify(bluetoothAdapter, never()).enable() + } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogRepositoryTest.kt new file mode 100644 index 000000000000..da8f60a9b926 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogRepositoryTest.kt @@ -0,0 +1,79 @@ +/* + * 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.qs.tiles.dialog.bluetooth + +import android.bluetooth.BluetoothAdapter +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import androidx.test.filters.SmallTest +import com.android.settingslib.bluetooth.CachedBluetoothDevice +import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager +import com.android.settingslib.bluetooth.LocalBluetoothManager +import com.android.systemui.SysuiTestCase +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.junit.MockitoJUnit +import org.mockito.junit.MockitoRule + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +class BluetoothTileDialogRepositoryTest : SysuiTestCase() { + + @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule() + + @Mock private lateinit var localBluetoothManager: LocalBluetoothManager + + @Mock private lateinit var bluetoothAdapter: BluetoothAdapter + + @Mock private lateinit var cachedDeviceManager: CachedBluetoothDeviceManager + + @Mock private lateinit var cachedDevicesCopy: Collection<CachedBluetoothDevice> + + private lateinit var repository: BluetoothTileDialogRepository + + @Before + fun setUp() { + `when`(localBluetoothManager.cachedDeviceManager).thenReturn(cachedDeviceManager) + `when`(cachedDeviceManager.cachedDevicesCopy).thenReturn(cachedDevicesCopy) + + repository = BluetoothTileDialogRepository(localBluetoothManager, bluetoothAdapter) + } + + @Test + fun testCachedDevices_bluetoothOff_emptyList() { + `when`(bluetoothAdapter.isEnabled).thenReturn(false) + + val result = repository.cachedDevices + + assertThat(result).isEmpty() + } + + @Test + fun testCachedDevices_bluetoothOn_returnDevice() { + `when`(bluetoothAdapter.isEnabled).thenReturn(true) + + val result = repository.cachedDevices + + assertThat(result).isEqualTo(cachedDevicesCopy) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogTest.kt new file mode 100644 index 000000000000..e1d177db2322 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogTest.kt @@ -0,0 +1,163 @@ +/* + * 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.qs.tiles.dialog.bluetooth + +import android.graphics.drawable.Drawable +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import android.view.LayoutInflater +import android.view.View +import android.view.View.GONE +import android.view.View.VISIBLE +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import androidx.test.filters.SmallTest +import com.android.settingslib.bluetooth.CachedBluetoothDevice +import com.android.systemui.SysuiTestCase +import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialog.Companion.DISABLED_ALPHA +import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialog.Companion.ENABLED_ALPHA +import com.android.systemui.res.R +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.junit.MockitoJUnit +import org.mockito.junit.MockitoRule + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +class BluetoothTileDialogTest : SysuiTestCase() { + companion object { + const val DEVICE_NAME = "device" + const val DEVICE_CONNECTION_SUMMARY = "active" + const val ENABLED = true + } + + @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule() + + @Mock private lateinit var cachedBluetoothDevice: CachedBluetoothDevice + + @Mock private lateinit var bluetoothTileDialogCallback: BluetoothTileDialogCallback + + @Mock private lateinit var drawable: Drawable + + private lateinit var icon: Pair<Drawable, String> + private lateinit var bluetoothTileDialog: BluetoothTileDialog + private lateinit var deviceItem: DeviceItem + + @Before + fun setUp() { + bluetoothTileDialog = BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, mContext) + icon = Pair(drawable, DEVICE_NAME) + deviceItem = + DeviceItem( + type = DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE, + cachedBluetoothDevice = cachedBluetoothDevice, + deviceName = DEVICE_NAME, + connectionSummary = DEVICE_CONNECTION_SUMMARY, + iconWithDescription = icon, + background = null + ) + `when`(cachedBluetoothDevice.isBusy).thenReturn(false) + } + + @Test + fun testShowDialog_createRecyclerViewWithAdapter() { + bluetoothTileDialog.show() + + val recyclerView = bluetoothTileDialog.findViewById<RecyclerView>(R.id.device_list) + + assertThat(bluetoothTileDialog.isShowing).isTrue() + assertThat(recyclerView).isNotNull() + assertThat(recyclerView?.visibility).isEqualTo(VISIBLE) + assertThat(recyclerView?.adapter).isNotNull() + assertThat(recyclerView?.layoutManager is LinearLayoutManager).isTrue() + } + + @Test + fun testShowDialog_displayBluetoothDevice() { + bluetoothTileDialog = BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, mContext) + bluetoothTileDialog.show() + bluetoothTileDialog.onDeviceItemUpdated(listOf(deviceItem), false) + + val recyclerView = bluetoothTileDialog.findViewById<RecyclerView>(R.id.device_list) + val adapter = recyclerView?.adapter as BluetoothTileDialog.Adapter + assertThat(adapter.itemCount).isEqualTo(1) + assertThat(adapter.getItem(0).deviceName).isEqualTo(DEVICE_NAME) + assertThat(adapter.getItem(0).connectionSummary).isEqualTo(DEVICE_CONNECTION_SUMMARY) + assertThat(adapter.getItem(0).iconWithDescription).isEqualTo(icon) + } + + @Test + fun testDeviceItemViewHolder_cachedDeviceNotBusy() { + deviceItem.isEnabled = true + deviceItem.alpha = ENABLED_ALPHA + + val view = + LayoutInflater.from(mContext).inflate(R.layout.bluetooth_device_item, null, false) + val viewHolder = + BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, mContext) + .Adapter() + .DeviceItemViewHolder(view) + viewHolder.bind(deviceItem, 0) + val container = view.findViewById<View>(R.id.bluetooth_device) + + assertThat(container).isNotNull() + assertThat(container!!.isEnabled).isTrue() + assertThat(container.alpha).isEqualTo(ENABLED_ALPHA) + assertThat(container.hasOnClickListeners()).isTrue() + } + + @Test + fun testDeviceItemViewHolder_cachedDeviceBusy() { + deviceItem.isEnabled = false + deviceItem.alpha = DISABLED_ALPHA + + val view = + LayoutInflater.from(mContext).inflate(R.layout.bluetooth_device_item, null, false) + val viewHolder = + BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, mContext) + .Adapter() + .DeviceItemViewHolder(view) + viewHolder.bind(deviceItem, 0) + val container = view.findViewById<View>(R.id.bluetooth_device) + + assertThat(container).isNotNull() + assertThat(container!!.isEnabled).isFalse() + assertThat(container.alpha).isEqualTo(DISABLED_ALPHA) + assertThat(container.hasOnClickListeners()).isTrue() + } + + @Test + fun testOnDeviceUpdated_hideSeeAll() { + bluetoothTileDialog = BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, mContext) + bluetoothTileDialog.show() + bluetoothTileDialog.onDeviceItemUpdated(listOf(deviceItem), false) + + val seeAllLayout = bluetoothTileDialog.findViewById<View>(R.id.see_all_layout) + val recyclerView = bluetoothTileDialog.findViewById<RecyclerView>(R.id.device_list) + val adapter = recyclerView?.adapter as BluetoothTileDialog.Adapter + + assertThat(seeAllLayout).isNotNull() + assertThat(seeAllLayout!!.visibility).isEqualTo(GONE) + assertThat(adapter.itemCount).isEqualTo(1) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModelTest.kt new file mode 100644 index 000000000000..975f1e25ba9d --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModelTest.kt @@ -0,0 +1,143 @@ +/* + * 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.qs.tiles.dialog.bluetooth + +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import android.widget.LinearLayout +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.animation.DialogLaunchAnimator +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.nullable +import com.android.systemui.util.time.FakeSystemClock +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.test.TestCoroutineScheduler +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.anyBoolean +import org.mockito.Mockito.never +import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` +import org.mockito.junit.MockitoJUnit +import org.mockito.junit.MockitoRule + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +class BluetoothTileDialogViewModelTest : SysuiTestCase() { + + @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule() + private val fakeSystemClock = FakeSystemClock() + private val backgroundExecutor = FakeExecutor(fakeSystemClock) + + private lateinit var bluetoothTileDialogViewModel: BluetoothTileDialogViewModel + + @Mock private lateinit var bluetoothStateInteractor: BluetoothStateInteractor + + @Mock private lateinit var deviceItemInteractor: DeviceItemInteractor + + @Mock private lateinit var dialogLaunchAnimator: DialogLaunchAnimator + + private lateinit var scheduler: TestCoroutineScheduler + private lateinit var dispatcher: CoroutineDispatcher + private lateinit var testScope: TestScope + + @Before + fun setUp() { + scheduler = TestCoroutineScheduler() + dispatcher = UnconfinedTestDispatcher(scheduler) + testScope = TestScope(dispatcher) + bluetoothTileDialogViewModel = + BluetoothTileDialogViewModel( + deviceItemInteractor, + bluetoothStateInteractor, + dialogLaunchAnimator, + testScope.backgroundScope, + dispatcher, + ) + `when`(deviceItemInteractor.deviceItemFlow).thenReturn(MutableStateFlow(null).asStateFlow()) + `when`(bluetoothStateInteractor.updateBluetoothStateFlow) + .thenReturn(MutableStateFlow(null).asStateFlow()) + `when`(deviceItemInteractor.updateDeviceItemsFlow) + .thenReturn(MutableStateFlow(Unit).asStateFlow()) + `when`(bluetoothStateInteractor.isBluetoothEnabled).thenReturn(true) + } + + @Test + fun testShowDialog_noAnimation() { + testScope.runTest { + bluetoothTileDialogViewModel.showDialog(context, null) + + assertThat(bluetoothTileDialogViewModel.dialog).isNotNull() + verify(dialogLaunchAnimator, never()).showFromView(any(), any(), any(), any()) + assertThat(bluetoothTileDialogViewModel.dialog?.isShowing).isTrue() + } + } + + @Test + fun testShowDialog_animated() { + testScope.runTest { + bluetoothTileDialogViewModel.showDialog(mContext, LinearLayout(mContext)) + + assertThat(bluetoothTileDialogViewModel.dialog).isNotNull() + verify(dialogLaunchAnimator).showFromView(any(), any(), nullable(), anyBoolean()) + } + } + + @Test + fun testShowDialog_animated_callInBackgroundThread() { + testScope.runTest { + backgroundExecutor.execute { + bluetoothTileDialogViewModel.showDialog(mContext, LinearLayout(mContext)) + + assertThat(bluetoothTileDialogViewModel.dialog).isNotNull() + verify(dialogLaunchAnimator).showFromView(any(), any(), nullable(), anyBoolean()) + } + } + } + + @Test + fun testShowDialog_fetchDeviceItem() { + testScope.runTest { + bluetoothTileDialogViewModel.showDialog(context, null) + + assertThat(bluetoothTileDialogViewModel.dialog).isNotNull() + verify(deviceItemInteractor).deviceItemFlow + } + } + + @Test + fun testShowDialog_withBluetoothStateValue() { + testScope.runTest { + bluetoothTileDialogViewModel.showDialog(context, null) + + assertThat(bluetoothTileDialogViewModel.dialog).isNotNull() + verify(bluetoothStateInteractor).updateBluetoothStateFlow + } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactoryTest.kt new file mode 100644 index 000000000000..34519023e316 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactoryTest.kt @@ -0,0 +1,87 @@ +/* + * 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.qs.tiles.dialog.bluetooth + +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import androidx.test.filters.SmallTest +import com.android.settingslib.bluetooth.CachedBluetoothDevice +import com.android.systemui.SysuiTestCase +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.junit.MockitoJUnit +import org.mockito.junit.MockitoRule + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +class DeviceItemFactoryTest : SysuiTestCase() { + + @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule() + + @Mock private lateinit var cachedDevice: CachedBluetoothDevice + + private val availableMediaDeviceItemFactory = AvailableMediaDeviceItemFactory() + private val connectedDeviceItemFactory = ConnectedDeviceItemFactory() + private val savedDeviceItemFactory = SavedDeviceItemFactory() + + @Before + fun setup() { + `when`(cachedDevice.name).thenReturn(DEVICE_NAME) + `when`(cachedDevice.connectionSummary).thenReturn(CONNECTION_SUMMARY) + } + + @Test + fun testAvailableMediaDeviceItemFactory_createFromCachedDevice() { + val deviceItem = availableMediaDeviceItemFactory.create(context, cachedDevice) + + assertDeviceItem(deviceItem, DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE) + } + + @Test + fun testConnectedDeviceItemFactory_createFromCachedDevice() { + val deviceItem = connectedDeviceItemFactory.create(context, cachedDevice) + + assertDeviceItem(deviceItem, DeviceItemType.CONNECTED_BLUETOOTH_DEVICE) + } + + @Test + fun testSavedDeviceItemFactory_createFromCachedDevice() { + val deviceItem = savedDeviceItemFactory.create(context, cachedDevice) + + assertDeviceItem(deviceItem, DeviceItemType.SAVED_BLUETOOTH_DEVICE) + assertThat(deviceItem.background).isNull() + } + + private fun assertDeviceItem(deviceItem: DeviceItem?, deviceItemType: DeviceItemType) { + assertThat(deviceItem).isNotNull() + assertThat(deviceItem!!.type).isEqualTo(deviceItemType) + assertThat(deviceItem.cachedBluetoothDevice).isEqualTo(cachedDevice) + assertThat(deviceItem.deviceName).isEqualTo(DEVICE_NAME) + assertThat(deviceItem.connectionSummary).isEqualTo(CONNECTION_SUMMARY) + } + + companion object { + const val DEVICE_NAME = "DeviceName" + const val CONNECTION_SUMMARY = "ConnectionSummary" + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractorTest.kt new file mode 100644 index 000000000000..df9914a8d012 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractorTest.kt @@ -0,0 +1,217 @@ +/* + * 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.qs.tiles.dialog.bluetooth + +import android.bluetooth.BluetoothAdapter +import android.bluetooth.BluetoothDevice +import android.content.Context +import android.media.AudioManager +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import androidx.test.filters.SmallTest +import com.android.settingslib.bluetooth.CachedBluetoothDevice +import com.android.settingslib.bluetooth.LocalBluetoothManager +import com.android.systemui.SysuiTestCase +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.junit.MockitoJUnit +import org.mockito.junit.MockitoRule + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +class DeviceItemInteractorTest : SysuiTestCase() { + + @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule() + + @Mock private lateinit var bluetoothTileDialogRepository: BluetoothTileDialogRepository + + @Mock private lateinit var cachedDevice1: CachedBluetoothDevice + + @Mock private lateinit var cachedDevice2: CachedBluetoothDevice + + @Mock private lateinit var device1: BluetoothDevice + + @Mock private lateinit var device2: BluetoothDevice + + @Mock private lateinit var deviceItem1: DeviceItem + + @Mock private lateinit var deviceItem2: DeviceItem + + @Mock private lateinit var audioManager: AudioManager + + @Mock private lateinit var adapter: BluetoothAdapter + + @Mock private lateinit var localBluetoothManager: LocalBluetoothManager + + private lateinit var interactor: DeviceItemInteractor + + private lateinit var dispatcher: CoroutineDispatcher + + private lateinit var testScope: TestScope + + @Before + fun setUp() { + dispatcher = StandardTestDispatcher() + testScope = TestScope(dispatcher) + interactor = + DeviceItemInteractor( + bluetoothTileDialogRepository, + audioManager, + adapter, + localBluetoothManager, + testScope.backgroundScope, + dispatcher + ) + + `when`(deviceItem1.cachedBluetoothDevice).thenReturn(cachedDevice1) + `when`(deviceItem2.cachedBluetoothDevice).thenReturn(cachedDevice2) + `when`(cachedDevice1.device).thenReturn(device1) + `when`(cachedDevice2.device).thenReturn(device2) + `when`(bluetoothTileDialogRepository.cachedDevices) + .thenReturn(listOf(cachedDevice1, cachedDevice2)) + } + + @Test + fun testUpdateDeviceItems_noCachedDevice_returnEmpty() { + testScope.runTest { + `when`(bluetoothTileDialogRepository.cachedDevices).thenReturn(emptyList()) + interactor.setDeviceItemFactoryListForTesting( + listOf(createFactory({ true }, deviceItem1)) + ) + + interactor.updateDeviceItems(mContext) + + assertThat(interactor.deviceItemFlow.value).isEmpty() + } + } + + @Test + fun testUpdateDeviceItems_hasCachedDevice_filterNotMatch_returnEmpty() { + testScope.runTest { + `when`(bluetoothTileDialogRepository.cachedDevices).thenReturn(listOf(cachedDevice1)) + interactor.setDeviceItemFactoryListForTesting( + listOf(createFactory({ false }, deviceItem1)) + ) + + interactor.updateDeviceItems(mContext) + + assertThat(interactor.deviceItemFlow.value).isEmpty() + } + } + + @Test + fun testUpdateDeviceItems_hasCachedDevice_filterMatch_returnDeviceItem() { + testScope.runTest { + `when`(bluetoothTileDialogRepository.cachedDevices).thenReturn(listOf(cachedDevice1)) + interactor.setDeviceItemFactoryListForTesting( + listOf(createFactory({ true }, deviceItem1)) + ) + + interactor.updateDeviceItems(mContext) + + assertThat(interactor.deviceItemFlow.value).hasSize(1) + assertThat(interactor.deviceItemFlow.value!![0]).isEqualTo(deviceItem1) + } + } + + @Test + fun testUpdateDeviceItems_hasCachedDevice_filterMatch_returnMultipleDeviceItem() { + testScope.runTest { + `when`(adapter.mostRecentlyConnectedDevices).thenReturn(null) + interactor.setDeviceItemFactoryListForTesting( + listOf(createFactory({ false }, deviceItem1), createFactory({ true }, deviceItem2)) + ) + + interactor.updateDeviceItems(mContext) + + assertThat(interactor.deviceItemFlow.value).hasSize(2) + assertThat(interactor.deviceItemFlow.value!![0]).isEqualTo(deviceItem2) + assertThat(interactor.deviceItemFlow.value!![1]).isEqualTo(deviceItem2) + } + } + + @Test + fun testUpdateDeviceItems_sortByDisplayPriority() { + testScope.runTest { + `when`(adapter.mostRecentlyConnectedDevices).thenReturn(null) + interactor.setDeviceItemFactoryListForTesting( + listOf( + createFactory({ cachedDevice -> cachedDevice.device == device1 }, deviceItem1), + createFactory({ cachedDevice -> cachedDevice.device == device2 }, deviceItem2) + ) + ) + interactor.setDisplayPriorityForTesting( + listOf( + DeviceItemType.SAVED_BLUETOOTH_DEVICE, + DeviceItemType.CONNECTED_BLUETOOTH_DEVICE + ) + ) + `when`(deviceItem1.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE) + `when`(deviceItem2.type).thenReturn(DeviceItemType.SAVED_BLUETOOTH_DEVICE) + + interactor.updateDeviceItems(mContext) + + assertThat(interactor.deviceItemFlow.value).isEqualTo(listOf(deviceItem2, deviceItem1)) + } + } + + @Test + fun testUpdateDeviceItems_sameType_sortByRecentlyConnected() { + testScope.runTest { + `when`(adapter.mostRecentlyConnectedDevices).thenReturn(listOf(device2, device1)) + interactor.setDeviceItemFactoryListForTesting( + listOf( + createFactory({ cachedDevice -> cachedDevice.device == device1 }, deviceItem1), + createFactory({ cachedDevice -> cachedDevice.device == device2 }, deviceItem2) + ) + ) + interactor.setDisplayPriorityForTesting( + listOf(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE) + ) + `when`(deviceItem1.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE) + `when`(deviceItem2.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE) + + interactor.updateDeviceItems(mContext) + + assertThat(interactor.deviceItemFlow.value).isEqualTo(listOf(deviceItem2, deviceItem1)) + } + } + + private fun createFactory( + isFilterMatchFunc: (CachedBluetoothDevice) -> Boolean, + deviceItem: DeviceItem + ): DeviceItemFactory { + return object : DeviceItemFactory() { + override fun isFilterMatched( + cachedDevice: CachedBluetoothDevice, + audioManager: AudioManager? + ) = isFilterMatchFunc(cachedDevice) + + override fun create(context: Context, cachedDevice: CachedBluetoothDevice) = deviceItem + } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayDialogControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayDialogControllerTest.java index 55813f60aecd..c108a80d0c72 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayDialogControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayDialogControllerTest.java @@ -28,7 +28,7 @@ import android.widget.TextView; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.util.concurrency.FakeExecutor; diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt index 9c8d14de1c74..6b918c6ba15b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt @@ -22,7 +22,6 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository import com.android.systemui.authentication.domain.model.AuthenticationMethodModel as DomainLayerAuthenticationMethodModel -import com.android.systemui.authentication.domain.model.AuthenticationMethodModel import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.shared.model.WakefulnessState @@ -48,7 +47,9 @@ import com.android.systemui.util.mockito.mock import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.launch import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest @@ -159,6 +160,8 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { repository = keyguardRepository, ) + private var bouncerSceneJob: Job? = null + @Before fun setUp() { shadeHeaderViewModel = @@ -288,7 +291,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { @Test fun withAuthMethodNone_deviceWakeUp_skipsLockscreen() = testScope.runTest { - setAuthMethod(AuthenticationMethodModel.None) + setAuthMethod(DomainLayerAuthenticationMethodModel.None) putDeviceToSleep(instantlyLockDevice = false) assertCurrentScene(SceneKey.Lockscreen) @@ -299,7 +302,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { @Test fun withAuthMethodSwipe_deviceWakeUp_doesNotSkipLockscreen() = testScope.runTest { - setAuthMethod(AuthenticationMethodModel.Swipe) + setAuthMethod(DomainLayerAuthenticationMethodModel.Swipe) putDeviceToSleep(instantlyLockDevice = false) assertCurrentScene(SceneKey.Lockscreen) @@ -364,6 +367,23 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { assertCurrentScene(SceneKey.Lockscreen) } + @Test + fun dismissingIme_whileOnPasswordBouncer_navigatesToLockscreen() = + testScope.runTest { + setAuthMethod(DomainLayerAuthenticationMethodModel.Password) + val upDestinationSceneKey by + collectLastValue(lockscreenSceneViewModel.upDestinationSceneKey) + assertThat(upDestinationSceneKey).isEqualTo(SceneKey.Bouncer) + emulateUserDrivenTransition( + to = upDestinationSceneKey, + ) + + dismissIme() + + assertCurrentScene(SceneKey.Lockscreen) + emulateUiSceneTransition() + } + /** * Asserts that the current scene in the view-model matches what's expected. * @@ -396,7 +416,9 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { // Set the lockscreen enabled bit _before_ set the auth method as the code picks up on the // lockscreen enabled bit _after_ the auth method is changed and the lockscreen enabled bit // is not an observable that can trigger a new evaluation. - authenticationRepository.setLockscreenEnabled(authMethod !is AuthenticationMethodModel.None) + authenticationRepository.setLockscreenEnabled( + authMethod !is DomainLayerAuthenticationMethodModel.None + ) authenticationRepository.setAuthenticationMethod(authMethod.toDataLayer()) if (!authMethod.isSecure) { // When the auth method is not secure, the device is never considered locked. @@ -455,6 +477,19 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { assertWithMessage("Visibility mismatch after scene transition from $from to ${to.key}!") .that(sceneContainerViewModel.isVisible.value) .isEqualTo(expectedVisible) + + bouncerSceneJob = + if (to.key == SceneKey.Bouncer) { + testScope.backgroundScope.launch { + bouncerViewModel.authMethod.collect { + // Do nothing. Need this to turn this otherwise cold flow, hot. + } + } + } else { + bouncerSceneJob?.cancel() + null + } + runCurrent() } /** @@ -573,4 +608,16 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { lockDevice() } } + + /** Emulates the dismissal of the IME (soft keyboard). */ + private fun TestScope.dismissIme( + showImeBeforeDismissing: Boolean = true, + ) { + if (showImeBeforeDismissing) { + bouncerViewModel.authMethod.value?.onImeVisibilityChanged(true) + } + + bouncerViewModel.authMethod.value?.onImeVisibilityChanged(false) + runCurrent() + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt index a6c25be1e6a5..d470d24489af 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt @@ -22,7 +22,7 @@ import android.testing.TestableLooper import android.view.View import android.widget.Spinner import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentCreatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentCreatorTest.kt index ca4486b533ff..36639d4b7ca4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentCreatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentCreatorTest.kt @@ -22,7 +22,7 @@ import android.content.Intent import android.net.Uri import androidx.test.ext.truth.content.IntentSubject.assertThat as assertThatIntent import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.mock diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt index d6720568cef5..d4e8d37b3b44 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt @@ -61,19 +61,19 @@ class MessageContainerControllerTest : SysuiTestCase() { workProfileData = WorkProfileMessageController.WorkProfileFirstRunData(appName, icon) val guideline = Guideline(mContext) - guideline.id = com.android.systemui.R.id.guideline + guideline.id = com.android.systemui.res.R.id.guideline screenshotView.addView(guideline) container = FrameLayout(mContext) - container.id = com.android.systemui.R.id.screenshot_message_container + container.id = com.android.systemui.res.R.id.screenshot_message_container screenshotView.addView(container) workProfileFirstRunView = FrameLayout(mContext) - workProfileFirstRunView.id = com.android.systemui.R.id.work_profile_first_run + workProfileFirstRunView.id = com.android.systemui.res.R.id.work_profile_first_run container.addView(workProfileFirstRunView) detectionNoticeView = FrameLayout(mContext) - detectionNoticeView.id = com.android.systemui.R.id.screenshot_detection_notice + detectionNoticeView.id = com.android.systemui.res.R.id.screenshot_detection_notice container.addView(detectionNoticeView) messageContainer.setView(screenshotView) diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java index 31f7771bb939..10bd6af7ddf0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java @@ -38,7 +38,7 @@ import android.widget.TextView; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.util.FakeSharedPreferences; diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java index ab91d9fc0f8d..0f33aaf20195 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java @@ -47,7 +47,7 @@ import androidx.test.rule.ActivityTestRule; import androidx.test.runner.intercepting.SingleActivityFactory; import com.android.internal.logging.UiEventLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.screenshot.ImageExporter; import com.android.systemui.settings.UserTracker; diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java index 674ce9cab0d2..3d5552719aca 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java @@ -57,7 +57,7 @@ import androidx.test.runner.intercepting.SingleActivityFactory; import com.android.internal.infra.ServiceConnector; import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IAppClipsService; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.dagger.qualifiers.Background; diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt index ed1397ff7013..152be6529464 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt @@ -25,7 +25,7 @@ import android.view.ViewGroup import android.view.WindowManagerPolicyConstants.EXTRA_FROM_BRIGHTNESS_KEY import androidx.test.filters.SmallTest import androidx.test.rule.ActivityTestRule -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.activity.SingleActivityFactory import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt index d75405fe503f..707a2971b1eb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt @@ -40,7 +40,6 @@ import org.mockito.Mock import org.mockito.Mockito.isNull import org.mockito.Mockito.never import org.mockito.Mockito.notNull -import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations import org.mockito.Mockito.`when` as whenever @@ -61,6 +60,8 @@ class BrightnessSliderControllerTest : SysuiTestCase() { private lateinit var motionEvent: MotionEvent @Mock private lateinit var listener: ToggleSlider.Listener + @Mock + private lateinit var mBrightnessSliderHapticPlugin: BrightnessSliderHapticPlugin @Captor private lateinit var seekBarChangeCaptor: ArgumentCaptor<SeekBar.OnSeekBarChangeListener> @@ -79,7 +80,12 @@ class BrightnessSliderControllerTest : SysuiTestCase() { whenever(motionEvent.copy()).thenReturn(motionEvent) mController = - BrightnessSliderController(brightnessSliderView, mFalsingManager, uiEventLogger) + BrightnessSliderController( + brightnessSliderView, + mFalsingManager, + uiEventLogger, + mBrightnessSliderHapticPlugin, + ) mController.init() mController.setOnChangedListener(listener) } @@ -94,6 +100,7 @@ class BrightnessSliderControllerTest : SysuiTestCase() { mController.onViewAttached() verify(brightnessSliderView).setOnSeekBarChangeListener(notNull()) + verify(mBrightnessSliderHapticPlugin).start() } @Test @@ -103,6 +110,7 @@ class BrightnessSliderControllerTest : SysuiTestCase() { verify(brightnessSliderView).setOnSeekBarChangeListener(isNull()) verify(brightnessSliderView).setOnDispatchTouchEventListener(isNull()) + verify(mBrightnessSliderHapticPlugin).stop() } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImplTest.kt new file mode 100644 index 000000000000..51629b5c01e3 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderHapticPluginImplTest.kt @@ -0,0 +1,102 @@ +/* + * 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.settings.brightness + +import android.view.VelocityTracker +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.haptics.slider.SeekableSliderEventProducer +import com.android.systemui.statusbar.VibratorHelper +import com.android.systemui.util.mockito.whenever +import com.android.systemui.util.time.FakeSystemClock +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.CoroutineDispatcher +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.mockito.ArgumentMatchers.anyInt +import org.mockito.Mock +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidJUnit4::class) +class BrightnessSliderHapticPluginImplTest : SysuiTestCase() { + + @Mock private lateinit var vibratorHelper: VibratorHelper + @Mock private lateinit var velocityTracker: VelocityTracker + @Mock private lateinit var mainDispatcher: CoroutineDispatcher + + private val systemClock = FakeSystemClock() + private val sliderEventProducer = SeekableSliderEventProducer() + + private lateinit var plugin: BrightnessSliderHapticPluginImpl + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + whenever(vibratorHelper.getPrimitiveDurations(anyInt())).thenReturn(intArrayOf(0)) + } + + @Test + fun start_beginsTrackingSlider() = runTest { + createPlugin(UnconfinedTestDispatcher(testScheduler)) + plugin.start() + + assertThat(plugin.isTracking).isTrue() + } + + @Test + fun stop_stopsTrackingSlider() = runTest { + createPlugin(UnconfinedTestDispatcher(testScheduler)) + // GIVEN that the plugin started the tracking component + plugin.start() + + // WHEN called to stop + plugin.stop() + + // THEN the tracking component stops + assertThat(plugin.isTracking).isFalse() + } + + @Test + fun start_afterStop_startsTheTrackingAgain() = runTest { + createPlugin(UnconfinedTestDispatcher(testScheduler)) + // GIVEN that the plugin started the tracking component + plugin.start() + + // WHEN the plugin is restarted + plugin.stop() + plugin.start() + + // THEN the tracking begins again + assertThat(plugin.isTracking).isTrue() + } + + private fun createPlugin(dispatcher: CoroutineDispatcher) { + plugin = + BrightnessSliderHapticPluginImpl( + vibratorHelper, + systemClock, + dispatcher, + velocityTracker, + sliderEventProducer, + ) + } +} 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 0a1eca69f1ce..2b3588aa6e3c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt @@ -22,7 +22,7 @@ import androidx.constraintlayout.widget.ConstraintSet import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID import androidx.constraintlayout.widget.ConstraintSet.START import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.google.common.truth.Expect import com.google.common.truth.Truth.assertThat diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt index 38a666eeb410..bff408a7ddba 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt @@ -20,7 +20,7 @@ import android.testing.AndroidTestingRunner import android.view.View import android.view.ViewGroup import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.StatusBarState.KEYGUARD diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java index 9130bc266d11..31c8a3d77d6b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java @@ -79,7 +79,7 @@ import com.android.keyguard.dagger.KeyguardStatusBarViewComponent; import com.android.keyguard.dagger.KeyguardStatusViewComponent; import com.android.keyguard.dagger.KeyguardUserSwitcherComponent; import com.android.keyguard.logging.KeyguardLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.AuthController; import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor; 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 911cab4f9dd7..37ec7622a836 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java @@ -57,7 +57,7 @@ import androidx.test.filters.SmallTest; import com.android.keyguard.FaceAuthApiRequestReason; import com.android.systemui.DejankUtils; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.flags.Flags; import com.android.systemui.keyguard.shared.model.WakeSleepReason; import com.android.systemui.keyguard.shared.model.WakefulnessModel; diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt index b0125f8289ec..aead53e7ce9f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt @@ -25,7 +25,7 @@ import android.view.ViewStub import androidx.test.filters.SmallTest import com.android.internal.util.CollectionUtils import com.android.keyguard.KeyguardClockSwitch.LARGE -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION import com.android.systemui.statusbar.StatusBarState.KEYGUARD diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java index dfd782b73a22..2d00e8c24f33 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java @@ -46,7 +46,7 @@ import android.view.WindowManager; import androidx.test.filters.SmallTest; import com.android.internal.colorextraction.ColorExtractor; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.AuthController; import com.android.systemui.colorextraction.SysuiColorExtractor; 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 3da5f6a4b7c0..223b1c431b2d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt @@ -26,7 +26,7 @@ import com.android.keyguard.KeyguardMessageAreaController import com.android.keyguard.KeyguardSecurityContainerController import com.android.keyguard.LockIconViewController import com.android.keyguard.dagger.KeyguardBouncerComponent -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.back.domain.interactor.BackActionInteractor import com.android.systemui.bouncer.data.factory.BouncerMessageFactory diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt index 04c4b45251f2..e8170163d616 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt @@ -25,7 +25,7 @@ import com.android.keyguard.KeyguardMessageAreaController import com.android.keyguard.KeyguardSecurityContainerController import com.android.keyguard.LockIconViewController import com.android.keyguard.dagger.KeyguardBouncerComponent -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.back.domain.interactor.BackActionInteractor import com.android.systemui.bouncer.data.factory.BouncerMessageFactory diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt index e9e6d31ff214..e70dbc7f4fda 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt @@ -27,7 +27,7 @@ import androidx.annotation.IdRes import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.Flags diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt index 6801f2fb7394..ac8c924fe689 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt @@ -27,7 +27,7 @@ import androidx.annotation.IdRes import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.Flags diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt index 8bb8f6247e25..f7d2497d0bbf 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt @@ -22,7 +22,7 @@ import android.view.ViewGroup import android.widget.FrameLayout import androidx.constraintlayout.widget.ConstraintLayout import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.qs.QSFragment import com.android.systemui.util.mockito.whenever diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt index d421acac2daa..2cd740d35c14 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt @@ -6,7 +6,7 @@ import android.graphics.Rect import android.testing.AndroidTestingRunner import android.view.DisplayCutout import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.battery.BatteryMeterView import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java index 849127ed10e6..fb0d4db4840a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java @@ -34,7 +34,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.keyguard.KeyguardStatusView; import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository; import com.android.systemui.dump.DumpManager; diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java index 6d288e1db1cb..5ca45f3df472 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java @@ -41,7 +41,7 @@ import android.view.MotionEvent; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.qs.QS; import org.junit.Test; diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt index 7d5f68e783d5..56061f64c315 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt @@ -35,7 +35,7 @@ import androidx.constraintlayout.motion.widget.MotionLayout import androidx.constraintlayout.widget.ConstraintSet import androidx.test.filters.SmallTest import com.android.app.animation.Interpolators -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.animation.ShadeInterpolation import com.android.systemui.battery.BatteryMeterView diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java index dae9c975b997..a657edfada27 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java @@ -31,7 +31,7 @@ import android.widget.TextView; import androidx.test.filters.SmallTest; import com.android.settingslib.mobile.TelephonyIcons; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt index 342b1c5b1ad2..d018cbbfbc24 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt @@ -25,7 +25,7 @@ import android.os.UserManager import androidx.test.filters.SmallTest import com.android.internal.logging.UiEventLogger import com.android.keyguard.KeyguardUpdateMonitor -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository import com.android.systemui.coroutines.collectLastValue diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/LargeScreenShadeInterpolatorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/LargeScreenShadeInterpolatorImplTest.kt index 36f82c2a0e1c..a844bffc3ea3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/LargeScreenShadeInterpolatorImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/LargeScreenShadeInterpolatorImplTest.kt @@ -2,7 +2,7 @@ package com.android.systemui.shade.transition import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.policy.FakeConfigurationController import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController diff --git a/packages/SystemUI/tests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt index f5a24ff0c731..eb418fd05b5f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt @@ -22,7 +22,7 @@ import android.content.res.TypedArray import android.testing.AndroidTestingRunner import android.util.AttributeSet import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.shared.R import com.android.systemui.SysuiTestCase import com.android.systemui.shared.shadow.DoubleShadowTextClock import com.android.systemui.util.mockito.whenever diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt index e92368df8663..7b0cd19ca7f2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt @@ -20,7 +20,7 @@ import android.testing.AndroidTestingRunner import android.view.LayoutInflater import androidx.test.filters.SmallTest import com.android.app.animation.Interpolators -import com.android.systemui.R +import com.android.systemui.customization.R import com.android.systemui.SysuiTestCase import com.android.systemui.animation.TextAnimator import com.android.systemui.util.mockito.any diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt index 3f3faf7f2327..bd3dae4f5fae 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt @@ -24,7 +24,7 @@ import android.util.TypedValue import android.view.LayoutInflater import android.widget.FrameLayout import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.customization.R import com.android.systemui.SysuiTestCase import com.android.systemui.plugins.ClockSettings import com.android.systemui.shared.clocks.DefaultClockController.Companion.DOZE_COLOR diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java index 280897d8bd75..b98dc0016066 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java @@ -39,7 +39,7 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java index d44846ec45b0..63e46d1895bd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerBaseTest.java @@ -56,7 +56,7 @@ import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.logging.KeyguardLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.AuthController; import com.android.systemui.biometrics.FaceHelpMessageDeferral; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java index 1240f26c8af8..2bcad1d27b62 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java @@ -73,7 +73,7 @@ import androidx.test.filters.SmallTest; import com.android.keyguard.TrustGrantFlags; import com.android.settingslib.fuelgauge.BatteryStatus; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dock.DockManager; import com.android.systemui.keyguard.KeyguardIndication; import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt index 673d63f3a07d..0b4de345e2d7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeQsTransitionControllerTest.kt @@ -18,7 +18,7 @@ package com.android.systemui.statusbar import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.qs.QS diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt index 2c9dfcc25324..6e990a7aae23 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt @@ -6,7 +6,7 @@ import android.testing.TestableLooper import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest import com.android.systemui.ExpandHelper -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector import com.android.systemui.classifier.FalsingCollectorFake diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt index a258f67932bd..68bc72b09f94 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt @@ -23,7 +23,7 @@ import android.view.Choreographer import android.view.View import android.view.ViewRootImpl import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.animation.ShadeInterpolation import com.android.systemui.dump.DumpManager diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java index c75aa81e4c43..544860e935f5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java @@ -36,7 +36,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.statusbar.IStatusBarService; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; import com.android.systemui.statusbar.notification.collection.NotifPipeline; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java index 8d016e30c0c1..1592c3007ec8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java @@ -52,7 +52,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.util.ContrastColorUtil; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt index aab4bc361d7b..b90582575970 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt @@ -75,6 +75,18 @@ class VibratorHelperTest : SysuiTestCase() { } @Test + fun testVibrate5() { + vibratorHelper.vibrate( + mock(VibrationEffect::class.java), + mock(VibrationAttributes::class.java) + ) + verifyAsync().vibrate( + any(VibrationEffect::class.java), + any(VibrationAttributes::class.java) + ) + } + + @Test fun testPerformHapticFeedback() { val constant = HapticFeedbackConstants.CONFIRM vibratorHelper.performHapticFeedback(view, constant) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/CallbackHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/CallbackHandlerTest.java index 2d29c80a15ac..44e3bb43c4ce 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/CallbackHandlerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/CallbackHandlerTest.java @@ -29,7 +29,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.settingslib.mobile.TelephonyIcons; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.connectivity.NetworkController.EmergencyListener; -import com.android.systemui.tests.R; +import com.android.systemui.res.R; import org.junit.Before; import org.junit.Test; @@ -179,7 +179,7 @@ public class CallbackHandlerTest extends SysuiTestCase { @Test public void testSignalCallback_setIsAirplaneMode() { IconState state = - new IconState(true, R.drawable.stat_sys_airplane_mode, "Test Description"); + new IconState(true, com.android.settingslib.R.drawable.stat_sys_airplane_mode, "Test Description"); mHandler.setIsAirplaneMode(state); waitForCallbacks(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java index 35b9814cd81d..375ca0639926 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java @@ -41,7 +41,7 @@ import android.testing.TestableLooper.RunWithLooper; import com.android.settingslib.graph.SignalDrawable; import com.android.settingslib.mobile.TelephonyIcons; import com.android.settingslib.net.DataUsageController; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.dump.DumpManager; import com.android.systemui.log.LogBuffer; import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt index 88ddc2d9ef03..31e1fef76383 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt @@ -22,7 +22,7 @@ import android.app.StatusBarManager.DISABLE_NONE import android.app.StatusBarManager.DISABLE_NOTIFICATION_ALERTS import android.content.res.Configuration import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager import com.android.systemui.log.LogBufferFactory diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java index 524ead22ee94..a59ba071d7e8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicChildBindControllerTest.java @@ -32,7 +32,7 @@ import android.util.ArrayMap; import android.view.LayoutInflater; import android.view.View; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.media.dialog.MediaOutputDialogFactory; import com.android.systemui.statusbar.notification.collection.NotificationEntry; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt index 470d34037e45..d86f8bbbeb15 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt @@ -16,7 +16,7 @@ import com.android.systemui.statusbar.notification.row.NotificationTestHelper import com.android.systemui.statusbar.notification.stack.NotificationListContainer import com.android.systemui.statusbar.phone.HeadsUpManagerPhone import com.android.systemui.statusbar.policy.HeadsUpUtil -import com.android.systemui.tests.R +import com.android.systemui.res.R import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue import kotlinx.coroutines.test.TestScope diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java index f0abf2f4a24f..c664c39f4432 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java @@ -33,7 +33,7 @@ import android.view.View; import android.view.animation.Interpolator; import com.android.app.animation.Interpolators; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.notification.stack.AnimationFilter; import com.android.systemui.statusbar.notification.stack.AnimationProperties; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java index 90f6201e29d7..ccc9dc0d9618 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java @@ -50,7 +50,7 @@ import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.RankingBuilder; import com.android.systemui.statusbar.SbnBuilder; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java index daa45db6b90c..f05436f66d82 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java @@ -61,7 +61,7 @@ import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; import com.android.internal.logging.testing.UiEventLoggerFake; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.settings.UserTracker; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt index 3f61af0425de..ccef1d56c6a0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt @@ -22,7 +22,7 @@ import android.testing.TestableLooper.RunWithLooper import android.view.View import androidx.test.filters.SmallTest import com.android.settingslib.Utils -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.notification.FakeShadowView import com.android.systemui.statusbar.notification.NotificationUtils diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt index c650e01263bc..d52cbce488ec 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt @@ -23,7 +23,7 @@ import android.net.Uri import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest import com.android.internal.widget.NotificationDrawableConsumer -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.graphics.ImageLoader import com.android.systemui.util.mockito.argumentCaptor @@ -70,7 +70,7 @@ class BigPictureIconManagerTest : SysuiTestCase() { } private val unsupportedIcon by lazy { Icon.createWithBitmap( - BitmapFactory.decodeResource(context.resources, R.drawable.dessert_zombiegingerbread) + BitmapFactory.decodeResource(context.resources, R.drawable.dessert_donutburger) ) } private val invalidIcon by lazy { Icon.createWithContentUri(Uri.parse("this.is/broken")) } @@ -100,7 +100,7 @@ class BigPictureIconManagerTest : SysuiTestCase() { } @Test - fun onIconUpdated_notSupportedType_fullImageLoaded() = + fun onIconUpdated_unsupportedType_fullImageLoaded() = testScope.runTest { // WHEN update with an unsupported icon iconManager.updateIcon(mockConsumer, unsupportedIcon).run() @@ -112,6 +112,16 @@ class BigPictureIconManagerTest : SysuiTestCase() { } @Test + fun onIconUpdated_withNull_drawableIsNull() = + testScope.runTest { + // WHEN update with null + iconManager.updateIcon(mockConsumer, null).run() + + // THEN consumer is updated with null + verify(mockConsumer).setImageDrawable(null) + } + + @Test fun onIconUpdated_invalidIcon_drawableIsNull() = testScope.runTest { // WHEN update with an invalid icon @@ -153,6 +163,43 @@ class BigPictureIconManagerTest : SysuiTestCase() { } @Test + fun onIconUpdated_iconAlreadySetForTheSameIcon_loadsIconAgain() = + testScope.runTest { + // GIVEN an icon is set + iconManager.updateIcon(mockConsumer, supportedIcon).run() + // AND the view is shown + iconManager.onViewShown(true) + runCurrent() + reset(mockConsumer) + // WHEN the icon is set again + iconManager.updateIcon(mockConsumer, supportedIcon).run() + + // THEN consumer is updated with the new image + verify(mockConsumer).setImageDrawable(drawableCaptor.capture()) + assertIsFullImage(drawableCaptor.value) + assertSize(drawableCaptor.value) + } + + @Test + fun onIconUpdated_iconAlreadySetForUnsupportedIcon_loadsNewIcon() = + testScope.runTest { + // GIVEN an unsupported icon is set + iconManager.updateIcon(mockConsumer, unsupportedIcon).run() + // AND the view is shown + iconManager.onViewShown(true) + runCurrent() + reset(mockConsumer) + + // WHEN a new icon is set + iconManager.updateIcon(mockConsumer, supportedIcon).run() + + // THEN consumer is updated with the new image + verify(mockConsumer).setImageDrawable(drawableCaptor.capture()) + assertIsFullImage(drawableCaptor.value) + assertSize(drawableCaptor.value) + } + + @Test fun onIconUpdated_supportedTypeButTooWide_resizedPlaceholderLoaded() = testScope.runTest { // GIVEN the max width is smaller than our image @@ -249,12 +296,10 @@ class BigPictureIconManagerTest : SysuiTestCase() { verifyZeroInteractions(mockConsumer) } - // nice to have tests - @Test - fun onViewShown_fullImageLoaded_nothingHappens() = + fun onViewShown_unsupportedIconLoaded_nothingHappens() = testScope.runTest { - // GIVEN full image is showing + // GIVEN full image is showing for an unsupported icon iconManager.updateIcon(mockConsumer, unsupportedIcon).run() reset(mockConsumer) @@ -267,10 +312,45 @@ class BigPictureIconManagerTest : SysuiTestCase() { } @Test + fun onViewShown_nullSetForIcon_nothingHappens() = + testScope.runTest { + // GIVEN null is set for the icon + iconManager.updateIcon(mockConsumer, null).run() + reset(mockConsumer) + + // WHEN the view is shown + iconManager.onViewShown(true) + runCurrent() + + // THEN nothing happens + verifyZeroInteractions(mockConsumer) + } + + @Test + fun onViewHidden_unsupportedIconLoadedAndViewIsShown_nothingHappens() = + testScope.runTest { + // GIVEN full image is showing for an unsupported icon + iconManager.updateIcon(mockConsumer, unsupportedIcon).run() + // AND the view is shown + iconManager.onViewShown(true) + runCurrent() + reset(mockConsumer) + + // WHEN the view goes off the screen + iconManager.onViewShown(false) + // AND we wait a bit + advanceTimeBy(FREE_IMAGE_DELAY_MS) + runCurrent() + + // THEN nothing happens + verifyZeroInteractions(mockConsumer) + } + + @Test fun onViewHidden_placeholderShowing_nothingHappens() = testScope.runTest { // GIVEN placeholder image is showing - iconManager.updateIcon(mockConsumer, unsupportedIcon).run() + iconManager.updateIcon(mockConsumer, supportedIcon).run() reset(mockConsumer) // WHEN the view is hidden @@ -296,6 +376,7 @@ class BigPictureIconManagerTest : SysuiTestCase() { iconManager.onViewShown(true) runCurrent() + // THEN nothing happens verifyZeroInteractions(mockConsumer) } @@ -303,7 +384,7 @@ class BigPictureIconManagerTest : SysuiTestCase() { fun onViewHidden_alreadyHidden_nothingHappens() = testScope.runTest { // GIVEN placeholder image is showing and the view is hidden - iconManager.updateIcon(mockConsumer, unsupportedIcon).run() + iconManager.updateIcon(mockConsumer, supportedIcon).run() iconManager.onViewShown(false) advanceTimeBy(FREE_IMAGE_DELAY_MS) runCurrent() diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java index cf1d2ca2859d..c9b77c5372df 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java @@ -54,7 +54,7 @@ import android.widget.ImageView; import android.widget.TextView; import com.android.internal.statusbar.IStatusBarService; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.statusbar.notification.AssistantFeedbackController; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FooterViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FooterViewTest.java index 90cb7341377d..b120c4747cb9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FooterViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FooterViewTest.java @@ -31,7 +31,7 @@ import android.widget.TextView; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java index e52cb572f289..b0996ad48d0a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java @@ -115,7 +115,7 @@ public class NotificationContentInflaterTest extends SysuiTestCase { public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mBuilder = new Notification.Builder(mContext).setSmallIcon( - R.drawable.ic_person) + com.android.systemui.res.R.drawable.ic_person) .setContentTitle("Title") .setContentText("Text") .setStyle(new Notification.BigTextStyle().bigText("big text")); @@ -191,7 +191,7 @@ public class NotificationContentInflaterTest extends SysuiTestCase { public void testInflationThrowsErrorDoesntCallUpdated() throws Exception { mRow.getPrivateLayout().removeAllViews(); mRow.getEntry().getSbn().getNotification().contentView - = new RemoteViews(mContext.getPackageName(), R.layout.status_bar); + = new RemoteViews(mContext.getPackageName(), com.android.systemui.res.R.layout.status_bar); inflateAndWait(true /* expectingException */, mNotificationInflater, FLAG_CONTENT_VIEW_ALL, mRow); assertTrue(mRow.getPrivateLayout().getChildCount() == 0); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java index 596e9a2613d7..1763d9b02358 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java @@ -74,7 +74,7 @@ import android.widget.TextView; import com.android.internal.logging.MetricsLogger; import com.android.settingslib.notification.ConversationIconFactory; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.people.widget.PeopleSpaceWidgetManager; import com.android.systemui.shade.ShadeController; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt index fdfb4f4612fd..7f9471e5271f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt @@ -22,7 +22,7 @@ import android.testing.ViewUtils import android.view.LayoutInflater import android.view.View import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import org.junit.After import org.junit.Before diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java index 8dd0488c924e..f0b4dd46654a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java @@ -66,7 +66,7 @@ import android.widget.TextView; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.testing.UiEventLoggerFake; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.notification.AssistantFeedbackController; import com.android.systemui.statusbar.notification.collection.NotificationEntry; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java index f8f7af071e4c..0a15f0de0bf4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java @@ -23,7 +23,7 @@ import android.testing.TestableResources; import android.testing.UiThreadTest; import android.util.KeyValueListParser; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java index 638694038a6a..ac680e6c902e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java @@ -88,7 +88,7 @@ import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder; import com.android.systemui.statusbar.policy.SmartReplyConstants; import com.android.systemui.statusbar.policy.SmartReplyStateInflater; import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent; -import com.android.systemui.tests.R; +import com.android.systemui.res.R; import com.android.systemui.wmshell.BubblesManager; import com.android.systemui.wmshell.BubblesTestActivity; @@ -495,7 +495,7 @@ public class NotificationTestHelper { Notification publicVersion = new Notification.Builder(mContext).setSmallIcon( R.drawable.ic_person) .setCustomContentView(new RemoteViews(mContext.getPackageName(), - R.layout.custom_view_dark)) + com.android.systemui.tests.R.layout.custom_view_dark)) .build(); Notification.Builder notificationBuilder = new Notification.Builder(mContext, "channelId") .setSmallIcon(R.drawable.ic_person) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java index 12c8fd5db751..e42ce2789e0b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java @@ -52,7 +52,7 @@ import android.widget.TextView; import com.android.internal.logging.MetricsLogger; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt index 0909ff2e5993..f4e236e5bbf9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt @@ -5,7 +5,7 @@ import android.testing.TestableLooper import android.view.LayoutInflater import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.R +import com.android.systemui.res.R import junit.framework.Assert.assertTrue import org.junit.Before import org.junit.Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt index 1dc0ab07349b..957cb885aa06 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt @@ -6,7 +6,7 @@ import android.view.LayoutInflater import android.widget.FrameLayout import androidx.test.filters.SmallTest import com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerProgress -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.animation.ShadeInterpolation import com.android.systemui.flags.FakeFeatureFlags diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java index 4307066e2d44..3a820e8087a8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java @@ -65,7 +65,7 @@ import androidx.test.filters.SmallTest; import com.android.keyguard.BouncerPanelExpansionCalculator; import com.android.systemui.ExpandHelper; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FakeFeatureFlags; @@ -154,6 +154,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { assertFalse(Flags.NSSL_DEBUG_REMOVE_ANIMATION.getDefault()); mFeatureFlags.set(Flags.NSSL_DEBUG_LINES, false); mFeatureFlags.set(Flags.NSSL_DEBUG_REMOVE_ANIMATION, false); + mFeatureFlags.set(Flags.LOCKSCREEN_ENABLE_LANDSCAPE, false); // Register the feature flags we use // TODO: Ideally we wouldn't need to set these unless a test actually reads them, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt index bc12bb0fca4e..2b3f9d0f3c39 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt @@ -21,7 +21,7 @@ import android.service.notification.StatusBarNotification import android.testing.AndroidTestingRunner import android.view.View.VISIBLE import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.media.controls.pipeline.MediaDataManager import com.android.systemui.statusbar.LockscreenShadeTransitionController diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt index d9c3c3cecf9c..a52466d2fa41 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt @@ -5,7 +5,7 @@ import android.content.pm.PackageManager import android.widget.FrameLayout import androidx.test.filters.SmallTest import com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerProgress -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.animation.ShadeInterpolation.getContentAlpha import com.android.systemui.dump.DumpManager diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt index 7fc399b44795..198f278bf43a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt @@ -19,7 +19,7 @@ package com.android.systemui.statusbar.notification.stack.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository import com.android.systemui.coroutines.collectLastValue diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt index bfc09103ba41..e254dd085b2e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt @@ -19,7 +19,7 @@ package com.android.systemui.statusbar.notification.stack.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.SharedNotificationContainerPosition import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository 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 e4a2236211b1..416694b29f69 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 @@ -50,7 +50,7 @@ import android.testing.TestableLooper.RunWithLooper; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.dagger.NightDisplayListenerModule; import com.android.systemui.plugins.qs.QSTile; 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 26c0fd695b95..5c3dde59596e 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 @@ -85,7 +85,7 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.TestScopeProvider; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.InitController; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController; import com.android.systemui.animation.ActivityLaunchAnimator; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java index bb20d1806bce..1bc522d72213 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java @@ -32,7 +32,7 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; import com.android.internal.logging.UiEventLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.shade.ShadeExpansionStateManager; import com.android.systemui.statusbar.AlertingNotificationManager; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt index 4aac8419af3b..ab441e39e862 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt @@ -20,7 +20,7 @@ import android.content.pm.PackageManager import android.test.suitebuilder.annotation.SmallTest import android.testing.AndroidTestingRunner import android.testing.TestableLooper -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.statusbar.StatusBarStateController diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java index 5d2b59b6e00e..03f5f005ee47 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java @@ -30,7 +30,7 @@ import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.doze.util.BurnInHelperKt; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java index 79f8dbd687ee..2b1ce0e16bbf 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java @@ -50,7 +50,7 @@ import com.android.keyguard.CarrierTextController; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.logging.KeyguardLogger; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.battery.BatteryMeterViewController; import com.android.systemui.flags.FakeFeatureFlagsClassic; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java index fe1205161e8d..e88fd95a5849 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java @@ -25,7 +25,7 @@ import android.view.View; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java index 47f15a1720a9..c5abd026b369 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java @@ -27,7 +27,7 @@ import android.content.Context; import android.os.UserHandle; import android.service.notification.StatusBarNotification; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.SbnBuilder; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java index b70c6dd1242d..d25a06b6c8b3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java @@ -29,7 +29,7 @@ import android.view.ViewConfiguration; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.util.concurrency.FakeExecutor; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitionsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitionsTest.kt index 4af1b24ba96c..c4568a9ecfe6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitionsTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitionsTest.kt @@ -19,7 +19,7 @@ package com.android.systemui.statusbar.phone import android.testing.TestableLooper import android.view.View import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT import com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt index 3a629e642d3d..b7560ad79026 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt @@ -27,7 +27,7 @@ import android.view.ViewTreeObserver.OnPreDrawListener import android.widget.FrameLayout import androidx.test.filters.SmallTest import androidx.test.platform.app.InstrumentationRegistry -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt index 63508e193bb8..1455693fc54b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListenerTest.kt @@ -31,7 +31,7 @@ import android.view.ViewGroupOverlay import android.widget.LinearLayout import androidx.annotation.ColorInt import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher.DarkChange import com.android.systemui.statusbar.policy.FakeConfigurationController diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java index b8f2cab3019e..bcb34d6d9342 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java @@ -48,7 +48,7 @@ import android.widget.FrameLayout; import androidx.test.filters.SmallTest; import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiBaseFragmentTest; import com.android.systemui.animation.AnimatorTestRule; import com.android.systemui.dump.DumpManager; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallBackgroundContainerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallBackgroundContainerTest.kt index ec074d76da10..f0a457e2c19f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallBackgroundContainerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallBackgroundContainerTest.kt @@ -21,7 +21,7 @@ import android.testing.TestableLooper import android.view.LayoutInflater import android.view.View import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import org.junit.Before diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallChronometerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallChronometerTest.kt index c3326b2bb7a2..7e25aa373097 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallChronometerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallChronometerTest.kt @@ -21,7 +21,7 @@ import android.testing.TestableLooper import android.view.LayoutInflater import android.view.View import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import org.junit.Before diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt index dc5d55ec274a..32320b45a36d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt @@ -30,7 +30,7 @@ import android.view.View import android.widget.LinearLayout import androidx.test.filters.SmallTest import com.android.internal.logging.testing.UiEventLoggerFake -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.ActivityStarter diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt index 5784be34ce25..6028712c29fc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt @@ -18,7 +18,7 @@ package com.android.systemui.statusbar.pipeline.ethernet.domain import androidx.test.filters.SmallTest import com.android.settingslib.AccessibilityContentDescriptions -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt index 59fc0aceec97..218fd33ac0fc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt @@ -24,7 +24,7 @@ import android.testing.ViewUtils import android.view.View import android.widget.ImageView import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.statusbar.StatusBarIconView diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt index 6624ec2ece77..15b9d61fc96b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt @@ -17,8 +17,9 @@ package com.android.systemui.statusbar.pipeline.shared.ui.viewmodel import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase +import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription import com.android.systemui.common.shared.model.Text import com.android.systemui.coroutines.collectLastValue import com.android.systemui.log.table.TableLogBuffer @@ -42,6 +43,7 @@ import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepo import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractorImpl import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiScanEntry +import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon import com.android.systemui.util.CarrierConfigTracker import com.android.systemui.util.mockito.mock import com.google.common.truth.Truth.assertThat @@ -72,6 +74,8 @@ class InternetTileViewModelTest : SysuiTestCase() { private val mobileConnectionRepository = FakeMobileConnectionRepository(SUB_1_ID, tableLogBuffer) + private val internet = context.getString(R.string.quick_settings_internet_label) + @Before fun setUp() { mobileConnectionRepository.apply { @@ -139,6 +143,9 @@ class InternetTileViewModelTest : SysuiTestCase() { level = 4, ssid = "test ssid", ) + val wifiIcon = + WifiIcon.fromModel(model = networkModel, context = context, showHotspotInfo = false) + as WifiIcon.Visible connectivityRepository.setWifiConnected() wifiRepository.setIsWifiDefault(true) @@ -149,6 +156,10 @@ class InternetTileViewModelTest : SysuiTestCase() { assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(WifiIcons.WIFI_NO_INTERNET_ICONS[4])) assertThat(latest?.iconId).isNull() + assertThat(latest?.contentDescription.loadContentDescription(context)) + .isEqualTo("$internet,test ssid") + val expectedSd = wifiIcon.contentDescription + assertThat(latest?.stateDescription).isEqualTo(expectedSd) } @Test @@ -281,6 +292,11 @@ class InternetTileViewModelTest : SysuiTestCase() { .isEqualTo(context.getString(R.string.quick_settings_networks_available)) assertThat(latest?.icon).isNull() assertThat(latest?.iconId).isEqualTo(R.drawable.ic_qs_no_internet_available) + assertThat(latest?.stateDescription).isNull() + val expectedCd = + "$internet,${context.getString(R.string.quick_settings_networks_available)}" + assertThat(latest?.contentDescription.loadContentDescription(context)) + .isEqualTo(expectedCd) } @Test @@ -300,6 +316,10 @@ class InternetTileViewModelTest : SysuiTestCase() { assertThat(latest?.secondaryLabel).isNull() assertThat(latest?.icon).isInstanceOf(SignalIcon::class.java) assertThat(latest?.iconId).isNull() + assertThat(latest?.stateDescription.loadContentDescription(context)) + .isEqualTo(latest?.secondaryTitle) + assertThat(latest?.contentDescription.loadContentDescription(context)) + .isEqualTo(internet) } @Test @@ -315,6 +335,9 @@ class InternetTileViewModelTest : SysuiTestCase() { .isEqualTo(ethernetIcon!!.contentDescription.toString()) assertThat(latest?.iconId).isEqualTo(R.drawable.stat_sys_ethernet_fully) assertThat(latest?.icon).isNull() + assertThat(latest?.stateDescription).isNull() + assertThat(latest?.contentDescription.loadContentDescription(context)) + .isEqualTo(latest?.secondaryTitle) } @Test @@ -330,6 +353,9 @@ class InternetTileViewModelTest : SysuiTestCase() { .isEqualTo(ethernetIcon!!.contentDescription.toString()) assertThat(latest?.iconId).isEqualTo(R.drawable.stat_sys_ethernet) assertThat(latest?.icon).isNull() + assertThat(latest?.stateDescription).isNull() + assertThat(latest?.contentDescription.loadContentDescription(context)) + .isEqualTo(latest?.secondaryTitle) } private fun setWifiNetworkWithHotspot(hotspot: WifiNetworkModel.HotspotDeviceType) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt index bbf048d6697f..a27f8990dec1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt @@ -25,7 +25,7 @@ import android.view.View import android.view.ViewGroup import android.widget.ImageView import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt index 655775465e1f..fb4ccb52929a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt @@ -24,7 +24,7 @@ import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.controls.dagger.ControlsComponent diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java index e5bbead520f2..64ebcd9e3abf 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java @@ -49,7 +49,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.testing.UiEventLoggerFake; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.statusbar.AlertingNotificationManager; import com.android.systemui.statusbar.AlertingNotificationManagerTest; import com.android.systemui.statusbar.notification.collection.NotificationEntry; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java index dc08aba7d5e5..3fae3f6b4054 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java @@ -38,7 +38,7 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; import com.android.systemui.settings.UserTracker; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java index e4318659bef9..bf280c9a2d54 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java @@ -37,7 +37,7 @@ import androidx.test.annotation.UiThreadTest; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.DevicePolicyManagerWrapper; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt index b86ca6fc5375..1250228e2d37 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt @@ -24,7 +24,7 @@ import android.view.View import android.widget.FrameLayout import androidx.test.filters.SmallTest import com.android.internal.logging.UiEventLogger -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.plugins.FalsingManager import com.android.systemui.qs.user.UserSwitchDialogController diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt index 1ab62d00d307..0bd6a685708b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt @@ -25,7 +25,7 @@ import android.view.View import android.view.ViewGroup import androidx.test.filters.SmallTest import com.android.internal.util.UserIcons -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.qs.tiles.UserDetailItemView import com.android.systemui.user.data.source.UserRecord diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt index cfb48a8f6995..635d63ed5eb2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt @@ -19,7 +19,7 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.CommandQueue import com.google.common.truth.Truth.assertThat 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 79feb417a062..658e6b01d7b4 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 @@ -67,7 +67,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.testing.UiEventLoggerFake; import com.android.systemui.Dependency; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.AnimatorTestRule; import com.android.systemui.flags.FakeFeatureFlags; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java index e4e0dc9ec39c..3555a7415435 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java @@ -29,7 +29,7 @@ import android.testing.TestableLooper; import android.testing.TestableResources; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.util.DeviceConfigProxyFake; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java index ae38958ecb44..4b6c68aeccc7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java @@ -47,7 +47,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; 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 d212c026d66e..5b9db4bf8869 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt @@ -31,7 +31,7 @@ import androidx.test.filters.SmallTest import com.android.internal.logging.InstanceId import com.android.internal.logging.UiEventLogger import com.android.systemui.InstanceIdSequenceFake -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.argumentCaptor diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt index 98bbb26eb703..ae4dfbd6ab31 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt @@ -26,7 +26,7 @@ import android.view.accessibility.AccessibilityManager import androidx.test.filters.SmallTest import com.android.internal.logging.InstanceId import com.android.internal.logging.testing.UiEventLoggerFake -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt index 8c21fac82dfe..1e7e1842fa33 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt @@ -33,7 +33,7 @@ import androidx.core.animation.doOnCancel import androidx.test.filters.SmallTest import com.android.internal.logging.InstanceId import com.android.internal.logging.testing.UiEventLoggerFake -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector import com.android.systemui.common.shared.model.ContentDescription diff --git a/packages/SystemUI/tests/src/com/android/systemui/toast/ToastUITest.java b/packages/SystemUI/tests/src/com/android/systemui/toast/ToastUITest.java index 7593e8429e60..85359ca3aebe 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/toast/ToastUITest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/toast/ToastUITest.java @@ -62,7 +62,7 @@ import android.widget.Toast; import androidx.test.filters.SmallTest; import com.android.internal.util.IntPair; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; import com.android.systemui.plugins.PluginManager; @@ -364,7 +364,7 @@ public class ToastUITest extends SysuiTestCase { // THEN the view can have unlimited lines assertThat(((TextView) mToastUI.mToast.getView() - .findViewById(com.android.systemui.R.id.text)) + .findViewById(com.android.systemui.res.R.id.text)) .getMaxLines()).isEqualTo(Integer.MAX_VALUE); } @@ -383,7 +383,7 @@ public class ToastUITest extends SysuiTestCase { // THEN the view is limited to 2 lines assertThat(((TextView) mToastUI.mToast.getView() - .findViewById(com.android.systemui.R.id.text)) + .findViewById(com.android.systemui.res.R.id.text)) .getMaxLines()).isEqualTo(2); } 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 5a54aff72af4..bbc49c859821 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 @@ -34,7 +34,7 @@ import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.GuestResetOrExitSessionReceiver import com.android.systemui.GuestResumeSessionReceiver -import com.android.systemui.R +import com.android.systemui.res.R import com.android.systemui.SysuiTestCase import com.android.systemui.animation.Expandable import com.android.systemui.common.shared.model.Text @@ -120,7 +120,7 @@ class UserInteractorTest : SysuiTestCase() { whenever(manager.getUserIcon(anyInt())).thenReturn(ICON) whenever(manager.canAddMoreUsers(any())).thenReturn(true) - overrideResource(R.drawable.ic_account_circle, GUEST_ICON) + overrideResource(com.android.settingslib.R.drawable.ic_account_circle, GUEST_ICON) overrideResource(R.dimen.max_avatar_size, 10) overrideResource( com.android.internal.R.string.config_supervisedUserCreationPackage, 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 aa9d62da4b2a..8e57dc1f8b2c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java @@ -57,7 +57,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.jank.InteractionJankMonitor; import com.android.systemui.Prefs; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.AnimatorTestRule; import com.android.systemui.dump.DumpManager; diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java index 53e5e7d859ac..82631744d12d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java @@ -37,7 +37,7 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.plugins.ActivityStarter; 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 7595a54a18fd..d8511e8f38e2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -87,7 +87,7 @@ import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.launcher3.icons.BubbleIconFactory; -import com.android.systemui.R; +import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.AuthController; import com.android.systemui.colorextraction.SysuiColorExtractor; @@ -1273,9 +1273,9 @@ public class BubblesTest extends SysuiTestCase { mBubbleController, mBubbleController.getStackView(), new BubbleIconFactory(mContext, - mContext.getResources().getDimensionPixelSize(R.dimen.bubble_size), - mContext.getResources().getDimensionPixelSize(R.dimen.bubble_badge_size), - mContext.getResources().getColor(R.color.important_conversation), + mContext.getResources().getDimensionPixelSize(com.android.wm.shell.R.dimen.bubble_size), + mContext.getResources().getDimensionPixelSize(com.android.wm.shell.R.dimen.bubble_badge_size), + mContext.getResources().getColor(com.android.launcher3.icons.R.color.important_conversation), mContext.getResources().getDimensionPixelSize( com.android.internal.R.dimen.importance_ring_stroke_width)), bubble, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java index 5ff57aad9f5d..2d76027ba744 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java @@ -28,6 +28,7 @@ import android.util.Log; import android.view.Display; import com.android.internal.annotations.GuardedBy; +import com.android.systemui.res.R; import java.util.Set; diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt index 16442bb525b6..dd513db03d34 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt @@ -38,7 +38,7 @@ class FakeKeyguardTransitionRepository : KeyguardTransitionRepository { } override fun startTransition(info: TransitionInfo, resetIfCanceled: Boolean): UUID? { - return null + return if (info.animator == null) UUID.randomUUID() else null } override fun updateTransition( diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorFactory.kt index 6dd41f488e2d..ceab8e9e52ee 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorFactory.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorFactory.kt @@ -72,7 +72,6 @@ object KeyguardDismissInteractorFactory { keyguardUpdateMonitor: KeyguardUpdateMonitor = mock(KeyguardUpdateMonitor::class.java), featureFlags: FakeFeatureFlagsClassic = FakeFeatureFlagsClassic().apply { - set(Flags.DELAY_BOUNCER, true) set(Flags.REFACTOR_KEYGUARD_DISMISS_INTENT, true) set(Flags.FULL_SCREEN_USER_SWITCHER, false) }, @@ -92,7 +91,6 @@ object KeyguardDismissInteractorFactory { context, keyguardUpdateMonitor, trustRepository, - featureFlags, testScope.backgroundScope, ) val alternateBouncerInteractor = diff --git a/packages/SystemUI/unfold/Android.bp b/packages/SystemUI/unfold/Android.bp index 1f0181f2e5bd..81fd8ce12f05 100644 --- a/packages/SystemUI/unfold/Android.bp +++ b/packages/SystemUI/unfold/Android.bp @@ -23,6 +23,7 @@ package { android_library { name: "SystemUIUnfoldLib", + use_resource_processor: true, srcs: [ "src/**/*.java", "src/**/*.kt", diff --git a/services/autofill/java/com/android/server/autofill/FieldClassificationEventLogger.java b/services/autofill/java/com/android/server/autofill/FieldClassificationEventLogger.java index ffb4632164a3..db2e18a0fd57 100644 --- a/services/autofill/java/com/android/server/autofill/FieldClassificationEventLogger.java +++ b/services/autofill/java/com/android/server/autofill/FieldClassificationEventLogger.java @@ -17,12 +17,19 @@ package com.android.server.autofill; import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED; +import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED__STATUS__STATUS_CANCELLED; +import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED__STATUS__STATUS_FAIL; +import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED__STATUS__STATUS_SUCCESS; +import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED__STATUS__STATUS_UNKNOWN; import static com.android.server.autofill.Helper.sVerbose; +import android.annotation.IntDef; import android.util.Slog; import com.android.internal.util.FrameworkStatsLog; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.Optional; /** @@ -36,6 +43,29 @@ public final class FieldClassificationEventLogger { mEventInternal = Optional.empty(); } + public static final int STATUS_SUCCESS = + AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED__STATUS__STATUS_SUCCESS; + public static final int STATUS_UNKNOWN = + AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED__STATUS__STATUS_UNKNOWN; + public static final int STATUS_FAIL = + AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED__STATUS__STATUS_FAIL; + public static final int STATUS_CANCELLED = + AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED__STATUS__STATUS_CANCELLED; + + /** + * Status of the FieldClassification IPC request. These are wrappers around + * {@link com.android.os.AtomsProto.AutofillFieldClassificationEventReported.FieldClassificationRequestStatus}. + */ + @IntDef(prefix = {"STATUS"}, value = { + STATUS_UNKNOWN, + STATUS_SUCCESS, + STATUS_FAIL, + STATUS_CANCELLED + }) + @Retention(RetentionPolicy.SOURCE) + public @interface FieldClassificationStatus { + } + /** * A factory constructor to create FieldClassificationEventLogger. */ @@ -56,7 +86,7 @@ public final class FieldClassificationEventLogger { } /** - * Set latency as long as mEventInternal presents. + * Set latency_millis as long as mEventInternal presents. */ public void maybeSetLatencyMillis(long timestamp) { mEventInternal.ifPresent(event -> { @@ -65,6 +95,69 @@ public final class FieldClassificationEventLogger { } /** + * Set count_classifications as long as mEventInternal presents. + */ + public void maybeSetCountClassifications(int countClassifications) { + mEventInternal.ifPresent(event -> { + event.mCountClassifications = countClassifications; + }); + } + + /** + * Set session_id as long as mEventInternal presents. + */ + public void maybeSetSessionId(int sessionId) { + mEventInternal.ifPresent(event -> { + event.mSessionId = sessionId; + }); + } + + /** + * Set request_id as long as mEventInternal presents. + */ + public void maybeSetRequestId(int requestId) { + mEventInternal.ifPresent(event -> { + event.mRequestId = requestId; + }); + } + + /** + * Set next_fill_request_id as long as mEventInternal presents. + */ + public void maybeSetNextFillRequestId(int nextFillRequestId) { + mEventInternal.ifPresent(event -> { + event.mNextFillRequestId = nextFillRequestId; + }); + } + + /** + * Set app_package_uid as long as mEventInternal presents. + */ + public void maybeSetAppPackageUid(int uid) { + mEventInternal.ifPresent(event -> { + event.mAppPackageUid = uid; + }); + } + + /** + * Set status as long as mEventInternal presents. + */ + public void maybeSetRequestStatus(@FieldClassificationStatus int status) { + mEventInternal.ifPresent(event -> { + event.mStatus = status; + }); + } + + /** + * Set is_session_gc as long as mEventInternal presents. + */ + public void maybeSetSessionGc(boolean isSessionGc) { + mEventInternal.ifPresent(event -> { + event.mIsSessionGc = isSessionGc; + }); + } + + /** * Log an AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED event. */ public void logAndEndEvent() { @@ -77,16 +170,37 @@ public final class FieldClassificationEventLogger { if (sVerbose) { Slog.v(TAG, "Log AutofillFieldClassificationEventReported:" + " mLatencyClassificationRequestMillis=" - + event.mLatencyClassificationRequestMillis); + + event.mLatencyClassificationRequestMillis + + " mCountClassifications=" + event.mCountClassifications + + " mSessionId=" + event.mSessionId + + " mRequestId=" + event.mRequestId + + " mNextFillRequestId=" + event.mNextFillRequestId + + " mAppPackageUid=" + event.mAppPackageUid + + " mStatus=" + event.mStatus + + " mIsSessionGc=" + event.mIsSessionGc); } FrameworkStatsLog.write( AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED, - event.mLatencyClassificationRequestMillis); + event.mLatencyClassificationRequestMillis, + event.mCountClassifications, + event.mSessionId, + event.mRequestId, + event.mNextFillRequestId, + event.mAppPackageUid, + event.mStatus, + event.mIsSessionGc); mEventInternal = Optional.empty(); } private static final class FieldClassificationEventInternal { long mLatencyClassificationRequestMillis = -1; + int mCountClassifications = -1; + int mSessionId = -1; + int mRequestId = -1; + int mNextFillRequestId = -1; + int mAppPackageUid = -1; + int mStatus; + boolean mIsSessionGc; FieldClassificationEventInternal() { } diff --git a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java index 11b45db29d5d..6b0fdb5f7fe0 100644 --- a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java +++ b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java @@ -211,15 +211,25 @@ public final class PresentationStatsEventLogger { public static final int DETECTION_PREFER_PCC = AUTOFILL_FILL_RESPONSE_REPORTED__DETECTION_PREFERENCE__DETECTION_PREFER_PCC; private final int mSessionId; + + /** + * For app_package_uid. + */ + private final int mCallingAppUid; private Optional<PresentationStatsEventInternal> mEventInternal; - private PresentationStatsEventLogger(int sessionId) { + private PresentationStatsEventLogger(int sessionId, int callingAppUid) { mSessionId = sessionId; + mCallingAppUid = callingAppUid; mEventInternal = Optional.empty(); } - public static PresentationStatsEventLogger forSessionId(int sessionId) { - return new PresentationStatsEventLogger(sessionId); + /** + * Create PresentationStatsEventLogger, populated with sessionId and the callingAppUid + */ + public static PresentationStatsEventLogger createPresentationLog( + int sessionId, int callingAppUid) { + return new PresentationStatsEventLogger(sessionId, callingAppUid); } public void startNewEvent() { @@ -508,6 +518,14 @@ public final class PresentationStatsEventLogger { return PICK_REASON_UNKNOWN; } + /** + * Set field_classification_request_id as long as mEventInternal presents. + */ + public void maybeSetFieldClassificationRequestId(int requestId) { + mEventInternal.ifPresent(event -> { + event.mFieldClassificationRequestId = requestId; + }); + } public void logAndEndEvent() { if (!mEventInternal.isPresent()) { @@ -547,7 +565,9 @@ public final class PresentationStatsEventLogger { + " mAvailablePccCount=" + event.mAvailablePccCount + " mAvailablePccOnlyCount=" + event.mAvailablePccOnlyCount + " mSelectedDatasetPickedReason=" + event.mSelectedDatasetPickedReason - + " mDetectionPreference=" + event.mDetectionPreference); + + " mDetectionPreference=" + event.mDetectionPreference + + " mFieldClassificationRequestId=" + event.mFieldClassificationRequestId + + " mAppPackageUid=" + mCallingAppUid); } // TODO(b/234185326): Distinguish empty responses from other no presentation reasons. @@ -584,7 +604,9 @@ public final class PresentationStatsEventLogger { event.mAvailablePccCount, event.mAvailablePccOnlyCount, event.mSelectedDatasetPickedReason, - event.mDetectionPreference); + event.mDetectionPreference, + event.mFieldClassificationRequestId, + mCallingAppUid); mEventInternal = Optional.empty(); } @@ -617,6 +639,7 @@ public final class PresentationStatsEventLogger { int mAvailablePccOnlyCount = -1; @DatasetPickedReason int mSelectedDatasetPickedReason = PICK_REASON_UNKNOWN; @DetectionPreference int mDetectionPreference = DETECTION_PREFER_UNKNOWN; + int mFieldClassificationRequestId = -1; PresentationStatsEventInternal() {} } diff --git a/services/autofill/java/com/android/server/autofill/RemoteFieldClassificationService.java b/services/autofill/java/com/android/server/autofill/RemoteFieldClassificationService.java index bcca0069eb34..50fabfdaef83 100644 --- a/services/autofill/java/com/android/server/autofill/RemoteFieldClassificationService.java +++ b/services/autofill/java/com/android/server/autofill/RemoteFieldClassificationService.java @@ -69,6 +69,9 @@ final class RemoteFieldClassificationService void onClassificationRequestFailure(int requestId, @Nullable CharSequence message); void onClassificationRequestTimeout(int requestId); void onServiceDied(@NonNull RemoteFieldClassificationService service); + void logFieldClassificationEvent( + long startTime, @NonNull FieldClassificationResponse response, + @FieldClassificationEventLogger.FieldClassificationStatus int status); } RemoteFieldClassificationService(Context context, ComponentName serviceName, @@ -149,15 +152,24 @@ final class RemoteFieldClassificationService new IFieldClassificationCallback.Stub() { @Override public void onCancellable(ICancellationSignal cancellation) { - logLatency(startTime); if (sDebug) { Log.d(TAG, "onCancellable"); } + FieldClassificationServiceCallbacks + fieldClassificationServiceCallbacks = + Helper.weakDeref( + fieldClassificationServiceCallbacksWeakRef, + TAG, "onCancellable " + ); + logFieldClassificationEvent( + startTime, + fieldClassificationServiceCallbacks, + FieldClassificationEventLogger.STATUS_CANCELLED, + null); } @Override public void onSuccess(FieldClassificationResponse response) { - logLatency(startTime); if (sDebug) { if (Build.IS_DEBUGGABLE) { Slog.d(TAG, "onSuccess Response: " + response); @@ -179,6 +191,11 @@ final class RemoteFieldClassificationService fieldClassificationServiceCallbacksWeakRef, TAG, "onSuccess " ); + logFieldClassificationEvent( + startTime, + fieldClassificationServiceCallbacks, + FieldClassificationEventLogger.STATUS_SUCCESS, + response); if (fieldClassificationServiceCallbacks == null) { return; } @@ -188,7 +205,6 @@ final class RemoteFieldClassificationService @Override public void onFailure() { - logLatency(startTime); if (sDebug) { Slog.d(TAG, "onFailure"); } @@ -198,6 +214,11 @@ final class RemoteFieldClassificationService fieldClassificationServiceCallbacksWeakRef, TAG, "onFailure " ); + logFieldClassificationEvent( + startTime, + fieldClassificationServiceCallbacks, + FieldClassificationEventLogger.STATUS_FAIL, + null); if (fieldClassificationServiceCallbacks == null) { return; } @@ -215,11 +236,24 @@ final class RemoteFieldClassificationService })); } - private void logLatency(long startTime) { - final FieldClassificationEventLogger logger = FieldClassificationEventLogger.createLogger(); - logger.startNewLogForRequest(); - logger.maybeSetLatencyMillis( - SystemClock.elapsedRealtime() - startTime); - logger.logAndEndEvent(); + private void logFieldClassificationEvent( + long startTime, + @Nullable FieldClassificationServiceCallbacks fieldClassificationServiceCallbacks, + @FieldClassificationEventLogger.FieldClassificationStatus int status, + FieldClassificationResponse response) { + if (fieldClassificationServiceCallbacks == null) { + final FieldClassificationEventLogger logger = + FieldClassificationEventLogger.createLogger(); + logger.startNewLogForRequest(); + logger.maybeSetLatencyMillis( + SystemClock.elapsedRealtime() - startTime); + logger.maybeSetSessionGc(true); + logger.maybeSetRequestStatus(status); + logger.logAndEndEvent(); + } else { + fieldClassificationServiceCallbacks.logFieldClassificationEvent( + startTime, response, status); + } + } } diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 1ae912544cc8..4e5b0589446a 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -229,6 +229,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState private static final String PCC_HINTS_DELIMITER = ","; public static final String EXTRA_KEY_DETECTIONS = "detections"; + private static final int DEFAULT__FILL_REQUEST_ID_SNAPSHOT = -2; + private static final int DEFAULT__FIELD_CLASSIFICATION_REQUEST_ID_SNAPSHOT = -2; final Object mLock; @@ -412,6 +414,20 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @GuardedBy("mLock") private long mUiShownTime; + /** + * Tracks the value of the fill request id at the time of issuing request for field + * classification. + */ + @GuardedBy("mLock") + private int mFillRequestIdSnapshot = DEFAULT__FILL_REQUEST_ID_SNAPSHOT; + + /** + * Tracks the value of the field classification id at the time of issuing request for fill + * request. + */ + @GuardedBy("mLock") + private int mFieldClassificationIdSnapshot = DEFAULT__FIELD_CLASSIFICATION_REQUEST_ID_SNAPSHOT; + @GuardedBy("mLock") private final LocalLog mUiLatencyHistory; @@ -673,6 +689,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (mPendingFillRequest == null) { return; } + mFieldClassificationIdSnapshot = sIdCounterForPcc.get(); if (mWaitForInlineRequest) { if (mPendingInlineSuggestionsRequest == null) { @@ -1239,6 +1256,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState + ", flags=" + flags); } mPresentationStatsEventLogger.maybeSetRequestId(requestId); + mPresentationStatsEventLogger.maybeSetFieldClassificationRequestId( + mFieldClassificationIdSnapshot); mFillRequestEventLogger.maybeSetRequestId(requestId); mFillRequestEventLogger.maybeSetAutofillServiceUid(getAutofillServiceUid()); if (mSessionFlags.mInlineSupportedByService) { @@ -1327,6 +1346,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @GuardedBy("mLock") private void requestAssistStructureForPccLocked(int flags) { if (!mClassificationState.shouldTriggerRequest()) return; + mFillRequestIdSnapshot = sIdCounter.get(); mClassificationState.updatePendingRequest(); // Get request id int requestId; @@ -1411,7 +1431,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mStartTime = SystemClock.elapsedRealtime(); mLatencyBaseTime = mStartTime; mRequestCount = 0; - mPresentationStatsEventLogger = PresentationStatsEventLogger.forSessionId(sessionId); + mPresentationStatsEventLogger = PresentationStatsEventLogger.createPresentationLog( + sessionId, uid); mFillRequestEventLogger = FillRequestEventLogger.forSessionId(sessionId); mFillResponseEventLogger = FillResponseEventLogger.forSessionId(sessionId); mSessionCommittedEventLogger = SessionCommittedEventLogger.forSessionId(sessionId); @@ -4301,6 +4322,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (viewState.getResponse() != null) { FillResponse response = viewState.getResponse(); mPresentationStatsEventLogger.maybeSetRequestId(response.getRequestId()); + mPresentationStatsEventLogger.maybeSetFieldClassificationRequestId( + mFieldClassificationIdSnapshot); mPresentationStatsEventLogger.maybeSetAvailableCount( response.getDatasets(), mCurrentViewId); } @@ -4478,6 +4501,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState public void onFillReady(@NonNull FillResponse response, @NonNull AutofillId filledId, @Nullable AutofillValue value, int flags) { synchronized (mLock) { + mPresentationStatsEventLogger.maybeSetFieldClassificationRequestId( + mFieldClassificationIdSnapshot); if (mDestroyed) { Slog.w(TAG, "Call to Session#onFillReady() rejected - session: " + id + " destroyed"); @@ -5389,6 +5414,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState List<Dataset> datasetList = newResponse.getDatasets(); + mPresentationStatsEventLogger.maybeSetFieldClassificationRequestId(sIdCounterForPcc.get()); mPresentationStatsEventLogger.maybeSetAvailableCount(datasetList, mCurrentViewId); mFillResponseEventLogger.maybeSetDatasetsCountAfterPotentialPccFiltering(datasetList); @@ -6451,7 +6477,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState return serviceInfo == null ? Process.INVALID_UID : serviceInfo.applicationInfo.uid; } - // FieldClassificationServiceCallbacks + // FieldClassificationServiceCallbacks start public void onClassificationRequestSuccess(@Nullable FieldClassificationResponse response) { mClassificationState.updateResponseReceived(response); } @@ -6472,6 +6498,28 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState // forceRemoveFromServiceLocked(); } } - // DetectionServiceCallbacks end + + @Override + public void logFieldClassificationEvent( + long startTime, FieldClassificationResponse response, + @FieldClassificationEventLogger.FieldClassificationStatus int status) { + final FieldClassificationEventLogger logger = FieldClassificationEventLogger.createLogger(); + logger.startNewLogForRequest(); + logger.maybeSetLatencyMillis( + SystemClock.elapsedRealtime() - startTime); + logger.maybeSetAppPackageUid(uid); + logger.maybeSetNextFillRequestId(mFillRequestIdSnapshot + 1); + logger.maybeSetRequestId(sIdCounterForPcc.get()); + logger.maybeSetSessionId(id); + int count = -1; + if (response != null) { + count = response.getClassifications().size(); + } + logger.maybeSetRequestStatus(status); + logger.maybeSetCountClassifications(count); + logger.logAndEndEvent(); + mFillRequestIdSnapshot = DEFAULT__FILL_REQUEST_ID_SNAPSHOT; + } + // FieldClassificationServiceCallbacks end } diff --git a/services/autofill/java/com/android/server/autofill/ui/BottomSheetLayout.java b/services/autofill/java/com/android/server/autofill/ui/BottomSheetLayout.java new file mode 100644 index 000000000000..06bbc2b0bdcb --- /dev/null +++ b/services/autofill/java/com/android/server/autofill/ui/BottomSheetLayout.java @@ -0,0 +1,108 @@ +/* + * 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.autofill.ui; + +import static com.android.server.autofill.Helper.sDebug; + +import android.annotation.Nullable; +import android.content.Context; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.util.Slog; +import android.widget.LinearLayout; + +import com.android.internal.R; + +/** + {@link LinearLayout} that displays content of save dialog. + */ +public class BottomSheetLayout extends LinearLayout { + + private static final String TAG = "BottomSheetLayout"; + + public BottomSheetLayout(Context context) { + super(context); + } + + public BottomSheetLayout(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public BottomSheetLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + public void onMeasure(int widthSpec, int heightSpec) { + if (getContext() == null || getContext().getResources() == null) { + super.onMeasure(widthSpec, heightSpec); + Slog.w(TAG, "onMeasure failed due to missing context or missing resources."); + return; + } + + if (getChildCount() == 0) { + // Should not happen + super.onMeasure(widthSpec, heightSpec); + Slog.wtf(TAG, "onMeasure failed due to missing children views."); + return; + } + + DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics(); + + final int pxOffset = getContext().getResources().getDimensionPixelSize( + R.dimen.autofill_dialog_offset); + final int outerMargin = getContext().getResources().getDimensionPixelSize( + R.dimen.autofill_save_outer_margin); + + final boolean includeHorizontalSpace = + getContext().getResources().getBoolean( + R.bool.autofill_dialog_horizontal_space_included); + + + final int screenHeight = displayMetrics.heightPixels; + final int screenWidth = displayMetrics.widthPixels; + + final int maxHeight = screenHeight - pxOffset - outerMargin; + + int maxWidth = screenWidth; + + if (includeHorizontalSpace) { + maxWidth -= 2 * pxOffset; + } + + maxWidth = + Math.min(maxWidth, getContext().getResources().getDimensionPixelSize( + R.dimen.autofill_dialog_max_width)); + + super.onMeasure(MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST)); + + + if (sDebug) { + Slog.d(TAG, "onMeasure() values in dp:" + + " screenHeight: " + screenHeight / displayMetrics.density + ", screenWidth: " + + screenWidth / displayMetrics.density + + ", maxHeight: " + maxHeight / displayMetrics.density + + ", maxWidth: " + maxWidth / displayMetrics.density + ", getMeasuredWidth(): " + + getMeasuredWidth() / displayMetrics.density + ", getMeasuredHeight(): " + + getMeasuredHeight() / displayMetrics.density); + } + setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight()); + } + + +} 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 4488d86c60b5..5635dd59e3f1 100644 --- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java @@ -48,7 +48,6 @@ import android.text.TextUtils; import android.text.method.LinkMovementMethod; import android.text.style.ClickableSpan; import android.util.ArraySet; -import android.util.DisplayMetrics; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; @@ -363,13 +362,6 @@ final class SaveUi { window.setCloseOnTouchOutside(true); final WindowManager.LayoutParams params = window.getAttributes(); - DisplayMetrics displayMetrics = new DisplayMetrics(); - window.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); - final int screenWidth = displayMetrics.widthPixels; - final int maxWidth = - context.getResources().getDimensionPixelSize(R.dimen.autofill_dialog_max_width); - params.width = Math.min(screenWidth, maxWidth); - params.accessibilityTitle = context.getString(R.string.autofill_save_accessibility_title); params.windowAnimations = R.style.AutofillSaveAnimation; params.setTrustedOverlay(); diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java index 3b02be5d6342..976504a8d880 100644 --- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java +++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java @@ -487,6 +487,13 @@ public class UserBackupManagerService { File baseStateDir, File dataDir, TransportManager transportManager) { + // check if we are past the retention period for BMM Events, + // if so delete expired events and do not print them to dumpsys + BackupManagerMonitorDumpsysUtils backupManagerMonitorDumpsysUtils = + new BackupManagerMonitorDumpsysUtils(); + if (backupManagerMonitorDumpsysUtils.deleteExpiredBMMEvents() && DEBUG){ + Slog.d(TAG, "BMM Events recorded for dumpsys have expired"); + } return new UserBackupManagerService( userId, context, @@ -657,6 +664,13 @@ public class UserBackupManagerService { // the pending backup set mBackupHandler.postDelayed(this::parseLeftoverJournals, INITIALIZATION_DELAY_MILLIS); + // check if we are past the retention period for BMM Events, + // if so delete expired events and do not print them to dumpsys + BackupManagerMonitorDumpsysUtils backupManagerMonitorDumpsysUtils = + new BackupManagerMonitorDumpsysUtils(); + mBackupHandler.postDelayed(backupManagerMonitorDumpsysUtils::deleteExpiredBMMEvents, + INITIALIZATION_DELAY_MILLIS); + mBackupPreferences = new UserBackupPreferences(mContext, mBaseStateDir); // Power management @@ -4181,7 +4195,19 @@ public class UserBackupManagerService { private void dumpBMMEvents(PrintWriter pw) { BackupManagerMonitorDumpsysUtils bm = new BackupManagerMonitorDumpsysUtils(); + if (bm.deleteExpiredBMMEvents()) { + pw.println("BACKUP MANAGER MONITOR EVENTS HAVE EXPIRED"); + return; + } File events = bm.getBMMEventsFile(); + if (events.length() == 0){ + // We have not recorded BMMEvents yet. + pw.println("NO BACKUP MANAGER MONITOR EVENTS"); + return; + } else if (bm.isFileLargerThanSizeLimit(events)){ + pw.println("BACKUP MANAGER MONITOR EVENTS FILE OVER SIZE LIMIT - " + + "future events will not be recorded"); + } pw.println("START OF BACKUP MANAGER MONITOR EVENTS"); try (BufferedReader reader = new BufferedReader(new FileReader(events))) { String line; diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java index e04bf11dad9f..bbec79d6cd47 100644 --- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java +++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java @@ -394,6 +394,20 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { // If we're starting a full-system restore, set up to begin widget ID remapping if (mIsSystemRestore) { AppWidgetBackupBridge.systemRestoreStarting(mUserId); + Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null); + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_START_SYSTEM_RESTORE, + null, + BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, + monitoringExtras); + } else { + //We are either performing RestoreAtInstall or Bmgr. + Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null); + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_START_RESTORE_AT_INSTALL, + null, + BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, + monitoringExtras); } try { @@ -421,6 +435,12 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { mStatus = transport.startRestore(mToken, packages); if (mStatus != BackupTransport.TRANSPORT_OK) { Slog.e(TAG, "Transport error " + mStatus + "; no restore possible"); + Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null); + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_DURING_START_RESTORE, + mCurrentPackage, + BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, + monitoringExtras); mStatus = BackupTransport.TRANSPORT_ERROR; executeNextState(UnifiedRestoreState.FINAL); return; @@ -528,6 +548,12 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { final String pkgName = (mRestoreDescription != null) ? mRestoreDescription.getPackageName() : null; if (pkgName == null) { + Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null); + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_CANNOT_GET_NEXT_PKG_NAME, + null, + BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, + monitoringExtras); Slog.e(TAG, "Failure getting next package name"); EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE); nextState = UnifiedRestoreState.FINAL; @@ -550,6 +576,14 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { Metadata metaInfo = mPmAgent.getRestoredMetadata(pkgName); if (metaInfo == null) { + PackageInfo pkgInfo = new PackageInfo(); + pkgInfo.packageName = pkgName; + Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null); + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_PM_AGENT_HAS_NO_METADATA, + pkgInfo, + BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, + monitoringExtras); Slog.e(TAG, "No metadata for " + pkgName); EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, pkgName, "Package metadata missing"); @@ -560,6 +594,13 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { try { mCurrentPackage = backupManagerService.getPackageManager().getPackageInfoAsUser( pkgName, PackageManager.GET_SIGNING_CERTIFICATES, mUserId); + Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null); + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_START_PACKAGE_RESTORE, + mCurrentPackage, + BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, + monitoringExtras); + } catch (NameNotFoundException e) { // Whoops, we thought we could restore this package but it // turns out not to be present. Skip it. @@ -641,12 +682,24 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { } else { // Unknown restore type; ignore this package and move on Slog.e(TAG, "Unrecognized restore type " + type); + Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);; + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_UNKNOWN_RESTORE_TYPE, + mCurrentPackage, + BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, + monitoringExtras); nextState = UnifiedRestoreState.RUNNING_QUEUE; return; } } catch (Exception e) { Slog.e(TAG, "Can't get next restore target from transport; halting: " + e.getMessage()); + Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null);; + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_NO_NEXT_RESTORE_TARGET, + mCurrentPackage, + BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, + monitoringExtras); EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE); nextState = UnifiedRestoreState.FINAL; return; @@ -663,6 +716,10 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { final String packageName = mCurrentPackage.packageName; // Validate some semantic requirements that apply in this way // only to the key/value restore API flow + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_KV_RESTORE, mCurrentPackage, + BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, + /*monitoringExtras*/ addRestoreOperationTypeToEvent(/*extras*/null)); if (mCurrentPackage.applicationInfo.backupAgentName == null || "".equals(mCurrentPackage.applicationInfo.backupAgentName)) { if (MORE_DEBUG) { @@ -721,6 +778,11 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { ++mCount; } catch (Exception e) { Slog.e(TAG, "Error when attempting restore: " + e.toString()); + Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null); + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_KV_AGENT_ERROR, mCurrentPackage, + BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, + monitoringExtras); keyValueAgentErrorCleanup(false); executeNextState(UnifiedRestoreState.RUNNING_QUEUE); } @@ -759,6 +821,12 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { // Transport-level failure. This failure could be specific to package currently in // restore. Slog.e(TAG, "Error getting restore data for " + packageName); + Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null); + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_KV_RESTORE, + mCurrentPackage, + BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, + monitoringExtras); EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE); stage.close(); downloadFile.delete(); @@ -815,6 +883,11 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { new ArrayList<>(getExcludedKeysForPackage(packageName))); } catch (Exception e) { Slog.e(TAG, "Unable to call app for restore: " + packageName, e); + Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null); + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_KV_AGENT_ERROR, mCurrentPackage, + BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, + monitoringExtras); EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, packageName, e.toString()); // Clears any pending timeout messages as well. @@ -888,6 +961,10 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { // // When finished, StreamFeederThread executes next state as appropriate on the // backup looper, and the overall unified restore task resumes + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE, mCurrentPackage, + BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, + /*monitoringExtras*/ addRestoreOperationTypeToEvent(/*extras*/null)); try { StreamFeederThread feeder = new StreamFeederThread(); if (MORE_DEBUG) { @@ -903,6 +980,11 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { // current target. We haven't asked the transport for data yet, though, // so we can do that simply by going back to running the restore queue. Slog.e(TAG, "Unable to construct pipes for stream restore!"); + Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null); + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_NO_FEEDER_THREAD, mCurrentPackage, + BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, + monitoringExtras); executeNextState(UnifiedRestoreState.RUNNING_QUEUE); } } @@ -927,6 +1009,10 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { } catch (Exception e) { final String packageName = mCurrentPackage.packageName; Slog.e(TAG, "Unable to finalize restore of " + packageName); + Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null); + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_AGENT_FAILURE, mCurrentPackage, + BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, monitoringExtras); EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, packageName, e.toString()); keyValueAgentErrorCleanup(true); @@ -1020,6 +1106,12 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { // handling will deal properly with that. Slog.e(TAG, "Error " + result + " streaming restore for " + mCurrentPackage.packageName); + Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null); + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_FULL_RESTORE, + mCurrentPackage, + BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, + monitoringExtras); EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE); status = result; } @@ -1032,6 +1124,12 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { // but potentially recoverable; abandon this package's restore but // carry on with the next restore target. Slog.e(TAG, "Unable to route data for restore"); + Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null); + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_FULL_AGENT_ERROR, + mCurrentPackage, + BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, + monitoringExtras); EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, mCurrentPackage.packageName, "I/O error on pipes"); status = BackupTransport.AGENT_ERROR; @@ -1040,6 +1138,12 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { // the sockets will wake up the engine and it will then tidy up the // remote end. Slog.e(TAG, "Transport failed during restore: " + e.getMessage()); + Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null); + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_FULL_RESTORE, + mCurrentPackage, + BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, + monitoringExtras); EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE); status = BackupTransport.TRANSPORT_ERROR; } finally { @@ -1213,6 +1317,13 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { } Slog.i(TAG, "Restore complete."); + Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null); + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_RESTORE_COMPLETE, + null, + BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, + monitoringExtras); + mListener.onFinished(callerLogString); } @@ -1313,6 +1424,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { @Override public void operationComplete(long unusedResult) { mOperationStorage.removeOperation(mEphemeralOpToken); + if (MORE_DEBUG) { Slog.i(TAG, "operationComplete() during restore: target=" + mCurrentPackage.packageName @@ -1341,6 +1453,11 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { // Okay, we're done with this package. Tidy up and go on to the next // app in the queue. int size = (int) mBackupDataName.length(); + Bundle monitoringExtras = addRestoreOperationTypeToEvent(/*extras*/null); + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_RESTORE_FINISHED, mCurrentPackage, + BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, + monitoringExtras); EventLog.writeEvent(EventLogTags.RESTORE_PACKAGE, mCurrentPackage.packageName, size); diff --git a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java index 0b55ca21371b..797aed9297a3 100644 --- a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java +++ b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java @@ -23,15 +23,22 @@ import android.os.Bundle; import android.os.Environment; import android.util.Slog; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.FastPrintWriter; +import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Map; +import java.util.concurrent.TimeUnit; /* @@ -46,12 +53,27 @@ public class BackupManagerMonitorDumpsysUtils { // Name of the subdirectory where the text file containing the BMM events will be stored. // Same as {@link UserBackupManagerFiles} private static final String BACKUP_PERSISTENT_DIR = "backup"; + private static final String INITIAL_SETUP_TIMESTAMP_KEY = "initialSetupTimestamp"; + // Retention period of 60 days (in millisec) for the BMM Events. + // After tha time has passed the text file containing the BMM events will be emptied + private static final long LOGS_RETENTION_PERIOD_MILLISEC = 60 * TimeUnit.DAYS.toMillis(1); + // Size limit for the text file containing the BMM events + private static final long BMM_FILE_SIZE_LIMIT_BYTES = 25 * 1024 * 1000; // 2.5 MB + + // We cache the value of IsAfterRetentionPeriod() to avoid unnecessary disk I/O + // mIsAfterRetentionPeriodCached tracks if we have cached the value of IsAfterRetentionPeriod() + private boolean mIsAfterRetentionPeriodCached = false; + // The cached value of IsAfterRetentionPeriod() + private boolean mIsAfterRetentionPeriod; + // If isFileLargerThanSizeLimit(bmmEvents) returns true we cache the value to avoid + // unnecessary disk I/O + private boolean mIsFileLargerThanSizeLimit = false; /** * Parses the BackupManagerMonitor bundle for a RESTORE event in a series of strings that * will be persisted in a text file and printed in the dumpsys. * - * If the evenntBundle passed is not a RESTORE event, return early + * If the eventBundle passed is not a RESTORE event, return early * * Key information related to the event: * - Timestamp (HAS TO ALWAYS BE THE FIRST LINE OF EACH EVENT) @@ -62,17 +84,22 @@ public class BackupManagerMonitorDumpsysUtils { * - Agent logs (if available) * * Example of formatting: - * RESTORE Event: [2023-08-18 17:16:00.735] Agent - Agent logging results - * Package name: com.android.wallpaperbackup - * Agent Logs: - * Data Type: wlp_img_system - * Item restored: 0/1 - * Agent Error - Category: no_wallpaper, Count: 1 - * Data Type: wlp_img_lock - * Item restored: 0/1 - * Agent Error - Category: no_wallpaper, Count: 1 + * [2023-09-21 14:43:33.824] - Agent logging results + * Package: com.android.wallpaperbackup + * Agent Logs: + * Data Type: wlp_img_system + * Item restored: 0/1 + * Agent Error - Category: no_wallpaper, Count: 1 + * Data Type: wlp_img_lock + * Item restored: 0/1 + * Agent Error - Category: no_wallpaper, Count: 1 */ public void parseBackupManagerMonitorRestoreEventForDumpsys(Bundle eventBundle) { + if (isAfterRetentionPeriod()) { + // We only log data for the first 60 days since setup + return; + } + if (eventBundle == null) { return; } @@ -89,8 +116,19 @@ public class BackupManagerMonitorDumpsysUtils { } File bmmEvents = getBMMEventsFile(); + if (bmmEvents.length() == 0) { + // We are parsing the first restore event. + // Time to also record the setup timestamp of the device + recordSetUpTimestamp(); + } + + if(isFileLargerThanSizeLimit(bmmEvents)){ + // Do not write more events if the file is over size limit + return; + } + try (FileOutputStream out = new FileOutputStream(bmmEvents, /*append*/ true); - PrintWriter pw = new FastPrintWriter(out);) { + PrintWriter pw = new FastPrintWriter(out);) { int eventCategory = eventBundle.getInt(BackupManagerMonitor.EXTRA_LOG_EVENT_CATEGORY); int eventId = eventBundle.getInt(BackupManagerMonitor.EXTRA_LOG_EVENT_ID); @@ -101,17 +139,16 @@ public class BackupManagerMonitorDumpsysUtils { return; } - pw.println("RESTORE Event: [" + timestamp() + "] " + - getCategory(eventCategory) + " - " + - getId(eventId)); + pw.println("[" + timestamp() + "] - " + getId(eventId)); if (eventBundle.containsKey(BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME)) { - pw.println("\tPackage name: " + pw.println("\tPackage: " + eventBundle.getString(BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME)); } // TODO(b/296818666): add extras to the events addAgentLogsIfAvailable(eventBundle, pw); + addExtrasIfAvailable(eventBundle, pw); } catch (java.io.IOException e) { Slog.e(TAG, "IO Exception when writing BMM events to file: " + e); } @@ -156,6 +193,37 @@ public class BackupManagerMonitorDumpsysUtils { } } + /** + * Extracts some extras (defined in BackupManagerMonitor as EXTRA_LOG_<description>) + * from the BackupManagerMonitor event. Not all extras have the same importance. For now only + * focus on extras relating to version mismatches between packages on the source and target. + * + * When an event with ID LOG_EVENT_ID_RESTORE_VERSION_HIGHER (trying to restore from higher to + * lower version of a package) parse: + * EXTRA_LOG_RESTORE_VERSION [int]: the version of the package on the source + * EXTRA_LOG_RESTORE_ANYWAY [bool]: if the package allows restore any version + * EXTRA_LOG_RESTORE_VERSION_TARGET [int]: an extra to record the package version on the target + */ + private void addExtrasIfAvailable(Bundle eventBundle, PrintWriter pw) { + if (eventBundle.getInt(BackupManagerMonitor.EXTRA_LOG_EVENT_ID) == + BackupManagerMonitor.LOG_EVENT_ID_RESTORE_VERSION_HIGHER) { + if (eventBundle.containsKey(BackupManagerMonitor.EXTRA_LOG_RESTORE_ANYWAY)) { + pw.println("\t\tPackage supports RestoreAnyVersion: " + + eventBundle.getBoolean(BackupManagerMonitor.EXTRA_LOG_RESTORE_ANYWAY)); + } + if (eventBundle.containsKey(BackupManagerMonitor.EXTRA_LOG_RESTORE_VERSION)) { + pw.println("\t\tPackage version on source: " + + eventBundle.getLong(BackupManagerMonitor.EXTRA_LOG_RESTORE_VERSION)); + } + if (eventBundle.containsKey( + BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_LONG_VERSION)) { + pw.println("\t\tPackage version on target: " + + eventBundle.getLong( + BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_LONG_VERSION)); + } + } + } + /* * Get the path of the text files which stores the BMM events */ @@ -165,6 +233,13 @@ public class BackupManagerMonitorDumpsysUtils { return fname; } + public boolean isFileLargerThanSizeLimit(File events){ + if (!mIsFileLargerThanSizeLimit) { + mIsFileLargerThanSizeLimit = events.length() > getBMMEventsFileSizeLimit(); + } + return mIsFileLargerThanSizeLimit; + } + private String timestamp() { long currentTime = System.currentTimeMillis(); Date date = new Date(currentTime); @@ -245,6 +320,32 @@ public class BackupManagerMonitorDumpsysUtils { case BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED -> "Transport non-incremental backup required"; case BackupManagerMonitor.LOG_EVENT_ID_AGENT_LOGGING_RESULTS -> "Agent logging results"; + case BackupManagerMonitor.LOG_EVENT_ID_START_SYSTEM_RESTORE -> "Start system restore"; + case BackupManagerMonitor.LOG_EVENT_ID_START_RESTORE_AT_INSTALL -> + "Start restore at install"; + case BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_DURING_START_RESTORE -> + "Transport error during start restore"; + case BackupManagerMonitor.LOG_EVENT_ID_CANNOT_GET_NEXT_PKG_NAME -> + "Cannot get next package name"; + case BackupManagerMonitor.LOG_EVENT_ID_UNKNOWN_RESTORE_TYPE -> "Unknown restore type"; + case BackupManagerMonitor.LOG_EVENT_ID_KV_RESTORE -> "KV restore"; + case BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE -> "Full restore"; + case BackupManagerMonitor.LOG_EVENT_ID_NO_NEXT_RESTORE_TARGET -> + "No next restore target"; + case BackupManagerMonitor.LOG_EVENT_ID_KV_AGENT_ERROR -> "KV agent error"; + case BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_RESTORE_FINISHED -> + "Package restore finished"; + case BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_KV_RESTORE -> + "Transport error KV restore"; + case BackupManagerMonitor.LOG_EVENT_ID_NO_FEEDER_THREAD -> "No feeder thread"; + case BackupManagerMonitor.LOG_EVENT_ID_FULL_AGENT_ERROR -> "Full agent error"; + case BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_FULL_RESTORE -> + "Transport error full restore"; + case BackupManagerMonitor.LOG_EVENT_ID_RESTORE_COMPLETE -> "Restore complete"; + case BackupManagerMonitor.LOG_EVENT_ID_START_PACKAGE_RESTORE -> + "Start package restore"; + case BackupManagerMonitor.LOG_EVENT_ID_AGENT_FAILURE -> + "Agent failure"; default -> "Unknown log event ID: " + code; }; return id; @@ -257,4 +358,128 @@ public class BackupManagerMonitorDumpsysUtils { default -> false; }; } + + /** + * Store the timestamp when the device was set up (date when the first BMM event is parsed) + * in a text file. + */ + @VisibleForTesting + void recordSetUpTimestamp() { + File setupDateFile = getSetUpDateFile(); + // record setup timestamp only once + if (setupDateFile.length() == 0) { + try (FileOutputStream out = new FileOutputStream(setupDateFile, /*append*/ true); + PrintWriter pw = new FastPrintWriter(out);) { + long currentDate = System.currentTimeMillis(); + pw.println(currentDate); + } catch (IOException e) { + Slog.w(TAG, "An error occurred while recording the setup date: " + + e.getMessage()); + } + } + + } + + @VisibleForTesting + String getSetUpDate() { + File fname = getSetUpDateFile(); + try (FileInputStream inputStream = new FileInputStream(fname); + InputStreamReader reader = new InputStreamReader(inputStream); + BufferedReader bufferedReader = new BufferedReader(reader);) { + return bufferedReader.readLine(); + } catch (Exception e) { + Slog.w(TAG, "An error occurred while reading the date: " + e.getMessage()); + return "Could not retrieve setup date"; + } + } + + @VisibleForTesting + static boolean isDateAfterNMillisec(long startTimeStamp, long endTimeStamp, long millisec) { + if (startTimeStamp > endTimeStamp) { + // Something has gone wrong, timeStamp1 should always precede timeStamp2. + // Out of caution return true: we would delete the logs rather than + // risking them being kept for longer than the retention period + return true; + } + long timeDifferenceMillis = endTimeStamp - startTimeStamp; + return (timeDifferenceMillis >= millisec); + } + + /** + * Check if current date is after retention period + */ + @VisibleForTesting + boolean isAfterRetentionPeriod() { + if (mIsAfterRetentionPeriodCached) { + return mIsAfterRetentionPeriod; + } else { + File setUpDateFile = getSetUpDateFile(); + if (setUpDateFile.length() == 0) { + // We are yet to record a setup date. This means we haven't parsed the first event. + mIsAfterRetentionPeriod = false; + mIsAfterRetentionPeriodCached = true; + return false; + } + try { + long setupTimestamp = Long.parseLong(getSetUpDate()); + long currentTimestamp = System.currentTimeMillis(); + mIsAfterRetentionPeriod = isDateAfterNMillisec(setupTimestamp, currentTimestamp, + getRetentionPeriodInMillisec()); + mIsAfterRetentionPeriodCached = true; + return mIsAfterRetentionPeriod; + } catch (NumberFormatException e) { + // An error occurred when parsing the setup timestamp. + // Out of caution return true: we would delete the logs rather than + // risking them being kept for longer than the retention period + mIsAfterRetentionPeriod = true; + mIsAfterRetentionPeriodCached = true; + return true; + } + } + } + + @VisibleForTesting + File getSetUpDateFile() { + File dataDir = new File(Environment.getDataDirectory(), BACKUP_PERSISTENT_DIR); + File setupDateFile = new File(dataDir, INITIAL_SETUP_TIMESTAMP_KEY + ".txt"); + return setupDateFile; + } + + @VisibleForTesting + long getRetentionPeriodInMillisec() { + return LOGS_RETENTION_PERIOD_MILLISEC; + } + + @VisibleForTesting + long getBMMEventsFileSizeLimit(){ + return BMM_FILE_SIZE_LIMIT_BYTES; + } + + /** + * Delete the BMM Events file after the retention period has passed. + * + * @return true if the retention period has passed false otherwise. + * we want to return true even if we were unable to delete the file, as this will prevent + * expired BMM events from being printed to the dumpsys + */ + public boolean deleteExpiredBMMEvents() { + try { + if (isAfterRetentionPeriod()) { + File bmmEvents = getBMMEventsFile(); + if (bmmEvents.exists()) { + if (bmmEvents.delete()) { + Slog.i(TAG, "Deleted expired BMM Events"); + } else { + Slog.e(TAG, "Unable to delete expired BMM Events"); + } + } + return true; + } + return false; + } catch (Exception e) { + // Handle any unexpected exceptions + // To be safe we return true as we want to avoid exposing expired BMMEvents + return true; + } + } } diff --git a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorEventSender.java b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorEventSender.java index 92e3107b6977..549d08c03933 100644 --- a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorEventSender.java +++ b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorEventSender.java @@ -222,4 +222,21 @@ public class BackupManagerMonitorEventSender { extras.putBoolean(key, value); return extras; } + + /** + * Adds given key-value pair in the bundle and returns the bundle. If bundle was null it will + * be created. + * + * @param extras - bundle where to add key-value to, if null a new bundle will be created. + * @param key - key. + * @param value - value. + * @return extras if it was not null and new bundle otherwise. + */ + public static Bundle putMonitoringExtra(Bundle extras, String key, int value) { + if (extras == null) { + extras = new Bundle(); + } + extras.putInt(key, value); + return extras; + } } diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java index 3b13410720af..31e5cb82d24c 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java @@ -37,6 +37,7 @@ import android.app.Activity; import android.app.ActivityOptions; import android.app.PendingIntent; import android.app.admin.DevicePolicyManager; +import android.app.compat.CompatChanges; import android.companion.AssociationInfo; import android.companion.virtual.IVirtualDevice; import android.companion.virtual.IVirtualDeviceActivityListener; @@ -51,6 +52,8 @@ import android.companion.virtual.audio.IAudioRoutingCallback; import android.companion.virtual.flags.Flags; import android.companion.virtual.sensor.VirtualSensor; import android.companion.virtual.sensor.VirtualSensorEvent; +import android.compat.annotation.ChangeId; +import android.compat.annotation.EnabledAfter; import android.content.AttributionSource; import android.content.ComponentName; import android.content.Context; @@ -75,6 +78,7 @@ import android.hardware.input.VirtualNavigationTouchpadConfig; import android.hardware.input.VirtualTouchEvent; import android.hardware.input.VirtualTouchscreenConfig; import android.os.Binder; +import android.os.Build; import android.os.IBinder; import android.os.LocaleList; import android.os.Looper; @@ -115,12 +119,33 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub private static final String TAG = "VirtualDeviceImpl"; + /** + * Virtual displays created by a {@link VirtualDeviceManager.VirtualDevice} are more consistent + * with virtual displays created via {@link DisplayManager} and allow for the creation of + * private, auto-mirror, and fixed orientation displays since + * {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}. + * + * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_PUBLIC + * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY + * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR + * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT + */ + @ChangeId + @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) + public static final long MAKE_VIRTUAL_DISPLAY_FLAGS_CONSISTENT_WITH_DISPLAY_MANAGER = + 294837146L; + private static final int DEFAULT_VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_TOUCH_FEEDBACK_DISABLED | DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL | DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH | DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_FOCUS; + private static final int DEFAULT_VIRTUAL_DISPLAY_FLAGS_PRE_VIC = + DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC + | DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT + | DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY; + private static final String PERSISTENT_ID_PREFIX_CDM_ASSOCIATION = "companion:"; /** @@ -130,6 +155,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub private final Object mVirtualDeviceLock = new Object(); + private final int mBaseVirtualDisplayFlags; + private final Context mContext; private final AssociationInfo mAssociationInfo; private final VirtualDeviceManagerService mService; @@ -311,6 +338,16 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub ? mParams.getBlockedActivities() : mParams.getAllowedActivities(); } + + int flags = DEFAULT_VIRTUAL_DISPLAY_FLAGS; + if (!CompatChanges.isChangeEnabled( + MAKE_VIRTUAL_DISPLAY_FLAGS_CONSISTENT_WITH_DISPLAY_MANAGER, mOwnerUid)) { + flags |= DEFAULT_VIRTUAL_DISPLAY_FLAGS_PRE_VIC; + } + if (mParams.getLockState() == VirtualDeviceParams.LOCK_STATE_ALWAYS_UNLOCKED) { + flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED; + } + mBaseVirtualDisplayFlags = flags; } @VisibleForTesting @@ -323,11 +360,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub * device. */ int getBaseVirtualDisplayFlags() { - int flags = DEFAULT_VIRTUAL_DISPLAY_FLAGS; - if (mParams.getLockState() == VirtualDeviceParams.LOCK_STATE_ALWAYS_UNLOCKED) { - flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED; - } - return flags; + return mBaseVirtualDisplayFlags; } /** Returns the camera access controller of this device. */ diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java index d94f4f22f2c9..556eba6ced76 100644 --- a/services/core/java/com/android/server/BatteryService.java +++ b/services/core/java/com/android/server/BatteryService.java @@ -167,6 +167,8 @@ public final class BatteryService extends SystemService { private int mBatteryNearlyFullLevel; private int mShutdownBatteryTemperature; + private static String sSystemUiPackage; + private int mPlugType; private int mLastPlugType = -1; // Extra state so we can detect first run @@ -228,6 +230,8 @@ public final class BatteryService extends SystemService { com.android.internal.R.integer.config_lowBatteryCloseWarningBump); mShutdownBatteryTemperature = mContext.getResources().getInteger( com.android.internal.R.integer.config_shutdownBatteryTemperature); + sSystemUiPackage = mContext.getResources().getString( + com.android.internal.R.string.config_systemUi); mBatteryLevelsEventQueue = new ArrayDeque<>(); mMetricsLogger = new MetricsLogger(); @@ -750,8 +754,21 @@ public final class BatteryService extends SystemService { + ", info:" + mHealthInfo.toString()); } - mHandler.post(() -> ActivityManager.broadcastStickyIntent(intent, AppOpsManager.OP_NONE, - mBatteryChangedOptions, UserHandle.USER_ALL)); + mHandler.post(() -> broadcastBatteryChangedIntent(intent, mBatteryChangedOptions)); + } + + private static void broadcastBatteryChangedIntent(Intent intent, Bundle options) { + // TODO (293959093): It is important that SystemUI receives this broadcast as soon as + // possible. Ideally, it should be using binder callbacks but until then, dispatch this + // as a foreground broadcast to SystemUI. + final Intent fgIntent = new Intent(intent); + fgIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); + fgIntent.setPackage(sSystemUiPackage); + ActivityManager.broadcastStickyIntent(fgIntent, AppOpsManager.OP_NONE, + options, UserHandle.USER_ALL); + + ActivityManager.broadcastStickyIntent(intent, new String[] {sSystemUiPackage}, + AppOpsManager.OP_NONE, options, UserHandle.USER_ALL); } private void sendBatteryLevelChangedIntentLocked() { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index cbc9ff16e6de..d3ce47c56e49 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -315,7 +315,6 @@ import android.net.ConnectivityManager; import android.net.Proxy; import android.net.Uri; import android.os.AppZygote; -import android.os.BatteryManager; import android.os.BatteryStats; import android.os.Binder; import android.os.BinderProxy; @@ -15096,16 +15095,6 @@ public class ActivityManagerService extends IActivityManager.Stub } } - // STOPSHIP(b/298884211): Remove this logging - if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) { - final int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); - if (level < 0) { - Slog.wtf(BroadcastQueue.TAG, "Unexpected broadcast: " + intent - + "; callingUid: " + callingUid + ", callingPid: " + callingPid, - new Throwable()); - } - } - int[] users; if (userId == UserHandle.USER_ALL) { // Caller wants broadcast to go to all started users. diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java index a3dac6dc3404..eb219a8819c6 100644 --- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java @@ -59,7 +59,6 @@ import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; -import android.os.BatteryManager; import android.os.Bundle; import android.os.BundleMerger; import android.os.Handler; @@ -1078,16 +1077,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue { queue.lastProcessState = app.mState.getCurProcState(); if (receiver instanceof BroadcastFilter) { notifyScheduleRegisteredReceiver(app, r, (BroadcastFilter) receiver); - // STOPSHIP(b/298884211): Remove this logging - if (Intent.ACTION_BATTERY_CHANGED.equals(receiverIntent.getAction())) { - int level = receiverIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); - if (level < 0) { - Slog.wtf(TAG, "Dispatching unexpected broadcast: " + receiverIntent - + " to " + receiver - + "; callingUid: " + r.callingUid - + ", callingPid: " + r.callingPid); - } - } thread.scheduleRegisteredReceiver( ((BroadcastFilter) receiver).receiverList.receiver, receiverIntent, r.resultCode, r.resultData, r.resultExtras, diff --git a/services/core/java/com/android/server/am/ForegroundServiceTypeLoggerModule.java b/services/core/java/com/android/server/am/ForegroundServiceTypeLoggerModule.java index e0a71d46641a..caafb421a147 100644 --- a/services/core/java/com/android/server/am/ForegroundServiceTypeLoggerModule.java +++ b/services/core/java/com/android/server/am/ForegroundServiceTypeLoggerModule.java @@ -220,6 +220,24 @@ public class ForegroundServiceTypeLoggerModule { final ArrayList<Long> timestampsFound = new ArrayList<>(); for (int i = 0, size = apiTypes.size(); i < size; i++) { final int apiType = apiTypes.get(i); + + // remove the FGS record from the stack + final ArrayMap<ComponentName, ServiceRecord> runningFgsOfType = + uidState.mRunningFgs.get(apiType); + if (runningFgsOfType == null) { + Slog.w(TAG, "Could not find appropriate running FGS for FGS stop for UID " + uid + + " in package " + record.packageName); + continue; + } + + runningFgsOfType.remove(record.getComponentName()); + if (runningFgsOfType.size() == 0) { + // there's no more FGS running for this type, just get rid of it + uidState.mRunningFgs.remove(apiType); + // but we need to keep track of the timestamp in case an API stops + uidState.mLastFgsTimeStamp.put(apiType, System.currentTimeMillis()); + } + final int apiTypeIndex = uidState.mOpenWithFgsCount.indexOfKey(apiType); if (apiTypeIndex < 0) { Slog.w(TAG, "Logger should be tracking FGS types correctly for UID " + uid @@ -238,22 +256,6 @@ public class ForegroundServiceTypeLoggerModule { // remove the last API close call uidState.mApiClosedCalls.remove(apiType); } - // remove the FGS record from the stack - final ArrayMap<ComponentName, ServiceRecord> runningFgsOfType = - uidState.mRunningFgs.get(apiType); - if (runningFgsOfType == null) { - Slog.w(TAG, "Could not find appropriate running FGS for FGS stop for UID " + uid - + " in package " + record.packageName); - continue; - } - - runningFgsOfType.remove(record.getComponentName()); - if (runningFgsOfType.size() == 0) { - // there's no more FGS running for this type, just get rid of it - uidState.mRunningFgs.remove(apiType); - // but we need to keep track of the timestamp in case an API stops - uidState.mLastFgsTimeStamp.put(apiType, System.currentTimeMillis()); - } } if (!apisFound.isEmpty()) { // time to log the call @@ -383,9 +385,14 @@ public class ForegroundServiceTypeLoggerModule { // initialize if we don't contain uidState.mOpenedWithoutFgsCount.put(apiType, 0); } - if (uidState.mOpenedWithoutFgsCount.get(apiType) != 0) { + int apiOpenWithoutFgsCount = uidState.mOpenedWithoutFgsCount.get(apiType); + if (apiOpenWithoutFgsCount != 0) { + apiOpenWithoutFgsCount -= 1; + if (apiOpenWithoutFgsCount == 0) { + uidState.mApiOpenCalls.remove(apiType); + } uidState.mOpenedWithoutFgsCount - .put(apiType, uidState.mOpenedWithoutFgsCount.get(apiType) - 1); + .put(apiType, apiOpenWithoutFgsCount); return System.currentTimeMillis(); } // This is a part of a valid active FGS diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java index 905589f70dc1..824bdd4ccb79 100644 --- a/services/core/java/com/android/server/app/GameManagerService.java +++ b/services/core/java/com/android/server/app/GameManagerService.java @@ -417,59 +417,6 @@ public final class GameManagerService extends IGameManagerService.Stub { } } - public enum FrameRate { - FPS_DEFAULT(0), - FPS_30(30), - FPS_36(36), - FPS_40(40), - FPS_45(45), - FPS_48(48), - FPS_60(60), - FPS_72(72), - FPS_90(90), - FPS_120(120), - FPS_144(144), - FPS_INVALID(-1); - - public final int fps; - - FrameRate(int fps) { - this.fps = fps; - } - } - - // Turn the raw string to the corresponding fps int. - // Return 0 when disabling, -1 for invalid fps. - static int getFpsInt(String raw) { - // TODO(b/243448953): make sure this translates to proper values based on current display - switch (raw) { - case "30": - return FrameRate.FPS_30.fps; - case "36": - return FrameRate.FPS_36.fps; - case "40": - return FrameRate.FPS_40.fps; - case "45": - return FrameRate.FPS_45.fps; - case "48": - return FrameRate.FPS_48.fps; - case "60": - return FrameRate.FPS_60.fps; - case "72": - return FrameRate.FPS_72.fps; - case "90": - return FrameRate.FPS_90.fps; - case "120": - return FrameRate.FPS_120.fps; - case "144": - return FrameRate.FPS_144.fps; - case "disable": - case "": - return FrameRate.FPS_DEFAULT.fps; - } - return FrameRate.FPS_INVALID.fps; - } - /** * Called by games to communicate the current state to the platform. * @@ -717,7 +664,12 @@ public final class GameManagerService extends IGameManagerService.Stub { } public synchronized int getFps() { - return GameManagerService.getFpsInt(mFps); + try { + final int fpsInt = Integer.parseInt(mFps); + return fpsInt; + } catch (NumberFormatException e) { + return 0; + } } synchronized String getFpsStr() { @@ -757,7 +709,12 @@ public final class GameManagerService extends IGameManagerService.Stub { } android.app.GameModeConfiguration toPublicGameModeConfig() { - int fpsOverride = getFpsInt(mFps); + int fpsOverride; + try { + fpsOverride = Integer.parseInt(mFps); + } catch (NumberFormatException e) { + fpsOverride = 0; + } // TODO(b/243448953): match to proper value in case of display change? fpsOverride = fpsOverride > 0 ? fpsOverride : android.app.GameModeConfiguration.FPS_OVERRIDE_NONE; diff --git a/services/core/java/com/android/server/app/GameManagerShellCommand.java b/services/core/java/com/android/server/app/GameManagerShellCommand.java index 00ff489ee0ff..ab57c4fe837e 100644 --- a/services/core/java/com/android/server/app/GameManagerShellCommand.java +++ b/services/core/java/com/android/server/app/GameManagerShellCommand.java @@ -241,8 +241,10 @@ public class GameManagerShellCommand extends ShellCommand { case "--fps": if (fpsStr == null) { fpsStr = getNextArgRequired(); - if (fpsStr != null && GameManagerService.getFpsInt(fpsStr) == -1) { - pw.println("Invalid frame rate '" + fpsStr + "'"); + try { + Integer.parseInt(fpsStr); + } catch (NumberFormatException e) { + pw.println("Invalid frame rate: '" + fpsStr + "'"); return -1; } } else { @@ -375,8 +377,8 @@ public class GameManagerShellCommand extends ShellCommand { pw.println(" --downscale [0.3|0.35|0.4|0.45|0.5|0.55|0.6|0.65"); pw.println(" |0.7|0.75|0.8|0.85|0.9|disable]: Set app to run at the"); pw.println(" specified scaling ratio."); - pw.println(" --fps [30|45|60|90|120|disable]: Set app to run at the specified fps,"); - pw.println(" if supported."); + pw.println(" --fps: Integer value to set app to run at the specified fps,"); + pw.println(" if supported. 0 to disable."); pw.println(" reset [--mode [2|3|performance|battery] --user <USER_ID>] <PACKAGE_NAME>"); pw.println(" Resets the game mode of the app to device configuration."); pw.println(" This should only be used to reset any override to non custom game mode"); diff --git a/services/core/java/com/android/server/audio/SoundDoseHelper.java b/services/core/java/com/android/server/audio/SoundDoseHelper.java index 95b6c2cef963..81365bfbf2a6 100644 --- a/services/core/java/com/android/server/audio/SoundDoseHelper.java +++ b/services/core/java/com/android/server/audio/SoundDoseHelper.java @@ -719,7 +719,9 @@ public class SoundDoseHelper { /*package*/ void initSafeMediaVolumeIndex() { for (int i = 0; i < mSafeMediaVolumeDevices.size(); ++i) { int deviceType = mSafeMediaVolumeDevices.keyAt(i); - mSafeMediaVolumeDevices.put(deviceType, getSafeDeviceMediaVolumeIndex(deviceType)); + if (mSafeMediaVolumeDevices.valueAt(i) == SAFE_MEDIA_VOLUME_UNINITIALIZED) { + mSafeMediaVolumeDevices.put(deviceType, getSafeDeviceMediaVolumeIndex(deviceType)); + } } } @@ -743,7 +745,7 @@ public class SoundDoseHelper { } /*package*/ boolean safeDevicesContains(int device) { - return mSafeMediaVolumeDevices.indexOfKey(device) >= 0; + return mSafeMediaVolumeDevices.get(device, SAFE_MEDIA_VOLUME_UNINITIALIZED) >= 0; } /*package*/ void invalidatPendingVolumeCommand() { @@ -1014,6 +1016,7 @@ public class SoundDoseHelper { initCsd(); synchronized (mSafeMediaVolumeStateLock) { + initSafeMediaVolumeIndex(); updateSafeMediaVolume_l(caller); } } @@ -1065,11 +1068,18 @@ public class SoundDoseHelper { } private int getSafeDeviceMediaVolumeIndex(int deviceType) { - // legacy implementation uses mSafeMediaVolumeIndex for wired HS/HP - // instead of computing it from the volume curves - if ((deviceType == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE - || deviceType == AudioSystem.DEVICE_OUT_WIRED_HEADSET) && !mEnableCsd.get()) { - return mSafeMediaVolumeIndex; + if (!mEnableCsd.get()) { + // legacy hearing safety only for wired and USB HS/HP + if (deviceType == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE + || deviceType == AudioSystem.DEVICE_OUT_WIRED_HEADSET) { + // legacy hearing safety uses mSafeMediaVolumeIndex for wired HS/HP + // instead of computing it from the volume curves + return mSafeMediaVolumeIndex; + } + + if (deviceType != AudioSystem.DEVICE_OUT_USB_HEADSET) { + return SAFE_MEDIA_VOLUME_UNINITIALIZED; + } } // determine UI volume index corresponding to the wanted safe gain in dBFS diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java index 50d375c56f4a..35fc43ae5f74 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java @@ -43,7 +43,6 @@ import com.android.server.biometrics.log.BiometricLogger; import com.android.server.biometrics.log.OperationContextExt; import com.android.server.biometrics.sensors.AuthSessionCoordinator; import com.android.server.biometrics.sensors.AuthenticationClient; -import com.android.server.biometrics.sensors.BiometricNotificationUtils; import com.android.server.biometrics.sensors.ClientMonitorCallback; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback; @@ -242,9 +241,6 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession, FaceAut vendorCode, getTargetUserId())); - if (error == BiometricConstants.BIOMETRIC_ERROR_RE_ENROLL) { - BiometricNotificationUtils.showReEnrollmentNotification(getContext()); - } super.onError(error, vendorCode); } diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java index df16c5bcc673..4ef2f1e98a80 100644 --- a/services/core/java/com/android/server/camera/CameraServiceProxy.java +++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java @@ -77,6 +77,7 @@ import android.view.WindowManagerGlobal; import com.android.framework.protobuf.nano.MessageNano; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; +import com.android.internal.camera.flags.Flags; import com.android.internal.util.FrameworkStatsLog; import com.android.server.LocalServices; import com.android.server.ServiceThread; @@ -244,6 +245,7 @@ public class CameraServiceProxy extends SystemService public List<CameraStreamStats> mStreamStats; public String mUserTag; public int mVideoStabilizationMode; + public boolean mUsedUltraWide; public final long mLogId; public final int mSessionIndex; @@ -271,7 +273,8 @@ public class CameraServiceProxy extends SystemService public void markCompleted(int internalReconfigure, long requestCount, long resultErrorCount, boolean deviceError, List<CameraStreamStats> streamStats, String userTag, - int videoStabilizationMode, CameraExtensionSessionStats extStats) { + int videoStabilizationMode, boolean usedUltraWide, + CameraExtensionSessionStats extStats) { if (mCompleted) { return; } @@ -284,6 +287,7 @@ public class CameraServiceProxy extends SystemService mStreamStats = streamStats; mUserTag = userTag; mVideoStabilizationMode = videoStabilizationMode; + mUsedUltraWide = usedUltraWide; mExtSessionStats = extStats; if (CameraServiceProxy.DEBUG) { Slog.v(TAG, "A camera facing " + cameraFacingToString(mCameraFacing) + @@ -873,6 +877,10 @@ public class CameraServiceProxy extends SystemService streamCount = e.mStreamStats.size(); } if (CameraServiceProxy.DEBUG) { + String ultrawideDebug = Flags.logUltrawideUsage() + ? ", wideAngleUsage " + e.mUsedUltraWide + : ""; + Slog.v(TAG, "CAMERA_ACTION_EVENT: action " + e.mAction + " clientName " + e.mClientName + ", duration " + e.getDuration() @@ -889,6 +897,7 @@ public class CameraServiceProxy extends SystemService + ", streamCount is " + streamCount + ", userTag is " + e.mUserTag + ", videoStabilizationMode " + e.mVideoStabilizationMode + + ultrawideDebug + ", logId " + e.mLogId + ", sessionIndex " + e.mSessionIndex + ", mExtSessionStats {type " + extensionType @@ -952,8 +961,9 @@ public class CameraServiceProxy extends SystemService MessageNano.toByteArray(streamProtos[2]), MessageNano.toByteArray(streamProtos[3]), MessageNano.toByteArray(streamProtos[4]), - e.mUserTag, e.mVideoStabilizationMode, e.mLogId, e.mSessionIndex, - extensionType, extensionIsAdvanced); + e.mUserTag, e.mVideoStabilizationMode, + e.mLogId, e.mSessionIndex, + extensionType, extensionIsAdvanced, e.mUsedUltraWide); } } @@ -1148,6 +1158,7 @@ public class CameraServiceProxy extends SystemService List<CameraStreamStats> streamStats = cameraState.getStreamStats(); String userTag = cameraState.getUserTag(); int videoStabilizationMode = cameraState.getVideoStabilizationMode(); + boolean usedUltraWide = Flags.logUltrawideUsage() ? cameraState.getUsedUltraWide() : false; long logId = cameraState.getLogId(); int sessionIdx = cameraState.getSessionIndex(); CameraExtensionSessionStats extSessionStats = cameraState.getExtensionSessionStats(); @@ -1205,7 +1216,7 @@ public class CameraServiceProxy extends SystemService Slog.w(TAG, "Camera " + cameraId + " was already marked as active"); oldEvent.markCompleted(/*internalReconfigure*/0, /*requestCount*/0, /*resultErrorCount*/0, /*deviceError*/false, streamStats, - /*userTag*/"", /*videoStabilizationMode*/-1, + /*userTag*/"", /*videoStabilizationMode*/-1, /*usedUltraWide*/false, new CameraExtensionSessionStats()); mCameraUsageHistory.add(oldEvent); } @@ -1217,7 +1228,7 @@ public class CameraServiceProxy extends SystemService doneEvent.markCompleted(internalReconfigureCount, requestCount, resultErrorCount, deviceError, streamStats, userTag, - videoStabilizationMode, extSessionStats); + videoStabilizationMode, usedUltraWide, extSessionStats); mCameraUsageHistory.add(doneEvent); // Do not double count device error deviceError = false; diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java index 1012bc1828c0..fac727f17283 100644 --- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java +++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java @@ -37,7 +37,8 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; -import android.app.TaskStackListener; +import android.app.ActivityManagerInternal; +import android.app.IProcessObserver; import android.content.Context; import android.hardware.devicestate.DeviceStateInfo; import android.hardware.devicestate.DeviceStateManager; @@ -184,7 +185,30 @@ public final class DeviceStateManagerService extends SystemService { private final SystemPropertySetter mSystemPropertySetter; @VisibleForTesting - TaskStackListener mOverrideRequestTaskStackListener = new OverrideRequestTaskStackListener(); + final IProcessObserver mProcessObserver = new IProcessObserver.Stub() { + @Override + public void onForegroundActivitiesChanged(int pid, int uid, boolean fg) { + synchronized (mLock) { + if (!shouldCancelOverrideRequestWhenRequesterNotOnTop()) { + return; + } + + OverrideRequest request = mActiveOverride.get(); + if (pid != request.getPid() || uid != request.getUid()) { + return; + } + if (!fg) { + mOverrideRequestController.cancelRequest(request); + } + } + } + + @Override + public void onProcessDied(int pid, int uid) {} + + @Override + public void onForegroundServicesChanged(int pid, int uid, int serviceTypes) {} + }; @VisibleForTesting ActivityTaskManagerInternal.ScreenObserver mOverrideRequestScreenObserver = new OverrideRequestScreenObserver(); @@ -239,8 +263,9 @@ public final class DeviceStateManagerService extends SystemService { mFoldedDeviceStates = readFoldedStates(); } - mActivityTaskManagerInternal.registerTaskStackListener(mOverrideRequestTaskStackListener); mActivityTaskManagerInternal.registerScreenObserver(mOverrideRequestScreenObserver); + LocalServices.getService(ActivityManagerInternal.class).registerProcessObserver( + mProcessObserver); } @VisibleForTesting @@ -1288,23 +1313,6 @@ public final class DeviceStateManagerService extends SystemService { return deviceState.hasFlag(DeviceState.FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP); } - private class OverrideRequestTaskStackListener extends TaskStackListener { - @Override - public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) - throws RemoteException { - synchronized (mLock) { - if (!shouldCancelOverrideRequestWhenRequesterNotOnTop()) { - return; - } - - OverrideRequest request = mActiveOverride.get(); - if (!isTopApp(request.getPid())) { - mOverrideRequestController.cancelRequest(request); - } - } - } - } - private class OverrideRequestScreenObserver implements ActivityTaskManagerInternal.ScreenObserver { diff --git a/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java b/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java index f4c84e7fe464..f9aefd0535d0 100644 --- a/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java +++ b/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java @@ -109,6 +109,7 @@ class DeviceStateNotificationController extends BroadcastReceiver { .setPackage(mContext.getPackageName()); final PendingIntent pendingIntent = PendingIntent.getBroadcast( mContext, 0 /* requestCode */, intent, PendingIntent.FLAG_IMMUTABLE); + showNotification( info.name, info.activeNotificationTitle, String.format(info.activeNotificationContent, requesterApplicationLabel), @@ -175,7 +176,7 @@ class DeviceStateNotificationController extends BroadcastReceiver { if (getNotificationInfos().get(state) == null) { return; } - mNotificationManager.cancel(NOTIFICATION_TAG, NOTIFICATION_ID); + mHandler.post(() -> mNotificationManager.cancel(NOTIFICATION_TAG, NOTIFICATION_ID)); } @Override @@ -219,8 +220,10 @@ class DeviceStateNotificationController extends BroadcastReceiver { builder.addAction(action); } - mNotificationManager.createNotificationChannel(channel); - mNotificationManager.notify(NOTIFICATION_TAG, NOTIFICATION_ID, builder.build()); + mHandler.post(() -> { + mNotificationManager.createNotificationChannel(channel); + mNotificationManager.notify(NOTIFICATION_TAG, NOTIFICATION_ID, builder.build()); + }); } private SparseArray<NotificationInfo> getNotificationInfos() { diff --git a/services/core/java/com/android/server/display/BrightnessRangeController.java b/services/core/java/com/android/server/display/BrightnessRangeController.java index 21273e0f2785..13ee47eb91c8 100644 --- a/services/core/java/com/android/server/display/BrightnessRangeController.java +++ b/services/core/java/com/android/server/display/BrightnessRangeController.java @@ -19,6 +19,7 @@ package com.android.server.display; import android.hardware.display.BrightnessInfo; import android.os.Handler; import android.os.IBinder; +import android.os.PowerManager; import com.android.server.display.brightness.clamper.HdrClamper; import com.android.server.display.feature.DisplayManagerFlags; @@ -52,17 +53,26 @@ class BrightnessRangeController { HdrClamper hdrClamper, DisplayManagerFlags flags) { mHbmController = hbmController; mModeChangeCallback = modeChangeCallback; - mUseHdrClamper = false; - mUseNbmController = flags.isNbmControllerEnabled(); - mNormalBrightnessModeController.resetNbmData(displayDeviceConfig.getLuxThrottlingData()); mHdrClamper = hdrClamper; + mUseHdrClamper = flags.isHdrClamperEnabled(); + mUseNbmController = flags.isNbmControllerEnabled(); + if (mUseNbmController) { + mNormalBrightnessModeController.resetNbmData( + displayDeviceConfig.getLuxThrottlingData()); + } + if (mUseHdrClamper) { + mHdrClamper.resetHdrConfig(displayDeviceConfig.getHdrBrightnessData()); + } + } void dump(PrintWriter pw) { pw.println("BrightnessRangeController:"); pw.println(" mUseNormalBrightnessController=" + mUseNbmController); + pw.println(" mUseHdrClamper=" + mUseHdrClamper); mHbmController.dump(pw); mNormalBrightnessModeController.dump(pw); + mHdrClamper.dump(pw); } void onAmbientLuxChange(float ambientLux) { @@ -91,6 +101,9 @@ class BrightnessRangeController { displayDeviceConfig::getHdrBrightnessFromSdr); } ); + if (mUseHdrClamper) { + mHdrClamper.resetHdrConfig(displayDeviceConfig.getHdrBrightnessData()); + } } void stop() { @@ -128,8 +141,10 @@ class BrightnessRangeController { } float getHdrBrightnessValue() { - float hdrBrightness = mHbmController.getHdrBrightnessValue(); - return Math.min(hdrBrightness, mHdrClamper.getMaxBrightness()); + float hdrBrightness = mHbmController.getHdrBrightnessValue(); + float brightnessMax = mUseHdrClamper ? mHdrClamper.getMaxBrightness() + : PowerManager.BRIGHTNESS_MAX; + return Math.min(hdrBrightness, brightnessMax); } float getTransitionPoint() { @@ -151,6 +166,6 @@ class BrightnessRangeController { } public float getHdrTransitionRate() { - return mHdrClamper.getTransitionRate(); + return mUseHdrClamper ? mHdrClamper.getTransitionRate() : -1; } } diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java index 3a6e5f93861b..507ae2676b16 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java +++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java @@ -303,6 +303,8 @@ import javax.xml.datatype.DatatypeConfigurationException; * * <screenBrightnessRampIncreaseMaxMillis>2000</screenBrightnessRampIncreaseMaxMillis> * <screenBrightnessRampDecreaseMaxMillis>3000</screenBrightnessRampDecreaseMaxMillis> + * <screenBrightnessRampIncreaseMaxIdleMillis>2000</screenBrightnessRampIncreaseMaxIdleMillis> + * <screenBrightnessRampDecreaseMaxIdleMillis>2000</screenBrightnessRampDecreaseMaxIdleMillis> * * <lightSensor> * <type>android.sensor.light</type> @@ -619,6 +621,8 @@ public class DisplayDeviceConfig { private float mBrightnessRampSlowIncreaseIdle = Float.NaN; private long mBrightnessRampDecreaseMaxMillis = 0; private long mBrightnessRampIncreaseMaxMillis = 0; + private long mBrightnessRampDecreaseMaxIdleMillis = 0; + private long mBrightnessRampIncreaseMaxIdleMillis = 0; private int mAmbientHorizonLong = AMBIENT_LIGHT_LONG_HORIZON_MILLIS; private int mAmbientHorizonShort = AMBIENT_LIGHT_SHORT_HORIZON_MILLIS; private float mScreenBrighteningMinThreshold = 0.0f; // Retain behaviour as though there is @@ -1078,6 +1082,14 @@ public class DisplayDeviceConfig { return mBrightnessRampIncreaseMaxMillis; } + public long getBrightnessRampDecreaseMaxIdleMillis() { + return mBrightnessRampDecreaseMaxIdleMillis; + } + + public long getBrightnessRampIncreaseMaxIdleMillis() { + return mBrightnessRampIncreaseMaxIdleMillis; + } + public int getAmbientHorizonLong() { return mAmbientHorizonLong; } @@ -1697,6 +1709,8 @@ public class DisplayDeviceConfig { + ", mBrightnessRampSlowIncreaseIdle=" + mBrightnessRampSlowIncreaseIdle + ", mBrightnessRampDecreaseMaxMillis=" + mBrightnessRampDecreaseMaxMillis + ", mBrightnessRampIncreaseMaxMillis=" + mBrightnessRampIncreaseMaxMillis + + ", mBrightnessRampDecreaseMaxIdleMillis=" + mBrightnessRampDecreaseMaxIdleMillis + + ", mBrightnessRampIncreaseMaxIdleMillis=" + mBrightnessRampIncreaseMaxIdleMillis + "\n" + "mAmbientHorizonLong=" + mAmbientHorizonLong + ", mAmbientHorizonShort=" + mAmbientHorizonShort @@ -1892,6 +1906,8 @@ public class DisplayDeviceConfig { mBrightnessRampSlowIncreaseIdle = PowerManager.BRIGHTNESS_MAX; mBrightnessRampDecreaseMaxMillis = 0; mBrightnessRampIncreaseMaxMillis = 0; + mBrightnessRampDecreaseMaxIdleMillis = 0; + mBrightnessRampIncreaseMaxIdleMillis = 0; setSimpleMappingStrategyValues(); loadAmbientLightSensorFromConfigXml(); setProxSensorUnspecified(); @@ -2767,6 +2783,19 @@ public class DisplayDeviceConfig { mBrightnessRampSlowDecreaseIdle = mBrightnessRampSlowDecrease; mBrightnessRampSlowIncreaseIdle = mBrightnessRampSlowIncrease; } + + final BigInteger increaseMaxIdle = config.getScreenBrightnessRampIncreaseMaxIdleMillis(); + if (increaseMaxIdle != null) { + mBrightnessRampIncreaseMaxIdleMillis = increaseMaxIdle.intValue(); + } else { + mBrightnessRampIncreaseMaxIdleMillis = mBrightnessRampIncreaseMaxMillis; + } + final BigInteger decreaseMaxIdle = config.getScreenBrightnessRampDecreaseMaxIdleMillis(); + if (decreaseMaxIdle != null) { + mBrightnessRampDecreaseMaxIdleMillis = decreaseMaxIdle.intValue(); + } else { + mBrightnessRampDecreaseMaxIdleMillis = mBrightnessRampDecreaseMaxMillis; + } } private void loadBrightnessRampsFromConfigXml() { diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 320684fe3a0f..bc81491aefbf 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -317,10 +317,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private final Clock mClock; private final Injector mInjector; - // Maximum time a ramp animation can take. + // Maximum time a ramp animation can take. private long mBrightnessRampIncreaseMaxTimeMillis; private long mBrightnessRampDecreaseMaxTimeMillis; + // Maximum time a ramp animation can take in idle mode. + private long mBrightnessRampIncreaseMaxTimeIdleMillis; + private long mBrightnessRampDecreaseMaxTimeIdleMillis; + // The pending power request. // Initially null until the first call to requestPowerState. @GuardedBy("mLock") @@ -585,6 +589,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private boolean mBootCompleted; + private final DisplayManagerFlags mFlags; + /** * Creates the display power controller. */ @@ -750,6 +756,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mPendingAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT; mBootCompleted = bootCompleted; + + mFlags = flags; } private void applyReduceBrightColorsSplineAdjustment() { @@ -1057,11 +1065,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call loadNitsRange(mContext.getResources()); setUpAutoBrightness(mContext.getResources(), mHandler); reloadReduceBrightColours(); - if (mScreenBrightnessRampAnimator != null) { - mScreenBrightnessRampAnimator.setAnimationTimeLimits( - mBrightnessRampIncreaseMaxTimeMillis, - mBrightnessRampDecreaseMaxTimeMillis); - } + setAnimatorRampSpeeds(/* isIdleMode= */ false); mBrightnessRangeController.loadFromConfig(hbmMetadata, token, info, mDisplayDeviceConfig); mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig( mDisplayDeviceConfig.getThermalBrightnessThrottlingDataMapByThrottlingId(), @@ -1102,9 +1106,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mScreenBrightnessRampAnimator = mInjector.getDualRampAnimator(mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS_FLOAT, DisplayPowerState.SCREEN_SDR_BRIGHTNESS_FLOAT); - mScreenBrightnessRampAnimator.setAnimationTimeLimits( - mBrightnessRampIncreaseMaxTimeMillis, - mBrightnessRampDecreaseMaxTimeMillis); + setAnimatorRampSpeeds(mAutomaticBrightnessController != null + && mAutomaticBrightnessController.isInIdleMode()); mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener); noteScreenState(mPowerState.getScreenState()); @@ -1323,6 +1326,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis(); mBrightnessRampIncreaseMaxTimeMillis = mDisplayDeviceConfig.getBrightnessRampIncreaseMaxMillis(); + mBrightnessRampDecreaseMaxTimeIdleMillis = + mDisplayDeviceConfig.getBrightnessRampDecreaseMaxIdleMillis(); + mBrightnessRampIncreaseMaxTimeIdleMillis = + mDisplayDeviceConfig.getBrightnessRampIncreaseMaxIdleMillis(); } private void loadNitsRange(Resources resources) { @@ -1349,6 +1356,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } else { mAutomaticBrightnessController.switchToInteractiveScreenBrightnessMode(); } + setAnimatorRampSpeeds(isIdle); } Message msg = mHandler.obtainMessage(); @@ -1357,6 +1365,21 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mHandler.sendMessageAtTime(msg, mClock.uptimeMillis()); } + private void setAnimatorRampSpeeds(boolean isIdle) { + if (mScreenBrightnessRampAnimator == null) { + return; + } + if (mFlags.isAdaptiveTone1Enabled() && isIdle) { + mScreenBrightnessRampAnimator.setAnimationTimeLimits( + mBrightnessRampIncreaseMaxTimeIdleMillis, + mBrightnessRampDecreaseMaxTimeIdleMillis); + } else { + mScreenBrightnessRampAnimator.setAnimationTimeLimits( + mBrightnessRampIncreaseMaxTimeMillis, + mBrightnessRampDecreaseMaxTimeMillis); + } + } + private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { @@ -2425,7 +2448,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call Slog.d(mTag, "Animating brightness: target=" + target + ", sdrTarget=" + sdrTarget + ", rate=" + rate); } - if (mScreenBrightnessRampAnimator.animateTo(target, sdrTarget, rate)) { + if (mScreenBrightnessRampAnimator.animateTo(target, sdrTarget, rate, false)) { Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", (int) target); String propertyKey = "debug.tracing.screen_brightness"; diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java index 597738e8b293..90a8490b6f49 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController2.java +++ b/services/core/java/com/android/server/display/DisplayPowerController2.java @@ -285,10 +285,14 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal private final Clock mClock; private final Injector mInjector; - // Maximum time a ramp animation can take. + // Maximum time a ramp animation can take. private long mBrightnessRampIncreaseMaxTimeMillis; private long mBrightnessRampDecreaseMaxTimeMillis; + // Maximum time a ramp animation can take in idle mode. + private long mBrightnessRampIncreaseMaxTimeIdleMillis; + private long mBrightnessRampDecreaseMaxTimeIdleMillis; + // The pending power request. // Initially null until the first call to requestPowerState. @GuardedBy("mLock") @@ -465,6 +469,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal private boolean mBootCompleted; + private final DisplayManagerFlags mFlags; + /** * Creates the display power controller. */ @@ -615,6 +621,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal R.bool.config_displayBrightnessBucketsInDoze); mBootCompleted = bootCompleted; + mFlags = flags; } private void applyReduceBrightColorsSplineAdjustment() { @@ -862,11 +869,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal loadNitsRange(mContext.getResources()); setUpAutoBrightness(mContext.getResources(), mHandler); reloadReduceBrightColours(); - if (mScreenBrightnessRampAnimator != null) { - mScreenBrightnessRampAnimator.setAnimationTimeLimits( - mBrightnessRampIncreaseMaxTimeMillis, - mBrightnessRampDecreaseMaxTimeMillis); - } + setAnimatorRampSpeeds(/* isIdleMode= */ false); mBrightnessRangeController.loadFromConfig(hbmMetadata, token, info, mDisplayDeviceConfig); mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig( @@ -908,9 +911,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mScreenBrightnessRampAnimator = mInjector.getDualRampAnimator(mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS_FLOAT, DisplayPowerState.SCREEN_SDR_BRIGHTNESS_FLOAT); - mScreenBrightnessRampAnimator.setAnimationTimeLimits( - mBrightnessRampIncreaseMaxTimeMillis, - mBrightnessRampDecreaseMaxTimeMillis); + setAnimatorRampSpeeds(mAutomaticBrightnessController != null + && mAutomaticBrightnessController.isInIdleMode()); mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener); noteScreenState(mPowerState.getScreenState()); @@ -1136,6 +1138,10 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis(); mBrightnessRampIncreaseMaxTimeMillis = mDisplayDeviceConfig.getBrightnessRampIncreaseMaxMillis(); + mBrightnessRampDecreaseMaxTimeIdleMillis = + mDisplayDeviceConfig.getBrightnessRampDecreaseMaxIdleMillis(); + mBrightnessRampIncreaseMaxTimeIdleMillis = + mDisplayDeviceConfig.getBrightnessRampIncreaseMaxIdleMillis(); } private void loadNitsRange(Resources resources) { @@ -1162,6 +1168,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal } else { mAutomaticBrightnessController.switchToInteractiveScreenBrightnessMode(); } + setAnimatorRampSpeeds(isIdle); } Message msg = mHandler.obtainMessage(); msg.what = MSG_SET_DWBC_STRONG_MODE; @@ -1169,6 +1176,21 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mHandler.sendMessageAtTime(msg, mClock.uptimeMillis()); } + private void setAnimatorRampSpeeds(boolean isIdle) { + if (mScreenBrightnessRampAnimator == null) { + return; + } + if (mFlags.isAdaptiveTone1Enabled() && isIdle) { + mScreenBrightnessRampAnimator.setAnimationTimeLimits( + mBrightnessRampIncreaseMaxTimeIdleMillis, + mBrightnessRampDecreaseMaxTimeIdleMillis); + } else { + mScreenBrightnessRampAnimator.setAnimationTimeLimits( + mBrightnessRampIncreaseMaxTimeMillis, + mBrightnessRampDecreaseMaxTimeMillis); + } + } + private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { @@ -1547,7 +1569,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal SCREEN_ANIMATION_RATE_MINIMUM); } else if (customTransitionRate > 0) { animateScreenBrightness(animateValue, sdrAnimateValue, - customTransitionRate); + customTransitionRate, /* ignoreAnimationLimits = */true); } else { boolean isIncreasing = animateValue > currentBrightness; final float rampSpeed; @@ -2017,11 +2039,17 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal } private void animateScreenBrightness(float target, float sdrTarget, float rate) { + animateScreenBrightness(target, sdrTarget, rate, /* ignoreAnimationLimits = */false); + } + + private void animateScreenBrightness(float target, float sdrTarget, float rate, + boolean ignoreAnimationLimits) { if (DEBUG) { Slog.d(mTag, "Animating brightness: target=" + target + ", sdrTarget=" + sdrTarget + ", rate=" + rate); } - if (mScreenBrightnessRampAnimator.animateTo(target, sdrTarget, rate)) { + if (mScreenBrightnessRampAnimator.animateTo(target, sdrTarget, rate, + ignoreAnimationLimits)) { Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", (int) target); String propertyKey = "debug.tracing.screen_brightness"; diff --git a/services/core/java/com/android/server/display/RampAnimator.java b/services/core/java/com/android/server/display/RampAnimator.java index 378cdba09520..5ba042c51a45 100644 --- a/services/core/java/com/android/server/display/RampAnimator.java +++ b/services/core/java/com/android/server/display/RampAnimator.java @@ -30,6 +30,8 @@ class RampAnimator<T> { private final T mObject; private final FloatProperty<T> mProperty; + private final Clock mClock; + private float mCurrentValue; // target in HLG space @@ -47,10 +49,14 @@ class RampAnimator<T> { private boolean mFirstTime = true; - RampAnimator(T object, FloatProperty<T> property) { + this(object, property, System::nanoTime); + } + + RampAnimator(T object, FloatProperty<T> property, Clock clock) { mObject = object; mProperty = property; + mClock = clock; } /** @@ -66,15 +72,24 @@ class RampAnimator<T> { /** * Sets the animation target and the rate of this ramp animator. - * + * Animation rate will be set ignoring maxTime animation limits * If this is the first time the property is being set or if the rate is 0, * the value jumps directly to the target. * * @param targetLinear The target value. * @param rate The convergence rate in units per second, or 0 to set the value immediately. + * @param ignoreAnimationLimits if mAnimationIncreaseMaxTimeSecs and + * mAnimationDecreaseMaxTimeSecs should be respected when adjusting + * animation speed * @return True if the target differs from the previous target. */ - boolean setAnimationTarget(float targetLinear, float rate) { + boolean setAnimationTarget(float targetLinear, float rate, boolean ignoreAnimationLimits) { + float maxIncreaseTimeSecs = ignoreAnimationLimits ? 0 : mAnimationIncreaseMaxTimeSecs; + float maxDecreaseTimeSecs = ignoreAnimationLimits ? 0 : mAnimationDecreaseMaxTimeSecs; + return setAnimationTarget(targetLinear, rate, maxIncreaseTimeSecs, maxDecreaseTimeSecs); + } + private boolean setAnimationTarget(float targetLinear, float rate, + float maxIncreaseTimeSecs, float maxDecreaseTimeSecs) { // Convert the target from the linear into the HLG space. final float target = BrightnessUtils.convertLinearToGamma(targetLinear); @@ -94,12 +109,12 @@ class RampAnimator<T> { } // Adjust the rate so that we do not exceed our maximum animation time. - if (target > mCurrentValue && mAnimationIncreaseMaxTimeSecs > 0.0f - && ((target - mCurrentValue) / rate) > mAnimationIncreaseMaxTimeSecs) { - rate = (target - mCurrentValue) / mAnimationIncreaseMaxTimeSecs; - } else if (target < mCurrentValue && mAnimationDecreaseMaxTimeSecs > 0.0f - && ((mCurrentValue - target) / rate) > mAnimationDecreaseMaxTimeSecs) { - rate = (mCurrentValue - target) / mAnimationDecreaseMaxTimeSecs; + if (target > mCurrentValue && maxIncreaseTimeSecs > 0.0f + && ((target - mCurrentValue) / rate) > maxIncreaseTimeSecs) { + rate = (target - mCurrentValue) / maxIncreaseTimeSecs; + } else if (target < mCurrentValue && maxDecreaseTimeSecs > 0.0f + && ((mCurrentValue - target) / rate) > maxDecreaseTimeSecs) { + rate = (mCurrentValue - target) / maxDecreaseTimeSecs; } // Adjust the rate based on the closest target. @@ -124,7 +139,7 @@ class RampAnimator<T> { if (!mAnimating && target != mCurrentValue) { mAnimating = true; mAnimatedValue = mCurrentValue; - mLastFrameTimeNanos = System.nanoTime(); + mLastFrameTimeNanos = mClock.nanoTime(); } return changed; @@ -184,6 +199,13 @@ class RampAnimator<T> { void onAnimationEnd(); } + interface Clock { + /** + * Returns current system time in nanoseconds. + */ + long nanoTime(); + } + static class DualRampAnimator<T> { private final Choreographer mChoreographer; private final RampAnimator<T> mFirst; @@ -219,11 +241,17 @@ class RampAnimator<T> { * @param linearFirstTarget The first target value in linear space. * @param linearSecondTarget The second target value in linear space. * @param rate The convergence rate in units per second, or 0 to set the value immediately. + * @param ignoreAnimationLimits if mAnimationIncreaseMaxTimeSecs and + * mAnimationDecreaseMaxTimeSecs should be respected + * when adjusting animation speed * @return True if either target differs from the previous target. */ - public boolean animateTo(float linearFirstTarget, float linearSecondTarget, float rate) { - boolean animationTargetChanged = mFirst.setAnimationTarget(linearFirstTarget, rate); - animationTargetChanged |= mSecond.setAnimationTarget(linearSecondTarget, rate); + public boolean animateTo(float linearFirstTarget, float linearSecondTarget, float rate, + boolean ignoreAnimationLimits) { + boolean animationTargetChanged = mFirst.setAnimationTarget(linearFirstTarget, rate, + ignoreAnimationLimits); + animationTargetChanged |= mSecond.setAnimationTarget(linearSecondTarget, rate, + ignoreAnimationLimits); boolean shouldBeAnimating = isAnimating(); if (shouldBeAnimating != mAwaitingCallback) { diff --git a/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java b/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java index 079a196234a8..a514136e62a2 100644 --- a/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java +++ b/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java @@ -16,40 +16,41 @@ package com.android.server.display.brightness.clamper; +import android.annotation.Nullable; import android.os.Handler; import android.os.PowerManager; -import com.android.internal.annotations.VisibleForTesting; +import com.android.server.display.config.HdrBrightnessData; -import java.util.HashMap; +import java.io.PrintWriter; import java.util.Map; public class HdrClamper { - private final Configuration mConfiguration = new Configuration(); - private final BrightnessClamperController.ClamperChangeListener mClamperChangeListener; private final Handler mHandler; private final Runnable mDebouncer; - private float mMaxBrightness = PowerManager.BRIGHTNESS_MAX; + @Nullable + private HdrBrightnessData mHdrBrightnessData = null; - // brightness change speed, in units per seconds, - private float mTransitionRate = -1f; + private float mAmbientLux = Float.MAX_VALUE; + private float mMaxBrightness = PowerManager.BRIGHTNESS_MAX; private float mDesiredMaxBrightness = PowerManager.BRIGHTNESS_MAX; - private float mDesiredTransitionDuration = -1; // in seconds + // brightness change speed, in units per seconds, + private float mTransitionRate = -1f; + private float mDesiredTransitionRate = -1f; public HdrClamper(BrightnessClamperController.ClamperChangeListener clamperChangeListener, Handler handler) { mClamperChangeListener = clamperChangeListener; mHandler = handler; mDebouncer = () -> { - mTransitionRate = Math.abs((mMaxBrightness - mDesiredMaxBrightness) - / mDesiredTransitionDuration); + mTransitionRate = mDesiredTransitionRate; mMaxBrightness = mDesiredMaxBrightness; mClamperChangeListener.onChanged(); }; @@ -65,46 +66,74 @@ public class HdrClamper { return mTransitionRate; } - /** * Updates brightness cap in response to ambient lux change. * Called by ABC in same looper: mHandler.getLooper() */ public void onAmbientLuxChange(float ambientLux) { - float expectedMaxBrightness = findBrightnessLimit(ambientLux); + mAmbientLux = ambientLux; + recalculateBrightnessCap(mHdrBrightnessData, ambientLux); + } + + /** + * Updates brightness cap config. + * Called in same looper: mHandler.getLooper() + */ + public void resetHdrConfig(HdrBrightnessData data) { + mHdrBrightnessData = data; + recalculateBrightnessCap(data, mAmbientLux); + } + + /** + * Dumps the state of HdrClamper. + */ + public void dump(PrintWriter pw) { + pw.println("HdrClamper:"); + pw.println(" mMaxBrightness=" + mMaxBrightness); + pw.println(" mDesiredMaxBrightness=" + mDesiredMaxBrightness); + pw.println(" mTransitionRate=" + mTransitionRate); + pw.println(" mDesiredTransitionRate=" + mDesiredTransitionRate); + pw.println(" mHdrBrightnessData=" + (mHdrBrightnessData == null ? "null" + : mHdrBrightnessData.toString())); + pw.println(" mAmbientLux=" + mAmbientLux); + } + + private void recalculateBrightnessCap(HdrBrightnessData data, float ambientLux) { + if (data == null) { + mHandler.removeCallbacks(mDebouncer); + return; + } + float expectedMaxBrightness = findBrightnessLimit(data, ambientLux); + if (mMaxBrightness == expectedMaxBrightness) { mDesiredMaxBrightness = mMaxBrightness; - mDesiredTransitionDuration = -1; + mDesiredTransitionRate = -1f; mTransitionRate = -1f; mHandler.removeCallbacks(mDebouncer); } else if (mDesiredMaxBrightness != expectedMaxBrightness) { mDesiredMaxBrightness = expectedMaxBrightness; long debounceTime; + long transitionDuration; if (mDesiredMaxBrightness > mMaxBrightness) { - debounceTime = mConfiguration.mIncreaseConfig.mDebounceTimeMillis; - mDesiredTransitionDuration = - (float) mConfiguration.mIncreaseConfig.mTransitionTimeMillis / 1000; + debounceTime = mHdrBrightnessData.mBrightnessIncreaseDebounceMillis; + transitionDuration = mHdrBrightnessData.mBrightnessIncreaseDurationMillis; } else { - debounceTime = mConfiguration.mDecreaseConfig.mDebounceTimeMillis; - mDesiredTransitionDuration = - (float) mConfiguration.mDecreaseConfig.mTransitionTimeMillis / 1000; + debounceTime = mHdrBrightnessData.mBrightnessDecreaseDebounceMillis; + transitionDuration = mHdrBrightnessData.mBrightnessDecreaseDurationMillis; } + mDesiredTransitionRate = Math.abs( + (mMaxBrightness - mDesiredMaxBrightness) * 1000f / transitionDuration); mHandler.removeCallbacks(mDebouncer); mHandler.postDelayed(mDebouncer, debounceTime); } } - @VisibleForTesting - Configuration getConfiguration() { - return mConfiguration; - } - - private float findBrightnessLimit(float ambientLux) { + private float findBrightnessLimit(HdrBrightnessData data, float ambientLux) { float foundAmbientBoundary = Float.MAX_VALUE; float foundMaxBrightness = PowerManager.BRIGHTNESS_MAX; for (Map.Entry<Float, Float> brightnessPoint : - mConfiguration.mMaxBrightnessLimits.entrySet()) { + data.mMaxBrightnessLimits.entrySet()) { float ambientBoundary = brightnessPoint.getKey(); // find ambient lux upper boundary closest to current ambient lux if (ambientBoundary > ambientLux && ambientBoundary < foundAmbientBoundary) { @@ -114,19 +143,4 @@ public class HdrClamper { } return foundMaxBrightness; } - - @VisibleForTesting - static class Configuration { - final Map<Float, Float> mMaxBrightnessLimits = new HashMap<>(); - final TransitionConfiguration mIncreaseConfig = new TransitionConfiguration(); - - final TransitionConfiguration mDecreaseConfig = new TransitionConfiguration(); - } - - @VisibleForTesting - static class TransitionConfiguration { - long mDebounceTimeMillis; - - long mTransitionTimeMillis; - } } diff --git a/services/core/java/com/android/server/display/config/HdrBrightnessData.java b/services/core/java/com/android/server/display/config/HdrBrightnessData.java index 06d3c5b87520..48d671d356f7 100644 --- a/services/core/java/com/android/server/display/config/HdrBrightnessData.java +++ b/services/core/java/com/android/server/display/config/HdrBrightnessData.java @@ -18,6 +18,8 @@ package com.android.server.display.config; import android.annotation.Nullable; +import com.android.internal.annotations.VisibleForTesting; + import java.util.HashMap; import java.util.List; import java.util.Map; @@ -52,7 +54,8 @@ public class HdrBrightnessData { */ public final long mBrightnessDecreaseDurationMillis; - private HdrBrightnessData(Map<Float, Float> maxBrightnessLimits, + @VisibleForTesting + public HdrBrightnessData(Map<Float, Float> maxBrightnessLimits, long brightnessIncreaseDebounceMillis, long brightnessIncreaseDurationMillis, long brightnessDecreaseDebounceMillis, long brightnessDecreaseDurationMillis) { mMaxBrightnessLimits = maxBrightnessLimits; diff --git a/services/core/java/com/android/server/display/feature/Android.bp b/services/core/java/com/android/server/display/feature/Android.bp index 27c48eda83c6..a0ead384c1d2 100644 --- a/services/core/java/com/android/server/display/feature/Android.bp +++ b/services/core/java/com/android/server/display/feature/Android.bp @@ -5,8 +5,3 @@ aconfig_declarations { "*.aconfig", ], } - -java_aconfig_library { - name: "display_flags_lib", - aconfig_declarations: "display_flags", -} diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java index aebd8a08ee3f..3f6bf1adfe48 100644 --- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java +++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java @@ -39,6 +39,14 @@ public class DisplayManagerFlags { Flags.FLAG_ENABLE_NBM_CONTROLLER, Flags::enableNbmController); + private final FlagState mHdrClamperFlagState = new FlagState( + Flags.FLAG_ENABLE_HDR_CLAMPER, + Flags::enableHdrClamper); + + private final FlagState mAdaptiveToneImprovements1 = new FlagState( + Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1, + Flags::enableAdaptiveToneImprovements1); + /** Returns whether connected display management is enabled or not. */ public boolean isConnectedDisplayManagementEnabled() { return mConnectedDisplayManagementFlagState.isEnabled(); @@ -49,6 +57,17 @@ public class DisplayManagerFlags { return mNbmControllerFlagState.isEnabled(); } + public boolean isHdrClamperEnabled() { + return mHdrClamperFlagState.isEnabled(); + } + + /** + * Returns whether adaptive tone improvements are enabled + */ + public boolean isAdaptiveTone1Enabled() { + return mAdaptiveToneImprovements1.isEnabled(); + } + private static class FlagState { private final String mName; diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig index 12306b039225..4d8600448c33 100644 --- a/services/core/java/com/android/server/display/feature/display_flags.aconfig +++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig @@ -14,6 +14,23 @@ flag { name: "enable_nbm_controller" namespace: "display_manager" description: "Feature flag for Normal Brightness Mode Controller" - bug: "277877297" + bug: "299527549" is_fixed_read_only: true } + +flag { + name: "enable_hdr_clamper" + namespace: "display_manager" + description: "Feature flag for HDR Clamper" + bug: "295100043" + is_fixed_read_only: true +} + +flag { + name: "enable_adaptive_tone_improvements_1" + namespace: "display_manager" + description: "Feature flag for Adaptive Tone Improvements" + bug: "299550755" + is_fixed_read_only: true +} + diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 032778c79768..d3ad6c437f78 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -3303,6 +3303,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } // Changing to a different IME. + IInputMethodInvoker curMethod = getCurMethodLocked(); + if (curMethod != null) { + curMethod.removeStylusHandwritingWindow(); + } final long ident = Binder.clearCallingIdentity(); try { // Set a subtype to this input method. diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java index a7c986d04fa4..ec858ee296e1 100644 --- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java +++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java @@ -513,6 +513,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { List<String> apkFiles = filesList .map(path -> path.toAbsolutePath().toString()) + .filter(str -> str.endsWith(".apk")) .collect(Collectors.toList()); sourceStampVerificationResult = SourceStampVerifier.verify(apkFiles); } catch (IOException e) { diff --git a/services/core/java/com/android/server/media/MediaKeyDispatcher.java b/services/core/java/com/android/server/media/MediaKeyDispatcher.java index 55511ad637ac..66cafabb1e6e 100644 --- a/services/core/java/com/android/server/media/MediaKeyDispatcher.java +++ b/services/core/java/com/android/server/media/MediaKeyDispatcher.java @@ -117,24 +117,11 @@ public abstract class MediaKeyDispatcher { /** * Gets the map of key code -> {@link KeyEventType} that have been overridden. - * <p> - * The list of valid key codes are the following: - * <ul> - * <li> {@link KeyEvent#KEYCODE_MEDIA_PLAY} - * <li> {@link KeyEvent#KEYCODE_MEDIA_PAUSE} - * <li> {@link KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE} - * <li> {@link KeyEvent#KEYCODE_MUTE} - * <li> {@link KeyEvent#KEYCODE_HEADSETHOOK} - * <li> {@link KeyEvent#KEYCODE_MEDIA_STOP} - * <li> {@link KeyEvent#KEYCODE_MEDIA_NEXT} - * <li> {@link KeyEvent#KEYCODE_MEDIA_PREVIOUS} - * <li> {@link KeyEvent#KEYCODE_VOLUME_UP} - * <li> {@link KeyEvent#KEYCODE_VOLUME_DOWN} - * <li> {@link KeyEvent#KEYCODE_VOLUME_MUTE} - * </ul> - * @see {@link KeyEvent#isMediaSessionKey(int)} + * + * <p>For the list of relevant key codes, see {@link KeyEvent#isMediaSessionKey(int)}. */ - @KeyEventType Map<Integer, Integer> getOverriddenKeyEvents() { + @KeyEventType + Map<Integer, Integer> getOverriddenKeyEvents() { return mOverriddenKeyEvents; } diff --git a/services/core/java/com/android/server/notification/NotificationAttentionHelper.java b/services/core/java/com/android/server/notification/NotificationAttentionHelper.java new file mode 100644 index 000000000000..75a0cf521a1d --- /dev/null +++ b/services/core/java/com/android/server/notification/NotificationAttentionHelper.java @@ -0,0 +1,951 @@ +/* + * 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.notification; + +import static android.app.Notification.FLAG_INSISTENT; +import static android.app.Notification.FLAG_ONLY_ALERT_ONCE; +import static android.app.NotificationManager.IMPORTANCE_MIN; +import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS; +import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR; +import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE; +import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS; +import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS; +import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS; + +import android.annotation.IntDef; +import android.app.ActivityManager; +import android.app.KeyguardManager; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.StatusBarManager; +import android.content.BroadcastReceiver; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.database.ContentObserver; +import android.media.AudioAttributes; +import android.media.AudioManager; +import android.media.IRingtonePlayer; +import android.net.Uri; +import android.os.Binder; +import android.os.RemoteException; +import android.os.SystemProperties; +import android.os.UserHandle; +import android.os.VibrationEffect; +import android.provider.Settings; +import android.telephony.PhoneStateListener; +import android.telephony.TelephonyManager; +import android.text.TextUtils; +import android.util.Log; +import android.util.Slog; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityManager; + +import com.android.internal.R; +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags; +import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.nano.MetricsProto; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.server.EventLogTags; +import com.android.server.lights.LightsManager; +import com.android.server.lights.LogicalLight; + +import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * NotificationManagerService helper for handling notification attention effects: + * make noise, vibrate, or flash the LED. + * @hide + */ +public final class NotificationAttentionHelper { + static final String TAG = "NotifAttentionHelper"; + static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + static final boolean DEBUG_INTERRUPTIVENESS = SystemProperties.getBoolean( + "debug.notification.interruptiveness", false); + + private final Context mContext; + private final PackageManager mPackageManager; + private final TelephonyManager mTelephonyManager; + private final NotificationManagerPrivate mNMP; + private final SystemUiSystemPropertiesFlags.FlagResolver mFlagResolver; + private AccessibilityManager mAccessibilityManager; + private KeyguardManager mKeyguardManager; + private AudioManager mAudioManager; + private final LightsManager mLightsManager; + private final NotificationUsageStats mUsageStats; + private final ZenModeHelper mZenModeHelper; + + private VibratorHelper mVibratorHelper; + // The last key in this list owns the hardware. + ArrayList<String> mLights = new ArrayList<>(); + private LogicalLight mNotificationLight; + private LogicalLight mAttentionLight; + + private final boolean mUseAttentionLight; + boolean mHasLight = true; + + private final SettingsObserver mSettingsObserver; + + private boolean mIsAutomotive; + private boolean mNotificationEffectsEnabledForAutomotive; + private boolean mDisableNotificationEffects; + private int mCallState; + private String mSoundNotificationKey; + private String mVibrateNotificationKey; + private boolean mSystemReady; + private boolean mInCallStateOffHook = false; + private boolean mScreenOn = true; + private boolean mUserPresent = false; + boolean mNotificationPulseEnabled; + private final Uri mInCallNotificationUri; + private final AudioAttributes mInCallNotificationAudioAttributes; + private final float mInCallNotificationVolume; + private Binder mCallNotificationToken = null; + + + public NotificationAttentionHelper(Context context, LightsManager lightsManager, + AccessibilityManager accessibilityManager, PackageManager packageManager, + NotificationUsageStats usageStats, + NotificationManagerPrivate notificationManagerPrivate, + ZenModeHelper zenModeHelper, SystemUiSystemPropertiesFlags.FlagResolver flagResolver) { + mContext = context; + mPackageManager = packageManager; + mTelephonyManager = context.getSystemService(TelephonyManager.class); + mAccessibilityManager = accessibilityManager; + mLightsManager = lightsManager; + mNMP = notificationManagerPrivate; + mUsageStats = usageStats; + mZenModeHelper = zenModeHelper; + mFlagResolver = flagResolver; + + mVibratorHelper = new VibratorHelper(context); + + mNotificationLight = mLightsManager.getLight(LightsManager.LIGHT_ID_NOTIFICATIONS); + mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION); + + Resources resources = context.getResources(); + mUseAttentionLight = resources.getBoolean(R.bool.config_useAttentionLight); + mHasLight = + resources.getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed); + + // Don't start allowing notifications until the setup wizard has run once. + // After that, including subsequent boots, init with notifications turned on. + // This works on the first boot because the setup wizard will toggle this + // flag at least once and we'll go back to 0 after that. + if (Settings.Global.getInt(context.getContentResolver(), + Settings.Global.DEVICE_PROVISIONED, 0) == 0) { + mDisableNotificationEffects = true; + } + + mInCallNotificationUri = Uri.parse( + "file://" + resources.getString(R.string.config_inCallNotificationSound)); + mInCallNotificationAudioAttributes = new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION) + .build(); + mInCallNotificationVolume = resources.getFloat(R.dimen.config_inCallNotificationVolume); + + mSettingsObserver = new SettingsObserver(); + } + + public void onSystemReady() { + mSystemReady = true; + + mIsAutomotive = mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0); + mNotificationEffectsEnabledForAutomotive = mContext.getResources().getBoolean( + R.bool.config_enableServerNotificationEffectsForAutomotive); + + mAudioManager = mContext.getSystemService(AudioManager.class); + mKeyguardManager = mContext.getSystemService(KeyguardManager.class); + + registerBroadcastListeners(); + } + + private void registerBroadcastListeners() { + if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { + mTelephonyManager.listen(new PhoneStateListener() { + @Override + public void onCallStateChanged(int state, String incomingNumber) { + if (mCallState == state) return; + if (DEBUG) Slog.d(TAG, "Call state changed: " + callStateToString(state)); + mCallState = state; + } + }, PhoneStateListener.LISTEN_CALL_STATE); + } + + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_SCREEN_ON); + filter.addAction(Intent.ACTION_SCREEN_OFF); + filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); + filter.addAction(Intent.ACTION_USER_PRESENT); + mContext.registerReceiverAsUser(mIntentReceiver, UserHandle.ALL, filter, null, null); + + mContext.getContentResolver().registerContentObserver( + SettingsObserver.NOTIFICATION_LIGHT_PULSE_URI, false, mSettingsObserver, + UserHandle.USER_ALL); + } + + @VisibleForTesting + /** + * Determine whether this notification should attempt to make noise, vibrate, or flash the LED + * @return buzzBeepBlink - bitfield (buzz ? 1 : 0) | (beep ? 2 : 0) | (blink ? 4 : 0) | + * (polite_attenuated ? 8 : 0) | (polite_muted ? 16 : 0) + */ + int buzzBeepBlinkLocked(NotificationRecord record, Signals signals) { + if (mIsAutomotive && !mNotificationEffectsEnabledForAutomotive) { + return 0; + } + boolean buzz = false; + boolean beep = false; + boolean blink = false; + + final String key = record.getKey(); + + if (DEBUG) { + Log.d(TAG, "buzzBeepBlinkLocked " + record); + } + + // Should this notification make noise, vibe, or use the LED? + final boolean aboveThreshold = + mIsAutomotive + ? record.getImportance() > NotificationManager.IMPORTANCE_DEFAULT + : record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT; + // Remember if this notification already owns the notification channels. + boolean wasBeep = key != null && key.equals(mSoundNotificationKey); + boolean wasBuzz = key != null && key.equals(mVibrateNotificationKey); + // These are set inside the conditional if the notification is allowed to make noise. + boolean hasValidVibrate = false; + boolean hasValidSound = false; + boolean sentAccessibilityEvent = false; + + // If the notification will appear in the status bar, it should send an accessibility event + final boolean suppressedByDnd = record.isIntercepted() + && (record.getSuppressedVisualEffects() & SUPPRESSED_EFFECT_STATUS_BAR) != 0; + if (!record.isUpdate + && record.getImportance() > IMPORTANCE_MIN + && !suppressedByDnd + && isNotificationForCurrentUser(record, signals)) { + sendAccessibilityEvent(record); + sentAccessibilityEvent = true; + } + + if (aboveThreshold && isNotificationForCurrentUser(record, signals)) { + if (mSystemReady && mAudioManager != null) { + Uri soundUri = record.getSound(); + hasValidSound = soundUri != null && !Uri.EMPTY.equals(soundUri); + VibrationEffect vibration = record.getVibration(); + // Demote sound to vibration if vibration missing & phone in vibration mode. + if (vibration == null + && hasValidSound + && (mAudioManager.getRingerModeInternal() + == AudioManager.RINGER_MODE_VIBRATE) + && mAudioManager.getStreamVolume( + AudioAttributes.toLegacyStreamType(record.getAudioAttributes())) == 0) { + boolean insistent = (record.getFlags() & Notification.FLAG_INSISTENT) != 0; + vibration = mVibratorHelper.createFallbackVibration(insistent); + } + hasValidVibrate = vibration != null; + boolean hasAudibleAlert = hasValidSound || hasValidVibrate; + if (hasAudibleAlert && !shouldMuteNotificationLocked(record, signals)) { + if (!sentAccessibilityEvent) { + sendAccessibilityEvent(record); + sentAccessibilityEvent = true; + } + if (DEBUG) Slog.v(TAG, "Interrupting!"); + boolean isInsistentUpdate = isInsistentUpdate(record); + if (hasValidSound) { + if (isInsistentUpdate) { + // don't reset insistent sound, it's jarring + beep = true; + } else { + if (isInCall()) { + playInCallNotification(); + beep = true; + } else { + beep = playSound(record, soundUri); + } + if (beep) { + mSoundNotificationKey = key; + } + } + } + + final boolean ringerModeSilent = + mAudioManager.getRingerModeInternal() + == AudioManager.RINGER_MODE_SILENT; + if (!isInCall() && hasValidVibrate && !ringerModeSilent) { + if (isInsistentUpdate) { + buzz = true; + } else { + buzz = playVibration(record, vibration, hasValidSound); + if (buzz) { + mVibrateNotificationKey = key; + } + } + } + + // Try to start flash notification event whenever an audible and non-suppressed + // notification is received + mAccessibilityManager.startFlashNotificationEvent(mContext, + AccessibilityManager.FLASH_REASON_NOTIFICATION, + record.getSbn().getPackageName()); + + } else if ((record.getFlags() & Notification.FLAG_INSISTENT) != 0) { + hasValidSound = false; + } + } + } + // If a notification is updated to remove the actively playing sound or vibrate, + // cancel that feedback now + if (wasBeep && !hasValidSound) { + clearSoundLocked(); + } + if (wasBuzz && !hasValidVibrate) { + clearVibrateLocked(); + } + + // light + // release the light + boolean wasShowLights = mLights.remove(key); + if (canShowLightsLocked(record, signals, aboveThreshold)) { + mLights.add(key); + updateLightsLocked(); + if (mUseAttentionLight && mAttentionLight != null) { + mAttentionLight.pulse(); + } + blink = true; + } else if (wasShowLights) { + updateLightsLocked(); + } + final int buzzBeepBlink = + (buzz ? 1 : 0) | (beep ? 2 : 0) | (blink ? 4 : 0); + if (buzzBeepBlink > 0) { + // Ignore summary updates because we don't display most of the information. + if (record.getSbn().isGroup() && record.getSbn().getNotification().isGroupSummary()) { + if (DEBUG_INTERRUPTIVENESS) { + Slog.v(TAG, "INTERRUPTIVENESS: " + + record.getKey() + " is not interruptive: summary"); + } + } else if (record.canBubble()) { + if (DEBUG_INTERRUPTIVENESS) { + Slog.v(TAG, "INTERRUPTIVENESS: " + + record.getKey() + " is not interruptive: bubble"); + } + } else { + record.setInterruptive(true); + if (DEBUG_INTERRUPTIVENESS) { + Slog.v(TAG, "INTERRUPTIVENESS: " + + record.getKey() + " is interruptive: alerted"); + } + } + MetricsLogger.action(record.getLogMaker() + .setCategory(MetricsEvent.NOTIFICATION_ALERT) + .setType(MetricsEvent.TYPE_OPEN) + .setSubtype(buzzBeepBlink)); + EventLogTags.writeNotificationAlert(key, buzz ? 1 : 0, beep ? 1 : 0, blink ? 1 : 0); + } + record.setAudiblyAlerted(buzz || beep); + + return buzzBeepBlink; + } + + boolean isInsistentUpdate(final NotificationRecord record) { + return (Objects.equals(record.getKey(), mSoundNotificationKey) + || Objects.equals(record.getKey(), mVibrateNotificationKey)) + && isCurrentlyInsistent(); + } + + boolean isCurrentlyInsistent() { + return isLoopingRingtoneNotification(mNMP.getNotificationByKey(mSoundNotificationKey)) + || isLoopingRingtoneNotification( + mNMP.getNotificationByKey(mVibrateNotificationKey)); + } + + boolean shouldMuteNotificationLocked(final NotificationRecord record, final Signals signals) { + // Suppressed because it's a silent update + final Notification notification = record.getNotification(); + if (record.isUpdate && (notification.flags & FLAG_ONLY_ALERT_ONCE) != 0) { + return true; + } + + // Suppressed because a user manually unsnoozed something (or similar) + if (record.shouldPostSilently()) { + return true; + } + + // muted by listener + final String disableEffects = disableNotificationEffects(record, signals.listenerHints); + if (disableEffects != null) { + ZenLog.traceDisableEffects(record, disableEffects); + return true; + } + + // suppressed due to DND + if (record.isIntercepted()) { + return true; + } + + // Suppressed because another notification in its group handles alerting + if (record.getSbn().isGroup()) { + if (notification.suppressAlertingDueToGrouping()) { + return true; + } + } + + // Suppressed for being too recently noisy + final String pkg = record.getSbn().getPackageName(); + if (mUsageStats.isAlertRateLimited(pkg)) { + Slog.e(TAG, "Muting recently noisy " + record.getKey()); + return true; + } + + // A different looping ringtone, such as an incoming call is playing + if (isCurrentlyInsistent() && !isInsistentUpdate(record)) { + return true; + } + + // Suppressed since it's a non-interruptive update to a bubble-suppressed notification + final boolean isBubbleOrOverflowed = record.canBubble() && (record.isFlagBubbleRemoved() + || record.getNotification().isBubbleNotification()); + if (record.isUpdate && !record.isInterruptive() && isBubbleOrOverflowed + && record.getNotification().getBubbleMetadata() != null) { + if (record.getNotification().getBubbleMetadata().isNotificationSuppressed()) { + return true; + } + } + + return false; + } + + private boolean isLoopingRingtoneNotification(final NotificationRecord playingRecord) { + if (playingRecord != null) { + if (playingRecord.getAudioAttributes().getUsage() == USAGE_NOTIFICATION_RINGTONE + && (playingRecord.getNotification().flags & FLAG_INSISTENT) != 0) { + return true; + } + } + return false; + } + + private boolean playSound(final NotificationRecord record, Uri soundUri) { + boolean looping = (record.getNotification().flags & FLAG_INSISTENT) != 0; + // play notifications if there is no user of exclusive audio focus + // and the stream volume is not 0 (non-zero volume implies not silenced by SILENT or + // VIBRATE ringer mode) + if (!mAudioManager.isAudioFocusExclusive() + && (mAudioManager.getStreamVolume( + AudioAttributes.toLegacyStreamType(record.getAudioAttributes())) != 0)) { + final long identity = Binder.clearCallingIdentity(); + try { + final IRingtonePlayer player = mAudioManager.getRingtonePlayer(); + if (player != null) { + if (DEBUG) { + Slog.v(TAG, "Playing sound " + soundUri + " with attributes " + + record.getAudioAttributes()); + } + player.playAsync(soundUri, record.getSbn().getUser(), looping, + record.getAudioAttributes()); + return true; + } + } catch (RemoteException e) { + Log.e(TAG, "Failed playSound: " + e); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + return false; + } + + private boolean playVibration(final NotificationRecord record, final VibrationEffect effect, + boolean delayVibForSound) { + // Escalate privileges so we can use the vibrator even if the + // notifying app does not have the VIBRATE permission. + final long identity = Binder.clearCallingIdentity(); + try { + if (delayVibForSound) { + new Thread(() -> { + // delay the vibration by the same amount as the notification sound + final int waitMs = mAudioManager.getFocusRampTimeMs( + AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, + record.getAudioAttributes()); + if (DEBUG) { + Slog.v(TAG, "Delaying vibration for notification " + + record.getKey() + " by " + waitMs + "ms"); + } + try { + Thread.sleep(waitMs); + } catch (InterruptedException e) { } + // Notifications might be canceled before it actually vibrates due to waitMs, + // so need to check that the notification is still valid for vibrate. + if (mNMP.getNotificationByKey(record.getKey()) != null) { + if (record.getKey().equals(mVibrateNotificationKey)) { + vibrate(record, effect, true); + } else { + if (DEBUG) { + Slog.v(TAG, "No vibration for notification " + + record.getKey() + ": a new notification is " + + "vibrating, or effects were cleared while waiting"); + } + } + } else { + Slog.w(TAG, "No vibration for canceled notification " + + record.getKey()); + } + }).start(); + } else { + vibrate(record, effect, false); + } + return true; + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + private void vibrate(NotificationRecord record, VibrationEffect effect, boolean delayed) { + // We need to vibrate as "android" so we can breakthrough DND. VibratorManagerService + // doesn't have a concept of vibrating on an app's behalf, so add the app information + // to the reason so we can still debug from bugreports + String reason = "Notification (" + record.getSbn().getOpPkg() + " " + + record.getSbn().getUid() + ") " + (delayed ? "(Delayed)" : ""); + mVibratorHelper.vibrate(effect, record.getAudioAttributes(), reason); + } + + void playInCallNotification() { + // TODO: Should we apply politeness to mInCallNotificationVolume ? + final ContentResolver cr = mContext.getContentResolver(); + if (mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_NORMAL + && Settings.Secure.getIntForUser(cr, + Settings.Secure.IN_CALL_NOTIFICATION_ENABLED, 1, cr.getUserId()) != 0) { + new Thread() { + @Override + public void run() { + final long identity = Binder.clearCallingIdentity(); + try { + final IRingtonePlayer player = mAudioManager.getRingtonePlayer(); + if (player != null) { + if (mCallNotificationToken != null) { + player.stop(mCallNotificationToken); + } + mCallNotificationToken = new Binder(); + player.play(mCallNotificationToken, mInCallNotificationUri, + mInCallNotificationAudioAttributes, + mInCallNotificationVolume, false); + } + } catch (RemoteException e) { + Log.e(TAG, "Failed playInCallNotification: " + e); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + }.start(); + } + } + + void clearSoundLocked() { + mSoundNotificationKey = null; + final long identity = Binder.clearCallingIdentity(); + try { + final IRingtonePlayer player = mAudioManager.getRingtonePlayer(); + if (player != null) { + player.stopAsync(); + } + } catch (RemoteException e) { + Log.e(TAG, "Failed clearSoundLocked: " + e); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + void clearVibrateLocked() { + mVibrateNotificationKey = null; + final long identity = Binder.clearCallingIdentity(); + try { + mVibratorHelper.cancelVibration(); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + private void clearLightsLocked() { + // light + mLights.clear(); + updateLightsLocked(); + } + + public void clearEffectsLocked(String key) { + if (key.equals(mSoundNotificationKey)) { + clearSoundLocked(); + } + if (key.equals(mVibrateNotificationKey)) { + clearVibrateLocked(); + } + boolean removed = mLights.remove(key); + if (removed) { + updateLightsLocked(); + } + } + + public void clearAttentionEffects() { + clearSoundLocked(); + clearVibrateLocked(); + clearLightsLocked(); + } + + void updateLightsLocked() { + if (mNotificationLight == null) { + return; + } + + // handle notification lights + NotificationRecord ledNotification = null; + while (ledNotification == null && !mLights.isEmpty()) { + final String owner = mLights.get(mLights.size() - 1); + ledNotification = mNMP.getNotificationByKey(owner); + if (ledNotification == null) { + Slog.wtfStack(TAG, "LED Notification does not exist: " + owner); + mLights.remove(owner); + } + } + + // Don't flash while we are in a call or screen is on + if (ledNotification == null || isInCall() || mScreenOn) { + mNotificationLight.turnOff(); + } else { + NotificationRecord.Light light = ledNotification.getLight(); + if (light != null && mNotificationPulseEnabled) { + // pulse repeatedly + mNotificationLight.setFlashing(light.color, LogicalLight.LIGHT_FLASH_TIMED, + light.onMs, light.offMs); + } + } + } + + boolean canShowLightsLocked(final NotificationRecord record, final Signals signals, + boolean aboveThreshold) { + // device lacks light + if (!mHasLight) { + return false; + } + // user turned lights off globally + if (!mNotificationPulseEnabled) { + return false; + } + // the notification/channel has no light + if (record.getLight() == null) { + return false; + } + // unimportant notification + if (!aboveThreshold) { + return false; + } + // suppressed due to DND + if ((record.getSuppressedVisualEffects() & SUPPRESSED_EFFECT_LIGHTS) != 0) { + return false; + } + // Suppressed because it's a silent update + final Notification notification = record.getNotification(); + if (record.isUpdate && (notification.flags & FLAG_ONLY_ALERT_ONCE) != 0) { + return false; + } + // Suppressed because another notification in its group handles alerting + if (record.getSbn().isGroup() && record.getNotification().suppressAlertingDueToGrouping()) { + return false; + } + // not if in call + if (isInCall()) { + return false; + } + // check current user + if (!isNotificationForCurrentUser(record, signals)) { + return false; + } + // Light, but only when the screen is off + return true; + } + + private String disableNotificationEffects(NotificationRecord record, int listenerHints) { + if (mDisableNotificationEffects) { + return "booleanState"; + } + + if ((listenerHints & HINT_HOST_DISABLE_EFFECTS) != 0) { + return "listenerHints"; + } + if (record != null && record.getAudioAttributes() != null) { + if ((listenerHints & HINT_HOST_DISABLE_NOTIFICATION_EFFECTS) != 0) { + if (record.getAudioAttributes().getUsage() + != AudioAttributes.USAGE_NOTIFICATION_RINGTONE) { + return "listenerNoti"; + } + } + if ((listenerHints & HINT_HOST_DISABLE_CALL_EFFECTS) != 0) { + if (record.getAudioAttributes().getUsage() + == AudioAttributes.USAGE_NOTIFICATION_RINGTONE) { + return "listenerCall"; + } + } + } + if (mCallState != TelephonyManager.CALL_STATE_IDLE && !mZenModeHelper.isCall(record)) { + return "callState"; + } + + return null; + } + + public void updateDisableNotificationEffectsLocked(int status) { + mDisableNotificationEffects = + (status & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0; + //if (disableNotificationEffects(null) != null) { + if (mDisableNotificationEffects) { + // cancel whatever is going on + clearAttentionEffects(); + } + } + + private boolean isInCall() { + if (mInCallStateOffHook) { + return true; + } + int audioMode = mAudioManager.getMode(); + if (audioMode == AudioManager.MODE_IN_CALL + || audioMode == AudioManager.MODE_IN_COMMUNICATION) { + return true; + } + return false; + } + + private static String callStateToString(int state) { + switch (state) { + case TelephonyManager.CALL_STATE_IDLE: return "CALL_STATE_IDLE"; + case TelephonyManager.CALL_STATE_RINGING: return "CALL_STATE_RINGING"; + case TelephonyManager.CALL_STATE_OFFHOOK: return "CALL_STATE_OFFHOOK"; + default: return "CALL_STATE_UNKNOWN_" + state; + } + } + + private boolean isNotificationForCurrentUser(final NotificationRecord record, + final Signals signals) { + final int currentUser; + final long token = Binder.clearCallingIdentity(); + try { + currentUser = ActivityManager.getCurrentUser(); + } finally { + Binder.restoreCallingIdentity(token); + } + return (record.getUserId() == UserHandle.USER_ALL || record.getUserId() == currentUser + || signals.isCurrentProfile); + } + + void sendAccessibilityEvent(NotificationRecord record) { + if (!mAccessibilityManager.isEnabled()) { + return; + } + + final Notification notification = record.getNotification(); + final CharSequence packageName = record.getSbn().getPackageName(); + final AccessibilityEvent event = + AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED); + event.setPackageName(packageName); + event.setClassName(Notification.class.getName()); + final int visibilityOverride = record.getPackageVisibilityOverride(); + final int notifVisibility = visibilityOverride == NotificationManager.VISIBILITY_NO_OVERRIDE + ? notification.visibility : visibilityOverride; + final int userId = record.getUser().getIdentifier(); + final boolean needPublic = userId >= 0 && mKeyguardManager.isDeviceLocked(userId); + if (needPublic && notifVisibility != Notification.VISIBILITY_PUBLIC) { + // Emit the public version if we're on the lockscreen and this notification isn't + // publicly visible. + event.setParcelableData(notification.publicVersion); + } else { + event.setParcelableData(notification); + } + final CharSequence tickerText = notification.tickerText; + if (!TextUtils.isEmpty(tickerText)) { + event.getText().add(tickerText); + } + + mAccessibilityManager.sendAccessibilityEvent(event); + } + + public void dump(PrintWriter pw, String prefix, NotificationManagerService.DumpFilter filter) { + pw.println("\n Notification attention state:"); + pw.print(prefix); + pw.println(" mSoundNotificationKey=" + mSoundNotificationKey); + pw.print(prefix); + pw.println(" mVibrateNotificationKey=" + mVibrateNotificationKey); + pw.print(prefix); + pw.println(" mDisableNotificationEffects=" + mDisableNotificationEffects); + pw.print(prefix); + pw.println(" mCallState=" + callStateToString(mCallState)); + pw.print(prefix); + pw.println(" mSystemReady=" + mSystemReady); + pw.print(prefix); + pw.println(" mNotificationPulseEnabled=" + mNotificationPulseEnabled); + + int N = mLights.size(); + if (N > 0) { + pw.print(prefix); + pw.println(" Lights List:"); + for (int i=0; i<N; i++) { + if (i == N - 1) { + pw.print(" > "); + } else { + pw.print(" "); + } + pw.println(mLights.get(i)); + } + pw.println(" "); + } + + } + + // External signals set from NMS + public static class Signals { + private final boolean isCurrentProfile; + private final int listenerHints; + + public Signals(boolean isCurrentProfile, int listenerHints) { + this.isCurrentProfile = isCurrentProfile; + this.listenerHints = listenerHints; + } + } + + //====================== Observers ============================= + private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + + if (action.equals(Intent.ACTION_SCREEN_ON)) { + // Keep track of screen on/off state, but do not turn off the notification light + // until user passes through the lock screen or views the notification. + mScreenOn = true; + updateLightsLocked(); + } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { + mScreenOn = false; + mUserPresent = false; + updateLightsLocked(); + } else if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) { + mInCallStateOffHook = TelephonyManager.EXTRA_STATE_OFFHOOK + .equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE)); + updateLightsLocked(); + } else if (action.equals(Intent.ACTION_USER_PRESENT)) { + mUserPresent = true; + // turn off LED when user passes through lock screen + if (mNotificationLight != null) { + mNotificationLight.turnOff(); + } + } + } + }; + + private final class SettingsObserver extends ContentObserver { + + private static final Uri NOTIFICATION_LIGHT_PULSE_URI = Settings.System.getUriFor( + Settings.System.NOTIFICATION_LIGHT_PULSE); + public SettingsObserver() { + super(null); + } + + @Override + public void onChange(boolean selfChange, Uri uri) { + if (NOTIFICATION_LIGHT_PULSE_URI.equals(uri)) { + boolean pulseEnabled = Settings.System.getIntForUser( + mContext.getContentResolver(), + Settings.System.NOTIFICATION_LIGHT_PULSE, 0, + UserHandle.USER_CURRENT) + != 0; + if (mNotificationPulseEnabled != pulseEnabled) { + mNotificationPulseEnabled = pulseEnabled; + updateLightsLocked(); + } + } + } + } + + + //TODO: cleanup most (all?) of these + //======================= FOR TESTS ===================== + @VisibleForTesting + void setIsAutomotive(boolean isAutomotive) { + mIsAutomotive = isAutomotive; + } + + @VisibleForTesting + void setNotificationEffectsEnabledForAutomotive(boolean isEnabled) { + mNotificationEffectsEnabledForAutomotive = isEnabled; + } + + @VisibleForTesting + void setSystemReady(boolean systemReady) { + mSystemReady = systemReady; + } + + @VisibleForTesting + void setKeyguardManager(KeyguardManager keyguardManager) { + mKeyguardManager = keyguardManager; + } + + @VisibleForTesting + void setAccessibilityManager(AccessibilityManager am) { + mAccessibilityManager = am; + } + + @VisibleForTesting + VibratorHelper getVibratorHelper() { + return mVibratorHelper; + } + + @VisibleForTesting + void setVibratorHelper(VibratorHelper helper) { + mVibratorHelper = helper; + } + + @VisibleForTesting + void setScreenOn(boolean on) { + mScreenOn = on; + } + + @VisibleForTesting + void setLights(LogicalLight light) { + mNotificationLight = light; + mAttentionLight = light; + mNotificationPulseEnabled = true; + mHasLight = true; + } + + @VisibleForTesting + void setAudioManager(AudioManager audioManager) { + mAudioManager = audioManager; + } + + @VisibleForTesting + void setInCallStateOffHook(boolean inCallStateOffHook) { + mInCallStateOffHook = inCallStateOffHook; + } + +} diff --git a/services/core/java/com/android/server/notification/NotificationManagerPrivate.java b/services/core/java/com/android/server/notification/NotificationManagerPrivate.java new file mode 100644 index 000000000000..2cc63ebfc962 --- /dev/null +++ b/services/core/java/com/android/server/notification/NotificationManagerPrivate.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.notification; + +import android.annotation.Nullable; + +/** + * Interface that allows components (helpers) to access NotificationRecords + * without an explicit reference to NotificationManagerService. + */ +interface NotificationManagerPrivate { + @Nullable + NotificationRecord getNotificationByKey(String key); +} diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index bada8165766c..802dfb182297 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -287,6 +287,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.compat.IPlatformCompat; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags; +import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags; import com.android.internal.logging.InstanceId; import com.android.internal.logging.InstanceIdSequence; import com.android.internal.logging.MetricsLogger; @@ -315,6 +316,7 @@ import com.android.server.SystemService; import com.android.server.job.JobSchedulerInternal; import com.android.server.lights.LightsManager; import com.android.server.lights.LogicalLight; +import com.android.server.notification.Flags; import com.android.server.notification.ManagedServices.ManagedServiceInfo; import com.android.server.notification.ManagedServices.UserProfiles; import com.android.server.notification.toast.CustomToastRecord; @@ -684,6 +686,7 @@ public class NotificationManagerService extends SystemService { private boolean mIsAutomotive; private boolean mNotificationEffectsEnabledForAutomotive; private DeviceConfig.OnPropertiesChangedListener mDeviceConfigChangedListener; + protected NotificationAttentionHelper mAttentionHelper; private int mWarnRemoteViewsSizeBytes; private int mStripRemoteViewsSizeBytes; @@ -1167,12 +1170,16 @@ public class NotificationManagerService extends SystemService { @Override public void onSetDisabled(int status) { synchronized (mNotificationLock) { - mDisableNotificationEffects = - (status & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0; - if (disableNotificationEffects(null) != null) { - // cancel whatever's going on - clearSoundLocked(); - clearVibrateLocked(); + if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) { + mAttentionHelper.updateDisableNotificationEffectsLocked(status); + } else { + mDisableNotificationEffects = + (status & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0; + if (disableNotificationEffects(null) != null) { + // cancel whatever's going on + clearSoundLocked(); + clearVibrateLocked(); + } } } } @@ -1309,9 +1316,13 @@ public class NotificationManagerService extends SystemService { public void clearEffects() { synchronized (mNotificationLock) { if (DBG) Slog.d(TAG, "clearEffects"); - clearSoundLocked(); - clearVibrateLocked(); - clearLightsLocked(); + if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) { + mAttentionHelper.clearAttentionEffects(); + } else { + clearSoundLocked(); + clearVibrateLocked(); + clearLightsLocked(); + } } } @@ -1534,7 +1545,12 @@ public class NotificationManagerService extends SystemService { int changedFlags = data.getFlags() ^ flags; if ((changedFlags & FLAG_SUPPRESS_NOTIFICATION) != 0) { // Suppress notification flag changed, clear any effects - clearEffectsLocked(key); + if (mFlagResolver.isEnabled( + NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) { + mAttentionHelper.clearEffectsLocked(key); + } else { + clearEffectsLocked(key); + } } data.setFlags(flags); // Shouldn't alert again just because of a flag change. @@ -1626,6 +1642,12 @@ public class NotificationManagerService extends SystemService { }; + NotificationManagerPrivate mNotificationManagerPrivate = key -> { + synchronized (mNotificationLock) { + return mNotificationsByKey.get(key); + } + }; + @VisibleForTesting void logSmartSuggestionsVisible(NotificationRecord r, int notificationLocation) { // If the newly visible notification has smart suggestions @@ -1873,19 +1895,28 @@ public class NotificationManagerService extends SystemService { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); - if (action.equals(Intent.ACTION_SCREEN_ON)) { - // Keep track of screen on/off state, but do not turn off the notification light - // until user passes through the lock screen or views the notification. - mScreenOn = true; - updateNotificationPulse(); - } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { - mScreenOn = false; - updateNotificationPulse(); - } else if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) { - mInCallStateOffHook = TelephonyManager.EXTRA_STATE_OFFHOOK + if (!mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) { + if (action.equals(Intent.ACTION_SCREEN_ON)) { + // Keep track of screen on/off state, but do not turn off the notification light + // until user passes through the lock screen or views the notification. + mScreenOn = true; + updateNotificationPulse(); + } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { + mScreenOn = false; + updateNotificationPulse(); + } else if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) { + mInCallStateOffHook = TelephonyManager.EXTRA_STATE_OFFHOOK .equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE)); - updateNotificationPulse(); - } else if (action.equals(Intent.ACTION_USER_STOPPED)) { + updateNotificationPulse(); + } else if (action.equals(Intent.ACTION_USER_PRESENT)) { + // turn off LED when user passes through lock screen + if (mNotificationLight != null) { + mNotificationLight.turnOff(); + } + } + } + + if (action.equals(Intent.ACTION_USER_STOPPED)) { int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); if (userHandle >= 0) { cancelAllNotificationsInt(MY_UID, MY_PID, null, null, 0, 0, userHandle, @@ -1898,11 +1929,6 @@ public class NotificationManagerService extends SystemService { REASON_PROFILE_TURNED_OFF); mSnoozeHelper.clearData(userHandle); } - } else if (action.equals(Intent.ACTION_USER_PRESENT)) { - // turn off LED when user passes through lock screen - if (mNotificationLight != null) { - mNotificationLight.turnOff(); - } } else if (action.equals(Intent.ACTION_USER_SWITCHED)) { final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL); mUserProfiles.updateCache(context); @@ -1976,8 +2002,10 @@ public class NotificationManagerService extends SystemService { ContentResolver resolver = getContext().getContentResolver(); resolver.registerContentObserver(NOTIFICATION_BADGING_URI, false, this, UserHandle.USER_ALL); - resolver.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI, + if (!mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) { + resolver.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI, false, this, UserHandle.USER_ALL); + } resolver.registerContentObserver(NOTIFICATION_RATE_LIMIT_URI, false, this, UserHandle.USER_ALL); resolver.registerContentObserver(NOTIFICATION_BUBBLES_URI, @@ -2000,13 +2028,15 @@ public class NotificationManagerService extends SystemService { public void update(Uri uri) { ContentResolver resolver = getContext().getContentResolver(); - if (uri == null || NOTIFICATION_LIGHT_PULSE_URI.equals(uri)) { - boolean pulseEnabled = Settings.System.getIntForUser(resolver, - Settings.System.NOTIFICATION_LIGHT_PULSE, 0, UserHandle.USER_CURRENT) + if (!mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) { + if (uri == null || NOTIFICATION_LIGHT_PULSE_URI.equals(uri)) { + boolean pulseEnabled = Settings.System.getIntForUser(resolver, + Settings.System.NOTIFICATION_LIGHT_PULSE, 0, UserHandle.USER_CURRENT) != 0; - if (mNotificationPulseEnabled != pulseEnabled) { - mNotificationPulseEnabled = pulseEnabled; - updateNotificationPulse(); + if (mNotificationPulseEnabled != pulseEnabled) { + mNotificationPulseEnabled = pulseEnabled; + updateNotificationPulse(); + } } } if (uri == null || NOTIFICATION_RATE_LIMIT_URI.equals(uri)) { @@ -2491,14 +2521,22 @@ public class NotificationManagerService extends SystemService { mToastRateLimiter = toastRateLimiter; + if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) { + mAttentionHelper = new NotificationAttentionHelper(getContext(), lightsManager, + mAccessibilityManager, mPackageManagerClient, usageStats, + mNotificationManagerPrivate, mZenModeHelper, flagResolver); + } + // register for various Intents. // If this is called within a test, make sure to unregister the intent receivers by // calling onDestroy() IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_SCREEN_ON); - filter.addAction(Intent.ACTION_SCREEN_OFF); - filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); - filter.addAction(Intent.ACTION_USER_PRESENT); + if (!mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) { + filter.addAction(Intent.ACTION_SCREEN_ON); + filter.addAction(Intent.ACTION_SCREEN_OFF); + filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); + filter.addAction(Intent.ACTION_USER_PRESENT); + } filter.addAction(Intent.ACTION_USER_STOPPED); filter.addAction(Intent.ACTION_USER_SWITCHED); filter.addAction(Intent.ACTION_USER_ADDED); @@ -2818,6 +2856,9 @@ public class NotificationManagerService extends SystemService { } registerNotificationPreferencesPullers(); new LockPatternUtils(getContext()).registerStrongAuthTracker(mStrongAuthTracker); + if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) { + mAttentionHelper.onSystemReady(); + } } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { // This observer will force an update when observe is called, causing us to // bind to listener services. @@ -6375,6 +6416,9 @@ public class NotificationManagerService extends SystemService { pw.println(" mMaxPackageEnqueueRate=" + mMaxPackageEnqueueRate); pw.println(" hideSilentStatusBar=" + mPreferencesHelper.shouldHideSilentStatusIcons()); + if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) { + mAttentionHelper.dump(pw, " ", filter); + } } pw.println(" mArchive=" + mArchive.toString()); mArchive.dumpImpl(pw, filter); @@ -7632,7 +7676,11 @@ public class NotificationManagerService extends SystemService { boolean wasPosted = removeFromNotificationListsLocked(r); cancelNotificationLocked(r, false, REASON_SNOOZED, wasPosted, null, SystemClock.elapsedRealtime()); - updateLightsLocked(); + if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) { + mAttentionHelper.updateLightsLocked(); + } else { + updateLightsLocked(); + } if (isSnoozable(r)) { if (mSnoozeCriterionId != null) { mAssistants.notifyAssistantSnoozedLocked(r, mSnoozeCriterionId); @@ -7761,7 +7809,11 @@ public class NotificationManagerService extends SystemService { cancelGroupChildrenLocked(r, mCallingUid, mCallingPid, listenerName, mSendDelete, childrenFlagChecker, mReason, mCancellationElapsedTimeMs); - updateLightsLocked(); + if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) { + mAttentionHelper.updateLightsLocked(); + } else { + updateLightsLocked(); + } if (mShortcutHelper != null) { mShortcutHelper.maybeListenForShortcutChangesForBubbles(r, true /* isRemoved */, @@ -8054,7 +8106,14 @@ public class NotificationManagerService extends SystemService { int buzzBeepBlinkLoggingCode = 0; if (!r.isHidden()) { - buzzBeepBlinkLoggingCode = buzzBeepBlinkLocked(r); + if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) { + buzzBeepBlinkLoggingCode = mAttentionHelper.buzzBeepBlinkLocked(r, + new NotificationAttentionHelper.Signals( + mUserProfiles.isCurrentProfile(r.getUserId()), + mListenerHints)); + } else { + buzzBeepBlinkLoggingCode = buzzBeepBlinkLocked(r); + } } if (notification.getSmallIcon() != null) { @@ -9034,7 +9093,13 @@ public class NotificationManagerService extends SystemService { || interruptiveChanged; if (interceptBefore && !record.isIntercepted() && record.isNewEnoughForAlerting(System.currentTimeMillis())) { - buzzBeepBlinkLocked(record); + if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) { + mAttentionHelper.buzzBeepBlinkLocked(record, + new NotificationAttentionHelper.Signals( + mUserProfiles.isCurrentProfile(record.getUserId()), mListenerHints)); + } else { + buzzBeepBlinkLocked(record); + } // Log alert after change in intercepted state to Zen Log as well ZenLog.traceAlertOnUpdatedIntercept(record); @@ -9408,18 +9473,22 @@ public class NotificationManagerService extends SystemService { }); } - // sound - if (canceledKey.equals(mSoundNotificationKey)) { - clearSoundLocked(); - } + if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) { + mAttentionHelper.clearEffectsLocked(canceledKey); + } else { + // sound + if (canceledKey.equals(mSoundNotificationKey)) { + clearSoundLocked(); + } - // vibrate - if (canceledKey.equals(mVibrateNotificationKey)) { - clearVibrateLocked(); - } + // vibrate + if (canceledKey.equals(mVibrateNotificationKey)) { + clearVibrateLocked(); + } - // light - mLights.remove(canceledKey); + // light + mLights.remove(canceledKey); + } } // Record usage stats @@ -9768,7 +9837,11 @@ public class NotificationManagerService extends SystemService { cancellationElapsedTimeMs); } } - updateLightsLocked(); + if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) { + mAttentionHelper.updateLightsLocked(); + } else { + updateLightsLocked(); + } } } diff --git a/services/core/java/com/android/server/pm/ApkChecksums.java b/services/core/java/com/android/server/pm/ApkChecksums.java index 5b93244c1710..50ed3b1859df 100644 --- a/services/core/java/com/android/server/pm/ApkChecksums.java +++ b/services/core/java/com/android/server/pm/ApkChecksums.java @@ -655,7 +655,7 @@ public class ApkChecksums { } } catch (SignatureNotFoundException e) { // Nothing - } catch (SecurityException e) { + } catch (SignatureException | SecurityException e) { Slog.e(TAG, "V4 signature error", e); } return null; diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java index 316c4aca1891..6baa889d61ae 100644 --- a/services/core/java/com/android/server/pm/ComputerEngine.java +++ b/services/core/java/com/android/server/pm/ComputerEngine.java @@ -1700,7 +1700,9 @@ public class ComputerEngine implements Computer { if (!listApex && ps.getPkg() != null && ps.getPkg().isApex()) { continue; } - if (listArchivedOnly && !isArchived(ps.getUserStateOrDefault(userId))) { + PackageUserStateInternal userState = ps.getUserStateOrDefault(userId); + if (listArchivedOnly && !userState.isInstalled() + && userState.getArchiveState() == null) { continue; } if (filterSharedLibPackage(ps, callingUid, userId, flags)) { @@ -1746,13 +1748,6 @@ public class ComputerEngine implements Computer { return new ParceledListSlice<>(list); } - // TODO(b/288142708) Check for userState.isInstalled() here once this bug is fixed. - // If an app has isInstalled() == true - it should not be filtered above in any case, currently - // it is. - private static boolean isArchived(PackageUserStateInternal userState) { - return userState.getArchiveState() != null; - } - public final ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter, int sourceUserId, int targetUserId) { ResolveInfo forwardingResolveInfo = new ResolveInfo(); diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java index caf263dac823..83f90a1c1b3c 100644 --- a/services/core/java/com/android/server/pm/DeletePackageHelper.java +++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java @@ -53,6 +53,7 @@ import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.text.TextUtils; +import android.util.ArraySet; import android.util.EventLog; import android.util.Log; import android.util.Slog; @@ -561,6 +562,17 @@ final class DeletePackageHelper { Slog.d(TAG, "Marking package:" + ps.getPackageName() + " uninstalled for user:" + nextUserId); } + + // Keep enabled and disabled components in case of DELETE_KEEP_DATA + ArraySet<String> enabledComponents = null; + ArraySet<String> disabledComponents = null; + if ((flags & PackageManager.DELETE_KEEP_DATA) != 0) { + enabledComponents = new ArraySet<String>( + ps.readUserState(nextUserId).getEnabledComponents()); + disabledComponents = new ArraySet<String>( + ps.readUserState(nextUserId).getDisabledComponents()); + } + // Preserve ArchiveState if this is not a full uninstall ArchiveState archiveState = (flags & DELETE_KEEP_DATA) == 0 @@ -580,8 +592,8 @@ final class DeletePackageHelper { false /*instantApp*/, false /*virtualPreload*/, null /*lastDisableAppCaller*/, - null /*enabledComponents*/, - null /*disabledComponents*/, + enabledComponents, + disabledComponents, PackageManager.INSTALL_REASON_UNKNOWN, PackageManager.UNINSTALL_REASON_UNKNOWN, null /*harmfulAppWarning*/, diff --git a/services/core/java/com/android/server/pm/PackageArchiver.java b/services/core/java/com/android/server/pm/PackageArchiver.java index 803b6e45cdca..f59188e9fd93 100644 --- a/services/core/java/com/android/server/pm/PackageArchiver.java +++ b/services/core/java/com/android/server/pm/PackageArchiver.java @@ -58,6 +58,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.server.pm.pkg.ArchiveState; import com.android.server.pm.pkg.ArchiveState.ArchiveActivityInfo; import com.android.server.pm.pkg.PackageStateInternal; +import com.android.server.pm.pkg.PackageUserState; import com.android.server.pm.pkg.PackageUserStateInternal; import java.io.ByteArrayOutputStream; @@ -101,6 +102,11 @@ public class PackageArchiver { this.mPm = mPm; } + /** Returns whether a package is archived for a user. */ + public static boolean isArchived(PackageUserState userState) { + return userState.getArchiveState() != null && !userState.isInstalled(); + } + void requestArchive( @NonNull String packageName, @NonNull String callerPackageName, @@ -354,8 +360,7 @@ public class PackageArchiver { private void verifyArchived(PackageStateInternal ps, int userId) throws PackageManager.NameNotFoundException { PackageUserStateInternal userState = ps.getUserStateOrDefault(userId); - // TODO(b/288142708) Check for isInstalled false here too. - if (userState.getArchiveState() == null) { + if (!isArchived(userState)) { throw new PackageManager.NameNotFoundException( TextUtils.formatSimple("Package %s is not currently archived.", ps.getPackageName())); diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index d699baa0d9ab..f554773becad 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -138,6 +138,7 @@ import android.os.incremental.IncrementalFileStorages; import android.os.incremental.IncrementalManager; import android.os.incremental.PerUidReadTimeouts; import android.os.incremental.StorageHealthCheckParams; +import android.os.incremental.V4Signature; import android.os.storage.StorageManager; import android.provider.DeviceConfig; import android.provider.Settings.Global; @@ -802,6 +803,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // entries like "lost+found". if (file.isDirectory()) return false; if (file.getName().endsWith(REMOVE_MARKER_EXTENSION)) return false; + if (file.getName().endsWith(V4Signature.EXT)) return false; if (isAppMetadata(file)) return false; if (DexMetadataHelper.isDexMetadataFile(file)) return false; if (VerityUtils.isFsveritySignatureFile(file)) return false; @@ -1502,6 +1504,21 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } @GuardedBy("mLock") + private void enableFsVerityToAddedApksWithIdsig() throws PackageManagerException { + try { + List<File> files = getAddedApksLocked(); + for (var file : files) { + if (new File(file.getPath() + V4Signature.EXT).exists()) { + VerityUtils.setUpFsverity(file.getPath()); + } + } + } catch (IOException e) { + throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE, + "Failed to enable fs-verity to verify with idsig: " + e); + } + } + + @GuardedBy("mLock") private List<ApkLite> getAddedApkLitesLocked() throws PackageManagerException { if (!isArchivedInstallation()) { List<File> files = getAddedApksLocked(); @@ -3294,6 +3311,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } + // Needs to happen before the first v4 signature verification, which happens in + // getAddedApkLitesLocked. + if (android.security.Flags.extendVbChainToUpdatedApk()) { + if (!isIncrementalInstallation()) { + enableFsVerityToAddedApksWithIdsig(); + } + } + final List<ApkLite> addedFiles = getAddedApkLitesLocked(); if (addedFiles.isEmpty() && (removeSplitList.size() == 0 || getStagedAppMetadataFile() != null)) { @@ -3656,6 +3681,16 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } @GuardedBy("mLock") + private void maybeStageV4SignatureLocked(File origFile, File targetFile) + throws PackageManagerException { + final File originalSignature = new File(origFile.getPath() + V4Signature.EXT); + if (originalSignature.exists()) { + final File stagedSignature = new File(targetFile.getPath() + V4Signature.EXT); + stageFileLocked(originalSignature, stagedSignature); + } + } + + @GuardedBy("mLock") private void maybeStageDexMetadataLocked(File origFile, File targetFile) throws PackageManagerException { final File dexMetadataFile = DexMetadataHelper.findDexMetadataForFile(origFile); @@ -3782,6 +3817,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // Stage APK's fs-verity signature if present. maybeStageFsveritySignatureLocked(origFile, targetFile, isFsVerityRequiredForApk(origFile, targetFile)); + // Stage APK's v4 signature if present. + if (android.security.Flags.extendVbChainToUpdatedApk()) { + maybeStageV4SignatureLocked(origFile, targetFile); + } // Stage dex metadata (.dm) and corresponding fs-verity signature if present. maybeStageDexMetadataLocked(origFile, targetFile); // Stage checksums (.digests) if present. @@ -3799,10 +3838,22 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } @GuardedBy("mLock") + private void maybeInheritV4SignatureLocked(File origFile) { + // Inherit the v4 signature file if present. + final File v4SignatureFile = new File(origFile.getPath() + V4Signature.EXT); + if (v4SignatureFile.exists()) { + mResolvedInheritedFiles.add(v4SignatureFile); + } + } + + @GuardedBy("mLock") private void inheritFileLocked(File origFile) { mResolvedInheritedFiles.add(origFile); maybeInheritFsveritySignatureLocked(origFile); + if (android.security.Flags.extendVbChainToUpdatedApk()) { + maybeInheritV4SignatureLocked(origFile); + } // Inherit the dex metadata if present. final File dexMetadataFile = diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 700fae953ead..33cb85c038a0 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -4681,9 +4681,12 @@ public class PackageManagerService implements PackageSender, TestUtilityService @UserIdInt int userId, @NonNull String recentCallingPackage, @NonNull String debugInfo) { synchronized (mLock) { - final PackageUserStateInternal userState = mSettings.getPackageLPr( - packageName).getUserStateOrDefault(userId); - if (userState.isQuarantined()) { + final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName); + // If the package doesn't exist, don't need to proceed to setPackageStoppedState. + if (pkgSetting == null) { + return; + } + if (pkgSetting.getUserStateOrDefault(userId).isQuarantined()) { Slog.i(TAG, "Component is quarantined+suspended but being used: " + packageName + " by " + recentCallingPackage + ", debugInfo: " diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 72a737084526..7264e2eff4aa 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -4568,6 +4568,10 @@ class PackageManagerShellCommand extends ShellCommand { PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, 0); + if (ai == null) { + Slog.e(TAG, "Failed to get ApplicationInfo for package name(" + pii.packageName + ")."); + return null; + } AssetManager am = new AssetManager(); am.addAssetPath(ai.publicSourceDir); res = new Resources(am, null, null); diff --git a/services/core/java/com/android/server/pm/PackageMetrics.java b/services/core/java/com/android/server/pm/PackageMetrics.java index 7ad336c9074d..24d2a265ebf6 100644 --- a/services/core/java/com/android/server/pm/PackageMetrics.java +++ b/services/core/java/com/android/server/pm/PackageMetrics.java @@ -310,18 +310,25 @@ final class PackageMetrics { if (!SecurityLog.isLoggingEnabled()) { return; } - final PackageSetting ps = mInstallRequest.getScannedPackageSetting(); - if (ps == null) { - return; - } - final String packageName = ps.getPackageName(); - final long versionCode = ps.getVersionCode(); - if (!mInstallRequest.isInstallReplace()) { - SecurityLog.writeEvent(SecurityLog.TAG_PACKAGE_INSTALLED, packageName, versionCode, - userId); - } else { - SecurityLog.writeEvent(SecurityLog.TAG_PACKAGE_UPDATED, packageName, versionCode, - userId); + // TODO: Remove temp try-catch to avoid IllegalStateException. The reason is because + // the scan result is null for installExistingPackageAsUser(). Because it's installing + // a package that's already existing, there's no scanning or parsing involved + try { + final PackageSetting ps = mInstallRequest.getScannedPackageSetting(); + if (ps == null) { + return; + } + final String packageName = ps.getPackageName(); + final long versionCode = ps.getVersionCode(); + if (!mInstallRequest.isInstallReplace()) { + SecurityLog.writeEvent(SecurityLog.TAG_PACKAGE_INSTALLED, packageName, versionCode, + userId); + } else { + SecurityLog.writeEvent(SecurityLog.TAG_PACKAGE_UPDATED, packageName, versionCode, + userId); + } + } catch (IllegalStateException | NullPointerException e) { + // no-op } } diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java index cc8e62409597..d16a81267370 100644 --- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java +++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java @@ -54,6 +54,7 @@ import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.server.SystemConfig; +import com.android.server.pm.PackageArchiver; import com.android.server.pm.parsing.pkg.AndroidPackageUtils; import com.android.server.pm.parsing.pkg.PackageImpl; import com.android.server.pm.pkg.AndroidPackage; @@ -401,14 +402,7 @@ public class PackageInfoUtils { ai.resourceDirs = overlayPaths.getResourceDirs().toArray(new String[0]); ai.overlayPaths = overlayPaths.getOverlayPaths().toArray(new String[0]); } - ai.isArchived = isArchived(state); - } - - // TODO(b/288142708) Check for userState.isInstalled() here once this bug is fixed. - // If an app has isInstalled() == true - it should not be filtered above in any case, currently - // it is. - private static boolean isArchived(PackageUserState userState) { - return userState.getArchiveState() != null; + ai.isArchived = PackageArchiver.isArchived(state); } @Nullable diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java index bf206537d912..d6a7dc6681b9 100644 --- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java @@ -218,6 +218,7 @@ final class DefaultPermissionGrantPolicy { STORAGE_PERMISSIONS.add(Manifest.permission.READ_MEDIA_AUDIO); STORAGE_PERMISSIONS.add(Manifest.permission.READ_MEDIA_VIDEO); STORAGE_PERMISSIONS.add(Manifest.permission.READ_MEDIA_IMAGES); + STORAGE_PERMISSIONS.add(Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED); } private static final Set<String> NEARBY_DEVICES_PERMISSIONS = new ArraySet<>(); diff --git a/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java b/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java index 3296c1f284af..150ca9ba2853 100644 --- a/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java +++ b/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java @@ -91,13 +91,14 @@ public class OneTimePermissionUserManager { mHandler = context.getMainThreadHandler(); } - void startPackageOneTimeSession(@NonNull String packageName, long timeoutMillis, + void startPackageOneTimeSession(@NonNull String packageName, int deviceId, long timeoutMillis, long revokeAfterKilledDelayMillis) { int uid; try { uid = mContext.getPackageManager().getPackageUid(packageName, 0); } catch (PackageManager.NameNotFoundException e) { - Log.e(LOG_TAG, "Unknown package name " + packageName, e); + Log.e(LOG_TAG, + "Unknown package name " + packageName + ", device ID " + deviceId, e); return; } @@ -107,7 +108,7 @@ public class OneTimePermissionUserManager { listener.updateSessionParameters(timeoutMillis, revokeAfterKilledDelayMillis); return; } - listener = new PackageInactivityListener(uid, packageName, timeoutMillis, + listener = new PackageInactivityListener(uid, packageName, deviceId, timeoutMillis, revokeAfterKilledDelayMillis); mListeners.put(uid, listener); } @@ -159,6 +160,7 @@ public class OneTimePermissionUserManager { private final int mUid; private final @NonNull String mPackageName; + private final int mDeviceId; private long mTimeout; private long mRevokeAfterKilledDelay; @@ -191,14 +193,15 @@ public class OneTimePermissionUserManager { } }; - private PackageInactivityListener(int uid, @NonNull String packageName, long timeout, - long revokeAfterkilledDelay) { + private PackageInactivityListener(int uid, @NonNull String packageName, int deviceId, + long timeout, long revokeAfterkilledDelay) { Log.i(LOG_TAG, "Start tracking " + packageName + ". uid=" + uid + " timeout=" + timeout + " killedDelay=" + revokeAfterkilledDelay); mUid = uid; mPackageName = packageName; + mDeviceId = deviceId; mTimeout = timeout; mRevokeAfterKilledDelay = revokeAfterkilledDelay == -1 ? DeviceConfig.getLong( @@ -232,7 +235,8 @@ public class OneTimePermissionUserManager { PROPERTY_KILLED_DELAY_CONFIG_KEY, DEFAULT_KILLED_DELAY_MILLIS) : revokeAfterKilledDelayMillis); Log.v(LOG_TAG, - "Updated params for " + mPackageName + ". timeout=" + mTimeout + "Updated params for " + mPackageName + ", device ID " + mDeviceId + + ". timeout=" + mTimeout + " killedDelay=" + mRevokeAfterKilledDelay); updateUidState(); } @@ -260,7 +264,7 @@ public class OneTimePermissionUserManager { private void updateUidState(int state) { Log.v(LOG_TAG, "Updating state for " + mPackageName + " (" + mUid + ")." - + " state=" + state); + + " device ID=" + mDeviceId + ", state=" + state); synchronized (mInnerLock) { // Remove any pending inactivity callback mHandler.removeCallbacksAndMessages(mToken); @@ -283,7 +287,7 @@ public class OneTimePermissionUserManager { if (DEBUG) { Log.d(LOG_TAG, "No longer gone after delayed revocation. " + "Rechecking for " + mPackageName + " (" + mUid - + ")."); + + "). device ID " + mDeviceId); } updateUidState(currentState); }, mToken, mRevokeAfterKilledDelay); @@ -292,7 +296,7 @@ public class OneTimePermissionUserManager { if (mTimerStart == TIMER_INACTIVE) { if (DEBUG) { Log.d(LOG_TAG, "Start the timer for " - + mPackageName + " (" + mUid + ")."); + + mPackageName + " (" + mUid + "). device ID " + mDeviceId); } mTimerStart = System.currentTimeMillis(); setAlarmLocked(); @@ -329,7 +333,8 @@ public class OneTimePermissionUserManager { } if (DEBUG) { - Log.d(LOG_TAG, "Scheduling alarm for " + mPackageName + " (" + mUid + ")."); + Log.d(LOG_TAG, "Scheduling alarm for " + mPackageName + " (" + mUid + ")." + + " device ID " + mDeviceId); } long revokeTime = mTimerStart + mTimeout; if (revokeTime > System.currentTimeMillis()) { @@ -349,7 +354,8 @@ public class OneTimePermissionUserManager { private void cancelAlarmLocked() { if (mIsAlarmSet) { if (DEBUG) { - Log.d(LOG_TAG, "Canceling alarm for " + mPackageName + " (" + mUid + ")."); + Log.d(LOG_TAG, "Canceling alarm for " + mPackageName + " (" + mUid + ")." + + " device ID " + mDeviceId); } mAlarmManager.cancel(this); mIsAlarmSet = false; @@ -366,17 +372,17 @@ public class OneTimePermissionUserManager { } if (DEBUG) { Log.d(LOG_TAG, "onPackageInactiveLocked stack trace for " - + mPackageName + " (" + mUid + ").", new RuntimeException()); + + mPackageName + " (" + mUid + "). device ID " + mDeviceId, + new RuntimeException()); } mIsFinished = true; cancelAlarmLocked(); mHandler.post( () -> { Log.i(LOG_TAG, "One time session expired for " - + mPackageName + " (" + mUid + ")."); - + + mPackageName + " (" + mUid + "). deviceID " + mDeviceId); mPermissionControllerManager.notifyOneTimePermissionSessionTimeout( - mPackageName); + mPackageName, mDeviceId); }); try { mIActivityManager.unregisterUidObserver(mObserver); @@ -391,7 +397,8 @@ public class OneTimePermissionUserManager { @Override public void onAlarm() { if (DEBUG) { - Log.d(LOG_TAG, "Alarm received for " + mPackageName + " (" + mUid + ")."); + Log.d(LOG_TAG, "Alarm received for " + mPackageName + " (" + mUid + ")." + + " device ID " + mDeviceId); } synchronized (mInnerLock) { if (!mIsAlarmSet) { diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 44eb28fc43f7..9610d051db95 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -404,15 +404,15 @@ public class PermissionManagerService extends IPermissionManager.Stub { @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS) @Override - public void startOneTimePermissionSession(String packageName, @UserIdInt int userId, - long timeoutMillis, long revokeAfterKilledDelayMillis) { + public void startOneTimePermissionSession(String packageName, int deviceId, + @UserIdInt int userId, long timeoutMillis, long revokeAfterKilledDelayMillis) { startOneTimePermissionSession_enforcePermission(); Objects.requireNonNull(packageName); final long token = Binder.clearCallingIdentity(); try { getOneTimePermissionUserManager(userId).startPackageOneTimeSession(packageName, - timeoutMillis, revokeAfterKilledDelayMillis); + deviceId, timeoutMillis, revokeAfterKilledDelayMillis); } finally { Binder.restoreCallingIdentity(token); } diff --git a/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java b/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java index 12795c6b6814..a76a7ce03170 100644 --- a/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java +++ b/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java @@ -393,29 +393,27 @@ public class PackageUserStateImpl extends WatchableImpl implements PackageUserSt } public @NonNull PackageUserStateImpl setDisabledComponents(@Nullable ArraySet<String> value) { - if (value == null) { - return this; - } if (mDisabledComponentsWatched == null) { mDisabledComponentsWatched = new WatchedArraySet<>(); mDisabledComponentsWatched.registerObserver(mSnapshot); } mDisabledComponentsWatched.clear(); - mDisabledComponentsWatched.addAll(value); + if (value != null) { + mDisabledComponentsWatched.addAll(value); + } onChanged(); return this; } public @NonNull PackageUserStateImpl setEnabledComponents(@Nullable ArraySet<String> value) { - if (value == null) { - return this; - } if (mEnabledComponentsWatched == null) { mEnabledComponentsWatched = new WatchedArraySet<>(); mEnabledComponentsWatched.registerObserver(mSnapshot); } mEnabledComponentsWatched.clear(); - mEnabledComponentsWatched.addAll(value); + if (value != null) { + mEnabledComponentsWatched.addAll(value); + } onChanged(); return this; } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index b420acdc0850..097656cac7f7 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -438,7 +438,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean mPreloadedRecentApps; final Object mServiceAcquireLock = new Object(); Vibrator mVibrator; // Vibrator for giving feedback of orientation changes - SearchManager mSearchManager; AccessibilityManager mAccessibilityManager; AccessibilityManagerInternal mAccessibilityManagerInternal; BurnInProtectionHelper mBurnInProtectionHelper; @@ -2217,7 +2216,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); mAppOpsManager = mContext.getSystemService(AppOpsManager.class); mSensorPrivacyManager = mContext.getSystemService(SensorPrivacyManager.class); - mSearchManager = mContext.getSystemService(SearchManager.class); mDisplayManager = mContext.getSystemService(DisplayManager.class); mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); @@ -3974,15 +3972,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { */ private int handleTransitionForKeyguardLw(boolean startKeyguardExitAnimation, boolean notifyOccluded) { + int redoLayout = 0; if (notifyOccluded) { - final int redoLayout = applyKeyguardOcclusionChange(); - if (redoLayout != 0) return redoLayout; + redoLayout = applyKeyguardOcclusionChange(); } if (startKeyguardExitAnimation) { if (DEBUG_KEYGUARD) Slog.d(TAG, "Starting keyguard exit animation"); startKeyguardExitAnimation(SystemClock.uptimeMillis()); } - return 0; + return redoLayout; } // There are several different flavors of "assistant" that can be launched from @@ -4009,8 +4007,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { args.putLong(Intent.EXTRA_TIME, eventTime); args.putInt(AssistUtils.INVOCATION_TYPE_KEY, invocationType); - if (mSearchManager != null) { - mSearchManager.launchAssist(args); + SearchManager searchManager = mContext.getSystemService(SearchManager.class); + if (searchManager != null) { + searchManager.launchAssist(args); } else { // Fallback to status bar if search manager doesn't exist (e.g. on wear). StatusBarManagerInternal statusBar = getStatusBarManagerInternal(); diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java index 4c9ec9d863bb..3c8e630dba2b 100644 --- a/services/core/java/com/android/server/wm/ActivityClientController.java +++ b/services/core/java/com/android/server/wm/ActivityClientController.java @@ -1018,8 +1018,7 @@ class ActivityClientController extends IActivityClientController.Stub { } try { - final ClientTransaction transaction = ClientTransaction.obtain( - r.app.getThread(), r.token); + final ClientTransaction transaction = ClientTransaction.obtain(r.app.getThread()); transaction.addCallback(EnterPipRequestedItem.obtain(r.token)); mService.getLifecycleManager().scheduleTransaction(transaction); return true; @@ -1040,8 +1039,7 @@ class ActivityClientController extends IActivityClientController.Stub { } try { - final ClientTransaction transaction = ClientTransaction.obtain( - r.app.getThread(), r.token); + final ClientTransaction transaction = ClientTransaction.obtain(r.app.getThread()); transaction.addCallback(PipStateTransactionItem.obtain(r.token, pipState)); mService.getLifecycleManager().scheduleTransaction(transaction); } catch (Exception e) { diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 5d0a457bbc43..d8245348d788 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1442,7 +1442,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A + "display, activityRecord=%s, displayId=%d, config=%s", this, displayId, config); - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token, + mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), MoveToDisplayItem.obtain(token, displayId, config)); } catch (RemoteException e) { // If process died, whatever. @@ -1459,7 +1459,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A ProtoLog.v(WM_DEBUG_CONFIGURATION, "Sending new config to %s, " + "config: %s", this, config); - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token, + mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), ActivityConfigurationChangeItem.obtain(token, config)); } catch (RemoteException e) { // If process died, whatever. @@ -1480,7 +1480,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A ProtoLog.v(WM_DEBUG_STATES, "Sending position change to %s, onTop: %b", this, onTop); - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token, + mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), TopResumedActivityChangeItem.obtain(token, onTop)); } catch (RemoteException e) { // If process died, whatever. @@ -2736,7 +2736,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } try { mTransferringSplashScreenState = TRANSFER_SPLASH_SCREEN_ATTACH_TO_CLIENT; - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token, + mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), TransferSplashScreenViewStateItem.obtain(token, parcelable, windowAnimationLeash)); scheduleTransferSplashScreenTimeout(); @@ -3903,7 +3903,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A try { if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + this); - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token, + mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), DestroyActivityItem.obtain(token, finishing, configChangeFlags)); } catch (Exception e) { // We can just ignore exceptions here... if the process has crashed, our death @@ -4809,9 +4809,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (isState(RESUMED) && attachedToProcess()) { try { - final ArrayList<ResultInfo> list = new ArrayList<ResultInfo>(); + final ArrayList<ResultInfo> list = new ArrayList<>(); list.add(new ResultInfo(resultWho, requestCode, resultCode, data)); - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token, + mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), ActivityResultItem.obtain(token, list)); return; } catch (Exception e) { @@ -4822,7 +4822,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // Schedule sending results now for Media Projection setup. if (forceSendForMediaProjection && attachedToProcess() && isState(STARTED, PAUSING, PAUSED, STOPPING, STOPPED)) { - final ClientTransaction transaction = ClientTransaction.obtain(app.getThread(), token); + final ClientTransaction transaction = ClientTransaction.obtain(app.getThread()); // Build result to be returned immediately. transaction.addCallback(ActivityResultItem.obtain( token, List.of(new ResultInfo(resultWho, requestCode, resultCode, data)))); @@ -4917,7 +4917,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // Making sure the client state is RESUMED after transaction completed and doing // so only if activity is currently RESUMED. Otherwise, client may have extra // life-cycle calls to RESUMED (and PAUSED later). - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token, + mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), NewIntentItem.obtain(token, ar, mState == RESUMED)); unsent = false; } catch (RemoteException e) { @@ -6152,7 +6152,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A EventLogTags.writeWmPauseActivity(mUserId, System.identityHashCode(this), shortComponentName, "userLeaving=false", "make-active"); try { - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token, + mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), PauseActivityItem.obtain(token, finishing, false /* userLeaving */, configChangeFlags, false /* dontReport */, mAutoEnteringPip)); } catch (Exception e) { @@ -6165,7 +6165,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A setState(STARTED, "makeActiveIfNeeded"); try { - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token, + mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), StartActivityItem.obtain(token, takeOptions())); } catch (Exception e) { Slog.w(TAG, "Exception thrown sending start: " + intent.getComponent(), e); @@ -6463,7 +6463,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } EventLogTags.writeWmStopActivity( mUserId, System.identityHashCode(this), shortComponentName); - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token, + mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), StopActivityItem.obtain(token, configChangeFlags)); mAtmService.mH.postDelayed(mStopTimeoutRunnable, STOP_TIMEOUT); @@ -9913,7 +9913,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } else { lifecycleItem = PauseActivityItem.obtain(token); } - final ClientTransaction transaction = ClientTransaction.obtain(app.getThread(), token); + final ClientTransaction transaction = ClientTransaction.obtain(app.getThread()); transaction.addCallback(callbackItem); transaction.setLifecycleStateRequest(lifecycleItem); mAtmService.getLifecycleManager().scheduleTransaction(transaction); @@ -10008,7 +10008,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // The process will be killed until the activity reports stopped with saved state (see // {@link ActivityTaskManagerService.activityStopped}). try { - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), token, + mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), StopActivityItem.obtain(token, 0 /* configChanges */)); } catch (RemoteException e) { Slog.w(TAG, "Exception thrown during restart " + this, e); diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index f38f6b0e4fa0..237bc9203415 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -6420,6 +6420,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (!restarting && hasVisibleActivities) { deferWindowLayout(); try { + final Task topTask = mRootWindowContainer.getTopDisplayFocusedRootTask(); + if (topTask != null + && topTask.topRunningActivity(true /* focusableOnly */) == null) { + topTask.adjustFocusToNextFocusableTask("handleAppDied"); + } if (!mRootWindowContainer.resumeFocusedTasksTopActivities()) { // If there was nothing to resume, and we are not already restarting // this process, but there is a visible activity that is hosted by the diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index 9bfc5534ef45..901975ba3614 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -795,10 +795,19 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { return false; } - // Try pausing the existing resumed activity in the Task if any. final Task task = r.getTask(); - if (task.pauseActivityIfNeeded(r, "realStart")) { - return false; + if (andResume) { + // Try pausing the existing resumed activity in the Task if any. + if (task.pauseActivityIfNeeded(r, "realStart")) { + return false; + } + final TaskFragment taskFragment = r.getTaskFragment(); + if (taskFragment != null && taskFragment.getResumedActivity() != null) { + if (taskFragment.startPausing(mUserLeaving, false /* uiSleeping */, r, + "realStart")) { + return false; + } + } } final Task rootTask = task.getRootTask(); @@ -919,7 +928,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { // Create activity launch transaction. final ClientTransaction clientTransaction = ClientTransaction.obtain( - proc.getThread(), r.token); + proc.getThread()); final boolean isTransitionForward = r.isTransitionForward(); final IBinder fragmentToken = r.getTaskFragment().getFragmentToken(); diff --git a/services/core/java/com/android/server/wm/ClientLifecycleManager.java b/services/core/java/com/android/server/wm/ClientLifecycleManager.java index 7430f0f1dc47..ef31837f810b 100644 --- a/services/core/java/com/android/server/wm/ClientLifecycleManager.java +++ b/services/core/java/com/android/server/wm/ClientLifecycleManager.java @@ -18,11 +18,10 @@ package com.android.server.wm; import android.annotation.NonNull; import android.app.IApplicationThread; +import android.app.servertransaction.ActivityLifecycleItem; import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.ClientTransactionItem; -import android.app.servertransaction.ActivityLifecycleItem; import android.os.Binder; -import android.os.IBinder; import android.os.RemoteException; /** @@ -36,13 +35,13 @@ class ClientLifecycleManager { // TODO(lifecycler): Use object pools for transactions and transaction items. /** - * Schedule a transaction, which may consist of multiple callbacks and a lifecycle request. + * Schedules a transaction, which may consist of multiple callbacks and a lifecycle request. * @param transaction A sequence of client transaction items. * @throws RemoteException * * @see ClientTransaction */ - void scheduleTransaction(ClientTransaction transaction) throws RemoteException { + void scheduleTransaction(@NonNull ClientTransaction transaction) throws RemoteException { final IApplicationThread client = transaction.getClient(); transaction.schedule(); if (!(client instanceof Binder)) { @@ -54,75 +53,22 @@ class ClientLifecycleManager { } /** - * Schedule a single lifecycle request or callback to client activity. - * @param client Target client. - * @param activityToken Target activity token. - * @param stateRequest A request to move target activity to a desired lifecycle state. - * @throws RemoteException - * - * @see ClientTransactionItem - */ - void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken, - @NonNull ActivityLifecycleItem stateRequest) throws RemoteException { - final ClientTransaction clientTransaction = transactionWithState(client, activityToken, - stateRequest); - scheduleTransaction(clientTransaction); - } - - /** - * Schedule a single callback delivery to client activity. + * Schedules a single transaction item, either a callback or a lifecycle request, delivery to + * client application. * @param client Target client. - * @param activityToken Target activity token. - * @param callback A request to deliver a callback. - * @throws RemoteException - * - * @see ClientTransactionItem - */ - void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken, - @NonNull ClientTransactionItem callback) throws RemoteException { - final ClientTransaction clientTransaction = transactionWithCallback(client, activityToken, - callback); - scheduleTransaction(clientTransaction); - } - - /** - * Schedule a single callback delivery to client application. - * @param client Target client. - * @param callback A request to deliver a callback. + * @param transactionItem A transaction item to deliver a message. * @throws RemoteException * * @see ClientTransactionItem */ void scheduleTransaction(@NonNull IApplicationThread client, - @NonNull ClientTransactionItem callback) throws RemoteException { - final ClientTransaction clientTransaction = transactionWithCallback(client, - null /* activityToken */, callback); + @NonNull ClientTransactionItem transactionItem) throws RemoteException { + final ClientTransaction clientTransaction = ClientTransaction.obtain(client); + if (transactionItem instanceof ActivityLifecycleItem) { + clientTransaction.setLifecycleStateRequest((ActivityLifecycleItem) transactionItem); + } else { + clientTransaction.addCallback(transactionItem); + } scheduleTransaction(clientTransaction); } - - /** - * @return A new instance of {@link ClientTransaction} with a single lifecycle state request. - * - * @see ClientTransaction - * @see ClientTransactionItem - */ - private static ClientTransaction transactionWithState(@NonNull IApplicationThread client, - @NonNull IBinder activityToken, @NonNull ActivityLifecycleItem stateRequest) { - final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken); - clientTransaction.setLifecycleStateRequest(stateRequest); - return clientTransaction; - } - - /** - * @return A new instance of {@link ClientTransaction} with a single callback invocation. - * - * @see ClientTransaction - * @see ClientTransactionItem - */ - private static ClientTransaction transactionWithCallback(@NonNull IApplicationThread client, - IBinder activityToken, @NonNull ClientTransactionItem callback) { - final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken); - clientTransaction.addCallback(callback); - return clientTransaction; - } } diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java index b499dad53326..06448d0c1e84 100644 --- a/services/core/java/com/android/server/wm/ContentRecorder.java +++ b/services/core/java/com/android/server/wm/ContentRecorder.java @@ -33,7 +33,6 @@ import android.media.projection.IMediaProjectionManager; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; -import android.provider.DeviceConfig; import android.view.ContentRecordingSession; import android.view.ContentRecordingSession.RecordContent; import android.view.Display; @@ -48,11 +47,6 @@ import com.android.internal.protolog.common.ProtoLog; final class ContentRecorder implements WindowContainerListener { /** - * The key for accessing the device config that controls if task recording is supported. - */ - @VisibleForTesting static final String KEY_RECORD_TASK_FEATURE = "record_task_content"; - - /** * The display content this class is handling recording for. */ @NonNull @@ -411,14 +405,6 @@ final class ContentRecorder implements WindowContainerListener { // TODO(206461622) Migrate to using the RootDisplayArea return dc; case RECORD_CONTENT_TASK: - if (!DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER, - KEY_RECORD_TASK_FEATURE, false)) { - handleStartRecordingFailed(); - ProtoLog.v(WM_DEBUG_CONTENT_RECORDING, - "Content Recording: Unable to record task since feature is disabled %d", - mDisplayContent.getDisplayId()); - return null; - } // Given the WindowToken of the region to record, retrieve the associated // SurfaceControl. if (tokenToRecord == null) { diff --git a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java index c4ed0dd9d606..534cdc2015e3 100644 --- a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java @@ -227,7 +227,7 @@ final class DisplayRotationCompatPolicy { "Refreshing activity for camera compatibility treatment, " + "activityRecord=%s", activity); final ClientTransaction transaction = ClientTransaction.obtain( - activity.app.getThread(), activity.token); + activity.app.getThread()); transaction.addCallback(RefreshCallbackItem.obtain(activity.token, cycleThroughStop ? ON_STOP : ON_PAUSE)); transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(activity.token, diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java index d2d6552a0c9c..735cbc4e4287 100644 --- a/services/core/java/com/android/server/wm/LetterboxUiController.java +++ b/services/core/java/com/android/server/wm/LetterboxUiController.java @@ -33,6 +33,7 @@ import static android.content.pm.ActivityInfo.OVERRIDE_RESPECT_REQUESTED_ORIENTA import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR; import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT; import static android.content.pm.ActivityInfo.OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION; +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; @@ -672,7 +673,8 @@ final class LetterboxUiController { // orientation. candidate = mActivityRecord.mWmService.mapOrientationRequest(candidate); - if (shouldApplyUserMinAspectRatioOverride() && !isFixedOrientation(candidate)) { + if (shouldApplyUserMinAspectRatioOverride() && (!isFixedOrientation(candidate) + || candidate == SCREEN_ORIENTATION_LOCKED)) { Slog.v(TAG, "Requested orientation " + screenOrientationToString(candidate) + " for " + mActivityRecord + " is overridden to " + screenOrientationToString(SCREEN_ORIENTATION_PORTRAIT) diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index b4b8a74d0d1b..261fc2eb26e0 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -3494,6 +3494,7 @@ class Task extends TaskFragment { info.topActivityLetterboxHeight = TaskInfo.PROPERTY_VALUE_UNSET; info.isUserFullscreenOverrideEnabled = top != null && top.mLetterboxUiController.shouldApplyUserFullscreenOverride(); + info.isTopActivityTransparent = top != null && !top.fillsParent(); info.isFromLetterboxDoubleTap = top != null && top.mLetterboxUiController.isFromDoubleTap(); if (info.isLetterboxDoubleTapEnabled) { info.topActivityLetterboxWidth = top.getBounds().width(); diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index d1b5350bd61a..5d95bc77edcb 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -1456,8 +1456,8 @@ class TaskFragment extends WindowContainer<WindowContainer> { } try { - final ClientTransaction transaction = - ClientTransaction.obtain(next.app.getThread(), next.token); + final ClientTransaction transaction = ClientTransaction.obtain( + next.app.getThread()); // Deliver all pending results. ArrayList<ResultInfo> a = next.results; if (a != null) { @@ -1741,7 +1741,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { prev.shortComponentName, "userLeaving=" + userLeaving, reason); mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(), - prev.token, PauseActivityItem.obtain(prev.token, prev.finishing, userLeaving, + PauseActivityItem.obtain(prev.token, prev.finishing, userLeaving, prev.configChangeFlags, pauseImmediately, autoEnteringPip)); } catch (Exception e) { // Ignore exception, if process died other code will cleanup. diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd index 4203e89ec618..d0a9c458a20f 100644 --- a/services/core/xsd/display-device-config/display-device-config.xsd +++ b/services/core/xsd/display-device-config/display-device-config.xsd @@ -96,6 +96,16 @@ <xs:element type="xs:nonNegativeInteger" name="screenBrightnessRampDecreaseMaxMillis"> <xs:annotation name="final"/> </xs:element> + <!-- Maximum time in milliseconds that a brightness increase animation + can take in idle mode. --> + <xs:element type="xs:nonNegativeInteger" name="screenBrightnessRampIncreaseMaxIdleMillis"> + <xs:annotation name="final"/> + </xs:element> + <!-- Maximum time in milliseconds that a brightness decrease animation + can take in idle mode. --> + <xs:element type="xs:nonNegativeInteger" name="screenBrightnessRampDecreaseMaxIdleMillis"> + <xs:annotation name="final"/> + </xs:element> <xs:element type="sensorDetails" name="lightSensor"> <xs:annotation name="final"/> </xs:element> diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt index ebd9b1c23a50..949b1f2cb74b 100644 --- a/services/core/xsd/display-device-config/schema/current.txt +++ b/services/core/xsd/display-device-config/schema/current.txt @@ -111,9 +111,11 @@ package com.android.server.display.config { method public com.android.server.display.config.RefreshRateConfigs getRefreshRate(); method @NonNull public final java.math.BigDecimal getScreenBrightnessDefault(); method @NonNull public final com.android.server.display.config.NitsMap getScreenBrightnessMap(); + method public final java.math.BigInteger getScreenBrightnessRampDecreaseMaxIdleMillis(); method public final java.math.BigInteger getScreenBrightnessRampDecreaseMaxMillis(); method public final java.math.BigDecimal getScreenBrightnessRampFastDecrease(); method public final java.math.BigDecimal getScreenBrightnessRampFastIncrease(); + method public final java.math.BigInteger getScreenBrightnessRampIncreaseMaxIdleMillis(); method public final java.math.BigInteger getScreenBrightnessRampIncreaseMaxMillis(); method public final java.math.BigDecimal getScreenBrightnessRampSlowDecrease(); method public final java.math.BigDecimal getScreenBrightnessRampSlowDecreaseIdle(); @@ -141,9 +143,11 @@ package com.android.server.display.config { method public void setRefreshRate(com.android.server.display.config.RefreshRateConfigs); method public final void setScreenBrightnessDefault(@NonNull java.math.BigDecimal); method public final void setScreenBrightnessMap(@NonNull com.android.server.display.config.NitsMap); + method public final void setScreenBrightnessRampDecreaseMaxIdleMillis(java.math.BigInteger); method public final void setScreenBrightnessRampDecreaseMaxMillis(java.math.BigInteger); method public final void setScreenBrightnessRampFastDecrease(java.math.BigDecimal); method public final void setScreenBrightnessRampFastIncrease(java.math.BigDecimal); + method public final void setScreenBrightnessRampIncreaseMaxIdleMillis(java.math.BigInteger); method public final void setScreenBrightnessRampIncreaseMaxMillis(java.math.BigInteger); method public final void setScreenBrightnessRampSlowDecrease(java.math.BigDecimal); method public final void setScreenBrightnessRampSlowDecreaseIdle(java.math.BigDecimal); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 84d1a452fa7e..f60493289bfb 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -16017,16 +16017,20 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public PackagePolicy getCredentialManagerPolicy() { + public PackagePolicy getCredentialManagerPolicy(int userId) { if (!mHasFeature) { return null; } final CallerIdentity caller = getCallerIdentity(); Preconditions.checkCallAuthorization( canWriteCredentialManagerPolicy(caller) || canQueryAdminPolicy(caller)); + if (userId != caller.getUserId()) { + Preconditions.checkCallAuthorization( + hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS)); + } synchronized (getLockObject()) { - ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()); + ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(userId); return (admin != null) ? admin.mCredentialManagerPolicy : null; } } diff --git a/services/permission/java/com/android/server/permission/access/permission/DevicePermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/DevicePermissionPolicy.kt index b2733d4ddb50..240585c000fd 100644 --- a/services/permission/java/com/android/server/permission/access/permission/DevicePermissionPolicy.kt +++ b/services/permission/java/com/android/server/permission/access/permission/DevicePermissionPolicy.kt @@ -16,6 +16,7 @@ package com.android.server.permission.access.permission +import android.permission.PermissionManager import android.util.Slog import com.android.modules.utils.BinaryXmlPullParser import com.android.modules.utils.BinaryXmlSerializer @@ -164,9 +165,18 @@ class DevicePermissionPolicy : SchemePolicy() { deviceId: String, userId: Int, permissionName: String - ): Int = - state.userStates[userId]?.appIdDevicePermissionFlags?.get(appId)?.get(deviceId) - ?.getWithDefault(permissionName, 0) ?: 0 + ): Int { + val flags = state.userStates[userId]?.appIdDevicePermissionFlags?.get(appId)?.get(deviceId) + ?.getWithDefault(permissionName, 0) ?: 0 + if (PermissionManager.DEBUG_DEVICE_PERMISSIONS) { + Slog.i( + LOG_TAG, "getPermissionFlags: appId=$appId, userId=$userId," + + " deviceId=$deviceId, permissionName=$permissionName," + + " flags=${PermissionFlags.toString(flags)}" + ) + } + return flags + } fun MutateStateScope.setPermissionFlags( appId: Int, @@ -202,6 +212,13 @@ class DevicePermissionPolicy : SchemePolicy() { val devicePermissionFlags = appIdDevicePermissionFlags.mutateOrPut(appId) { MutableIndexedReferenceMap() } + if (PermissionManager.DEBUG_DEVICE_PERMISSIONS) { + Slog.i( + LOG_TAG, "setPermissionFlags(): appId=$appId, userId=$userId," + + " deviceId=$deviceId, permissionName=$permissionName," + + " newFlags=${PermissionFlags.toString(newFlags)}" + ) + } val permissionFlags = devicePermissionFlags.mutateOrPut(deviceId) { MutableIndexedMap() } permissionFlags.putWithDefault(permissionName, newFlags, 0) if (permissionFlags.isEmpty()) { 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 1e052c037b3c..cee2524657dc 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 @@ -985,7 +985,7 @@ class PermissionService( ) { val appOpPolicy = service.getSchemePolicy(UidUri.SCHEME, AppOpUri.SCHEME) as AppIdAppOpPolicy - val appOpName = checkNotNull(AppOpsManager.permissionToOp(permissionName)) + val appOpName = AppOpsManager.permissionToOp(permissionName)!! val mode = if (isGranted) AppOpsManager.MODE_ALLOWED else AppOpsManager.MODE_ERRORED with(appOpPolicy) { setAppOpMode(packageState.appId, userId, appOpName, mode) } } diff --git a/services/tests/displayservicetests/Android.bp b/services/tests/displayservicetests/Android.bp index e28028f9fc2b..0275c7df4648 100644 --- a/services/tests/displayservicetests/Android.bp +++ b/services/tests/displayservicetests/Android.bp @@ -29,6 +29,7 @@ android_test { static_libs: [ "androidx.test.ext.junit", "androidx.test.rules", + "flag-junit", "frameworks-base-testutils", "junit", "junit-params", diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java index 7374901763db..6ef150c80037 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java @@ -103,12 +103,6 @@ public final class DisplayDeviceConfigTest { assertEquals(mDisplayDeviceConfig.getName(), "Example Display"); assertEquals(mDisplayDeviceConfig.getAmbientHorizonLong(), 5000); assertEquals(mDisplayDeviceConfig.getAmbientHorizonShort(), 50); - assertEquals(mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis(), 3000); - assertEquals(mDisplayDeviceConfig.getBrightnessRampIncreaseMaxMillis(), 2000); - assertEquals(mDisplayDeviceConfig.getBrightnessRampFastDecrease(), 0.01f, ZERO_DELTA); - assertEquals(mDisplayDeviceConfig.getBrightnessRampFastIncrease(), 0.02f, ZERO_DELTA); - assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowIncrease(), 0.04f, ZERO_DELTA); - assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowDecrease(), 0.03f, ZERO_DELTA); assertEquals(mDisplayDeviceConfig.getBrightnessDefault(), 0.5f, ZERO_DELTA); assertArrayEquals(mDisplayDeviceConfig.getBrightness(), BRIGHTNESS, ZERO_DELTA); assertArrayEquals(mDisplayDeviceConfig.getNits(), NITS, ZERO_DELTA); @@ -235,7 +229,8 @@ public final class DisplayDeviceConfigTest { @Test public void testInvalidLuxThrottling() throws Exception { setupDisplayDeviceConfigFromDisplayConfigFile( - getContent(getInvalidLuxThrottling(), getValidProxSensor())); + getContent(getInvalidLuxThrottling(), getValidProxSensor(), + /* includeIdleMode= */ true)); Map<DisplayDeviceConfig.BrightnessLimitMapType, Map<Float, Float>> luxThrottlingData = mDisplayDeviceConfig.getLuxThrottlingData(); @@ -258,6 +253,10 @@ public final class DisplayDeviceConfigTest { // We should fall back to the config resource verifyConfigValuesFromConfigResource(); + assertEquals(3000, mDisplayDeviceConfig.getAutoBrightnessBrighteningLightDebounce()); + assertEquals(4000, mDisplayDeviceConfig.getAutoBrightnessDarkeningLightDebounce()); + assertEquals(3000, mDisplayDeviceConfig.getAutoBrightnessBrighteningLightDebounceIdle()); + assertEquals(4000, mDisplayDeviceConfig.getAutoBrightnessDarkeningLightDebounceIdle()); } @Test @@ -438,7 +437,8 @@ public final class DisplayDeviceConfigTest { @Test public void testProximitySensorWithEmptyValuesFromDisplayConfig() throws IOException { setupDisplayDeviceConfigFromDisplayConfigFile( - getContent(getValidLuxThrottling(), getProxSensorWithEmptyValues())); + getContent(getValidLuxThrottling(), getProxSensorWithEmptyValues(), + /* includeIdleMode= */ true)); assertNull(mDisplayDeviceConfig.getProximitySensor()); } @@ -577,6 +577,39 @@ public final class DisplayDeviceConfigTest { assertEquals(mDisplayDeviceConfig.getAutoBrightnessDarkeningLightDebounceIdle(), 1500); } + @Test + public void testBrightnessRamps() throws IOException { + setupDisplayDeviceConfigFromDisplayConfigFile(); + + assertEquals(mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis(), 3000); + assertEquals(mDisplayDeviceConfig.getBrightnessRampIncreaseMaxMillis(), 2000); + assertEquals(mDisplayDeviceConfig.getBrightnessRampDecreaseMaxIdleMillis(), 5000); + assertEquals(mDisplayDeviceConfig.getBrightnessRampIncreaseMaxIdleMillis(), 4000); + assertEquals(mDisplayDeviceConfig.getBrightnessRampFastDecrease(), 0.01f, ZERO_DELTA); + assertEquals(mDisplayDeviceConfig.getBrightnessRampFastIncrease(), 0.02f, ZERO_DELTA); + assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowDecrease(), 0.03f, ZERO_DELTA); + assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowIncrease(), 0.04f, ZERO_DELTA); + assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowDecreaseIdle(), 0.05f, ZERO_DELTA); + assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowIncreaseIdle(), 0.06f, ZERO_DELTA); + } + + @Test + public void testBrightnessRamps_IdleFallsBackToConfigInteractive() throws IOException { + setupDisplayDeviceConfigFromDisplayConfigFile(getContent(getValidLuxThrottling(), + getValidProxSensor(), /* includeIdleMode= */ false)); + + assertEquals(mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis(), 3000); + assertEquals(mDisplayDeviceConfig.getBrightnessRampIncreaseMaxMillis(), 2000); + assertEquals(mDisplayDeviceConfig.getBrightnessRampDecreaseMaxIdleMillis(), 3000); + assertEquals(mDisplayDeviceConfig.getBrightnessRampIncreaseMaxIdleMillis(), 2000); + assertEquals(mDisplayDeviceConfig.getBrightnessRampFastDecrease(), 0.01f, ZERO_DELTA); + assertEquals(mDisplayDeviceConfig.getBrightnessRampFastIncrease(), 0.02f, ZERO_DELTA); + assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowDecrease(), 0.03f, ZERO_DELTA); + assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowIncrease(), 0.04f, ZERO_DELTA); + assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowDecreaseIdle(), 0.03f, ZERO_DELTA); + assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowIncreaseIdle(), 0.04f, ZERO_DELTA); + } + private String getValidLuxThrottling() { return "<luxThrottling>\n" + " <brightnessLimitMap>\n" @@ -731,11 +764,103 @@ public final class DisplayDeviceConfigTest { + "</hdrBrightnessConfig>"; } + private String getRampSpeedsIdle() { + return "<brighteningLightDebounceIdleMillis>" + + "2500" + + "</brighteningLightDebounceIdleMillis>\n" + + "<darkeningLightDebounceIdleMillis>" + + "1500" + + "</darkeningLightDebounceIdleMillis>\n"; + } + + private String getThresholdsIdle() { + return "<ambientBrightnessChangeThresholdsIdle>\n" + + "<brighteningThresholds>\n" + + "<minimum>20</minimum>\n" + + "<brightnessThresholdPoints>\n" + + "<brightnessThresholdPoint>\n" + + "<threshold>0</threshold><percentage>21</percentage>\n" + + "</brightnessThresholdPoint>\n" + + "<brightnessThresholdPoint>\n" + + "<threshold>500</threshold><percentage>22</percentage>\n" + + "</brightnessThresholdPoint>\n" + + "<brightnessThresholdPoint>\n" + + "<threshold>600</threshold><percentage>23</percentage>\n" + + "</brightnessThresholdPoint>\n" + + "</brightnessThresholdPoints>\n" + + "</brighteningThresholds>\n" + + "<darkeningThresholds>\n" + + "<minimum>40</minimum>\n" + + "<brightnessThresholdPoints>\n" + + "<brightnessThresholdPoint>\n" + + "<threshold>0</threshold><percentage>23</percentage>\n" + + "</brightnessThresholdPoint>\n" + + "<brightnessThresholdPoint>\n" + + "<threshold>700</threshold><percentage>24</percentage>\n" + + "</brightnessThresholdPoint>\n" + + "<brightnessThresholdPoint>\n" + + "<threshold>800</threshold><percentage>25</percentage>\n" + + "</brightnessThresholdPoint>\n" + + "</brightnessThresholdPoints>\n" + + "</darkeningThresholds>\n" + + "</ambientBrightnessChangeThresholdsIdle>\n" + + "<displayBrightnessChangeThresholdsIdle>\n" + + "<brighteningThresholds>\n" + + "<minimum>0.2</minimum>\n" + + "<brightnessThresholdPoints>\n" + + "<brightnessThresholdPoint>\n" + + "<threshold>0</threshold><percentage>17</percentage>\n" + + "</brightnessThresholdPoint>\n" + + "<brightnessThresholdPoint>\n" + + "<threshold>0.12</threshold><percentage>18</percentage>\n" + + "</brightnessThresholdPoint>\n" + + "<brightnessThresholdPoint>\n" + + "<threshold>0.22</threshold><percentage>19</percentage>\n" + + "</brightnessThresholdPoint>\n" + + "</brightnessThresholdPoints>\n" + + "</brighteningThresholds>\n" + + "<darkeningThresholds>\n" + + "<minimum>0.4</minimum>\n" + + "<brightnessThresholdPoints>\n" + + "<brightnessThresholdPoint>\n" + + "<threshold>0</threshold><percentage>19</percentage>\n" + + "</brightnessThresholdPoint>\n" + + "<brightnessThresholdPoint>\n" + + "<threshold>0.13</threshold><percentage>20</percentage>\n" + + "</brightnessThresholdPoint>\n" + + "<brightnessThresholdPoint>\n" + + "<threshold>0.23</threshold><percentage>21</percentage>\n" + + "</brightnessThresholdPoint>\n" + + "</brightnessThresholdPoints>\n" + + "</darkeningThresholds>\n" + + "</displayBrightnessChangeThresholdsIdle>\n"; + } + + private String getScreenBrightnessRampSlowIdle() { + return "<screenBrightnessRampSlowDecreaseIdle>" + + "0.05" + + "</screenBrightnessRampSlowDecreaseIdle>\n" + + "<screenBrightnessRampSlowIncreaseIdle>" + + "0.06" + + "</screenBrightnessRampSlowIncreaseIdle>\n"; + } + + private String getScreenBrightnessRampCapsIdle() { + return "<screenBrightnessRampIncreaseMaxIdleMillis>" + + "4000" + + "</screenBrightnessRampIncreaseMaxIdleMillis>\n" + + "<screenBrightnessRampDecreaseMaxIdleMillis>" + + "5000" + + "</screenBrightnessRampDecreaseMaxIdleMillis>\n"; + + } private String getContent() { - return getContent(getValidLuxThrottling(), getValidProxSensor()); + return getContent(getValidLuxThrottling(), getValidProxSensor(), + /* includeIdleMode= */ true); } - private String getContent(String brightnessCapConfig, String proxSensor) { + private String getContent(String brightnessCapConfig, String proxSensor, + boolean includeIdleMode) { return "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" + "<displayConfiguration>\n" + "<name>Example Display</name>\n" @@ -778,12 +903,7 @@ public final class DisplayDeviceConfigTest { + "<autoBrightness>\n" + "<brighteningLightDebounceMillis>2000</brighteningLightDebounceMillis>\n" + "<darkeningLightDebounceMillis>1000</darkeningLightDebounceMillis>\n" - + "<brighteningLightDebounceIdleMillis>" - + "2500" - + "</brighteningLightDebounceIdleMillis>\n" - + "<darkeningLightDebounceIdleMillis>" - + "1500" - + "</darkeningLightDebounceIdleMillis>\n" + + (includeIdleMode ? getRampSpeedsIdle() : "") + "<displayBrightnessMapping>\n" + "<displayBrightnessPoint>\n" + "<lux>50</lux>\n" @@ -899,76 +1019,19 @@ public final class DisplayDeviceConfigTest { + "</brightnessThresholdPoints>\n" + "</darkeningThresholds>\n" + "</displayBrightnessChangeThresholds>\n" - + "<ambientBrightnessChangeThresholdsIdle>\n" - + "<brighteningThresholds>\n" - + "<minimum>20</minimum>\n" - + "<brightnessThresholdPoints>\n" - + "<brightnessThresholdPoint>\n" - + "<threshold>0</threshold><percentage>21</percentage>\n" - + "</brightnessThresholdPoint>\n" - + "<brightnessThresholdPoint>\n" - + "<threshold>500</threshold><percentage>22</percentage>\n" - + "</brightnessThresholdPoint>\n" - + "<brightnessThresholdPoint>\n" - + "<threshold>600</threshold><percentage>23</percentage>\n" - + "</brightnessThresholdPoint>\n" - + "</brightnessThresholdPoints>\n" - + "</brighteningThresholds>\n" - + "<darkeningThresholds>\n" - + "<minimum>40</minimum>\n" - + "<brightnessThresholdPoints>\n" - + "<brightnessThresholdPoint>\n" - + "<threshold>0</threshold><percentage>23</percentage>\n" - + "</brightnessThresholdPoint>\n" - + "<brightnessThresholdPoint>\n" - + "<threshold>700</threshold><percentage>24</percentage>\n" - + "</brightnessThresholdPoint>\n" - + "<brightnessThresholdPoint>\n" - + "<threshold>800</threshold><percentage>25</percentage>\n" - + "</brightnessThresholdPoint>\n" - + "</brightnessThresholdPoints>\n" - + "</darkeningThresholds>\n" - + "</ambientBrightnessChangeThresholdsIdle>\n" - + "<displayBrightnessChangeThresholdsIdle>\n" - + "<brighteningThresholds>\n" - + "<minimum>0.2</minimum>\n" - + "<brightnessThresholdPoints>\n" - + "<brightnessThresholdPoint>\n" - + "<threshold>0</threshold><percentage>17</percentage>\n" - + "</brightnessThresholdPoint>\n" - + "<brightnessThresholdPoint>\n" - + "<threshold>0.12</threshold><percentage>18</percentage>\n" - + "</brightnessThresholdPoint>\n" - + "<brightnessThresholdPoint>\n" - + "<threshold>0.22</threshold><percentage>19</percentage>\n" - + "</brightnessThresholdPoint>\n" - + "</brightnessThresholdPoints>\n" - + "</brighteningThresholds>\n" - + "<darkeningThresholds>\n" - + "<minimum>0.4</minimum>\n" - + "<brightnessThresholdPoints>\n" - + "<brightnessThresholdPoint>\n" - + "<threshold>0</threshold><percentage>19</percentage>\n" - + "</brightnessThresholdPoint>\n" - + "<brightnessThresholdPoint>\n" - + "<threshold>0.13</threshold><percentage>20</percentage>\n" - + "</brightnessThresholdPoint>\n" - + "<brightnessThresholdPoint>\n" - + "<threshold>0.23</threshold><percentage>21</percentage>\n" - + "</brightnessThresholdPoint>\n" - + "</brightnessThresholdPoints>\n" - + "</darkeningThresholds>\n" - + "</displayBrightnessChangeThresholdsIdle>\n" - + "<screenBrightnessRampFastDecrease>0.01</screenBrightnessRampFastDecrease> " - + "<screenBrightnessRampFastIncrease>0.02</screenBrightnessRampFastIncrease> " - + "<screenBrightnessRampSlowDecrease>0.03</screenBrightnessRampSlowDecrease>" - + "<screenBrightnessRampSlowIncrease>0.04</screenBrightnessRampSlowIncrease>" + + (includeIdleMode ? getThresholdsIdle() : "") + + "<screenBrightnessRampFastDecrease>0.01</screenBrightnessRampFastDecrease>\n" + + "<screenBrightnessRampFastIncrease>0.02</screenBrightnessRampFastIncrease>\n" + + "<screenBrightnessRampSlowDecrease>0.03</screenBrightnessRampSlowDecrease>\n" + + "<screenBrightnessRampSlowIncrease>0.04</screenBrightnessRampSlowIncrease>\n" + + (includeIdleMode ? getScreenBrightnessRampSlowIdle() : "") + "<screenBrightnessRampIncreaseMaxMillis>" + "2000" - + "</screenBrightnessRampIncreaseMaxMillis>" + + "</screenBrightnessRampIncreaseMaxMillis>\n" + "<screenBrightnessRampDecreaseMaxMillis>" + "3000" - + "</screenBrightnessRampDecreaseMaxMillis>" + + "</screenBrightnessRampDecreaseMaxMillis>\n" + + (includeIdleMode ? getScreenBrightnessRampCapsIdle() : "") + "<ambientLightHorizonLong>5000</ambientLightHorizonLong>\n" + "<ambientLightHorizonShort>50</ambientLightHorizonShort>\n" + "<screenBrightnessRampIncreaseMaxMillis>" @@ -1201,6 +1264,13 @@ public final class DisplayDeviceConfigTest { when(mResources.getString(com.android.internal.R.string.config_displayLightSensorType)) .thenReturn("test_light_sensor"); + when(mResources.getInteger( + R.integer.config_autoBrightnessBrighteningLightDebounce)) + .thenReturn(3000); + when(mResources.getInteger( + R.integer.config_autoBrightnessDarkeningLightDebounce)) + .thenReturn(4000); + mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, true); } diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java index 89e28cb8ab83..9174899dfe6c 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java @@ -53,6 +53,10 @@ import android.os.PowerManager; import android.os.SystemProperties; import android.os.UserHandle; import android.os.test.TestLooper; +import android.platform.test.annotations.RequiresFlagsDisabled; +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.provider.Settings; import android.testing.TestableContext; import android.util.FloatProperty; @@ -71,6 +75,7 @@ import com.android.server.display.brightness.BrightnessEvent; import com.android.server.display.brightness.clamper.HdrClamper; import com.android.server.display.color.ColorDisplayService; import com.android.server.display.feature.DisplayManagerFlags; +import com.android.server.display.feature.flags.Flags; import com.android.server.display.layout.Layout; import com.android.server.display.whitebalance.DisplayWhiteBalanceController; import com.android.server.policy.WindowManagerPolicy; @@ -108,12 +113,16 @@ public final class DisplayPowerController2Test { private static final float BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE = 0.5f; private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE = 0.6f; + private static final long BRIGHTNESS_RAMP_INCREASE_MAX = 1000; + private static final long BRIGHTNESS_RAMP_DECREASE_MAX = 2000; + private static final long BRIGHTNESS_RAMP_INCREASE_MAX_IDLE = 3000; + private static final long BRIGHTNESS_RAMP_DECREASE_MAX_IDLE = 4000; + private OffsettableClock mClock; private TestLooper mTestLooper; private Handler mHandler; private DisplayPowerControllerHolder mHolder; private Sensor mProxSensor; - @Mock private DisplayPowerCallbacks mDisplayPowerCallbacksMock; @Mock @@ -130,6 +139,8 @@ public final class DisplayPowerController2Test { private ColorDisplayService.ColorDisplayServiceInternal mCdsiMock; @Mock private DisplayWhiteBalanceController mDisplayWhiteBalanceControllerMock; + @Mock + private DisplayManagerFlags mDisplayManagerFlagsMock; @Captor private ArgumentCaptor<SensorEventListener> mSensorEventListenerCaptor; @@ -145,6 +156,9 @@ public final class DisplayPowerController2Test { .spyStatic(BatteryStatsService.class) .build(); + @Rule + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + @Before public void setUp() throws Exception { mClock = new OffsettableClock.Stopped(); @@ -335,9 +349,9 @@ public final class DisplayPowerController2Test { when(mHolder.brightnessSetting.getBrightness()).thenReturn(leadBrightness); listener.onBrightnessChanged(leadBrightness); advanceTime(1); // Send messages, run updatePowerState - verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(), anyFloat()); + verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(), anyFloat(), eq(false)); verify(followerDpc.animator).animateTo(eq(followerBrightness), anyFloat(), - anyFloat()); + anyFloat(), eq(false)); clearInvocations(mHolder.animator, followerDpc.animator); @@ -351,9 +365,9 @@ public final class DisplayPowerController2Test { listener.onBrightnessChanged(brightness); advanceTime(1); // Send messages, run updatePowerState verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); } @Test @@ -383,9 +397,9 @@ public final class DisplayPowerController2Test { listener.onBrightnessChanged(brightness); advanceTime(1); // Send messages, run updatePowerState verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); } @Test @@ -413,9 +427,9 @@ public final class DisplayPowerController2Test { listener.onBrightnessChanged(brightness); advanceTime(1); // Send messages, run updatePowerState verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); } @Test @@ -445,9 +459,9 @@ public final class DisplayPowerController2Test { listener.onBrightnessChanged(brightness); advanceTime(1); // Send messages, run updatePowerState verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); } @Test @@ -484,11 +498,11 @@ public final class DisplayPowerController2Test { advanceTime(1); // Run updatePowerState verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); // One triggered by handleBrightnessModeChange, another triggered by setBrightnessToFollow verify(followerDpc.hbmController, times(2)).onAmbientLuxChange(ambientLux); verify(followerDpc.animator, times(2)).animateTo(eq(followerBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(leadBrightness); when(followerDpc.displayPowerState.getScreenBrightness()).thenReturn(followerBrightness); @@ -515,10 +529,10 @@ public final class DisplayPowerController2Test { // The second time, the animation rate should be slow verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE)); + eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE), eq(false)); verify(followerDpc.hbmController).onAmbientLuxChange(ambientLux); verify(followerDpc.animator).animateTo(eq(followerBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE)); + eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE), eq(false)); } @Test @@ -552,7 +566,7 @@ public final class DisplayPowerController2Test { followerListener.onBrightnessChanged(initialFollowerBrightness); advanceTime(1); verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); when(followerDpc.displayPowerState.getScreenBrightness()) .thenReturn(initialFollowerBrightness); @@ -573,11 +587,11 @@ public final class DisplayPowerController2Test { listener.onBrightnessChanged(brightness); advanceTime(1); // Send messages, run updatePowerState verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness); when(followerDpc.displayPowerState.getScreenBrightness()).thenReturn(brightness); @@ -588,7 +602,7 @@ public final class DisplayPowerController2Test { mHolder.dpc.removeDisplayBrightnessFollower(followerDpc.dpc); advanceTime(1); verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE), eq(false)); when(followerDpc.displayPowerState.getScreenBrightness()) .thenReturn(initialFollowerBrightness); @@ -606,10 +620,11 @@ public final class DisplayPowerController2Test { listener.onBrightnessChanged(brightness); advanceTime(1); // Send messages, run updatePowerState verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); - verify(followerDpc.animator, never()).animateTo(anyFloat(), anyFloat(), anyFloat()); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); + verify(followerDpc.animator, never()).animateTo(anyFloat(), anyFloat(), anyFloat(), + anyBoolean()); verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); } @Test @@ -652,9 +667,9 @@ public final class DisplayPowerController2Test { secondFollowerListener.onBrightnessChanged(initialFollowerBrightness); advanceTime(1); verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); when(followerHolder.displayPowerState.getScreenBrightness()) .thenReturn(initialFollowerBrightness); @@ -677,11 +692,11 @@ public final class DisplayPowerController2Test { listener.onBrightnessChanged(brightness); advanceTime(1); // Send messages, run updatePowerState verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(followerHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(secondFollowerHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness); when(followerHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness); @@ -692,9 +707,9 @@ public final class DisplayPowerController2Test { mHolder.dpc.stop(); advanceTime(1); verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE), eq(false)); verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE), eq(false)); clearInvocations(followerHolder.animator, secondFollowerHolder.animator); } @@ -716,7 +731,7 @@ public final class DisplayPowerController2Test { advanceTime(1); // Run updatePowerState verify(mHolder.animator).animateTo(eq(sdrBrightness), eq(sdrBrightness), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(sdrBrightness); when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(sdrBrightness); @@ -730,7 +745,7 @@ public final class DisplayPowerController2Test { advanceTime(1); // Run updatePowerState verify(mHolder.animator).animateTo(eq(hdrBrightness), eq(sdrBrightness), - eq(BRIGHTNESS_RAMP_RATE_MINIMUM)); + eq(BRIGHTNESS_RAMP_RATE_MINIMUM), eq(false)); } @Test @@ -756,7 +771,7 @@ public final class DisplayPowerController2Test { advanceTime(1); // Run updatePowerState verify(mHolder.animator).animateTo(eq(hdrBrightness), eq(sdrBrightness), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(hdrBrightness); when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(sdrBrightness); @@ -769,7 +784,7 @@ public final class DisplayPowerController2Test { advanceTime(1); // Run updatePowerState verify(mHolder.animator).animateTo(eq(sdrBrightness), eq(sdrBrightness), - eq(BRIGHTNESS_RAMP_RATE_MINIMUM)); + eq(BRIGHTNESS_RAMP_RATE_MINIMUM), eq(false)); } @Test @@ -823,7 +838,7 @@ public final class DisplayPowerController2Test { verify(mHolder.screenOffBrightnessSensorController, atLeastOnce()) .getAutomaticScreenBrightness(); - verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat()); + verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat(), eq(false)); } @Test @@ -861,7 +876,7 @@ public final class DisplayPowerController2Test { verify(mHolder.screenOffBrightnessSensorController, atLeastOnce()) .getAutomaticScreenBrightness(); - verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat()); + verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat(), eq(false)); } @Test @@ -1104,7 +1119,8 @@ public final class DisplayPowerController2Test { mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); advanceTime(1); // Run updatePowerState // One triggered by handleBrightnessModeChange, another triggered by onDisplayChanged - verify(mHolder.animator, times(2)).animateTo(eq(newBrightness), anyFloat(), anyFloat()); + verify(mHolder.animator, times(2)).animateTo(eq(newBrightness), anyFloat(), anyFloat(), + eq(false)); } @Test @@ -1213,7 +1229,7 @@ public final class DisplayPowerController2Test { advanceTime(1); // Run updatePowerState verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness); brightness = 0.05f; @@ -1225,7 +1241,7 @@ public final class DisplayPowerController2Test { // The second time, the animation rate should be slow verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE)); + eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE), eq(false)); brightness = 0.9f; when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness( @@ -1235,7 +1251,7 @@ public final class DisplayPowerController2Test { advanceTime(1); // Run updatePowerState // The third time, the animation rate should be slow verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE)); + eq(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE), eq(false)); } @Test @@ -1254,9 +1270,35 @@ public final class DisplayPowerController2Test { } @Test - public void testRampRateForHdrContent() { + public void testRampRateForHdrContent_HdrClamperOff() { + float hdrBrightness = 0.8f; + float clampedBrightness = 0.6f; + float transitionRate = 1.5f; + + DisplayPowerRequest dpr = new DisplayPowerRequest(); + when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); + when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(.2f); + when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(.1f); + when(mHolder.hbmController.getHighBrightnessMode()).thenReturn( + BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR); + when(mHolder.hbmController.getHdrBrightnessValue()).thenReturn(hdrBrightness); + when(mHolder.hdrClamper.getMaxBrightness()).thenReturn(clampedBrightness); + when(mHolder.hdrClamper.getTransitionRate()).thenReturn(transitionRate); + + mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); + advanceTime(1); // Run updatePowerState + + verify(mHolder.animator, atLeastOnce()).animateTo(eq(hdrBrightness), anyFloat(), + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); + } + + @Test + public void testRampRateForHdrContent_HdrClamperOn() { float clampedBrightness = 0.6f; - float transitionRate = 35.5f; + float transitionRate = 1.5f; + DisplayManagerFlags flags = mock(DisplayManagerFlags.class); + when(flags.isHdrClamperEnabled()).thenReturn(true); + mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID, /* isEnabled= */ true, flags); DisplayPowerRequest dpr = new DisplayPowerRequest(); when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); @@ -1272,7 +1314,114 @@ public final class DisplayPowerController2Test { advanceTime(1); // Run updatePowerState verify(mHolder.animator, atLeastOnce()).animateTo(eq(clampedBrightness), anyFloat(), - eq(transitionRate)); + eq(transitionRate), eq(true)); + } + + @Test + @RequiresFlagsDisabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1) + public void testRampMaxTimeInteractiveThenIdle() { + // Send a display power request + DisplayPowerRequest dpr = new DisplayPowerRequest(); + dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; + dpr.useProximitySensor = true; + mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */); + + // Run updatePowerState + advanceTime(1); + + setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class), + mHolder.config, /* isEnabled= */ true); + verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX, + BRIGHTNESS_RAMP_DECREASE_MAX); + + // switch to idle mode + mHolder.dpc.setAutomaticScreenBrightnessMode(/* idle= */ true); + advanceTime(1); + + // A second time, when switching to idle mode. + verify(mHolder.animator, times(2)).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX, + BRIGHTNESS_RAMP_DECREASE_MAX); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1) + public void testRampMaxTimeInteractiveThenIdle_DifferentValues() { + DisplayManagerFlags flags = mock(DisplayManagerFlags.class); + when(flags.isAdaptiveTone1Enabled()).thenReturn(true); + mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID, /* isEnabled= */ true, flags); + + // Send a display power request + DisplayPowerRequest dpr = new DisplayPowerRequest(); + dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; + dpr.useProximitySensor = true; + mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */); + + // Run updatePowerState + advanceTime(1); + + setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class), + mHolder.config, /* isEnabled= */ true); + verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX, + BRIGHTNESS_RAMP_DECREASE_MAX); + + // switch to idle mode + mHolder.dpc.setAutomaticScreenBrightnessMode(/* idle= */ true); + advanceTime(1); + + // A second time, when switching to idle mode. + verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE, + BRIGHTNESS_RAMP_DECREASE_MAX_IDLE); + } + + @Test + @RequiresFlagsDisabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1) + public void testRampMaxTimeIdle() { + // Send a display power request + DisplayPowerRequest dpr = new DisplayPowerRequest(); + dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; + dpr.useProximitySensor = true; + mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */); + // Run updatePowerState + advanceTime(1); + // Once on setup + verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX, + BRIGHTNESS_RAMP_DECREASE_MAX); + + setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class), + mHolder.config, /* isEnabled= */ true); + + // switch to idle mode + mHolder.dpc.setAutomaticScreenBrightnessMode(true); + + // A second time when switching to idle mode. + verify(mHolder.animator, times(2)).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX, + BRIGHTNESS_RAMP_DECREASE_MAX); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1) + public void testRampMaxTimeIdle_DifferentValues() { + DisplayManagerFlags flags = mock(DisplayManagerFlags.class); + when(flags.isAdaptiveTone1Enabled()).thenReturn(true); + mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID, /* isEnabled= */ true, flags); + + // Send a display power request + DisplayPowerRequest dpr = new DisplayPowerRequest(); + dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; + dpr.useProximitySensor = true; + mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */); + + // Run updatePowerState + advanceTime(1); + + setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class), + mHolder.config, /* isEnabled= */ true); + + // switch to idle mode + mHolder.dpc.setAutomaticScreenBrightnessMode(true); + + verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE, + BRIGHTNESS_RAMP_DECREASE_MAX_IDLE); } /** @@ -1338,6 +1487,7 @@ public final class DisplayPowerController2Test { }); when(displayDeviceConfigMock.getScreenOffBrightnessSensorValueToLux()) .thenReturn(new int[0]); + when(displayDeviceConfigMock.getBrightnessRampFastDecrease()) .thenReturn(BRIGHTNESS_RAMP_RATE_FAST_DECREASE); when(displayDeviceConfigMock.getBrightnessRampFastIncrease()) @@ -1350,6 +1500,15 @@ public final class DisplayPowerController2Test { .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE); when(displayDeviceConfigMock.getBrightnessRampSlowDecreaseIdle()) .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE); + + when(displayDeviceConfigMock.getBrightnessRampIncreaseMaxMillis()) + .thenReturn(BRIGHTNESS_RAMP_INCREASE_MAX); + when(displayDeviceConfigMock.getBrightnessRampDecreaseMaxMillis()) + .thenReturn(BRIGHTNESS_RAMP_DECREASE_MAX); + when(displayDeviceConfigMock.getBrightnessRampIncreaseMaxIdleMillis()) + .thenReturn(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE); + when(displayDeviceConfigMock.getBrightnessRampDecreaseMaxIdleMillis()) + .thenReturn(BRIGHTNESS_RAMP_DECREASE_MAX_IDLE); } private DisplayPowerControllerHolder createDisplayPowerController(int displayId, @@ -1359,6 +1518,12 @@ public final class DisplayPowerController2Test { private DisplayPowerControllerHolder createDisplayPowerController(int displayId, String uniqueId, boolean isEnabled) { + return createDisplayPowerController(displayId, uniqueId, isEnabled, + mock(DisplayManagerFlags.class)); + } + + private DisplayPowerControllerHolder createDisplayPowerController(int displayId, + String uniqueId, boolean isEnabled, DisplayManagerFlags flags) { final DisplayPowerState displayPowerState = mock(DisplayPowerState.class); final DualRampAnimator<DisplayPowerState> animator = mock(DualRampAnimator.class); final AutomaticBrightnessController automaticBrightnessController = @@ -1371,7 +1536,6 @@ public final class DisplayPowerController2Test { mock(ScreenOffBrightnessSensorController.class); final HighBrightnessModeController hbmController = mock(HighBrightnessModeController.class); final HdrClamper hdrClamper = mock(HdrClamper.class); - final DisplayManagerFlags flags = mock(DisplayManagerFlags.class); when(hbmController.getCurrentBrightnessMax()).thenReturn(PowerManager.BRIGHTNESS_MAX); @@ -1391,13 +1555,14 @@ public final class DisplayPowerController2Test { final DisplayPowerController2 dpc = new DisplayPowerController2( mContext, injector, mDisplayPowerCallbacksMock, mHandler, mSensorManagerMock, mDisplayBlankerMock, display, - mBrightnessTrackerMock, brightnessSetting, () -> {}, + mBrightnessTrackerMock, brightnessSetting, () -> { + }, hbmMetadata, /* bootCompleted= */ false, flags); return new DisplayPowerControllerHolder(dpc, display, displayPowerState, brightnessSetting, animator, automaticBrightnessController, wakelockController, screenOffBrightnessSensorController, hbmController, hdrClamper, hbmMetadata, - brightnessMappingStrategy, injector); + brightnessMappingStrategy, injector, config); } /** @@ -1419,6 +1584,7 @@ public final class DisplayPowerController2Test { public final HighBrightnessModeMetadata hbmMetadata; public final BrightnessMappingStrategy brightnessMappingStrategy; public final DisplayPowerController2.Injector injector; + public final DisplayDeviceConfig config; DisplayPowerControllerHolder(DisplayPowerController2 dpc, LogicalDisplay display, DisplayPowerState displayPowerState, BrightnessSetting brightnessSetting, @@ -1430,7 +1596,8 @@ public final class DisplayPowerController2Test { HdrClamper hdrClamper, HighBrightnessModeMetadata hbmMetadata, BrightnessMappingStrategy brightnessMappingStrategy, - DisplayPowerController2.Injector injector) { + DisplayPowerController2.Injector injector, + DisplayDeviceConfig config) { this.dpc = dpc; this.display = display; this.displayPowerState = displayPowerState; @@ -1444,6 +1611,7 @@ public final class DisplayPowerController2Test { this.hbmMetadata = hbmMetadata; this.brightnessMappingStrategy = brightnessMappingStrategy; this.injector = injector; + this.config = config; } } diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java index 971ece365f30..412b65f5835a 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java @@ -53,6 +53,10 @@ import android.os.PowerManager; import android.os.SystemProperties; import android.os.UserHandle; import android.os.test.TestLooper; +import android.platform.test.annotations.RequiresFlagsDisabled; +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.provider.Settings; import android.testing.TestableContext; import android.util.FloatProperty; @@ -71,6 +75,7 @@ import com.android.server.display.RampAnimator.DualRampAnimator; import com.android.server.display.brightness.BrightnessEvent; import com.android.server.display.color.ColorDisplayService; import com.android.server.display.feature.DisplayManagerFlags; +import com.android.server.display.feature.flags.Flags; import com.android.server.display.layout.Layout; import com.android.server.display.whitebalance.DisplayWhiteBalanceController; import com.android.server.policy.WindowManagerPolicy; @@ -107,6 +112,11 @@ public final class DisplayPowerControllerTest { private static final float BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE = 0.5f; private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE = 0.6f; + private static final long BRIGHTNESS_RAMP_INCREASE_MAX = 1000; + private static final long BRIGHTNESS_RAMP_DECREASE_MAX = 2000; + private static final long BRIGHTNESS_RAMP_INCREASE_MAX_IDLE = 3000; + private static final long BRIGHTNESS_RAMP_DECREASE_MAX_IDLE = 4000; + private OffsettableClock mClock; private TestLooper mTestLooper; private Handler mHandler; @@ -129,6 +139,9 @@ public final class DisplayPowerControllerTest { private ColorDisplayService.ColorDisplayServiceInternal mCdsiMock; @Mock private DisplayWhiteBalanceController mDisplayWhiteBalanceControllerMock; + @Mock + private DisplayManagerFlags mDisplayManagerFlagsMock; + @Captor private ArgumentCaptor<SensorEventListener> mSensorEventListenerCaptor; @@ -147,6 +160,9 @@ public final class DisplayPowerControllerTest { @Rule public LocalServiceKeeperRule mLocalServiceKeeperRule = new LocalServiceKeeperRule(); + @Rule + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + @Before public void setUp() throws Exception { mClock = new OffsettableClock.Stopped(); @@ -336,9 +352,9 @@ public final class DisplayPowerControllerTest { listener.onBrightnessChanged(leadBrightness); advanceTime(1); // Send messages, run updatePowerState verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(followerDpc.animator).animateTo(eq(followerBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(leadBrightness); when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(followerBrightness); @@ -354,9 +370,9 @@ public final class DisplayPowerControllerTest { listener.onBrightnessChanged(brightness); advanceTime(1); // Send messages, run updatePowerState verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); } @Test @@ -387,9 +403,9 @@ public final class DisplayPowerControllerTest { listener.onBrightnessChanged(brightness); advanceTime(1); // Send messages, run updatePowerState verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); } @Test @@ -418,9 +434,9 @@ public final class DisplayPowerControllerTest { listener.onBrightnessChanged(brightness); advanceTime(1); // Send messages, run updatePowerState verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); } @Test @@ -451,9 +467,9 @@ public final class DisplayPowerControllerTest { listener.onBrightnessChanged(brightness); advanceTime(1); // Send messages, run updatePowerState verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); } @Test @@ -491,11 +507,11 @@ public final class DisplayPowerControllerTest { advanceTime(1); // Run updatePowerState verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); // One triggered by handleBrightnessModeChange, another triggered by setBrightnessToFollow verify(followerDpc.hbmController, times(2)).onAmbientLuxChange(ambientLux); verify(followerDpc.animator, times(2)).animateTo(eq(followerBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(leadBrightness); when(followerDpc.displayPowerState.getScreenBrightness()).thenReturn(followerBrightness); @@ -522,10 +538,10 @@ public final class DisplayPowerControllerTest { // The second time, the animation rate should be slow verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE)); + eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE), eq(false)); verify(followerDpc.hbmController).onAmbientLuxChange(ambientLux); verify(followerDpc.animator).animateTo(eq(followerBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE)); + eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE), eq(false)); } @Test @@ -560,7 +576,7 @@ public final class DisplayPowerControllerTest { followerListener.onBrightnessChanged(initialFollowerBrightness); advanceTime(1); verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); when(followerDpc.displayPowerState.getScreenBrightness()) .thenReturn(initialFollowerBrightness); @@ -581,11 +597,11 @@ public final class DisplayPowerControllerTest { listener.onBrightnessChanged(brightness); advanceTime(1); // Send messages, run updatePowerState verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness); when(followerDpc.displayPowerState.getScreenBrightness()).thenReturn(brightness); @@ -596,7 +612,7 @@ public final class DisplayPowerControllerTest { mHolder.dpc.removeDisplayBrightnessFollower(followerDpc.dpc); advanceTime(1); verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE), eq(false)); when(followerDpc.displayPowerState.getScreenBrightness()) .thenReturn(initialFollowerBrightness); @@ -614,10 +630,11 @@ public final class DisplayPowerControllerTest { listener.onBrightnessChanged(brightness); advanceTime(1); // Send messages, run updatePowerState verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); - verify(followerDpc.animator, never()).animateTo(anyFloat(), anyFloat(), anyFloat()); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); + verify(followerDpc.animator, never()).animateTo(anyFloat(), anyFloat(), anyFloat(), + anyBoolean()); verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); } @Test @@ -661,9 +678,9 @@ public final class DisplayPowerControllerTest { secondFollowerListener.onBrightnessChanged(initialFollowerBrightness); advanceTime(1); verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); when(followerHolder.displayPowerState.getScreenBrightness()) .thenReturn(initialFollowerBrightness); @@ -686,11 +703,11 @@ public final class DisplayPowerControllerTest { listener.onBrightnessChanged(brightness); advanceTime(1); // Send messages, run updatePowerState verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(followerHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); verify(secondFollowerHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness); when(followerHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness); @@ -701,9 +718,9 @@ public final class DisplayPowerControllerTest { mHolder.dpc.stop(); advanceTime(1); verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE), eq(false)); verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE), eq(false)); clearInvocations(followerHolder.animator, secondFollowerHolder.animator); } @@ -756,7 +773,7 @@ public final class DisplayPowerControllerTest { verify(mHolder.screenOffBrightnessSensorController, atLeastOnce()) .getAutomaticScreenBrightness(); - verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat()); + verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat(), eq(false)); } @Test @@ -793,7 +810,7 @@ public final class DisplayPowerControllerTest { verify(mHolder.screenOffBrightnessSensorController, atLeastOnce()) .getAutomaticScreenBrightness(); - verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat()); + verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat(), eq(false)); } @Test @@ -1038,7 +1055,8 @@ public final class DisplayPowerControllerTest { mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); advanceTime(1); // Run updatePowerState // One triggered by handleBrightnessModeChange, another triggered by onDisplayChanged - verify(mHolder.animator, times(2)).animateTo(eq(newBrightness), anyFloat(), anyFloat()); + verify(mHolder.animator, times(2)).animateTo(eq(newBrightness), anyFloat(), anyFloat(), + eq(false)); } @Test @@ -1147,7 +1165,7 @@ public final class DisplayPowerControllerTest { advanceTime(1); // Run updatePowerState verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness); brightness = 0.05f; @@ -1159,7 +1177,7 @@ public final class DisplayPowerControllerTest { // The second time, the animation rate should be slow verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE)); + eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE), eq(false)); brightness = 0.9f; when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness( @@ -1169,7 +1187,7 @@ public final class DisplayPowerControllerTest { advanceTime(1); // Run updatePowerState // The third time, the animation rate should be slow verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), - eq(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE)); + eq(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE), eq(false)); } @Test @@ -1204,7 +1222,7 @@ public final class DisplayPowerControllerTest { advanceTime(1); // Run updatePowerState verify(mHolder.animator).animateTo(eq(sdrBrightness), eq(sdrBrightness), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(sdrBrightness); when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(sdrBrightness); @@ -1218,7 +1236,7 @@ public final class DisplayPowerControllerTest { advanceTime(1); // Run updatePowerState verify(mHolder.animator).animateTo(eq(hdrBrightness), eq(sdrBrightness), - eq(BRIGHTNESS_RAMP_RATE_MINIMUM)); + eq(BRIGHTNESS_RAMP_RATE_MINIMUM), eq(false)); } @Test @@ -1242,7 +1260,7 @@ public final class DisplayPowerControllerTest { advanceTime(1); // Run updatePowerState verify(mHolder.animator).animateTo(eq(hdrBrightness), eq(sdrBrightness), - eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false)); when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(hdrBrightness); when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(sdrBrightness); @@ -1255,7 +1273,111 @@ public final class DisplayPowerControllerTest { advanceTime(1); // Run updatePowerState verify(mHolder.animator).animateTo(eq(sdrBrightness), eq(sdrBrightness), - eq(BRIGHTNESS_RAMP_RATE_MINIMUM)); + eq(BRIGHTNESS_RAMP_RATE_MINIMUM), eq(false)); + } + + @Test + @RequiresFlagsDisabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1) + public void testRampMaxTimeInteractiveThenIdle() { + // Send a display power request + DisplayPowerRequest dpr = new DisplayPowerRequest(); + dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; + dpr.useProximitySensor = true; + mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */); + + // Run updatePowerState + advanceTime(1); + + setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class), + mHolder.config, /* isEnabled= */ true); + + verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX, + BRIGHTNESS_RAMP_DECREASE_MAX); + + // switch to idle + mHolder.dpc.setAutomaticScreenBrightnessMode(/* idle= */ true); + advanceTime(1); + + verify(mHolder.animator, times(2)).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX, + BRIGHTNESS_RAMP_DECREASE_MAX); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1) + public void testRampMaxTimeInteractiveThenIdle_DifferentValues() { + when(mDisplayManagerFlagsMock.isAdaptiveTone1Enabled()).thenReturn(true); + // Send a display power request + DisplayPowerRequest dpr = new DisplayPowerRequest(); + dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; + dpr.useProximitySensor = true; + mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */); + + // Run updatePowerState + advanceTime(1); + + setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class), + mHolder.config, /* isEnabled= */ true); + + verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX, + BRIGHTNESS_RAMP_DECREASE_MAX); + + // switch to idle + mHolder.dpc.setAutomaticScreenBrightnessMode(/* idle= */ true); + advanceTime(1); + + verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE, + BRIGHTNESS_RAMP_DECREASE_MAX_IDLE); + } + + @Test + @RequiresFlagsDisabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1) + public void testRampMaxTimeIdle() { + // Send a display power request + DisplayPowerRequest dpr = new DisplayPowerRequest(); + dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; + dpr.useProximitySensor = true; + mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */); + + // Run updatePowerState + advanceTime(1); + + // once on setup + verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX, + BRIGHTNESS_RAMP_DECREASE_MAX); + + setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class), + mHolder.config, /* isEnabled= */ true); + + // switch to idle mode + mHolder.dpc.setAutomaticScreenBrightnessMode(true); + + // second time when switching to idle screen brightness mode + verify(mHolder.animator, times(2)).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX, + BRIGHTNESS_RAMP_DECREASE_MAX); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1) + public void testRampMaxTimeIdle_DifferentValues() { + when(mDisplayManagerFlagsMock.isAdaptiveTone1Enabled()).thenReturn(true); + + // Send a display power request + DisplayPowerRequest dpr = new DisplayPowerRequest(); + dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; + dpr.useProximitySensor = true; + mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */); + + // Run updatePowerState + advanceTime(1); + + setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class), + mHolder.config, /* isEnabled= */ true); + + // switch to idle mode + mHolder.dpc.setAutomaticScreenBrightnessMode(true); + + verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE, + BRIGHTNESS_RAMP_DECREASE_MAX_IDLE); } private void advanceTime(long timeMs) { @@ -1313,6 +1435,7 @@ public final class DisplayPowerControllerTest { }); when(displayDeviceConfigMock.getScreenOffBrightnessSensorValueToLux()) .thenReturn(new int[0]); + when(displayDeviceConfigMock.getBrightnessRampFastDecrease()) .thenReturn(BRIGHTNESS_RAMP_RATE_FAST_DECREASE); when(displayDeviceConfigMock.getBrightnessRampFastIncrease()) @@ -1325,6 +1448,15 @@ public final class DisplayPowerControllerTest { .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE); when(displayDeviceConfigMock.getBrightnessRampSlowIncreaseIdle()) .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE); + + when(displayDeviceConfigMock.getBrightnessRampIncreaseMaxMillis()) + .thenReturn(BRIGHTNESS_RAMP_INCREASE_MAX); + when(displayDeviceConfigMock.getBrightnessRampDecreaseMaxMillis()) + .thenReturn(BRIGHTNESS_RAMP_DECREASE_MAX); + when(displayDeviceConfigMock.getBrightnessRampIncreaseMaxIdleMillis()) + .thenReturn(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE); + when(displayDeviceConfigMock.getBrightnessRampDecreaseMaxIdleMillis()) + .thenReturn(BRIGHTNESS_RAMP_DECREASE_MAX_IDLE); } private DisplayPowerControllerHolder createDisplayPowerController(int displayId, @@ -1356,7 +1488,6 @@ public final class DisplayPowerControllerTest { final HighBrightnessModeMetadata hbmMetadata = mock(HighBrightnessModeMetadata.class); final BrightnessSetting brightnessSetting = mock(BrightnessSetting.class); final DisplayDeviceConfig config = mock(DisplayDeviceConfig.class); - final DisplayManagerFlags flags = mock(DisplayManagerFlags.class); setUpDisplay(displayId, uniqueId, display, device, config, isEnabled); @@ -1364,11 +1495,11 @@ public final class DisplayPowerControllerTest { mContext, injector, mDisplayPowerCallbacksMock, mHandler, mSensorManagerMock, mDisplayBlankerMock, display, mBrightnessTrackerMock, brightnessSetting, () -> {}, - hbmMetadata, /* bootCompleted= */ false, flags); + hbmMetadata, /* bootCompleted= */ false, mDisplayManagerFlagsMock); return new DisplayPowerControllerHolder(dpc, display, displayPowerState, brightnessSetting, animator, automaticBrightnessController, screenOffBrightnessSensorController, - hbmController, hbmMetadata, brightnessMappingStrategy, injector); + hbmController, hbmMetadata, brightnessMappingStrategy, injector, config); } /** @@ -1387,6 +1518,7 @@ public final class DisplayPowerControllerTest { public final HighBrightnessModeMetadata hbmMetadata; public final BrightnessMappingStrategy brightnessMappingStrategy; public final DisplayPowerController.Injector injector; + public final DisplayDeviceConfig config; DisplayPowerControllerHolder(DisplayPowerController dpc, LogicalDisplay display, DisplayPowerState displayPowerState, BrightnessSetting brightnessSetting, @@ -1396,7 +1528,8 @@ public final class DisplayPowerControllerTest { HighBrightnessModeController hbmController, HighBrightnessModeMetadata hbmMetadata, BrightnessMappingStrategy brightnessMappingStrategy, - DisplayPowerController.Injector injector) { + DisplayPowerController.Injector injector, + DisplayDeviceConfig config) { this.dpc = dpc; this.display = display; this.displayPowerState = displayPowerState; @@ -1408,6 +1541,7 @@ public final class DisplayPowerControllerTest { this.hbmMetadata = hbmMetadata; this.brightnessMappingStrategy = brightnessMappingStrategy; this.injector = injector; + this.config = config; } } diff --git a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java index c0128ae38a28..1c43418f9276 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java @@ -28,7 +28,9 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.PropertyInvalidatedCache; +import android.content.Context; import android.graphics.Point; +import android.os.IBinder; import android.util.SparseArray; import android.view.Display; import android.view.DisplayInfo; @@ -40,7 +42,6 @@ import androidx.test.filters.SmallTest; import com.android.server.display.layout.Layout; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import java.io.InputStream; @@ -56,6 +57,9 @@ public class LogicalDisplayTest { private LogicalDisplay mLogicalDisplay; private DisplayDevice mDisplayDevice; + private DisplayAdapter mDisplayAdapter; + private Context mContext; + private IBinder mDisplayToken; private DisplayDeviceRepository mDeviceRepo; private final DisplayDeviceInfo mDisplayDeviceInfo = new DisplayDeviceInfo(); @@ -64,6 +68,9 @@ public class LogicalDisplayTest { // Share classloader to allow package private access. System.setProperty("dexmaker.share_classloader", "true"); mDisplayDevice = mock(DisplayDevice.class); + mDisplayAdapter = mock(DisplayAdapter.class); + mContext = mock(Context.class); + mDisplayToken = mock(IBinder.class); mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice); mDisplayDeviceInfo.copyFrom(new DisplayDeviceInfo()); @@ -131,33 +138,43 @@ public class LogicalDisplayTest { assertEquals(expectedPosition, mLogicalDisplay.getDisplayPosition()); } - // TODO: b/288880734 - fix test after display tests migration @Test - @Ignore public void testDisplayInputFlags() { + DisplayDevice displayDevice = new DisplayDevice(mDisplayAdapter, mDisplayToken, + "unique_display_id", mContext) { + @Override + public boolean hasStableUniqueId() { + return false; + } + + @Override + public DisplayDeviceInfo getDisplayDeviceInfoLocked() { + return mDisplayDeviceInfo; + } + }; SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class); - mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false); + mLogicalDisplay.configureDisplayLocked(t, displayDevice, false); verify(t).setDisplayFlags(any(), eq(SurfaceControl.DISPLAY_RECEIVES_INPUT)); reset(t); mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_NONE; - mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false); + mLogicalDisplay.configureDisplayLocked(t, displayDevice, false); verify(t).setDisplayFlags(any(), eq(0)); reset(t); mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_VIRTUAL; - mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false); + mLogicalDisplay.configureDisplayLocked(t, displayDevice, false); verify(t).setDisplayFlags(any(), eq(SurfaceControl.DISPLAY_RECEIVES_INPUT)); reset(t); mLogicalDisplay.setEnabledLocked(false); - mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false); + mLogicalDisplay.configureDisplayLocked(t, displayDevice, false); verify(t).setDisplayFlags(any(), eq(0)); reset(t); mLogicalDisplay.setEnabledLocked(true); mDisplayDeviceInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL; - mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false); + mLogicalDisplay.configureDisplayLocked(t, displayDevice, false); verify(t).setDisplayFlags(any(), eq(SurfaceControl.DISPLAY_RECEIVES_INPUT)); reset(t); } diff --git a/services/tests/displayservicetests/src/com/android/server/display/RampAnimatorTest.java b/services/tests/displayservicetests/src/com/android/server/display/RampAnimatorTest.java index 2820da7c49c1..810a8b2c8297 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/RampAnimatorTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/RampAnimatorTest.java @@ -28,6 +28,8 @@ import org.junit.Test; @SmallTest public class RampAnimatorTest { + private static final float FLOAT_TOLERANCE = 0.0000001f; + private RampAnimator<TestObject> mRampAnimator; private final TestObject mTestObject = new TestObject(); @@ -46,16 +48,46 @@ public class RampAnimatorTest { @Before public void setUp() { - mRampAnimator = new RampAnimator<>(mTestObject, mTestProperty); + mRampAnimator = new RampAnimator<>(mTestObject, mTestProperty, () -> 0); } @Test public void testInitialValueUsedInLastAnimationStep() { - mRampAnimator.setAnimationTarget(0.67f, 0.1f); + mRampAnimator.setAnimationTarget(0.67f, 0.1f, false); assertEquals(0.67f, mTestObject.mValue, 0); } + @Test + public void testAnimationStep_respectTimeLimits() { + // animation is limited to 2s + mRampAnimator.setAnimationTimeLimits(2_000, 2_000); + // initial brightness value, applied immediately, in HLG = 0.8716434 + mRampAnimator.setAnimationTarget(0.5f, 0.1f, false); + // expected brightness, in HLG = 0.9057269 + // delta = 0.0340835, duration = 3.40835s > 2s + // new rate = delta/2 = 0.01704175 u/s + mRampAnimator.setAnimationTarget(0.6f, 0.01f, false); + // animation step = 1s, new HGL = 0.88868515 + mRampAnimator.performNextAnimationStep(1_000_000_000); + // converted back to Linear + assertEquals(0.54761934f, mTestObject.mValue, FLOAT_TOLERANCE); + } + + @Test + public void testAnimationStep_ignoreTimeLimits() { + // animation is limited to 2s + mRampAnimator.setAnimationTimeLimits(2_000, 2_000); + // initial brightness value, applied immediately, in HLG = 0.8716434 + mRampAnimator.setAnimationTarget(0.5f, 0.1f, false); + // rate = 0.01f, time limits are ignored + mRampAnimator.setAnimationTarget(0.6f, 0.01f, true); + // animation step = 1s, new HGL = 0.8816434 + mRampAnimator.performNextAnimationStep(1_000_000_000); + // converted back to Linear + assertEquals(0.52739114f, mTestObject.mValue, FLOAT_TOLERANCE); + } + private static class TestObject { private float mValue; } diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java index 0ebe46ac0c88..37d966d044c5 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java @@ -24,6 +24,7 @@ import android.os.PowerManager; import androidx.test.filters.SmallTest; +import com.android.server.display.config.HdrBrightnessData; import com.android.server.testutils.OffsettableClock; import com.android.server.testutils.TestHandler; @@ -34,6 +35,8 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +import java.util.Map; + @SmallTest public class HdrClamperTest { @@ -108,10 +111,13 @@ public class HdrClamperTest { } private void configureClamper() { - mHdrClamper.getConfiguration().mMaxBrightnessLimits.put(500f, 0.6f); - mHdrClamper.getConfiguration().mIncreaseConfig.mDebounceTimeMillis = 1000; - mHdrClamper.getConfiguration().mIncreaseConfig.mTransitionTimeMillis = 1500; - mHdrClamper.getConfiguration().mDecreaseConfig.mDebounceTimeMillis = 2000; - mHdrClamper.getConfiguration().mDecreaseConfig.mTransitionTimeMillis = 2500; + HdrBrightnessData data = new HdrBrightnessData( + Map.of(500f, 0.6f), + /* brightnessIncreaseDebounceMillis= */ 1000, + /* brightnessIncreaseDurationMillis= */ 1500, + /* brightnessDecreaseDebounceMillis= */ 2000, + /* brightnessDecreaseDurationMillis= */2500 + ); + mHdrClamper.resetHdrConfig(data); } } diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtilsTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtilsTest.java index 8e17b3a58769..dcd531751cd7 100644 --- a/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtilsTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtilsTest.java @@ -17,26 +17,33 @@ package com.android.server.backup.utils; import static org.junit.Assert.assertTrue; - +import static org.testng.AssertJUnit.assertFalse; +import android.app.backup.BackupAnnotations; import android.app.backup.BackupManagerMonitor; import android.os.Bundle; - import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; - import java.io.File; +import java.io.FileWriter; public class BackupManagerMonitorDumpsysUtilsTest { - private File mTempFile; + private long mRetentionPeriod; + private File mTempBMMEventsFile; + private File mTempSetUpDateFile; + + private long mSizeLimit; private TestBackupManagerMonitorDumpsysUtils mBackupManagerMonitorDumpsysUtils; @Rule public TemporaryFolder tmp = new TemporaryFolder(); @Before public void setUp() throws Exception { - mTempFile = tmp.newFile("testbmmevents.txt"); + mRetentionPeriod = 30 * 60 * 1000; + mSizeLimit = 25 * 1024 * 1000; + mTempBMMEventsFile = tmp.newFile("testbmmevents.txt"); + mTempSetUpDateFile = tmp.newFile("testSetUpDate.txt"); mBackupManagerMonitorDumpsysUtils = new TestBackupManagerMonitorDumpsysUtils(); } @@ -46,7 +53,7 @@ public class BackupManagerMonitorDumpsysUtilsTest { throws Exception { mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(null); - assertTrue(mTempFile.length() == 0); + assertTrue(mTempBMMEventsFile.length() == 0); } @@ -57,7 +64,7 @@ public class BackupManagerMonitorDumpsysUtilsTest { event.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_CATEGORY, 1); mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event); - assertTrue(mTempFile.length() == 0); + assertTrue(mTempBMMEventsFile.length() == 0); } @Test @@ -67,18 +74,236 @@ public class BackupManagerMonitorDumpsysUtilsTest { event.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_ID, 1); mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event); - assertTrue(mTempFile.length() == 0); + assertTrue(mTempBMMEventsFile.length() == 0); + } + + @Test + public void parseBackupManagerMonitorEventForDumpsys_eventWithCategoryAndId_eventIsWrittenToFile() + throws Exception { + Bundle event = createRestoreBMMEvent(); + mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event); + + assertTrue(mTempBMMEventsFile.length() != 0); + } + + @Test + public void parseBackupManagerMonitorEventForDumpsys_firstEvent_recordSetUpTimestamp() + throws Exception { + assertTrue(mTempBMMEventsFile.length()==0); + assertTrue(mTempSetUpDateFile.length()==0); + + Bundle event = createRestoreBMMEvent(); + mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event); + + assertTrue(mTempBMMEventsFile.length() != 0); + assertTrue(mTempSetUpDateFile.length()!=0); + } + + @Test + public void parseBackupManagerMonitorEventForDumpsys_notFirstEvent_doNotChangeSetUpTimestamp() + throws Exception { + Bundle event1 = createRestoreBMMEvent(); + mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event1); + String setUpTimestampBefore = mBackupManagerMonitorDumpsysUtils.getSetUpDate(); + + Bundle event2 = createRestoreBMMEvent(); + mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event2); + String setUpTimestampAfter = mBackupManagerMonitorDumpsysUtils.getSetUpDate(); + + assertTrue(setUpTimestampBefore.equals(setUpTimestampAfter)); + } + + + @Test + public void parseBackupManagerMonitorEventForDumpsys_fileOverSizeLimit_doNotRecordEvents() + throws Exception { + assertTrue(mTempBMMEventsFile.length() == 0); + Bundle event = createRestoreBMMEvent(); + mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event); + long fileSizeBefore = mTempBMMEventsFile.length(); + + mBackupManagerMonitorDumpsysUtils.setTestSizeLimit(0); + mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event); + long fileSizeAfter = mTempBMMEventsFile.length(); + assertTrue(mBackupManagerMonitorDumpsysUtils.isFileLargerThanSizeLimit(mTempBMMEventsFile)); + assertTrue(fileSizeBefore == fileSizeAfter); + } + + @Test + public void parseBackupManagerMonitorEventForDumpsys_fileUnderSizeLimit_recordEvents() + throws Exception { + assertTrue(mTempBMMEventsFile.length() == 0); + Bundle event = createRestoreBMMEvent(); + + mBackupManagerMonitorDumpsysUtils.setTestSizeLimit(25 * 1024 * 1000); + mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event); + assertFalse(mBackupManagerMonitorDumpsysUtils.isFileLargerThanSizeLimit(mTempBMMEventsFile)); + assertTrue(mTempBMMEventsFile.length() != 0); + } + + @Test + public void deleteExpiredBackupManagerMonitorEvent_eventsAreExpired_deleteEventsAndReturnTrue() + throws Exception { + Bundle event = createRestoreBMMEvent(); + mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event); + assertTrue(mTempBMMEventsFile.length() != 0); + // Re-initialise the test BackupManagerMonitorDumpsysUtils to + // clear the cached value of isAfterRetentionPeriod + mBackupManagerMonitorDumpsysUtils = new TestBackupManagerMonitorDumpsysUtils(); + + // set a retention period of 0 second + mBackupManagerMonitorDumpsysUtils.setTestRetentionPeriod(0); + + assertTrue(mBackupManagerMonitorDumpsysUtils.deleteExpiredBMMEvents()); + assertFalse(mTempBMMEventsFile.exists()); + } + + @Test + public void deleteExpiredBackupManagerMonitorEvent_eventsAreNotExpired_returnFalse() throws + Exception { + Bundle event = createRestoreBMMEvent(); + mBackupManagerMonitorDumpsysUtils.parseBackupManagerMonitorRestoreEventForDumpsys(event); + assertTrue(mTempBMMEventsFile.length() != 0); + + // set a retention period of 30 minutes + mBackupManagerMonitorDumpsysUtils.setTestRetentionPeriod(30 * 60 * 1000); + + assertFalse(mBackupManagerMonitorDumpsysUtils.deleteExpiredBMMEvents()); + assertTrue(mTempBMMEventsFile.length() != 0); + } + + @Test + public void isAfterRetentionPeriod_afterRetentionPeriod_returnTrue() throws + Exception { + mBackupManagerMonitorDumpsysUtils.recordSetUpTimestamp(); + + // set a retention period of 0 second + mBackupManagerMonitorDumpsysUtils.setTestRetentionPeriod(0); + + assertTrue(mBackupManagerMonitorDumpsysUtils.isAfterRetentionPeriod()); + } + + @Test + public void isAfterRetentionPeriod_beforeRetentionPeriod_returnFalse() throws + Exception { + mBackupManagerMonitorDumpsysUtils.recordSetUpTimestamp(); + + // set a retention period of 30 minutes + mBackupManagerMonitorDumpsysUtils.setTestRetentionPeriod(30 * 60 * 1000); + + assertFalse(mBackupManagerMonitorDumpsysUtils.isAfterRetentionPeriod()); + } + + @Test + public void isAfterRetentionPeriod_noSetupDate_returnFalse() throws + Exception { + assertTrue(mTempSetUpDateFile.length() == 0); + + assertFalse(mBackupManagerMonitorDumpsysUtils.isAfterRetentionPeriod()); + } + + @Test + public void isDateAfterNMillisec_date1IsAfterThanDate2_returnTrue() throws + Exception { + long timestamp1 = System.currentTimeMillis(); + long timestamp2 = timestamp1 - 1; + + assertTrue(mBackupManagerMonitorDumpsysUtils.isDateAfterNMillisec(timestamp1, timestamp2, + 0)); + } + + @Test + public void isDateAfterNMillisec_date1IsAfterNMillisecFromDate2_returnTrue() throws + Exception { + long timestamp1 = System.currentTimeMillis(); + long timestamp2 = timestamp1 + 10; + + assertTrue(mBackupManagerMonitorDumpsysUtils.isDateAfterNMillisec(timestamp1, timestamp2, + 10)); + } + + @Test + public void isDateAfterNMillisec_date1IsLessThanNMillisecFromDate2_returnFalse() throws + Exception { + long timestamp1 = System.currentTimeMillis(); + long timestamp2 = timestamp1 + 10; + + assertFalse(mBackupManagerMonitorDumpsysUtils.isDateAfterNMillisec(timestamp1, timestamp2, + 11)); + } + + @Test + public void recordSetUpTimestamp_timestampNotSetBefore_setTimestamp() throws + Exception { + assertTrue(mTempSetUpDateFile.length() == 0); + + mBackupManagerMonitorDumpsysUtils.recordSetUpTimestamp(); + + assertTrue(mTempSetUpDateFile.length() != 0); + } + + @Test + public void recordSetUpTimestamp_timestampSetBefore_doNothing() throws + Exception { + mBackupManagerMonitorDumpsysUtils.recordSetUpTimestamp(); + assertTrue(mTempSetUpDateFile.length() != 0); + String timestampBefore = mBackupManagerMonitorDumpsysUtils.getSetUpDate(); + + mBackupManagerMonitorDumpsysUtils.recordSetUpTimestamp(); + + assertTrue(mTempSetUpDateFile.length() != 0); + String timestampAfter = mBackupManagerMonitorDumpsysUtils.getSetUpDate(); + assertTrue(timestampAfter.equals(timestampBefore)); + } + + private Bundle createRestoreBMMEvent() { + Bundle event = new Bundle(); + event.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_ID, 1); + event.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_CATEGORY, 1); + event.putInt(BackupManagerMonitor.EXTRA_LOG_OPERATION_TYPE, + BackupAnnotations.OperationType.RESTORE); + return event; } private class TestBackupManagerMonitorDumpsysUtils extends BackupManagerMonitorDumpsysUtils { + + private long testRetentionPeriod; + private long testSizeLimit; + TestBackupManagerMonitorDumpsysUtils() { super(); + this.testRetentionPeriod = mRetentionPeriod; + this.testSizeLimit = mSizeLimit; + } + + public void setTestRetentionPeriod(long testRetentionPeriod) { + this.testRetentionPeriod = testRetentionPeriod; + } + public void setTestSizeLimit(long testSizeLimit) { + this.testSizeLimit = testSizeLimit; } @Override public File getBMMEventsFile() { - return mTempFile; + return mTempBMMEventsFile; } + + @Override + File getSetUpDateFile() { + return mTempSetUpDateFile; + } + + @Override + long getRetentionPeriodInMillisec() { + return testRetentionPeriod; + } + + @Override + long getBMMEventsFileSizeLimit(){ + return testSizeLimit; + } + + } } diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorEventSenderTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorEventSenderTest.java index 3af2932ee937..604a68d12f5e 100644 --- a/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorEventSenderTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupManagerMonitorEventSenderTest.java @@ -340,8 +340,9 @@ public class BackupManagerMonitorEventSenderTest { @Test public void putMonitoringExtraLong_bundleExists_fillsBundleCorrectly() throws Exception { Bundle bundle = new Bundle(); + long value = 123; - Bundle result = mBackupManagerMonitorEventSender.putMonitoringExtra(bundle, "key", 123); + Bundle result = mBackupManagerMonitorEventSender.putMonitoringExtra(bundle, "key", value); assertThat(result).isEqualTo(bundle); assertThat(result.size()).isEqualTo(1); @@ -350,7 +351,8 @@ public class BackupManagerMonitorEventSenderTest { @Test public void putMonitoringExtraLong_bundleDoesNotExist_fillsBundleCorrectly() throws Exception { - Bundle result = mBackupManagerMonitorEventSender.putMonitoringExtra(null, "key", 123); + long value = 123; + Bundle result = mBackupManagerMonitorEventSender.putMonitoringExtra(null, "key", value); assertThat(result).isNotNull(); assertThat(result.size()).isEqualTo(1); @@ -377,4 +379,25 @@ public class BackupManagerMonitorEventSenderTest { assertThat(result.size()).isEqualTo(1); assertThat(result.getBoolean("key")).isTrue(); } + + @Test + public void putMonitoringExtraInt_bundleExists_fillsBundleCorrectly() throws Exception { + Bundle bundle = new Bundle(); + + Bundle result = mBackupManagerMonitorEventSender.putMonitoringExtra(bundle, "key", 1); + + assertThat(result).isEqualTo(bundle); + assertThat(result.size()).isEqualTo(1); + assertThat(result.getInt("key")).isEqualTo(1); + } + + @Test + public void putMonitoringExtraInt_bundleDoesNotExist_fillsBundleCorrectly() + throws Exception { + Bundle result = mBackupManagerMonitorEventSender.putMonitoringExtra(null, "key", 1); + + assertThat(result).isNotNull(); + assertThat(result.size()).isEqualTo(1); + assertThat(result.getInt("key")).isEqualTo(1); + } } diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java index b97fd4b3277b..eb50556821eb 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java @@ -315,7 +315,8 @@ public class PackageArchiverTest { } @Test - public void unarchiveApp_notArchived() { + public void unarchiveApp_notArchived_missingArchiveState() { + mUserState.setInstalled(false); Exception e = assertThrows( ParcelableException.class, () -> mArchiveManager.requestUnarchive(PACKAGE, CALLER_PACKAGE, @@ -326,8 +327,21 @@ public class PackageArchiverTest { } @Test - public void unarchiveApp_noInstallerFound() { + public void unarchiveApp_notArchived_stillInstalled() { mUserState.setArchiveState(createArchiveState()); + Exception e = assertThrows( + ParcelableException.class, + () -> mArchiveManager.requestUnarchive(PACKAGE, CALLER_PACKAGE, + UserHandle.CURRENT)); + assertThat(e.getCause()).isInstanceOf(PackageManager.NameNotFoundException.class); + assertThat(e.getCause()).hasMessageThat().isEqualTo( + String.format("Package %s is not currently archived.", PACKAGE)); + } + + + @Test + public void unarchiveApp_noInstallerFound() { + mUserState.setArchiveState(createArchiveState()).setInstalled(false); InstallSource otherInstallSource = InstallSource.create( CALLER_PACKAGE, diff --git a/services/tests/servicestests/src/com/android/server/am/FgsLoggerTest.java b/services/tests/servicestests/src/com/android/server/am/FgsLoggerTest.java index f5005fdf1459..38bb3dea6ee3 100644 --- a/services/tests/servicestests/src/com/android/server/am/FgsLoggerTest.java +++ b/services/tests/servicestests/src/com/android/server/am/FgsLoggerTest.java @@ -152,6 +152,50 @@ public class FgsLoggerTest { } @Test + public void testApiStartStopFgs() throws InterruptedException { + ServiceRecord record = ServiceRecord.newEmptyInstanceForTest(null); + record.foregroundServiceType = ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA; + + mFgsLogger.logForegroundServiceApiEventBegin(FOREGROUND_SERVICE_API_TYPE_CAMERA, + 1, 1, "aPackageHasNoName"); + Thread.sleep(2000); + + resetAndVerifyZeroInteractions(); + + mFgsLogger.logForegroundServiceApiEventEnd(FOREGROUND_SERVICE_API_TYPE_CAMERA, 1, 1); + + resetAndVerifyZeroInteractions(); + + mFgsLogger.logForegroundServiceStart(1, 1, record); + + resetAndVerifyZeroInteractions(); + } + + @Test + public void testFgsStartStopApiStartStop() throws InterruptedException { + ServiceRecord record = ServiceRecord.newEmptyInstanceForTest(null); + record.foregroundServiceType = ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA; + + mFgsLogger.logForegroundServiceStart(1, 1, record); + + resetAndVerifyZeroInteractions(); + + mFgsLogger.logForegroundServiceStop(1, record); + + resetAndVerifyZeroInteractions(); + + mFgsLogger.logForegroundServiceApiEventBegin(FOREGROUND_SERVICE_API_TYPE_CAMERA, + 1, 1, "aPackageHasNoName"); + Thread.sleep(2000); + + resetAndVerifyZeroInteractions(); + + mFgsLogger.logForegroundServiceApiEventEnd(FOREGROUND_SERVICE_API_TYPE_CAMERA, 1, 1); + + resetAndVerifyZeroInteractions(); + } + + @Test public void testMultipleStartStopApis() throws InterruptedException { ServiceRecord record = ServiceRecord.newEmptyInstanceForTest(null); record.foregroundServiceType = ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA; diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java index 8f88ba6ff9a7..7d735632b675 100644 --- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java @@ -30,7 +30,6 @@ import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertThrows; -import android.app.ActivityManager; import android.hardware.devicestate.DeviceStateInfo; import android.hardware.devicestate.DeviceStateRequest; import android.hardware.devicestate.IDeviceStateManagerCallback; @@ -582,10 +581,10 @@ public final class DeviceStateManagerServiceTest { // When the app is foreground, the state should not change () -> { int pid = Binder.getCallingPid(); - when(mWindowProcessController.getPid()).thenReturn(pid); + int uid = Binder.getCallingUid(); try { - mService.mOverrideRequestTaskStackListener.onTaskMovedToFront( - new ActivityManager.RunningTaskInfo()); + mService.mProcessObserver.onForegroundActivitiesChanged(pid, uid, + true /* foregroundActivities */); } catch (RemoteException e) { throw new RuntimeException(e); } @@ -594,8 +593,11 @@ public final class DeviceStateManagerServiceTest { () -> { when(mWindowProcessController.getPid()).thenReturn(FAKE_PROCESS_ID); try { - mService.mOverrideRequestTaskStackListener.onTaskMovedToFront( - new ActivityManager.RunningTaskInfo()); + int pid = Binder.getCallingPid(); + int uid = Binder.getCallingUid(); + mService.mProcessObserver.onForegroundActivitiesChanged(pid, uid, + false /* foregroundActivities */); + } catch (RemoteException e) { throw new RuntimeException(e); } diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateNotificationControllerTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateNotificationControllerTest.java index 728606f9f628..bb0de032d987 100644 --- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateNotificationControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateNotificationControllerTest.java @@ -33,6 +33,8 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.Handler; +import android.os.Looper; +import android.os.Message; import android.platform.test.annotations.Presubmit; import android.util.SparseArray; @@ -89,11 +91,12 @@ public class DeviceStateNotificationControllerTest { @Before public void setup() throws Exception { Context context = InstrumentationRegistry.getInstrumentation().getContext(); - Handler handler = mock(Handler.class); PackageManager packageManager = mock(PackageManager.class); Runnable cancelStateRunnable = mock(Runnable.class); ApplicationInfo applicationInfo = mock(ApplicationInfo.class); + Handler handler = new DeviceStateNotificationControllerTestHandler(Looper.getMainLooper()); + final SparseArray<DeviceStateNotificationController.NotificationInfo> notificationInfos = new SparseArray<>(); notificationInfos.put(STATE_WITH_ACTIVE_NOTIFICATION, @@ -259,4 +262,16 @@ public class DeviceStateNotificationControllerTest { assertEquals(Locale.ITALY, mNotificationInfoProvider.getCachedLocale()); clearInvocations(mNotificationInfoProvider); } + + private static class DeviceStateNotificationControllerTestHandler extends Handler { + DeviceStateNotificationControllerTestHandler(Looper looper) { + super(looper); + } + + @Override + public boolean sendMessageAtTime(Message msg, long uptimeMillis) { + msg.getCallback().run(); + return true; + } + } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java new file mode 100644 index 000000000000..81867df74abd --- /dev/null +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java @@ -0,0 +1,1973 @@ +/* + * 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.notification; + +import static android.app.Notification.FLAG_BUBBLE; +import static android.app.Notification.GROUP_ALERT_ALL; +import static android.app.Notification.GROUP_ALERT_CHILDREN; +import static android.app.Notification.GROUP_ALERT_SUMMARY; +import static android.app.NotificationManager.IMPORTANCE_HIGH; +import static android.app.NotificationManager.IMPORTANCE_LOW; +import static android.app.NotificationManager.IMPORTANCE_MIN; +import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS; +import static android.media.AudioAttributes.USAGE_NOTIFICATION; +import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.mockito.ArgumentMatchers.anyFloat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyObject; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.after; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.annotation.SuppressLint; +import android.app.ActivityManager; +import android.app.KeyguardManager; +import android.app.Notification; +import android.app.Notification.Builder; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.pm.PackageManager; +import android.graphics.Color; +import android.graphics.drawable.Icon; +import android.media.AudioAttributes; +import android.media.AudioManager; +import android.net.Uri; +import android.os.Handler; +import android.os.Process; +import android.os.RemoteException; +import android.os.UserHandle; +import android.os.VibrationAttributes; +import android.os.VibrationEffect; +import android.os.Vibrator; +import android.provider.Settings; +import android.service.notification.NotificationListenerService; +import android.service.notification.StatusBarNotification; +import android.test.suitebuilder.annotation.SmallTest; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityManager; +import android.view.accessibility.IAccessibilityManager; +import android.view.accessibility.IAccessibilityManagerClient; +import androidx.test.runner.AndroidJUnit4; +import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags; +import com.android.internal.config.sysui.TestableFlagResolver; +import com.android.internal.logging.InstanceIdSequence; +import com.android.internal.logging.InstanceIdSequenceFake; +import com.android.internal.util.IntPair; +import com.android.server.UiServiceTestCase; +import com.android.server.lights.LightsManager; +import com.android.server.lights.LogicalLight; +import com.android.server.pm.PackageManagerService; +import java.util.Objects; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatcher; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.mockito.verification.VerificationMode; + +@SmallTest +@RunWith(AndroidJUnit4.class) +@SuppressLint("GuardedBy") +public class NotificationAttentionHelperTest extends UiServiceTestCase { + + @Mock AudioManager mAudioManager; + @Mock Vibrator mVibrator; + @Mock android.media.IRingtonePlayer mRingtonePlayer; + @Mock LogicalLight mLight; + @Mock + NotificationManagerService.WorkerHandler mHandler; + @Mock + NotificationUsageStats mUsageStats; + @Mock + IAccessibilityManager mAccessibilityService; + @Mock + KeyguardManager mKeyguardManager; + NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake(); + private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake( + 1 << 30); + + private NotificationManagerService mService; + private String mPkg = "com.android.server.notification"; + private int mId = 1001; + private int mOtherId = 1002; + private String mTag = null; + private int mUid = 1000; + private int mPid = 2000; + private android.os.UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser()); + private NotificationChannel mChannel; + + private NotificationAttentionHelper mAttentionHelper; + private TestableFlagResolver mTestFlagResolver = new TestableFlagResolver(); + private AccessibilityManager mAccessibilityManager; + private static final NotificationAttentionHelper.Signals DEFAULT_SIGNALS = + new NotificationAttentionHelper.Signals(false, 0); + + private VibrateRepeatMatcher mVibrateOnceMatcher = new VibrateRepeatMatcher(-1); + private VibrateRepeatMatcher mVibrateLoopMatcher = new VibrateRepeatMatcher(0); + + private static final long[] CUSTOM_VIBRATION = new long[] { + 300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400, + 300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400, + 300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400 }; + private static final Uri CUSTOM_SOUND = Settings.System.DEFAULT_ALARM_ALERT_URI; + private static final AudioAttributes CUSTOM_ATTRIBUTES = new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN) + .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION) + .build(); + private static final int CUSTOM_LIGHT_COLOR = Color.BLACK; + private static final int CUSTOM_LIGHT_ON = 10000; + private static final int CUSTOM_LIGHT_OFF = 10000; + private static final int MAX_VIBRATION_DELAY = 1000; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + getContext().addMockSystemService(Vibrator.class, mVibrator); + + when(mAudioManager.isAudioFocusExclusive()).thenReturn(false); + when(mAudioManager.getRingtonePlayer()).thenReturn(mRingtonePlayer); + when(mAudioManager.getStreamVolume(anyInt())).thenReturn(10); + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); + when(mAudioManager.getFocusRampTimeMs(anyInt(), any(AudioAttributes.class))).thenReturn(50); + when(mUsageStats.isAlertRateLimited(any())).thenReturn(false); + when(mVibrator.hasFrequencyControl()).thenReturn(false); + when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(false); + + long serviceReturnValue = IntPair.of( + AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED, + AccessibilityEvent.TYPES_ALL_MASK); + when(mAccessibilityService.addClient(any(), anyInt())).thenReturn(serviceReturnValue); + mAccessibilityManager = + new AccessibilityManager(getContext(), Handler.getMain(), mAccessibilityService, 0, + true); + verify(mAccessibilityService).addClient(any(IAccessibilityManagerClient.class), anyInt()); + assertTrue(mAccessibilityManager.isEnabled()); + + // TODO (b/291907312): remove feature flag + mTestFlagResolver.setFlagOverride(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR, true); + + mService = spy(new NotificationManagerService(getContext(), mNotificationRecordLogger, + mNotificationInstanceIdSequence)); + + initAttentionHelper(mTestFlagResolver); + + mChannel = new NotificationChannel("test", "test", IMPORTANCE_HIGH); + } + + private void initAttentionHelper(TestableFlagResolver flagResolver) { + mAttentionHelper = new NotificationAttentionHelper(getContext(), mock(LightsManager.class), + mAccessibilityManager, getContext().getPackageManager(), mUsageStats, + mService.mNotificationManagerPrivate, mock(ZenModeHelper.class), flagResolver); + mAttentionHelper.setVibratorHelper(new VibratorHelper(getContext())); + mAttentionHelper.setAudioManager(mAudioManager); + mAttentionHelper.setSystemReady(true); + mAttentionHelper.setLights(mLight); + mAttentionHelper.setScreenOn(false); + mAttentionHelper.setAccessibilityManager(mAccessibilityManager); + mAttentionHelper.setKeyguardManager(mKeyguardManager); + mAttentionHelper.setScreenOn(false); + mAttentionHelper.setInCallStateOffHook(false); + mAttentionHelper.mNotificationPulseEnabled = true; + } + + // + // Convenience functions for creating notification records + // + + private NotificationRecord getNoisyOtherNotification() { + return getNotificationRecord(mOtherId, false /* insistent */, false /* once */, + true /* noisy */, true /* buzzy*/, false /* lights */); + } + + private NotificationRecord getBeepyNotification() { + return getNotificationRecord(mId, false /* insistent */, false /* once */, + true /* noisy */, false /* buzzy*/, false /* lights */); + } + + private NotificationRecord getBeepyOtherNotification() { + return getNotificationRecord(mOtherId, false /* insistent */, false /* once */, + true /* noisy */, false /* buzzy*/, false /* lights */); + } + + private NotificationRecord getBeepyOnceNotification() { + return getNotificationRecord(mId, false /* insistent */, true /* once */, + true /* noisy */, false /* buzzy*/, false /* lights */); + } + + private NotificationRecord getQuietNotification() { + return getNotificationRecord(mId, false /* insistent */, true /* once */, + false /* noisy */, false /* buzzy*/, false /* lights */); + } + + private NotificationRecord getQuietOtherNotification() { + return getNotificationRecord(mOtherId, false /* insistent */, false /* once */, + false /* noisy */, false /* buzzy*/, false /* lights */); + } + + private NotificationRecord getQuietOnceNotification() { + return getNotificationRecord(mId, false /* insistent */, true /* once */, + false /* noisy */, false /* buzzy*/, false /* lights */); + } + + private NotificationRecord getInsistentBeepyNotification() { + return getNotificationRecord(mId, true /* insistent */, false /* once */, + true /* noisy */, false /* buzzy*/, false /* lights */); + } + + private NotificationRecord getInsistentBeepyOnceNotification() { + return getNotificationRecord(mId, true /* insistent */, true /* once */, + true /* noisy */, false /* buzzy*/, false /* lights */); + } + + private NotificationRecord getInsistentBeepyLeanbackNotification() { + return getLeanbackNotificationRecord(mId, true /* insistent */, false /* once */, + true /* noisy */, false /* buzzy*/, false /* lights */); + } + + private NotificationRecord getBuzzyNotification() { + return getNotificationRecord(mId, false /* insistent */, false /* once */, + false /* noisy */, true /* buzzy*/, false /* lights */); + } + + private NotificationRecord getBuzzyOtherNotification() { + return getNotificationRecord(mOtherId, false /* insistent */, false /* once */, + false /* noisy */, true /* buzzy*/, false /* lights */); + } + + private NotificationRecord getBuzzyOnceNotification() { + return getNotificationRecord(mId, false /* insistent */, true /* once */, + false /* noisy */, true /* buzzy*/, false /* lights */); + } + + private NotificationRecord getInsistentBuzzyNotification() { + return getNotificationRecord(mId, true /* insistent */, false /* once */, + false /* noisy */, true /* buzzy*/, false /* lights */); + } + + private NotificationRecord getBuzzyBeepyNotification() { + return getNotificationRecord(mId, false /* insistent */, false /* once */, + true /* noisy */, true /* buzzy*/, false /* lights */); + } + + private NotificationRecord getLightsNotification() { + return getNotificationRecord(mId, false /* insistent */, false /* once */, + false /* noisy */, false /* buzzy*/, true /* lights */); + } + + private NotificationRecord getLightsOnceNotification() { + return getNotificationRecord(mId, false /* insistent */, true /* once */, + false /* noisy */, false /* buzzy*/, true /* lights */); + } + + private NotificationRecord getCallRecord(int id, NotificationChannel channel, boolean looping) { + final Builder builder = new Builder(getContext()) + .setContentTitle("foo") + .setSmallIcon(android.R.drawable.sym_def_app_icon) + .setPriority(Notification.PRIORITY_HIGH); + Notification n = builder.build(); + if (looping) { + n.flags |= Notification.FLAG_INSISTENT; + } + StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id, mTag, mUid, + mPid, n, mUser, null, System.currentTimeMillis()); + NotificationRecord r = new NotificationRecord(getContext(), sbn, channel); + mService.addNotification(r); + + return r; + } + + private NotificationRecord getNotificationRecord(int id, boolean insistent, boolean once, + boolean noisy, boolean buzzy, boolean lights) { + return getNotificationRecord(id, insistent, once, noisy, buzzy, lights, buzzy, noisy, + lights, null, Notification.GROUP_ALERT_ALL, false); + } + + private NotificationRecord getLeanbackNotificationRecord(int id, boolean insistent, + boolean once, + boolean noisy, boolean buzzy, boolean lights) { + return getNotificationRecord(id, insistent, once, noisy, buzzy, lights, true, true, + true, + null, Notification.GROUP_ALERT_ALL, true); + } + + private NotificationRecord getBeepyNotificationRecord(String groupKey, int groupAlertBehavior) { + return getNotificationRecord(mId, false, false, true, false, false, true, true, true, + groupKey, groupAlertBehavior, false); + } + + private NotificationRecord getLightsNotificationRecord(String groupKey, + int groupAlertBehavior) { + return getNotificationRecord(mId, false, false, false, false, true /*lights*/, true, + true, true, groupKey, groupAlertBehavior, false); + } + + private NotificationRecord getNotificationRecord(int id, + boolean insistent, boolean once, + boolean noisy, boolean buzzy, boolean lights, boolean defaultVibration, + boolean defaultSound, boolean defaultLights, String groupKey, int groupAlertBehavior, + boolean isLeanback) { + + final Builder builder = new Builder(getContext()) + .setContentTitle("foo") + .setSmallIcon(android.R.drawable.sym_def_app_icon) + .setPriority(Notification.PRIORITY_HIGH) + .setOnlyAlertOnce(once); + + int defaults = 0; + if (noisy) { + if (defaultSound) { + defaults |= Notification.DEFAULT_SOUND; + mChannel.setSound(Settings.System.DEFAULT_NOTIFICATION_URI, + Notification.AUDIO_ATTRIBUTES_DEFAULT); + } else { + builder.setSound(CUSTOM_SOUND); + mChannel.setSound(CUSTOM_SOUND, CUSTOM_ATTRIBUTES); + } + } else { + mChannel.setSound(null, null); + } + if (buzzy) { + if (defaultVibration) { + defaults |= Notification.DEFAULT_VIBRATE; + } else { + builder.setVibrate(CUSTOM_VIBRATION); + mChannel.setVibrationPattern(CUSTOM_VIBRATION); + } + mChannel.enableVibration(true); + } else { + mChannel.setVibrationPattern(null); + mChannel.enableVibration(false); + } + + if (lights) { + if (defaultLights) { + defaults |= Notification.DEFAULT_LIGHTS; + } else { + builder.setLights(CUSTOM_LIGHT_COLOR, CUSTOM_LIGHT_ON, CUSTOM_LIGHT_OFF); + } + mChannel.enableLights(true); + } else { + mChannel.enableLights(false); + } + builder.setDefaults(defaults); + + builder.setGroup(groupKey); + builder.setGroupAlertBehavior(groupAlertBehavior); + + Notification n = builder.build(); + if (insistent) { + n.flags |= Notification.FLAG_INSISTENT; + } + + Context context = spy(getContext()); + PackageManager packageManager = spy(context.getPackageManager()); + when(context.getPackageManager()).thenReturn(packageManager); + when(packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) + .thenReturn(isLeanback); + + StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id, mTag, mUid, + mPid, n, mUser, null, System.currentTimeMillis()); + NotificationRecord r = new NotificationRecord(context, sbn, mChannel); + mService.addNotification(r); + return r; + } + + // + // Convenience functions for interacting with mocks + // + + private void verifyNeverBeep() throws RemoteException { + verify(mRingtonePlayer, never()).playAsync(any(), any(), anyBoolean(), any()); + } + + private void verifyBeepUnlooped() throws RemoteException { + verify(mRingtonePlayer, times(1)).playAsync(any(), any(), eq(false), any()); + } + + private void verifyBeepLooped() throws RemoteException { + verify(mRingtonePlayer, times(1)).playAsync(any(), any(), eq(true), any()); + } + + private void verifyBeep(int times) throws RemoteException { + verify(mRingtonePlayer, times(times)).playAsync(any(), any(), anyBoolean(), any()); + } + + private void verifyNeverStopAudio() throws RemoteException { + verify(mRingtonePlayer, never()).stopAsync(); + } + + private void verifyStopAudio() throws RemoteException { + verify(mRingtonePlayer, times(1)).stopAsync(); + } + + private void verifyNeverVibrate() { + verify(mVibrator, never()).vibrate(anyInt(), anyString(), any(), anyString(), + any(VibrationAttributes.class)); + } + + private void verifyVibrate() { + verifyVibrate(/* times= */ 1); + } + + private void verifyVibrate(int times) { + verifyVibrate(mVibrateOnceMatcher, times(times)); + } + + private void verifyVibrateLooped() { + verifyVibrate(mVibrateLoopMatcher, times(1)); + } + + private void verifyDelayedVibrateLooped() { + verifyVibrate(mVibrateLoopMatcher, timeout(MAX_VIBRATION_DELAY).times(1)); + } + + private void verifyDelayedVibrate(VibrationEffect effect) { + verifyVibrate(argument -> Objects.equals(effect, argument), + timeout(MAX_VIBRATION_DELAY).times(1)); + } + + private void verifyDelayedNeverVibrate() { + verify(mVibrator, after(MAX_VIBRATION_DELAY).never()).vibrate(anyInt(), anyString(), any(), + anyString(), any(VibrationAttributes.class)); + } + + private void verifyVibrate(ArgumentMatcher<VibrationEffect> effectMatcher, + VerificationMode verification) { + ArgumentCaptor<VibrationAttributes> captor = + ArgumentCaptor.forClass(VibrationAttributes.class); + verify(mVibrator, verification).vibrate(eq(Process.SYSTEM_UID), + eq(PackageManagerService.PLATFORM_PACKAGE_NAME), argThat(effectMatcher), + anyString(), captor.capture()); + assertEquals(0, (captor.getValue().getFlags() + & VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY)); + } + + private void verifyStopVibrate() { + int alarmClassUsageFilter = + VibrationAttributes.USAGE_CLASS_ALARM | ~VibrationAttributes.USAGE_CLASS_MASK; + verify(mVibrator, times(1)).cancel(eq(alarmClassUsageFilter)); + } + + private void verifyNeverStopVibrate() { + verify(mVibrator, never()).cancel(); + verify(mVibrator, never()).cancel(anyInt()); + } + + private void verifyNeverLights() { + verify(mLight, never()).setFlashing(anyInt(), anyInt(), anyInt(), anyInt()); + } + + private void verifyLights() { + verify(mLight, times(1)).setFlashing(anyInt(), anyInt(), anyInt(), anyInt()); + } + + // + // Tests + // + + @Test + public void testLights() throws Exception { + NotificationRecord r = getLightsNotification(); + r.setSystemImportance(NotificationManager.IMPORTANCE_DEFAULT); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyLights(); + assertTrue(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testBeep() throws Exception { + NotificationRecord r = getBeepyNotification(); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyBeepUnlooped(); + verifyNeverVibrate(); + verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt()); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testLockedPrivateA11yRedaction() throws Exception { + NotificationRecord r = getBeepyNotification(); + r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE); + r.getNotification().visibility = Notification.VISIBILITY_PRIVATE; + when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true); + AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class); + when(accessibilityManager.isEnabled()).thenReturn(true); + mAttentionHelper.setAccessibilityManager(accessibilityManager); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + ArgumentCaptor<AccessibilityEvent> eventCaptor = + ArgumentCaptor.forClass(AccessibilityEvent.class); + + verify(accessibilityManager, times(1)) + .sendAccessibilityEvent(eventCaptor.capture()); + + AccessibilityEvent event = eventCaptor.getValue(); + assertEquals(r.getNotification().publicVersion, event.getParcelableData()); + } + + @Test + public void testLockedOverridePrivateA11yRedaction() throws Exception { + NotificationRecord r = getBeepyNotification(); + r.setPackageVisibilityOverride(Notification.VISIBILITY_PRIVATE); + r.getNotification().visibility = Notification.VISIBILITY_PUBLIC; + when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true); + AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class); + when(accessibilityManager.isEnabled()).thenReturn(true); + mAttentionHelper.setAccessibilityManager(accessibilityManager); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + ArgumentCaptor<AccessibilityEvent> eventCaptor = + ArgumentCaptor.forClass(AccessibilityEvent.class); + + verify(accessibilityManager, times(1)) + .sendAccessibilityEvent(eventCaptor.capture()); + + AccessibilityEvent event = eventCaptor.getValue(); + assertEquals(r.getNotification().publicVersion, event.getParcelableData()); + } + + @Test + public void testLockedPublicA11yNoRedaction() throws Exception { + NotificationRecord r = getBeepyNotification(); + r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE); + r.getNotification().visibility = Notification.VISIBILITY_PUBLIC; + when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(true); + AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class); + when(accessibilityManager.isEnabled()).thenReturn(true); + mAttentionHelper.setAccessibilityManager(accessibilityManager); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + ArgumentCaptor<AccessibilityEvent> eventCaptor = + ArgumentCaptor.forClass(AccessibilityEvent.class); + + verify(accessibilityManager, times(1)) + .sendAccessibilityEvent(eventCaptor.capture()); + + AccessibilityEvent event = eventCaptor.getValue(); + assertEquals(r.getNotification(), event.getParcelableData()); + } + + @Test + public void testUnlockedPrivateA11yNoRedaction() throws Exception { + NotificationRecord r = getBeepyNotification(); + r.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE); + r.getNotification().visibility = Notification.VISIBILITY_PRIVATE; + when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(false); + AccessibilityManager accessibilityManager = Mockito.mock(AccessibilityManager.class); + when(accessibilityManager.isEnabled()).thenReturn(true); + mAttentionHelper.setAccessibilityManager(accessibilityManager); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + ArgumentCaptor<AccessibilityEvent> eventCaptor = + ArgumentCaptor.forClass(AccessibilityEvent.class); + + verify(accessibilityManager, times(1)) + .sendAccessibilityEvent(eventCaptor.capture()); + + AccessibilityEvent event = eventCaptor.getValue(); + assertEquals(r.getNotification(), event.getParcelableData()); + } + + @Test + public void testBeepInsistently() throws Exception { + NotificationRecord r = getInsistentBeepyNotification(); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyBeepLooped(); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testNoLeanbackBeep() throws Exception { + NotificationRecord r = getInsistentBeepyLeanbackNotification(); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyNeverBeep(); + assertFalse(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testNoBeepForAutomotiveIfEffectsDisabled() throws Exception { + mAttentionHelper.setIsAutomotive(true); + mAttentionHelper.setNotificationEffectsEnabledForAutomotive(false); + + NotificationRecord r = getBeepyNotification(); + r.setSystemImportance(NotificationManager.IMPORTANCE_HIGH); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyNeverBeep(); + assertFalse(r.isInterruptive()); + } + + @Test + public void testNoBeepForImportanceDefaultInAutomotiveIfEffectsEnabled() throws Exception { + mAttentionHelper.setIsAutomotive(true); + mAttentionHelper.setNotificationEffectsEnabledForAutomotive(true); + + NotificationRecord r = getBeepyNotification(); + r.setSystemImportance(NotificationManager.IMPORTANCE_DEFAULT); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyNeverBeep(); + assertFalse(r.isInterruptive()); + } + + @Test + public void testBeepForImportanceHighInAutomotiveIfEffectsEnabled() throws Exception { + mAttentionHelper.setIsAutomotive(true); + mAttentionHelper.setNotificationEffectsEnabledForAutomotive(true); + + NotificationRecord r = getBeepyNotification(); + r.setSystemImportance(NotificationManager.IMPORTANCE_HIGH); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyBeepUnlooped(); + assertTrue(r.isInterruptive()); + } + + @Test + public void testNoInterruptionForMin() throws Exception { + NotificationRecord r = getBeepyNotification(); + r.setSystemImportance(NotificationManager.IMPORTANCE_MIN); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyNeverBeep(); + verifyNeverVibrate(); + assertFalse(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testNoInterruptionForIntercepted() throws Exception { + NotificationRecord r = getBeepyNotification(); + r.setIntercepted(true); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyNeverBeep(); + verifyNeverVibrate(); + assertFalse(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testBeepTwice() throws Exception { + NotificationRecord r = getBeepyNotification(); + + // set up internal state + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + Mockito.reset(mRingtonePlayer); + + // update should beep + r.isUpdate = true; + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verifyBeepUnlooped(); + verify(mAccessibilityService, times(2)).sendAccessibilityEvent(any(), anyInt()); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testHonorAlertOnlyOnceForBeep() throws Exception { + NotificationRecord r = getBeepyNotification(); + NotificationRecord s = getBeepyOnceNotification(); + s.isUpdate = true; + + // set up internal state + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + Mockito.reset(mRingtonePlayer); + + // update should not beep + mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS); + verifyNeverBeep(); + verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt()); + } + + @Test + public void testNoisyUpdateDoesNotCancelAudio() throws Exception { + NotificationRecord r = getBeepyNotification(); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + r.isUpdate = true; + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyNeverStopAudio(); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testNoisyOnceUpdateDoesNotCancelAudio() throws Exception { + NotificationRecord r = getBeepyNotification(); + NotificationRecord s = getBeepyOnceNotification(); + s.isUpdate = true; + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS); + + verifyNeverStopAudio(); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + assertFalse(s.isInterruptive()); + assertEquals(-1, s.getLastAudiblyAlertedMs()); + } + + /** + * Tests the case where the user re-posts a {@link Notification} with looping sound where + * {@link Notification.Builder#setOnlyAlertOnce(true)} has been called. This should silence + * the sound associated with the notification. + * @throws Exception + */ + @Test + public void testNoisyOnceUpdateDoesCancelAudio() throws Exception { + NotificationRecord r = getInsistentBeepyNotification(); + NotificationRecord s = getInsistentBeepyOnceNotification(); + s.isUpdate = true; + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS); + + verifyStopAudio(); + } + + @Test + public void testQuietUpdateDoesNotCancelAudioFromOther() throws Exception { + NotificationRecord r = getBeepyNotification(); + NotificationRecord s = getQuietNotification(); + s.isUpdate = true; + NotificationRecord other = getNoisyOtherNotification(); + + // set up internal state + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + mAttentionHelper.buzzBeepBlinkLocked(other, DEFAULT_SIGNALS); // this takes the audio stream + Mockito.reset(mRingtonePlayer); + + // should not stop noise, since we no longer own it + mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS); // this no longer owns the stream + verifyNeverStopAudio(); + assertTrue(other.isInterruptive()); + assertNotEquals(-1, other.getLastAudiblyAlertedMs()); + } + + @Test + public void testQuietInterloperDoesNotCancelAudio() throws Exception { + NotificationRecord r = getBeepyNotification(); + NotificationRecord other = getQuietOtherNotification(); + + // set up internal state + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + Mockito.reset(mRingtonePlayer); + + // should not stop noise, since it does not own it + mAttentionHelper.buzzBeepBlinkLocked(other, DEFAULT_SIGNALS); + verifyNeverStopAudio(); + } + + @Test + public void testQuietUpdateCancelsAudio() throws Exception { + NotificationRecord r = getBeepyNotification(); + NotificationRecord s = getQuietNotification(); + s.isUpdate = true; + + // set up internal state + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + Mockito.reset(mRingtonePlayer); + + // quiet update should stop making noise + mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS); + verifyStopAudio(); + assertFalse(s.isInterruptive()); + assertEquals(-1, s.getLastAudiblyAlertedMs()); + } + + @Test + public void testQuietOnceUpdateCancelsAudio() throws Exception { + NotificationRecord r = getBeepyNotification(); + NotificationRecord s = getQuietOnceNotification(); + s.isUpdate = true; + + // set up internal state + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + Mockito.reset(mRingtonePlayer); + + // stop making noise - this is a weird corner case, but quiet should override once + mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS); + verifyStopAudio(); + assertFalse(s.isInterruptive()); + assertEquals(-1, s.getLastAudiblyAlertedMs()); + } + + @Test + public void testInCallNotification() throws Exception { + NotificationRecord r = getBeepyNotification(); + + mAttentionHelper = spy(mAttentionHelper); + + // set up internal state + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + Mockito.reset(mRingtonePlayer); + + mAttentionHelper.setInCallStateOffHook(true); + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verify(mAttentionHelper, times(1)).playInCallNotification(); + verifyNeverBeep(); // doesn't play normal beep + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testNoDemoteSoundToVibrateIfVibrateGiven() throws Exception { + NotificationRecord r = getBuzzyBeepyNotification(); + assertTrue(r.getSound() != null); + + // the phone is quiet + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE); + when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyDelayedVibrate(r.getVibration()); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testNoDemoteSoundToVibrateIfNonNotificationStream() throws Exception { + NotificationRecord r = getBeepyNotification(); + assertTrue(r.getSound() != null); + assertNull(r.getVibration()); + + // the phone is quiet + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE); + when(mAudioManager.getStreamVolume(anyInt())).thenReturn(1); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyNeverVibrate(); + verifyBeepUnlooped(); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testDemoteSoundToVibrate() throws Exception { + NotificationRecord r = getBeepyNotification(); + assertTrue(r.getSound() != null); + assertNull(r.getVibration()); + + // the phone is quiet + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE); + when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyDelayedVibrate( + mAttentionHelper.getVibratorHelper().createFallbackVibration( + /* insistent= */ false)); + verify(mRingtonePlayer, never()).playAsync(anyObject(), anyObject(), anyBoolean(), + anyObject()); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testDemoteInsistentSoundToVibrate() throws Exception { + NotificationRecord r = getInsistentBeepyNotification(); + assertTrue(r.getSound() != null); + assertNull(r.getVibration()); + + // the phone is quiet + when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0); + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyDelayedVibrateLooped(); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testVibrate() throws Exception { + NotificationRecord r = getBuzzyNotification(); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyNeverBeep(); + verifyVibrate(); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testInsistentVibrate() { + NotificationRecord r = getInsistentBuzzyNotification(); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verifyVibrateLooped(); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testVibrateTwice() { + NotificationRecord r = getBuzzyNotification(); + + // set up internal state + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + Mockito.reset(mVibrator); + + // update should vibrate + r.isUpdate = true; + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verifyVibrate(); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testPostSilently() throws Exception { + NotificationRecord r = getBuzzyNotification(); + r.setPostSilently(true); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyNeverBeep(); + assertFalse(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testGroupAlertSummarySilenceChild() throws Exception { + NotificationRecord child = getBeepyNotificationRecord("a", GROUP_ALERT_SUMMARY); + + mAttentionHelper.buzzBeepBlinkLocked(child, DEFAULT_SIGNALS); + + verifyNeverBeep(); + assertFalse(child.isInterruptive()); + assertEquals(-1, child.getLastAudiblyAlertedMs()); + } + + @Test + public void testGroupAlertSummaryNoSilenceSummary() throws Exception { + NotificationRecord summary = getBeepyNotificationRecord("a", GROUP_ALERT_SUMMARY); + summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY; + + mAttentionHelper.buzzBeepBlinkLocked(summary, DEFAULT_SIGNALS); + + verifyBeepUnlooped(); + // summaries are never interruptive for notification counts + assertFalse(summary.isInterruptive()); + assertNotEquals(-1, summary.getLastAudiblyAlertedMs()); + } + + @Test + public void testGroupAlertSummaryNoSilenceNonGroupChild() throws Exception { + NotificationRecord nonGroup = getBeepyNotificationRecord(null, GROUP_ALERT_SUMMARY); + + mAttentionHelper.buzzBeepBlinkLocked(nonGroup, DEFAULT_SIGNALS); + + verifyBeepUnlooped(); + assertTrue(nonGroup.isInterruptive()); + assertNotEquals(-1, nonGroup.getLastAudiblyAlertedMs()); + } + + @Test + public void testGroupAlertChildSilenceSummary() throws Exception { + NotificationRecord summary = getBeepyNotificationRecord("a", GROUP_ALERT_CHILDREN); + summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY; + + mAttentionHelper.buzzBeepBlinkLocked(summary, DEFAULT_SIGNALS); + + verifyNeverBeep(); + assertFalse(summary.isInterruptive()); + assertEquals(-1, summary.getLastAudiblyAlertedMs()); + } + + @Test + public void testGroupAlertChildNoSilenceChild() throws Exception { + NotificationRecord child = getBeepyNotificationRecord("a", GROUP_ALERT_CHILDREN); + + mAttentionHelper.buzzBeepBlinkLocked(child, DEFAULT_SIGNALS); + + verifyBeepUnlooped(); + assertTrue(child.isInterruptive()); + assertNotEquals(-1, child.getLastAudiblyAlertedMs()); + } + + @Test + public void testGroupAlertChildNoSilenceNonGroupSummary() throws Exception { + NotificationRecord nonGroup = getBeepyNotificationRecord(null, GROUP_ALERT_CHILDREN); + + mAttentionHelper.buzzBeepBlinkLocked(nonGroup, DEFAULT_SIGNALS); + + verifyBeepUnlooped(); + assertTrue(nonGroup.isInterruptive()); + assertNotEquals(-1, nonGroup.getLastAudiblyAlertedMs()); + } + + @Test + public void testGroupAlertAllNoSilenceGroup() throws Exception { + NotificationRecord group = getBeepyNotificationRecord("a", GROUP_ALERT_ALL); + + mAttentionHelper.buzzBeepBlinkLocked(group, DEFAULT_SIGNALS); + + verifyBeepUnlooped(); + assertTrue(group.isInterruptive()); + assertNotEquals(-1, group.getLastAudiblyAlertedMs()); + } + + @Test + public void testHonorAlertOnlyOnceForBuzz() throws Exception { + NotificationRecord r = getBuzzyNotification(); + NotificationRecord s = getBuzzyOnceNotification(); + s.isUpdate = true; + + // set up internal state + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + Mockito.reset(mVibrator); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + + // update should not beep + mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS); + verifyNeverVibrate(); + assertFalse(s.isInterruptive()); + assertEquals(-1, s.getLastAudiblyAlertedMs()); + } + + @Test + public void testNoisyUpdateDoesNotCancelVibrate() throws Exception { + NotificationRecord r = getBuzzyNotification(); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + r.isUpdate = true; + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyNeverStopVibrate(); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testNoisyOnceUpdateDoesNotCancelVibrate() throws Exception { + NotificationRecord r = getBuzzyNotification(); + NotificationRecord s = getBuzzyOnceNotification(); + s.isUpdate = true; + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS); + + verifyNeverStopVibrate(); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + assertFalse(s.isInterruptive()); + assertEquals(-1, s.getLastAudiblyAlertedMs()); + } + + @Test + public void testQuietUpdateDoesNotCancelVibrateFromOther() throws Exception { + NotificationRecord r = getBuzzyNotification(); + NotificationRecord s = getQuietNotification(); + s.isUpdate = true; + NotificationRecord other = getNoisyOtherNotification(); + + // set up internal state + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + // this takes the vibrate stream + mAttentionHelper.buzzBeepBlinkLocked(other, DEFAULT_SIGNALS); + Mockito.reset(mVibrator); + + // should not stop vibrate, since we no longer own it + mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS); // this no longer owns the stream + verifyNeverStopVibrate(); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + assertTrue(other.isInterruptive()); + assertNotEquals(-1, other.getLastAudiblyAlertedMs()); + assertFalse(s.isInterruptive()); + assertEquals(-1, s.getLastAudiblyAlertedMs()); + } + + @Test + public void testQuietInterloperDoesNotCancelVibrate() throws Exception { + NotificationRecord r = getBuzzyNotification(); + NotificationRecord other = getQuietOtherNotification(); + + // set up internal state + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + Mockito.reset(mVibrator); + + // should not stop noise, since it does not own it + mAttentionHelper.buzzBeepBlinkLocked(other, DEFAULT_SIGNALS); + verifyNeverStopVibrate(); + assertFalse(other.isInterruptive()); + assertEquals(-1, other.getLastAudiblyAlertedMs()); + } + + @Test + public void testQuietUpdateCancelsVibrate() { + NotificationRecord r = getBuzzyNotification(); + NotificationRecord s = getQuietNotification(); + s.isUpdate = true; + + // set up internal state + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verifyVibrate(); + + // quiet update should stop making noise + mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS); + verifyStopVibrate(); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + assertFalse(s.isInterruptive()); + assertEquals(-1, s.getLastAudiblyAlertedMs()); + } + + @Test + public void testQuietOnceUpdateCancelVibrate() throws Exception { + NotificationRecord r = getBuzzyNotification(); + NotificationRecord s = getQuietOnceNotification(); + s.isUpdate = true; + + // set up internal state + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verifyVibrate(); + + // stop making noise - this is a weird corner case, but quiet should override once + mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS); + verifyStopVibrate(); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + assertFalse(s.isInterruptive()); + assertEquals(-1, s.getLastAudiblyAlertedMs()); + } + + @Test + public void testQuietUpdateCancelsDemotedVibrate() throws Exception { + NotificationRecord r = getBeepyNotification(); + NotificationRecord s = getQuietNotification(); + + // the phone is quiet + when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0); + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verifyDelayedVibrate(mAttentionHelper.getVibratorHelper().createFallbackVibration(false)); + + // quiet update should stop making noise + mAttentionHelper.buzzBeepBlinkLocked(s, DEFAULT_SIGNALS); + verifyStopVibrate(); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + assertFalse(s.isInterruptive()); + assertEquals(-1, s.getLastAudiblyAlertedMs()); + } + + @Test + public void testEmptyUriSoundTreatedAsNoSound() throws Exception { + NotificationChannel channel = new NotificationChannel("test", "test", IMPORTANCE_HIGH); + channel.setSound(Uri.EMPTY, null); + final Notification n = new Builder(getContext(), "test") + .setSmallIcon(android.R.drawable.sym_def_app_icon).build(); + + StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid, + mPid, n, mUser, null, System.currentTimeMillis()); + NotificationRecord r = new NotificationRecord(getContext(), sbn, channel); + mService.addNotification(r); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verifyNeverBeep(); + assertFalse(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testRepeatedSoundOverLimitMuted() throws Exception { + when(mUsageStats.isAlertRateLimited(any())).thenReturn(true); + + NotificationRecord r = getBeepyNotification(); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verifyNeverBeep(); + assertFalse(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testPostingSilentNotificationDoesNotAffectRateLimiting() throws Exception { + NotificationRecord r = getQuietNotification(); + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verify(mUsageStats, never()).isAlertRateLimited(any()); + } + + @Test + public void testPostingGroupSuppressedDoesNotAffectRateLimiting() throws Exception { + NotificationRecord summary = getBeepyNotificationRecord("a", GROUP_ALERT_CHILDREN); + summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY; + + mAttentionHelper.buzzBeepBlinkLocked(summary, DEFAULT_SIGNALS); + verify(mUsageStats, never()).isAlertRateLimited(any()); + } + + @Test + public void testGroupSuppressionFailureDoesNotAffectRateLimiting() { + NotificationRecord summary = getBeepyNotificationRecord("a", GROUP_ALERT_SUMMARY); + summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY; + + mAttentionHelper.buzzBeepBlinkLocked(summary, DEFAULT_SIGNALS); + verify(mUsageStats, times(1)).isAlertRateLimited(any()); + } + + @Test + public void testCrossUserSoundMuted() throws Exception { + final Notification n = new Builder(getContext(), "test") + .setSmallIcon(android.R.drawable.sym_def_app_icon).build(); + + int userId = mUser.getIdentifier() + 1; + StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid, + mPid, n, UserHandle.of(userId), null, System.currentTimeMillis()); + NotificationRecord r = new NotificationRecord(getContext(), sbn, + new NotificationChannel("test", "test", IMPORTANCE_HIGH)); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verifyNeverBeep(); + assertFalse(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testA11yMinInitialPost() throws Exception { + NotificationRecord r = getQuietNotification(); + r.setSystemImportance(IMPORTANCE_MIN); + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verify(mAccessibilityService, never()).sendAccessibilityEvent(any(), anyInt()); + } + + @Test + public void testA11yQuietInitialPost() throws Exception { + NotificationRecord r = getQuietNotification(); + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt()); + } + + @Test + public void testA11yQuietUpdate() throws Exception { + NotificationRecord r = getQuietNotification(); + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + r.isUpdate = true; + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt()); + } + + @Test + public void testA11yCrossUserEventNotSent() throws Exception { + final Notification n = new Builder(getContext(), "test") + .setSmallIcon(android.R.drawable.sym_def_app_icon).build(); + int userId = mUser.getIdentifier() + 1; + StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid, + mPid, n, UserHandle.of(userId), null, System.currentTimeMillis()); + NotificationRecord r = new NotificationRecord(getContext(), sbn, + new NotificationChannel("test", "test", IMPORTANCE_HIGH)); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verify(mAccessibilityService, never()).sendAccessibilityEvent(any(), anyInt()); + } + + @Test + public void testLightsScreenOn() { + mAttentionHelper.setScreenOn(true); + NotificationRecord r = getLightsNotification(); + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verifyNeverLights(); + assertTrue(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testLightsInCall() { + mAttentionHelper.setInCallStateOffHook(true); + NotificationRecord r = getLightsNotification(); + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verifyNeverLights(); + assertFalse(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testLightsSilentUpdate() { + NotificationRecord r = getLightsOnceNotification(); + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verifyLights(); + assertTrue(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + + r = getLightsOnceNotification(); + r.isUpdate = true; + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + // checks that lights happened once, i.e. this new call didn't trigger them again + verifyLights(); + assertFalse(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testLightsUnimportant() { + NotificationRecord r = getLightsNotification(); + r.setSystemImportance(IMPORTANCE_LOW); + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verifyNeverLights(); + assertFalse(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testLightsNoLights() { + NotificationRecord r = getQuietNotification(); + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verifyNeverLights(); + assertFalse(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testLightsNoLightOnDevice() { + mAttentionHelper.mHasLight = false; + NotificationRecord r = getLightsNotification(); + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verifyNeverLights(); + assertFalse(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testLightsLightsOffGlobally() { + mAttentionHelper.mNotificationPulseEnabled = false; + NotificationRecord r = getLightsNotification(); + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verifyNeverLights(); + assertFalse(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testLightsDndIntercepted() { + NotificationRecord r = getLightsNotification(); + r.setSuppressedVisualEffects(SUPPRESSED_EFFECT_LIGHTS); + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verifyNeverLights(); + assertFalse(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testGroupAlertSummaryNoLightsChild() { + NotificationRecord child = getLightsNotificationRecord("a", GROUP_ALERT_SUMMARY); + + mAttentionHelper.buzzBeepBlinkLocked(child, DEFAULT_SIGNALS); + + verifyNeverLights(); + assertFalse(child.isInterruptive()); + assertEquals(-1, child.getLastAudiblyAlertedMs()); + } + + @Test + public void testGroupAlertSummaryLightsSummary() { + NotificationRecord summary = getLightsNotificationRecord("a", GROUP_ALERT_SUMMARY); + summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY; + + mAttentionHelper.buzzBeepBlinkLocked(summary, DEFAULT_SIGNALS); + + verifyLights(); + // summaries should never count for interruptiveness counts + assertFalse(summary.isInterruptive()); + assertEquals(-1, summary.getLastAudiblyAlertedMs()); + } + + @Test + public void testGroupAlertSummaryLightsNonGroupChild() { + NotificationRecord nonGroup = getLightsNotificationRecord(null, GROUP_ALERT_SUMMARY); + + mAttentionHelper.buzzBeepBlinkLocked(nonGroup, DEFAULT_SIGNALS); + + verifyLights(); + assertTrue(nonGroup.isInterruptive()); + assertEquals(-1, nonGroup.getLastAudiblyAlertedMs()); + } + + @Test + public void testGroupAlertChildNoLightsSummary() { + NotificationRecord summary = getLightsNotificationRecord("a", GROUP_ALERT_CHILDREN); + summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY; + + mAttentionHelper.buzzBeepBlinkLocked(summary, DEFAULT_SIGNALS); + + verifyNeverLights(); + assertFalse(summary.isInterruptive()); + assertEquals(-1, summary.getLastAudiblyAlertedMs()); + } + + @Test + public void testGroupAlertChildLightsChild() { + NotificationRecord child = getLightsNotificationRecord("a", GROUP_ALERT_CHILDREN); + + mAttentionHelper.buzzBeepBlinkLocked(child, DEFAULT_SIGNALS); + + verifyLights(); + assertTrue(child.isInterruptive()); + assertEquals(-1, child.getLastAudiblyAlertedMs()); + } + + @Test + public void testGroupAlertChildLightsNonGroupSummary() { + NotificationRecord nonGroup = getLightsNotificationRecord(null, GROUP_ALERT_CHILDREN); + + mAttentionHelper.buzzBeepBlinkLocked(nonGroup, DEFAULT_SIGNALS); + + verifyLights(); + assertTrue(nonGroup.isInterruptive()); + assertEquals(-1, nonGroup.getLastAudiblyAlertedMs()); + } + + @Test + public void testGroupAlertAllLightsGroup() { + NotificationRecord group = getLightsNotificationRecord("a", GROUP_ALERT_ALL); + + mAttentionHelper.buzzBeepBlinkLocked(group, DEFAULT_SIGNALS); + + verifyLights(); + assertTrue(group.isInterruptive()); + assertEquals(-1, group.getLastAudiblyAlertedMs()); + } + + @Test + public void testLightsCheckCurrentUser() { + final Notification n = new Builder(getContext(), "test") + .setSmallIcon(android.R.drawable.sym_def_app_icon).build(); + int userId = mUser.getIdentifier() + 10; + StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid, + mPid, n, UserHandle.of(userId), null, System.currentTimeMillis()); + NotificationRecord r = new NotificationRecord(getContext(), sbn, + new NotificationChannel("test", "test", IMPORTANCE_HIGH)); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + verifyNeverLights(); + assertFalse(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testListenerHintCall() throws Exception { + NotificationChannel ringtoneChannel = + new NotificationChannel("ringtone", "", IMPORTANCE_HIGH); + ringtoneChannel.setSound(Settings.System.DEFAULT_RINGTONE_URI, + new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build()); + NotificationRecord r = getCallRecord(1, ringtoneChannel, true); + + mAttentionHelper.buzzBeepBlinkLocked(r, new NotificationAttentionHelper.Signals(false, + NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS)); + + verifyNeverBeep(); + } + + @Test + public void testListenerHintCall_notificationSound() throws Exception { + NotificationRecord r = getBeepyNotification(); + + mAttentionHelper.buzzBeepBlinkLocked(r, new NotificationAttentionHelper.Signals(false, + NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS)); + + verifyBeepUnlooped(); + } + + @Test + public void testListenerHintNotification() throws Exception { + NotificationRecord r = getBeepyNotification(); + + mAttentionHelper.buzzBeepBlinkLocked(r, new NotificationAttentionHelper.Signals(false, + NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS)); + + verifyNeverBeep(); + } + + @Test + public void testListenerHintBoth() throws Exception { + NotificationChannel ringtoneChannel = + new NotificationChannel("ringtone", "", IMPORTANCE_HIGH); + ringtoneChannel.setSound(Settings.System.DEFAULT_RINGTONE_URI, + new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build()); + NotificationRecord r = getCallRecord(1, ringtoneChannel, true); + NotificationRecord s = getBeepyNotification(); + + mAttentionHelper.buzzBeepBlinkLocked(r, new NotificationAttentionHelper.Signals(false, + NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS + | NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS)); + mAttentionHelper.buzzBeepBlinkLocked(s, new NotificationAttentionHelper.Signals(false, + NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS + | NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS)); + + verifyNeverBeep(); + } + + @Test + public void testListenerHintNotification_callSound() throws Exception { + NotificationChannel ringtoneChannel = + new NotificationChannel("ringtone", "", IMPORTANCE_HIGH); + ringtoneChannel.setSound(Settings.System.DEFAULT_RINGTONE_URI, + new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build()); + NotificationRecord r = getCallRecord(1, ringtoneChannel, true); + + mAttentionHelper.buzzBeepBlinkLocked(r, new NotificationAttentionHelper.Signals(false, + NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS)); + + verifyBeepLooped(); + } + + @Test + public void testCannotInterruptRingtoneInsistentBeep() throws Exception { + NotificationChannel ringtoneChannel = + new NotificationChannel("ringtone", "", IMPORTANCE_HIGH); + ringtoneChannel.setSound(Settings.System.DEFAULT_RINGTONE_URI, + new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build()); + NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, true); + mService.addNotification(ringtoneNotification); + + mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS); + verifyBeepLooped(); + + NotificationRecord interrupter = getBeepyOtherNotification(); + assertTrue(mAttentionHelper.shouldMuteNotificationLocked(interrupter, DEFAULT_SIGNALS)); + mAttentionHelper.buzzBeepBlinkLocked(interrupter, DEFAULT_SIGNALS); + + verifyBeep(1); + + assertFalse(interrupter.isInterruptive()); + assertEquals(-1, interrupter.getLastAudiblyAlertedMs()); + } + + @Test + public void testRingtoneInsistentBeep_canUpdate() throws Exception { + NotificationChannel ringtoneChannel = + new NotificationChannel("ringtone", "", IMPORTANCE_HIGH); + ringtoneChannel.setSound(Uri.fromParts("a", "b", "c"), + new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build()); + ringtoneChannel.enableVibration(true); + NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, true); + mService.addNotification(ringtoneNotification); + assertFalse(mAttentionHelper.shouldMuteNotificationLocked(ringtoneNotification, + DEFAULT_SIGNALS)); + mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS); + verifyBeepLooped(); + verifyDelayedVibrateLooped(); + Mockito.reset(mVibrator); + Mockito.reset(mRingtonePlayer); + + assertFalse(mAttentionHelper.shouldMuteNotificationLocked(ringtoneNotification, + DEFAULT_SIGNALS)); + mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS); + + // beep wasn't reset + verifyNeverBeep(); + verifyNeverVibrate(); + verifyNeverStopAudio(); + verifyNeverStopVibrate(); + } + + @Test + public void testRingtoneInsistentBeep_clearEffectsStopsSoundAndVibration() throws Exception { + NotificationChannel ringtoneChannel = + new NotificationChannel("ringtone", "", IMPORTANCE_HIGH); + ringtoneChannel.setSound(Uri.fromParts("a", "b", "c"), + new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build()); + ringtoneChannel.enableVibration(true); + NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, true); + mService.addNotification(ringtoneNotification); + assertFalse(mAttentionHelper.shouldMuteNotificationLocked(ringtoneNotification, + DEFAULT_SIGNALS)); + mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS); + verifyBeepLooped(); + verifyDelayedVibrateLooped(); + + mAttentionHelper.clearSoundLocked(); + mAttentionHelper.clearVibrateLocked(); + + verifyStopAudio(); + verifyStopVibrate(); + } + + @Test + public void testRingtoneInsistentBeep_neverVibratesWhenEffectsClearedBeforeDelay() + throws Exception { + NotificationChannel ringtoneChannel = + new NotificationChannel("ringtone", "", IMPORTANCE_HIGH); + ringtoneChannel.setSound(Uri.fromParts("a", "b", "c"), + new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build()); + ringtoneChannel.enableVibration(true); + NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, true); + mService.addNotification(ringtoneNotification); + assertFalse(mAttentionHelper.shouldMuteNotificationLocked(ringtoneNotification, + DEFAULT_SIGNALS)); + mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS); + verifyBeepLooped(); + verifyNeverVibrate(); + + mAttentionHelper.clearSoundLocked(); + mAttentionHelper.clearVibrateLocked(); + + verifyStopAudio(); + verifyDelayedNeverVibrate(); + } + + @Test + public void testCannotInterruptRingtoneInsistentBuzz() { + NotificationChannel ringtoneChannel = + new NotificationChannel("ringtone", "", IMPORTANCE_HIGH); + ringtoneChannel.setSound(Uri.EMPTY, + new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build()); + ringtoneChannel.enableVibration(true); + NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, true); + assertFalse(mAttentionHelper.shouldMuteNotificationLocked(ringtoneNotification, + DEFAULT_SIGNALS)); + + mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS); + verifyVibrateLooped(); + + NotificationRecord interrupter = getBuzzyOtherNotification(); + assertTrue(mAttentionHelper.shouldMuteNotificationLocked(interrupter, DEFAULT_SIGNALS)); + mAttentionHelper.buzzBeepBlinkLocked(interrupter, DEFAULT_SIGNALS); + + verifyVibrate(1); + + assertFalse(interrupter.isInterruptive()); + assertEquals(-1, interrupter.getLastAudiblyAlertedMs()); + } + + @Test + public void testCanInterruptRingtoneNonInsistentBeep() throws Exception { + NotificationChannel ringtoneChannel = + new NotificationChannel("ringtone", "", IMPORTANCE_HIGH); + ringtoneChannel.setSound(Settings.System.DEFAULT_RINGTONE_URI, + new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build()); + NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, false); + + mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS); + verifyBeepUnlooped(); + + NotificationRecord interrupter = getBeepyOtherNotification(); + mAttentionHelper.buzzBeepBlinkLocked(interrupter, DEFAULT_SIGNALS); + + verifyBeep(2); + + assertTrue(interrupter.isInterruptive()); + } + + @Test + public void testCanInterruptRingtoneNonInsistentBuzz() { + NotificationChannel ringtoneChannel = + new NotificationChannel("ringtone", "", IMPORTANCE_HIGH); + ringtoneChannel.setSound(null, + new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build()); + ringtoneChannel.enableVibration(true); + NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, false); + + mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS); + verifyVibrate(); + + NotificationRecord interrupter = getBuzzyOtherNotification(); + mAttentionHelper.buzzBeepBlinkLocked(interrupter, DEFAULT_SIGNALS); + + verifyVibrate(2); + + assertTrue(interrupter.isInterruptive()); + } + + @Test + public void testRingtoneInsistentBeep_doesNotBlockFutureSoundsOnceStopped() throws Exception { + NotificationChannel ringtoneChannel = + new NotificationChannel("ringtone", "", IMPORTANCE_HIGH); + ringtoneChannel.setSound(Settings.System.DEFAULT_RINGTONE_URI, + new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build()); + NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, true); + + mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS); + verifyBeepLooped(); + + mAttentionHelper.clearSoundLocked(); + + NotificationRecord interrupter = getBeepyOtherNotification(); + mAttentionHelper.buzzBeepBlinkLocked(interrupter, DEFAULT_SIGNALS); + + verifyBeep(2); + + assertTrue(interrupter.isInterruptive()); + } + + @Test + public void testRingtoneInsistentBuzz_doesNotBlockFutureSoundsOnceStopped() { + NotificationChannel ringtoneChannel = + new NotificationChannel("ringtone", "", IMPORTANCE_HIGH); + ringtoneChannel.setSound(null, + new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build()); + ringtoneChannel.enableVibration(true); + NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, true); + + mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS); + verifyVibrateLooped(); + + mAttentionHelper.clearVibrateLocked(); + + NotificationRecord interrupter = getBuzzyOtherNotification(); + mAttentionHelper.buzzBeepBlinkLocked(interrupter, DEFAULT_SIGNALS); + + verifyVibrate(2); + + assertTrue(interrupter.isInterruptive()); + } + + @Test + public void testCanInterruptNonRingtoneInsistentBeep() throws Exception { + NotificationChannel fakeRingtoneChannel = + new NotificationChannel("ringtone", "", IMPORTANCE_HIGH); + NotificationRecord ringtoneNotification = getCallRecord(1, fakeRingtoneChannel, true); + + mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS); + verifyBeepLooped(); + + NotificationRecord interrupter = getBeepyOtherNotification(); + mAttentionHelper.buzzBeepBlinkLocked(interrupter, DEFAULT_SIGNALS); + + verifyBeep(2); + + assertTrue(interrupter.isInterruptive()); + } + + @Test + public void testCanInterruptNonRingtoneInsistentBuzz() { + NotificationChannel fakeRingtoneChannel = + new NotificationChannel("ringtone", "", IMPORTANCE_HIGH); + fakeRingtoneChannel.enableVibration(true); + fakeRingtoneChannel.setSound(null, + new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION).build()); + NotificationRecord ringtoneNotification = getCallRecord(1, fakeRingtoneChannel, true); + + mAttentionHelper.buzzBeepBlinkLocked(ringtoneNotification, DEFAULT_SIGNALS); + + NotificationRecord interrupter = getBuzzyOtherNotification(); + mAttentionHelper.buzzBeepBlinkLocked(interrupter, DEFAULT_SIGNALS); + + verifyVibrate(2); + + assertTrue(interrupter.isInterruptive()); + } + + @Test + public void testBubbleSuppressedNotificationDoesntMakeSound() { + Notification.BubbleMetadata metadata = new Notification.BubbleMetadata.Builder( + mock(PendingIntent.class), mock(Icon.class)) + .build(); + + NotificationRecord record = getBuzzyNotification(); + metadata.setFlags(Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION); + record.getNotification().setBubbleMetadata(metadata); + record.setAllowBubble(true); + record.getNotification().flags |= FLAG_BUBBLE; + record.isUpdate = true; + record.setInterruptive(false); + + mAttentionHelper.buzzBeepBlinkLocked(record, DEFAULT_SIGNALS); + verifyNeverVibrate(); + } + + @Test + public void testOverflowBubbleSuppressedNotificationDoesntMakeSound() { + Notification.BubbleMetadata metadata = new Notification.BubbleMetadata.Builder( + mock(PendingIntent.class), mock(Icon.class)) + .build(); + + NotificationRecord record = getBuzzyNotification(); + metadata.setFlags(Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION); + record.getNotification().setBubbleMetadata(metadata); + record.setFlagBubbleRemoved(true); + record.setAllowBubble(true); + record.isUpdate = true; + record.setInterruptive(false); + + mAttentionHelper.buzzBeepBlinkLocked(record, DEFAULT_SIGNALS); + verifyNeverVibrate(); + } + + @Test + public void testBubbleUpdateMakesSound() { + Notification.BubbleMetadata metadata = new Notification.BubbleMetadata.Builder( + mock(PendingIntent.class), mock(Icon.class)) + .build(); + + NotificationRecord record = getBuzzyNotification(); + record.getNotification().setBubbleMetadata(metadata); + record.setAllowBubble(true); + record.getNotification().flags |= FLAG_BUBBLE; + record.isUpdate = true; + record.setInterruptive(true); + + mAttentionHelper.buzzBeepBlinkLocked(record, DEFAULT_SIGNALS); + verifyVibrate(1); + } + + @Test + public void testNewBubbleSuppressedNotifMakesSound() { + Notification.BubbleMetadata metadata = new Notification.BubbleMetadata.Builder( + mock(PendingIntent.class), mock(Icon.class)) + .build(); + + NotificationRecord record = getBuzzyNotification(); + metadata.setFlags(Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION); + record.getNotification().setBubbleMetadata(metadata); + record.setAllowBubble(true); + record.getNotification().flags |= FLAG_BUBBLE; + record.isUpdate = false; + record.setInterruptive(true); + + mAttentionHelper.buzzBeepBlinkLocked(record, DEFAULT_SIGNALS); + verifyVibrate(1); + } + + @Test + public void testStartFlashNotificationEvent_receiveBeepyNotification() throws Exception { + NotificationRecord r = getBeepyNotification(); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyBeepUnlooped(); + verifyNeverVibrate(); + verify(mAccessibilityService).startFlashNotificationEvent(any(), anyInt(), + eq(r.getSbn().getPackageName())); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testStartFlashNotificationEvent_receiveBuzzyNotification() throws Exception { + NotificationRecord r = getBuzzyNotification(); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyNeverBeep(); + verifyVibrate(); + verify(mAccessibilityService).startFlashNotificationEvent(any(), anyInt(), + eq(r.getSbn().getPackageName())); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testStartFlashNotificationEvent_receiveBuzzyBeepyNotification() throws Exception { + NotificationRecord r = getBuzzyBeepyNotification(); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyBeepUnlooped(); + verifyDelayedVibrate(r.getVibration()); + verify(mAccessibilityService).startFlashNotificationEvent(any(), anyInt(), + eq(r.getSbn().getPackageName())); + assertTrue(r.isInterruptive()); + assertNotEquals(-1, r.getLastAudiblyAlertedMs()); + } + + @Test + public void testStartFlashNotificationEvent_receiveBuzzyBeepyNotification_ringerModeSilent() + throws Exception { + NotificationRecord r = getBuzzyBeepyNotification(); + when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT); + when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0); + + mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS); + + verifyNeverBeep(); + verifyNeverVibrate(); + verify(mAccessibilityService).startFlashNotificationEvent(any(), anyInt(), + eq(r.getSbn().getPackageName())); + assertFalse(r.isInterruptive()); + assertEquals(-1, r.getLastAudiblyAlertedMs()); + } + + static class VibrateRepeatMatcher implements ArgumentMatcher<VibrationEffect> { + private final int mRepeatIndex; + + VibrateRepeatMatcher(int repeatIndex) { + mRepeatIndex = repeatIndex; + } + + @Override + public boolean matches(VibrationEffect actual) { + if (actual instanceof VibrationEffect.Composed + && ((VibrationEffect.Composed) actual).getRepeatIndex() == mRepeatIndex) { + return true; + } + // All non-waveform effects are essentially one shots. + return mRepeatIndex == -1; + } + + @Override + public String toString() { + return "repeatIndex=" + mRepeatIndex; + } + } +} diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 4576e9be07ad..9543a2de1e13 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -84,6 +84,7 @@ import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; +import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR; import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.FSI_FORCE_DEMOTE; import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.SHOW_STICKY_HUN_FOR_DENIED_FSI; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN; @@ -272,6 +273,7 @@ import com.google.common.collect.ImmutableList; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -279,6 +281,7 @@ import org.mockito.ArgumentMatcher; import org.mockito.ArgumentMatchers; import org.mockito.InOrder; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; @@ -372,6 +375,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { private DevicePolicyManagerInternal mDevicePolicyManager; @Mock private PowerManager mPowerManager; + @Mock + private LightsManager mLightsManager; private final ArrayList<WakeLock> mAcquiredWakeLocks = new ArrayList<>(); private final TestPostNotificationTrackerFactory mPostNotificationTrackerFactory = new TestPostNotificationTrackerFactory(); @@ -503,9 +508,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { setDpmAppOppsExemptFromDismissal(false); - mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger, - mNotificationInstanceIdSequence); - // Use this testable looper. mTestableLooper = TestableLooper.get(this); // MockPackageManager - default returns ApplicationInfo with matching calling UID @@ -527,8 +529,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { Object[] args = invocation.getArguments(); return (int) args[1] == mUid; }); - final LightsManager mockLightsManager = mock(LightsManager.class); - when(mockLightsManager.getLight(anyInt())).thenReturn(mock(LogicalLight.class)); + when(mLightsManager.getLight(anyInt())).thenReturn(mock(LogicalLight.class)); when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false); when(mUgmInternal.newUriPermissionOwner(anyString())).thenReturn(mPermOwner); @@ -601,6 +602,15 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { return wl; }); + // TODO (b/291907312): remove feature flag + mTestFlagResolver.setFlagOverride(ENABLE_ATTENTION_HELPER_REFACTOR, false); + initNMS(); + } + + private void initNMS() throws Exception { + mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger, + mNotificationInstanceIdSequence); + // apps allowed as convos mService.setStringArrayResourceValue(PKG_O); @@ -617,7 +627,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mWorkerHandler = spy(mService.new WorkerHandler(mTestableLooper.getLooper())); mService.init(mWorkerHandler, mRankingHandler, mPackageManager, mPackageManagerClient, - mockLightsManager, mListeners, mAssistants, mConditionProviders, mCompanionMgr, + mLightsManager, mListeners, mAssistants, mConditionProviders, mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager, mGroupHelper, mAm, mAtm, mAppUsageStats, mDevicePolicyManager, mUgm, mUgmInternal, mAppOpsManager, mUm, mHistoryManager, mStatsManager, @@ -628,11 +638,17 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // Return first true for RoleObserver main-thread check when(mMainLooper.isCurrentThread()).thenReturn(true).thenReturn(false); mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY, mMainLooper); + Mockito.reset(mHistoryManager); verify(mHistoryManager, never()).onBootPhaseAppsCanStart(); mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START, mMainLooper); verify(mHistoryManager).onBootPhaseAppsCanStart(); - mService.setAudioManager(mAudioManager); + // TODO b/291907312: remove feature flag + if (mTestFlagResolver.isEnabled(ENABLE_ATTENTION_HELPER_REFACTOR)) { + mService.mAttentionHelper.setAudioManager(mAudioManager); + } else { + mService.setAudioManager(mAudioManager); + } mStrongAuthTracker = mService.new StrongAuthTrackerFake(mContext); mService.setStrongAuthTracker(mStrongAuthTracker); @@ -1653,6 +1669,23 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testEnqueueNotificationWithTag_WritesExpectedLogs_NAHRefactor() throws Exception { + // TODO b/291907312: remove feature flag + mTestFlagResolver.setFlagOverride(ENABLE_ATTENTION_HELPER_REFACTOR, true); + // Cleanup NMS before re-initializing + if (mService != null) { + try { + mService.onDestroy(); + } catch (IllegalStateException | IllegalArgumentException e) { + // can throw if a broadcast receiver was never registered + } + } + initNMS(); + + testEnqueueNotificationWithTag_WritesExpectedLogs(); + } + + @Test public void testEnqueueNotificationWithTag_LogsOnMajorUpdates() throws Exception { final String tag = "testEnqueueNotificationWithTag_LogsOnMajorUpdates"; Notification original = new Notification.Builder(mContext, @@ -9015,6 +9048,24 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testOnBubbleMetadataChangedToSuppressNotification_soundStopped_NAHRefactor() + throws Exception { + // TODO b/291907312: remove feature flag + mTestFlagResolver.setFlagOverride(ENABLE_ATTENTION_HELPER_REFACTOR, true); + // Cleanup NMS before re-initializing + if (mService != null) { + try { + mService.onDestroy(); + } catch (IllegalStateException | IllegalArgumentException e) { + // can throw if a broadcast receiver was never registered + } + } + initNMS(); + + testOnBubbleMetadataChangedToSuppressNotification_soundStopped(); + } + + @Test public void testGrantInlineReplyUriPermission_recordExists() throws Exception { int userId = UserManager.isHeadlessSystemUserMode() ? UserHandle.getUserId(UID_HEADLESS) diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java index 6d46d9ccf02e..ef28ffa7da8f 100644 --- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java +++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java @@ -77,6 +77,7 @@ import android.os.PowerManagerInternal; import android.os.RemoteException; import android.os.UserHandle; import android.os.Vibrator; +import android.os.VibratorInfo; import android.service.dreams.DreamManagerInternal; import android.telecom.TelecomManager; import android.util.FeatureFlagUtils; @@ -138,6 +139,7 @@ class TestPhoneWindowManager { @Mock private TelecomManager mTelecomManager; @Mock private NotificationManager mNotificationManager; @Mock private Vibrator mVibrator; + @Mock private VibratorInfo mVibratorInfo; @Mock private PowerManager mPowerManager; @Mock private WindowManagerPolicy.WindowManagerFuncs mWindowManagerFuncsImpl; @Mock private InputMethodManagerInternal mInputMethodManagerInternal; @@ -246,6 +248,7 @@ class TestPhoneWindowManager { doReturn(mTelecomManager).when(mPhoneWindowManager).getTelecommService(); doNothing().when(mNotificationManager).silenceNotificationSound(); doReturn(mNotificationManager).when(mPhoneWindowManager).getNotificationService(); + doReturn(mVibratorInfo).when(mVibrator).getInfo(); doReturn(mVibrator).when(mContext).getSystemService(eq(Context.VIBRATOR_SERVICE)); final PowerManager.WakeLock wakeLock = mock(PowerManager.WakeLock.class); @@ -447,7 +450,7 @@ class TestPhoneWindowManager { } void overrideSearchManager(SearchManager searchManager) { - mPhoneWindowManager.mSearchManager = searchManager; + doReturn(searchManager).when(mContext).getSystemService(eq(SearchManager.class)); } void assumeResolveActivityNotNull() { 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 8ec3ac6ca3fd..0494dfdfb1ec 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -489,7 +489,7 @@ public class ActivityRecordTests extends WindowTestsBase { ensureActivityConfiguration(activity); verify(mAtm.getLifecycleManager(), never()) - .scheduleTransaction(any(), any(), isA(ActivityConfigurationChangeItem.class)); + .scheduleTransaction(any(), isA(ActivityConfigurationChangeItem.class)); } @Test @@ -519,7 +519,7 @@ public class ActivityRecordTests extends WindowTestsBase { final ActivityConfigurationChangeItem expected = ActivityConfigurationChangeItem.obtain(activity.token, newConfig); verify(mAtm.getLifecycleManager()).scheduleTransaction( - eq(activity.app.getThread()), eq(activity.token), eq(expected)); + eq(activity.app.getThread()), eq(expected)); } @Test @@ -599,7 +599,7 @@ public class ActivityRecordTests extends WindowTestsBase { final ActivityConfigurationChangeItem expected = ActivityConfigurationChangeItem.obtain(activity.token, newConfig); verify(mAtm.getLifecycleManager()).scheduleTransaction(eq(activity.app.getThread()), - eq(activity.token), eq(expected)); + eq(expected)); verify(displayRotation).onSetRequestedOrientation(); } @@ -817,7 +817,7 @@ public class ActivityRecordTests extends WindowTestsBase { final ActivityConfigurationChangeItem expected = ActivityConfigurationChangeItem.obtain(activity.token, newConfig); verify(mAtm.getLifecycleManager()).scheduleTransaction( - eq(activity.app.getThread()), eq(activity.token), eq(expected)); + eq(activity.app.getThread()), eq(expected)); } finally { stack.getDisplayArea().removeChild(stack); } @@ -1787,9 +1787,10 @@ public class ActivityRecordTests extends WindowTestsBase { final ActivityRecord activity = createActivityWithTask(); final WindowProcessController wpc = activity.app; setup.accept(activity); + clearInvocations(mAtm.getLifecycleManager()); activity.getTask().removeImmediately("test"); try { - verify(mAtm.getLifecycleManager()).scheduleTransaction(any(), eq(activity.token), + verify(mAtm.getLifecycleManager()).scheduleTransaction(any(), isA(DestroyActivityItem.class)); } catch (RemoteException ignored) { } diff --git a/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java b/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java index 28dd458a786c..a18dbaf39575 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java @@ -23,7 +23,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import android.app.IApplicationThread; import android.app.servertransaction.ClientTransaction; -import android.os.Binder; import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; @@ -40,8 +39,7 @@ public class ClientLifecycleManagerTests { @Test public void testScheduleAndRecycleBinderClientTransaction() throws Exception { - ClientTransaction item = spy(ClientTransaction.obtain(mock(IApplicationThread.class), - new Binder())); + ClientTransaction item = spy(ClientTransaction.obtain(mock(IApplicationThread.class))); ClientLifecycleManager clientLifecycleManager = new ClientLifecycleManager(); clientLifecycleManager.scheduleTransaction(item); @@ -51,8 +49,7 @@ public class ClientLifecycleManagerTests { @Test public void testScheduleNoRecycleNonBinderClientTransaction() throws Exception { - ClientTransaction item = spy(ClientTransaction.obtain(mock(IApplicationThread.Stub.class), - new Binder())); + ClientTransaction item = spy(ClientTransaction.obtain(mock(IApplicationThread.Stub.class))); ClientLifecycleManager clientLifecycleManager = new ClientLifecycleManager(); clientLifecycleManager.scheduleTransaction(item); diff --git a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java index 3d3531e92abe..d2eb1cc0222b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java @@ -31,7 +31,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; -import static com.android.server.wm.ContentRecorder.KEY_RECORD_TASK_FEATURE; import static com.google.common.truth.Truth.assertThat; @@ -51,25 +50,21 @@ import android.graphics.Point; import android.graphics.Rect; import android.os.IBinder; import android.platform.test.annotations.Presubmit; -import android.provider.DeviceConfig; import android.view.ContentRecordingSession; import android.view.DisplayInfo; import android.view.Gravity; import android.view.SurfaceControl; -import androidx.annotation.NonNull; import androidx.test.filters.SmallTest; import com.android.server.wm.ContentRecorder.MediaProjectionManagerWrapper; -import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import java.util.concurrent.CountDownLatch; /** * Tests for the {@link ContentRecorder} class. @@ -93,9 +88,6 @@ public class ContentRecorderTests extends WindowTestsBase { private ContentRecorder mContentRecorder; @Mock private MediaProjectionManagerWrapper mMediaProjectionManagerWrapper; private SurfaceControl mRecordedSurface; - // Handle feature flag. - private ConfigListener mConfigListener; - private CountDownLatch mLatch; @Before public void setUp() { MockitoAnnotations.initMocks(this); @@ -133,23 +125,11 @@ public class ContentRecorderTests extends WindowTestsBase { mWaitingDisplaySession.setVirtualDisplayId(displayId); mWaitingDisplaySession.setWaitingForConsent(true); - mConfigListener = new ConfigListener(); - DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER, - mContext.getMainExecutor(), mConfigListener); - mLatch = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER, KEY_RECORD_TASK_FEATURE, - "true", true); - // Skip unnecessary operations of relayout. spyOn(mWm.mWindowPlacerLocked); doNothing().when(mWm.mWindowPlacerLocked).performSurfacePlacement(anyBoolean()); } - @After - public void teardown() { - DeviceConfig.removeOnPropertiesChangedListener(mConfigListener); - } - @Test public void testIsCurrentlyRecording() { assertThat(mContentRecorder.isCurrentlyRecording()).isFalse(); @@ -184,24 +164,6 @@ public class ContentRecorderTests extends WindowTestsBase { } @Test - public void testUpdateRecording_task_featureDisabled() { - mLatch = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER, KEY_RECORD_TASK_FEATURE, - "false", false); - mContentRecorder.setContentRecordingSession(mTaskSession); - mContentRecorder.updateRecording(); - assertThat(mContentRecorder.isCurrentlyRecording()).isFalse(); - } - - @Test - public void testUpdateRecording_task_featureEnabled() { - // Feature already enabled; don't need to again. - mContentRecorder.setContentRecordingSession(mTaskSession); - mContentRecorder.updateRecording(); - assertThat(mContentRecorder.isCurrentlyRecording()).isTrue(); - } - - @Test public void testUpdateRecording_task_nullToken() { ContentRecordingSession session = mTaskSession; session.setVirtualDisplayId(mDisplaySession.getVirtualDisplayId()); @@ -703,13 +665,4 @@ public class ContentRecorderTests extends WindowTestsBase { anyInt()); return mirroredSurface; } - - private class ConfigListener implements DeviceConfig.OnPropertiesChangedListener { - @Override - public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) { - if (mLatch != null && properties.getKeyset().contains(KEY_RECORD_TASK_FEATURE)) { - mLatch.countDown(); - } - } - } } 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 1b44c01bfab5..2af67452283b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java @@ -571,8 +571,7 @@ public final class DisplayRotationCompatPolicyTests extends WindowTestsBase { verify(mActivity.mLetterboxUiController, times(refreshRequested ? 1 : 0)) .setIsRefreshAfterRotationRequested(true); - final ClientTransaction transaction = ClientTransaction.obtain( - mActivity.app.getThread(), mActivity.token); + final ClientTransaction transaction = ClientTransaction.obtain(mActivity.app.getThread()); transaction.addCallback(RefreshCallbackItem.obtain(mActivity.token, cycleThroughStop ? ON_STOP : ON_PAUSE)); transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(mActivity.token, 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 381b27b68b41..5f92fd5f12e7 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java @@ -32,6 +32,7 @@ import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_ import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT; import static android.content.pm.ActivityInfo.OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; @@ -819,6 +820,9 @@ public class LetterboxUiControllerTest extends WindowTestsBase { assertEquals(mController.overrideOrientationIfNeeded( /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED), SCREEN_ORIENTATION_PORTRAIT); + assertEquals(mController.overrideOrientationIfNeeded( + /* candidate */ SCREEN_ORIENTATION_LOCKED), SCREEN_ORIENTATION_PORTRAIT); + // unchanged if orientation is specified assertEquals(mController.overrideOrientationIfNeeded( /* candidate */ SCREEN_ORIENTATION_LANDSCAPE), SCREEN_ORIENTATION_LANDSCAPE); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java index d85d9b5729a0..2d5b72b3c680 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java @@ -111,7 +111,7 @@ public class WindowContextListenerControllerTests extends WindowTestsBase { return null; } final WindowContextInfoChangeItem infoChangeItem = (WindowContextInfoChangeItem) item; - infoChangeItem.execute(mHandler, null, null); + infoChangeItem.execute(mHandler, null /* pendingActions */); return null; }).when(mWpc).scheduleClientTransactionItem(any()); } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java index ebe40b05162d..b89182d728ec 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java @@ -330,7 +330,7 @@ public class WindowProcessControllerTests extends WindowTestsBase { ArgumentCaptor.forClass(ConfigurationChangeItem.class); verify(clientManager).scheduleTransaction(eq(thread), captor.capture()); final ClientTransactionHandler client = mock(ClientTransactionHandler.class); - captor.getValue().preExecute(client, null /* token */); + captor.getValue().preExecute(client); final ArgumentCaptor<Configuration> configCaptor = ArgumentCaptor.forClass(Configuration.class); verify(client).updatePendingConfiguration(configCaptor.capture()); diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 7db32a9f1ad9..f93c70388129 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -85,6 +85,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemProperties; +import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; @@ -452,7 +453,9 @@ public class UsageStatsService extends SystemService implements // Read pending reported events from disk and merge them with those stored in memory final LinkedList<Event> pendingEvents = new LinkedList<>(); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "loadPendingEvents"); loadPendingEventsLocked(userId, pendingEvents); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); final LinkedList<Event> eventsInMem = mReportedEvents.get(userId); if (eventsInMem != null) { pendingEvents.addAll(eventsInMem); @@ -967,6 +970,12 @@ public class UsageStatsService extends SystemService implements mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget(); return; } + + if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) { + final String traceTag = "usageStatsQueueEvent(" + userId + ") #" + + UserUsageStatsService.eventToString(event.mEventType); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, traceTag); + } synchronized (mLock) { LinkedList<Event> events = mReportedEvents.get(userId); if (events == null) { @@ -980,6 +989,7 @@ public class UsageStatsService extends SystemService implements mHandler.sendEmptyMessageDelayed(MSG_FLUSH_TO_DISK, FLUSH_INTERVAL); } } + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } /** @@ -1944,17 +1954,23 @@ public class UsageStatsService extends SystemService implements case MSG_FLUSH_TO_DISK: flushToDisk(); break; - case MSG_UNLOCKED_USER: + case MSG_UNLOCKED_USER: { + final int userId = msg.arg1; try { - onUserUnlocked(msg.arg1); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, + "usageStatsHandleUserUnlocked(" + userId + ")"); + onUserUnlocked(userId); } catch (Exception e) { - if (mUserManager.isUserUnlocked(msg.arg1)) { + if (mUserManager.isUserUnlocked(userId)) { throw e; // rethrow exception - user is unlocked } else { Slog.w(TAG, "Attempted to unlock stopped or removed user " + msg.arg1); } + } finally { + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } break; + } case MSG_REMOVE_USER: onUserRemoved(msg.arg1); break; @@ -1986,7 +2002,10 @@ public class UsageStatsService extends SystemService implements break; case MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK: { final int userId = msg.arg1; + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, + "usageStatsHandleEstimatedLaunchTimesOnUser(" + userId + ")"); handleEstimatedLaunchTimesOnUserUnlock(userId); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } break; case MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED: { diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java index 7d2e1a4ed86a..b5d8096deac0 100644 --- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java @@ -1306,7 +1306,7 @@ class UserUsageStatsService { } } - private static String eventToString(int eventType) { + static String eventToString(int eventType) { switch (eventType) { case Event.NONE: return "NONE"; diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java index faf97b57594e..de2e9527e7b8 100644 --- a/telephony/java/android/telephony/SubscriptionInfo.java +++ b/telephony/java/android/telephony/SubscriptionInfo.java @@ -18,6 +18,7 @@ package android.telephony; import static android.text.TextUtils.formatSimple; +import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; @@ -44,6 +45,7 @@ import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; +import com.android.internal.telephony.flags.Flags; import com.android.internal.telephony.util.TelephonyUtils; import com.android.telephony.Rlog; @@ -255,6 +257,11 @@ public class SubscriptionInfo implements Parcelable { private final boolean mIsGroupDisabled; /** + * Whether this subscription is used for communicating with non-terrestrial networks. + */ + private final boolean mIsNtn; + + /** * @hide * * @deprecated Use {@link SubscriptionInfo.Builder}. @@ -378,6 +385,7 @@ public class SubscriptionInfo implements Parcelable { this.mAreUiccApplicationsEnabled = areUiccApplicationsEnabled; this.mPortIndex = portIndex; this.mUsageSetting = usageSetting; + this.mIsNtn = false; } /** @@ -416,6 +424,7 @@ public class SubscriptionInfo implements Parcelable { this.mAreUiccApplicationsEnabled = builder.mAreUiccApplicationsEnabled; this.mPortIndex = builder.mPortIndex; this.mUsageSetting = builder.mUsageSetting; + this.mIsNtn = builder.mIsNtn; } /** @@ -862,6 +871,17 @@ public class SubscriptionInfo implements Parcelable { return mUsageSetting; } + /** + * Check if the subscription is exclusively for non-terrestrial networks. + * + * @return {@code true} if it is a non-terrestrial network subscription, {@code false} + * otherwise. + */ + @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) + public boolean isNtn() { + return mIsNtn; + } + @NonNull public static final Parcelable.Creator<SubscriptionInfo> CREATOR = new Parcelable.Creator<SubscriptionInfo>() { @@ -898,6 +918,7 @@ public class SubscriptionInfo implements Parcelable { UiccAccessRule.CREATOR)) .setUiccApplicationsEnabled(source.readBoolean()) .setUsageSetting(source.readInt()) + .setNtn(source.readBoolean()) .build(); } @@ -939,6 +960,7 @@ public class SubscriptionInfo implements Parcelable { dest.writeTypedArray(mCarrierConfigAccessRules, flags); dest.writeBoolean(mAreUiccApplicationsEnabled); dest.writeInt(mUsageSetting); + dest.writeBoolean(mIsNtn); } @Override @@ -1001,6 +1023,7 @@ public class SubscriptionInfo implements Parcelable { + " mType=" + SubscriptionManager.subscriptionTypeToString(mType) + " areUiccApplicationsEnabled=" + mAreUiccApplicationsEnabled + " usageSetting=" + SubscriptionManager.usageSettingToString(mUsageSetting) + + " ntn=" + mIsNtn + "]"; } @@ -1025,7 +1048,8 @@ public class SubscriptionInfo implements Parcelable { that.mCardString) && Arrays.equals(mNativeAccessRules, that.mNativeAccessRules) && Arrays.equals(mCarrierConfigAccessRules, that.mCarrierConfigAccessRules) && Objects.equals(mGroupUuid, that.mGroupUuid) - && mCountryIso.equals(that.mCountryIso) && mGroupOwner.equals(that.mGroupOwner); + && mCountryIso.equals(that.mCountryIso) && mGroupOwner.equals(that.mGroupOwner) + && mIsNtn == that.mIsNtn; } @Override @@ -1034,7 +1058,7 @@ public class SubscriptionInfo implements Parcelable { mDisplayNameSource, mIconTint, mNumber, mDataRoaming, mMcc, mMnc, mIsEmbedded, mCardString, mIsOpportunistic, mGroupUuid, mCountryIso, mCarrierId, mProfileClass, mType, mGroupOwner, mAreUiccApplicationsEnabled, mPortIndex, mUsageSetting, mCardId, - mIsGroupDisabled); + mIsGroupDisabled, mIsNtn); result = 31 * result + Arrays.hashCode(mEhplmns); result = 31 * result + Arrays.hashCode(mHplmns); result = 31 * result + Arrays.hashCode(mNativeAccessRules); @@ -1234,6 +1258,11 @@ public class SubscriptionInfo implements Parcelable { private int mUsageSetting = SubscriptionManager.USAGE_SETTING_UNKNOWN; /** + * {@code true} if it is a non-terrestrial network subscription, {@code false} otherwise. + */ + private boolean mIsNtn = false; + + /** * Default constructor. */ public Builder() { @@ -1275,6 +1304,7 @@ public class SubscriptionInfo implements Parcelable { mAreUiccApplicationsEnabled = info.mAreUiccApplicationsEnabled; mPortIndex = info.mPortIndex; mUsageSetting = info.mUsageSetting; + mIsNtn = info.mIsNtn; } /** @@ -1660,6 +1690,18 @@ public class SubscriptionInfo implements Parcelable { } /** + * Set whether the subscription is exclusively used for non-terrestrial networks or not. + * + * @param isNtn {@code true} if the subscription is for NTN, {@code false} otherwise. + * @return The builder. + */ + @NonNull + public Builder setNtn(boolean isNtn) { + mIsNtn = isNtn; + return this; + } + + /** * Build the {@link SubscriptionInfo}. * * @return The {@link SubscriptionInfo} instance. diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 6d9c1e6f052e..29149b95e471 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -1117,6 +1117,14 @@ public class SubscriptionManager { public static final String SATELLITE_ATTACH_ENABLED_FOR_CARRIER = SimInfo.COLUMN_SATELLITE_ATTACH_ENABLED_FOR_CARRIER; + /** + * TelephonyProvider column name to identify eSIM profile of a non-terrestrial network. + * By default, it's disabled. + * <P>Type: INTEGER (int)</P> + * @hide + */ + public static final String IS_NTN = SimInfo.COLUMN_IS_NTN; + /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"USAGE_SETTING_"}, diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java index 6130af5abdfa..a4527f12a199 100644 --- a/telephony/java/android/telephony/satellite/SatelliteManager.java +++ b/telephony/java/android/telephony/satellite/SatelliteManager.java @@ -724,6 +724,17 @@ public final class SatelliteManager { */ public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED = 7; /** + * A transition state indicating that Telephony is waiting for satellite modem to connect to a + * satellite network before sending a datagram or polling for datagrams. If the satellite modem + * successfully connects to a satellite network, either + * {@link #SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING} or + * {@link #SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING} will be sent. Otherwise, + * either {@link #SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED} or + * {@link #SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED} will be sent. + */ + @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) + public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_WAITING_TO_CONNECT = 8; + /** * The datagram transfer state is unknown. This generic datagram transfer state should be used * only when the datagram transfer state cannot be mapped to other specific datagram transfer * states. @@ -740,6 +751,7 @@ public final class SatelliteManager { SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_SUCCESS, SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_NONE, SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED, + SATELLITE_DATAGRAM_TRANSFER_STATE_WAITING_TO_CONNECT, SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN }) @Retention(RetentionPolicy.SOURCE) diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl index 21a6b447d6a4..a5a23e8659d8 100644 --- a/telephony/java/com/android/internal/telephony/ISub.aidl +++ b/telephony/java/com/android/internal/telephony/ISub.aidl @@ -323,49 +323,49 @@ interface ISub { */ UserHandle getSubscriptionUserHandle(int subId); - /** - * Check if subscription and user are associated with each other. - * - * @param subscriptionId the subId of the subscription - * @param userHandle user handle of the user - * @return {@code true} if subscription is associated with user - * {code true} if there are no subscriptions on device - * else {@code false} if subscription is not associated with user. - * - * @throws IllegalArgumentException if subscription is invalid. - * @throws SecurityException if the caller doesn't have permissions required. - * @throws IllegalStateException if subscription service is not available. - * - * @hide - */ - boolean isSubscriptionAssociatedWithUser(int subscriptionId, in UserHandle userHandle); - - /** - * Get list of subscriptions associated with user. - * - * @param userHandle user handle of the user - * @return list of subscriptionInfo associated with the user. - * - * @throws SecurityException if the caller doesn't have permissions required. - * @throws IllegalStateException if subscription service is not available. - * - * @hide - */ - List<SubscriptionInfo> getSubscriptionInfoListAssociatedWithUser(in UserHandle userHandle); - - /** - * Called during setup wizard restore flow to attempt to restore the backed up sim-specific - * configs to device for all existing SIMs in the subscription database - * {@link Telephony.SimInfo}. Internally, it will store the backup data in an internal file. - * This file will persist on device for device's lifetime and will be used later on when a SIM - * is inserted to restore that specific SIM's settings. End result is subscription database is - * modified to match any backed up configs for the appropriate inserted SIMs. - * - * <p> - * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any - * {@link Telephony.SimInfo} entry is updated as the result of this method call. - * - * @param data with the sim specific configs to be backed up. - */ - void restoreAllSimSpecificSettingsFromBackup(in byte[] data); + /** + * Check if subscription and user are associated with each other. + * + * @param subscriptionId the subId of the subscription + * @param userHandle user handle of the user + * @return {@code true} if subscription is associated with user + * {code true} if there are no subscriptions on device + * else {@code false} if subscription is not associated with user. + * + * @throws IllegalArgumentException if subscription is invalid. + * @throws SecurityException if the caller doesn't have permissions required. + * @throws IllegalStateException if subscription service is not available. + * + * @hide + */ + boolean isSubscriptionAssociatedWithUser(int subscriptionId, in UserHandle userHandle); + + /** + * Get list of subscriptions associated with user. + * + * @param userHandle user handle of the user + * @return list of subscriptionInfo associated with the user. + * + * @throws SecurityException if the caller doesn't have permissions required. + * @throws IllegalStateException if subscription service is not available. + * + * @hide + */ + List<SubscriptionInfo> getSubscriptionInfoListAssociatedWithUser(in UserHandle userHandle); + + /** + * Called during setup wizard restore flow to attempt to restore the backed up sim-specific + * configs to device for all existing SIMs in the subscription database + * {@link Telephony.SimInfo}. Internally, it will store the backup data in an internal file. + * This file will persist on device for device's lifetime and will be used later on when a SIM + * is inserted to restore that specific SIM's settings. End result is subscription database is + * modified to match any backed up configs for the appropriate inserted SIMs. + * + * <p> + * The {@link Uri} {@link #SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI} is notified if any + * {@link Telephony.SimInfo} entry is updated as the result of this method call. + * + * @param data with the sim specific configs to be backed up. + */ + void restoreAllSimSpecificSettingsFromBackup(in byte[] data); } diff --git a/tests/CompanionDeviceMultiDeviceTests/host/cdm_base_test.py b/tests/CompanionDeviceMultiDeviceTests/host/cdm_base_test.py index bb10658c25c3..e74a30c62d8b 100644 --- a/tests/CompanionDeviceMultiDeviceTests/host/cdm_base_test.py +++ b/tests/CompanionDeviceMultiDeviceTests/host/cdm_base_test.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # Lint as: python3 """ Base class for setting up devices for CDM functionalities. diff --git a/tests/CompanionDeviceMultiDeviceTests/host/cdm_transport_test.py b/tests/CompanionDeviceMultiDeviceTests/host/cdm_transport_test.py index 5516c0f8e09f..bf7e1f3c90c7 100644 --- a/tests/CompanionDeviceMultiDeviceTests/host/cdm_transport_test.py +++ b/tests/CompanionDeviceMultiDeviceTests/host/cdm_transport_test.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # Lint as: python3 """ Test E2E CDM functions on mobly. diff --git a/tests/CtsSurfaceControlTestsStaging/Android.bp b/tests/CtsSurfaceControlTestsStaging/Android.bp index 3272cef2eb79..680952157fdc 100644 --- a/tests/CtsSurfaceControlTestsStaging/Android.bp +++ b/tests/CtsSurfaceControlTestsStaging/Android.bp @@ -36,6 +36,7 @@ android_test { "androidx.test.rules", "compatibility-device-util-axt", "com.google.android.material_material", + "SurfaceFlingerProperties", "truth-prebuilt", ], resource_dirs: ["src/main/res"], diff --git a/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/GraphicsActivity.java b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/GraphicsActivity.java index 4b12053af5c7..79348d104745 100644 --- a/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/GraphicsActivity.java +++ b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/GraphicsActivity.java @@ -30,6 +30,7 @@ import android.hardware.display.DisplayManager; import android.os.Bundle; import android.os.Handler; import android.os.Looper; +import android.sysprop.SurfaceFlingerProperties; import android.util.Log; import android.view.Display; import android.view.Surface; @@ -45,6 +46,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; /** * An Activity to help with frame rate testing. @@ -217,6 +219,27 @@ public class GraphicsActivity extends Activity { postBuffer(); } + Surface getSurface() { + return mSurface; + } + + SurfaceControl getSurfaceControl() { + return mSurfaceControl; + } + + public int setFrameRate(float frameRate) { + Log.i(TAG, + String.format("Setting frame rate for %s: frameRate=%.2f", mName, frameRate)); + + int rc = 0; + try (SurfaceControl.Transaction transaction = new SurfaceControl.Transaction()) { + transaction.setFrameRate( + mSurfaceControl, frameRate, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT); + transaction.apply(); + } + return rc; + } + public int setFrameRateCategory(int category) { Log.i(TAG, String.format( @@ -230,6 +253,19 @@ public class GraphicsActivity extends Activity { return rc; } + public int setFrameRateSelectionStrategy(int strategy) { + Log.i(TAG, + String.format("Setting frame rate selection strategy for %s: strategy=%d", + mName, strategy)); + + int rc = 0; + try (SurfaceControl.Transaction transaction = new SurfaceControl.Transaction()) { + transaction.setFrameRateSelectionStrategy(mSurfaceControl, strategy); + transaction.apply(); + } + return rc; + } + public void setVisibility(boolean visible) { Log.i(TAG, String.format("Setting visibility for %s: %s", mName, @@ -342,6 +378,11 @@ public class GraphicsActivity extends Activity { uniqueFrameRates.add(frameRate); } } + Log.i(TAG, + "**** Available display refresh rates: " + + uniqueFrameRates.stream() + .map(Object::toString) + .collect(Collectors.joining(", "))); return uniqueFrameRates; } @@ -358,6 +399,10 @@ public class GraphicsActivity extends Activity { <= FRAME_RATE_TOLERANCE; } + private boolean frameRateEquals(float frameRate1, float frameRate2) { + return Math.abs(frameRate1 - frameRate2) <= FRAME_RATE_TOLERANCE; + } + // Waits until our SurfaceHolder has a surface and the activity is resumed. private void waitForPreconditions() throws InterruptedException { assertNotSame( @@ -447,9 +492,22 @@ public class GraphicsActivity extends Activity { verifyCompatibleAndStableFrameRate(0, surfaces); } - // Set expectedFrameRate to 0.0 to verify only stable frame rate. + private void verifyExactAndStableFrameRate( + float expectedFrameRate, + TestSurface... surfaces) throws InterruptedException { + verifyFrameRate(expectedFrameRate, false, surfaces); + } + private void verifyCompatibleAndStableFrameRate( - float expectedFrameRate, TestSurface... surfaces) throws InterruptedException { + float expectedFrameRate, + TestSurface... surfaces) throws InterruptedException { + verifyFrameRate(expectedFrameRate, true, surfaces); + } + + // Set expectedFrameRate to 0.0 to verify only stable frame rate. + private void verifyFrameRate( + float expectedFrameRate, boolean multiplesAllowed, + TestSurface... surfaces) throws InterruptedException { Log.i(TAG, "Verifying compatible and stable frame rate"); long nowNanos = System.nanoTime(); long gracePeriodEndTimeNanos = @@ -457,9 +515,19 @@ public class GraphicsActivity extends Activity { while (true) { if (expectedFrameRate > FRAME_RATE_TOLERANCE) { // expectedFrameRate > 0 // Wait until we switch to a compatible frame rate. - while (!isFrameRateMultiple(mDeviceFrameRate, expectedFrameRate) - && !waitForEvents(gracePeriodEndTimeNanos, surfaces)) { - // Empty + Log.i(TAG, + "Verifying expected frame rate: actual (device)=" + mDeviceFrameRate + + " expected=" + expectedFrameRate); + if (multiplesAllowed) { + while (!isFrameRateMultiple(mDeviceFrameRate, expectedFrameRate) + && !waitForEvents(gracePeriodEndTimeNanos, surfaces)) { + // Empty + } + } else { + while (!frameRateEquals(mDeviceFrameRate, expectedFrameRate) + && !waitForEvents(gracePeriodEndTimeNanos, surfaces)) { + // Empty + } } nowNanos = System.nanoTime(); if (nowNanos >= gracePeriodEndTimeNanos) { @@ -604,12 +672,65 @@ public class GraphicsActivity extends Activity { "frame rate category=" + category); } + private void testSurfaceControlFrameRateSelectionStrategyInternal(int parentStrategy) + throws InterruptedException { + Log.i(TAG, + "**** Running testSurfaceControlFrameRateSelectionStrategy for strategy " + + parentStrategy); + TestSurface parent = null; + TestSurface child = null; + try { + parent = new TestSurface(mSurfaceView.getSurfaceControl(), mSurface, + "testSurfaceParent", mSurfaceView.getHolder().getSurfaceFrame(), + /*visible=*/true, Color.RED); + child = new TestSurface(parent.getSurfaceControl(), parent.getSurface(), + "testSurfaceChild", mSurfaceView.getHolder().getSurfaceFrame(), + /*visible=*/true, Color.BLUE); + + // Test + Display display = getDisplay(); + List<Float> frameRates = getRefreshRates(display.getMode(), display); + assumeTrue("**** SKIPPED due to frame rate override disabled", + SurfaceFlingerProperties.enable_frame_rate_override().orElse(true)); + float childFrameRate = Collections.max(frameRates); + float parentFrameRate = childFrameRate / 2; + int initialNumEvents = mModeChangedEvents.size(); + parent.setFrameRate(parentFrameRate); + parent.setFrameRateSelectionStrategy(parentStrategy); + child.setFrameRate(childFrameRate); + + // Verify + float expectedFrameRate = + parentStrategy == SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN + ? parentFrameRate + : childFrameRate; + verifyExactAndStableFrameRate(expectedFrameRate, parent, child); + verifyModeSwitchesDontChangeResolution(initialNumEvents, mModeChangedEvents.size()); + } finally { + if (parent != null) { + parent.release(); + } + if (child != null) { + child.release(); + } + } + } + + public void testSurfaceControlFrameRateSelectionStrategy(int parentStrategy) + throws InterruptedException { + runTestsWithPreconditions( + () -> testSurfaceControlFrameRateSelectionStrategyInternal(parentStrategy), + "frame rate strategy=" + parentStrategy); + } + private float getExpectedFrameRate(int category) { Display display = getDisplay(); List<Float> frameRates = getRefreshRates(display.getMode(), display); - if (category == Surface.FRAME_RATE_CATEGORY_DEFAULT - || category == Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE) { + if (category == Surface.FRAME_RATE_CATEGORY_DEFAULT) { + // Max due to default vote and no other frame rate specifications. + return Collections.max(frameRates); + } else if (category == Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE) { return Collections.min(frameRates); } diff --git a/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlTest.java b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlTest.java index ccbda7f2fdf0..bed9cff75e1d 100644 --- a/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlTest.java +++ b/tests/CtsSurfaceControlTestsStaging/src/main/java/android/view/surfacecontroltests/SurfaceControlTest.java @@ -23,11 +23,14 @@ import android.hardware.display.DisplayManager; import android.os.SystemProperties; import android.support.test.uiautomator.UiDevice; import android.view.Surface; +import android.view.SurfaceControl; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.rule.ActivityTestRule; +import com.android.compatibility.common.util.DisplayUtil; + import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -59,19 +62,15 @@ public class SurfaceControlTest { uiDevice.executeShellCommand("wm dismiss-keyguard"); InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity( - Manifest.permission.LOG_COMPAT_CHANGE, - Manifest.permission.READ_COMPAT_CHANGE_CONFIG, Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE, - Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS, - Manifest.permission.MANAGE_GAME_MODE); + Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS); // Prevent DisplayManager from limiting the allowed refresh rate range based on // non-app policies (e.g. low battery, user settings, etc). mDisplayManager = activity.getSystemService(DisplayManager.class); mDisplayManager.setShouldAlwaysRespectAppRequestedMode(true); - mInitialRefreshRateSwitchingType = - toSwitchingType(mDisplayManager.getMatchContentFrameRateUserPreference()); + mInitialRefreshRateSwitchingType = DisplayUtil.getRefreshRateSwitchingType(mDisplayManager); mDisplayManager.setRefreshRateSwitchingType( DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS); } @@ -118,16 +117,18 @@ public class SurfaceControlTest { activity.testSurfaceControlFrameRateCategory(Surface.FRAME_RATE_CATEGORY_DEFAULT); } - private int toSwitchingType(int matchContentFrameRateUserPreference) { - switch (matchContentFrameRateUserPreference) { - case DisplayManager.MATCH_CONTENT_FRAMERATE_NEVER: - return DisplayManager.SWITCHING_TYPE_NONE; - case DisplayManager.MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY: - return DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS; - case DisplayManager.MATCH_CONTENT_FRAMERATE_ALWAYS: - return DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS; - default: - return -1; - } + @Test + public void testSurfaceControlFrameRateSelectionStrategySelf() throws InterruptedException { + GraphicsActivity activity = mActivityRule.getActivity(); + activity.testSurfaceControlFrameRateSelectionStrategy( + SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_SELF); + } + + @Test + public void testSurfaceControlFrameRateSelectionStrategyOverrideChildren() + throws InterruptedException { + GraphicsActivity activity = mActivityRule.getActivity(); + activity.testSurfaceControlFrameRateSelectionStrategy( + SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN); } } diff --git a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml index f867c989232d..9198ae184b18 100644 --- a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml +++ b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml @@ -102,6 +102,20 @@ <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> + <activity android:name=".PortraitImmersiveActivity" + android:taskAffinity="com.android.server.wm.flicker.testapp.PortraitImmersiveActivity" + android:immersive="true" + android:resizeableActivity="true" + android:screenOrientation="portrait" + android:theme="@android:style/Theme.NoTitleBar" + android:configChanges="screenSize" + android:label="PortraitImmersiveActivity" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> + </activity> <activity android:name=".LaunchTransparentActivity" android:resizeableActivity="false" android:screenOrientation="portrait" diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java index 7c5e9a3f86b5..8b334c0a8588 100644 --- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java +++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java @@ -73,6 +73,12 @@ public class ActivityOptions { FLICKER_APP_PACKAGE + ".NonResizeablePortraitActivity"); } + public static class PortraitImmersiveActivity { + public static final String LABEL = "PortraitImmersiveActivity"; + public static final ComponentName COMPONENT = new ComponentName(FLICKER_APP_PACKAGE, + FLICKER_APP_PACKAGE + ".PortraitImmersiveActivity"); + } + public static class TransparentActivity { public static final String LABEL = "TransparentActivity"; public static final ComponentName COMPONENT = new ComponentName(FLICKER_APP_PACKAGE, diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PortraitImmersiveActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PortraitImmersiveActivity.java new file mode 100644 index 000000000000..0a7f81cba747 --- /dev/null +++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PortraitImmersiveActivity.java @@ -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. + */ + +package com.android.server.wm.flicker.testapp; + +public class PortraitImmersiveActivity extends GameActivity { +} diff --git a/tools/lint/fix/Android.bp b/tools/lint/fix/Android.bp index 43f21221ae5a..ddacf57c3a3e 100644 --- a/tools/lint/fix/Android.bp +++ b/tools/lint/fix/Android.bp @@ -25,6 +25,11 @@ python_binary_host { name: "lint_fix", main: "soong_lint_fix.py", srcs: ["soong_lint_fix.py"], + version: { + py3: { + embedded_launcher: true, + }, + }, } python_library_host { diff --git a/tools/lint/fix/soong_lint_fix.py b/tools/lint/fix/soong_lint_fix.py index b42f9eec99d0..4a2e37e51d71 100644 --- a/tools/lint/fix/soong_lint_fix.py +++ b/tools/lint/fix/soong_lint_fix.py @@ -213,5 +213,5 @@ def _setup_parser(): if __name__ == "__main__": opts = SoongLintFixOptions() - opts.parse_args(sys.argv) + opts.parse_args() SoongLintFix(opts).run() diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java index bc41829f16d2..71ac94ba2ee4 100644 --- a/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java +++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java @@ -334,6 +334,7 @@ public class SharedConnectivityManager { if (mServiceConnection != null) { mContext.unbindService(mServiceConnection); mServiceConnection = null; + mService = null; } } |